mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-19 19:46:51 +00:00
Compare commits
423 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccc96c8725 | ||
|
|
4faf76794d | ||
|
|
56570ec604 | ||
|
|
4047f135f7 | ||
|
|
690cbe3ad3 | ||
|
|
04e76ed506 | ||
|
|
d22f807084 | ||
|
|
75440856af | ||
|
|
c614b92c5f | ||
|
|
84e3db30f1 | ||
|
|
50b5fc7545 | ||
|
|
f36c01abf6 | ||
|
|
d259771ce9 | ||
|
|
9fd0b096bd | ||
|
|
1bbc765028 | ||
|
|
a232722f64 | ||
|
|
2c1ffa929c | ||
|
|
2b66d270c0 | ||
|
|
0e19232f45 | ||
|
|
f4d9e8e520 | ||
|
|
d0041334fa | ||
|
|
3b68d8a94e | ||
|
|
fc8e22b82e | ||
|
|
6caae9e886 | ||
|
|
d145d3a8ec | ||
|
|
d4e9c0afdc | ||
|
|
e0cdf4ff49 | ||
|
|
a4bb697787 | ||
|
|
3e2f81d640 | ||
|
|
768c56400c | ||
|
|
af314cbbdf | ||
|
|
17a3d23d68 | ||
|
|
e3be519b25 | ||
|
|
51ad8f8065 | ||
|
|
960b829ece | ||
|
|
23999c96bf | ||
|
|
3b3ba70670 | ||
|
|
690118c2bd | ||
|
|
3bee9cb951 | ||
|
|
abe76ccf0f | ||
|
|
ed4f61acd7 | ||
|
|
007b8cd888 | ||
|
|
1f63bb15eb | ||
|
|
9027f8b604 | ||
|
|
c4317c5707 | ||
|
|
a0835eae54 | ||
|
|
2556921110 | ||
|
|
fcbe42f080 | ||
|
|
b6f6407c31 | ||
|
|
82ec04552c | ||
|
|
fe62a0a2a7 | ||
|
|
ba6ebdee15 | ||
|
|
ede966f2d1 | ||
|
|
74d93e324c | ||
|
|
37b3f7aa3f | ||
|
|
9921e9c72b | ||
|
|
6edb80ea29 | ||
|
|
15b386bce3 | ||
|
|
225edbf745 | ||
|
|
e8fb5d39a1 | ||
|
|
3544b7de7a | ||
|
|
e3f56556cf | ||
|
|
8e0a84a502 | ||
|
|
90f1e3a80d | ||
|
|
82e38b0156 | ||
|
|
640aa11f3b | ||
|
|
b939a292df | ||
|
|
099ef5d358 | ||
|
|
6de0682439 | ||
|
|
efcf71fd2b | ||
|
|
acf7c0c4d8 | ||
|
|
443b180f32 | ||
|
|
3222d4980d | ||
|
|
e246eed99d | ||
|
|
b69d61dd77 | ||
|
|
2d76c2730a | ||
|
|
6b364dc420 | ||
|
|
d5b20d5446 | ||
|
|
05c001807e | ||
|
|
011da05712 | ||
|
|
2e96982e60 | ||
|
|
6abe0b375c | ||
|
|
dc6be6f06b | ||
|
|
47e2976fd1 | ||
|
|
38ce9eb0c4 | ||
|
|
3b52b173e8 | ||
|
|
b8ccee5f30 | ||
|
|
0cfe7fdc45 | ||
|
|
42ff2307fa | ||
|
|
b25e7fcb89 | ||
|
|
79aebed40e | ||
|
|
f5c08baabb | ||
|
|
a883b2cf63 | ||
|
|
398d4b2612 | ||
|
|
4a7c0e8297 | ||
|
|
67df6728f6 | ||
|
|
0178cd7530 | ||
|
|
cb92231835 | ||
|
|
6e8fd3c3f8 | ||
|
|
6451ef173c | ||
|
|
7af5e8931f | ||
|
|
9045cc7d65 | ||
|
|
5ff8436c1a | ||
|
|
a5ccaf9595 | ||
|
|
423c140670 | ||
|
|
e8ef183623 | ||
|
|
000e2c07f8 | ||
|
|
c1c69b00b4 | ||
|
|
d5edf03042 | ||
|
|
305ac037fe | ||
|
|
23910dbab4 | ||
|
|
632f4228f0 | ||
|
|
1268cb565c | ||
|
|
c55e47f6af | ||
|
|
03fc63ad14 | ||
|
|
a124141537 | ||
|
|
0fabb5bc2f | ||
|
|
1fff81c214 | ||
|
|
67264c047f | ||
|
|
34eaf6f0f2 | ||
|
|
8405a7672d | ||
|
|
66a3246a23 | ||
|
|
34482f6710 | ||
|
|
f550d1e9f3 | ||
|
|
d99e598e7a | ||
|
|
eb59b691d8 | ||
|
|
d5d76d9b9a | ||
|
|
3c933befbb | ||
|
|
fc4a40ec8b | ||
|
|
d197b81351 | ||
|
|
b1f619a90a | ||
|
|
f70c1f0644 | ||
|
|
b23530be4c | ||
|
|
1fe74c9690 | ||
|
|
5d39155519 | ||
|
|
dfe83e5c51 | ||
|
|
e7166ba5d4 | ||
|
|
b6c9d4d6a9 | ||
|
|
0c92a594f4 | ||
|
|
4dacdb180f | ||
|
|
c1ad4243bb | ||
|
|
66934af579 | ||
|
|
9f3ddfc88b | ||
|
|
466f7030c6 | ||
|
|
7d38bec26d | ||
|
|
67d7d225cc | ||
|
|
24edad15ae | ||
|
|
6d56a0791f | ||
|
|
cd1d77c572 | ||
|
|
69690f1e37 | ||
|
|
2dddd625a1 | ||
|
|
d66b6f7192 | ||
|
|
ba592c1ca3 | ||
|
|
0ede0acc6a | ||
|
|
5b676e8f93 | ||
|
|
5d91f5f398 | ||
|
|
62959cc883 | ||
|
|
bab4b404f4 | ||
|
|
5ecd24d66a | ||
|
|
db373a826b | ||
|
|
80ae211b72 | ||
|
|
99a4be134b | ||
|
|
1ddfd2a4f7 | ||
|
|
d972f6e041 | ||
|
|
cf756c5774 | ||
|
|
4252bd0bb1 | ||
|
|
cb6e626193 | ||
|
|
77c384633b | ||
|
|
64de303b59 | ||
|
|
88cae21ab4 | ||
|
|
66e4986944 | ||
|
|
b3e08b47b9 | ||
|
|
85508f45b4 | ||
|
|
f07cc32be0 | ||
|
|
2c43522bf9 | ||
|
|
adf35f8e18 | ||
|
|
04ff4fa47c | ||
|
|
0d30e3359f | ||
|
|
b1bfac5144 | ||
|
|
30e2be13f0 | ||
|
|
dc1cdf4254 | ||
|
|
c4bd9208ce | ||
|
|
01f8aff3e0 | ||
|
|
60f3ebca62 | ||
|
|
0db7df6c14 | ||
|
|
74a8b3038a | ||
|
|
de1d4fa4eb | ||
|
|
07fd5cb29c | ||
|
|
ee7da14019 | ||
|
|
e5adbf1f08 | ||
|
|
7f9179193e | ||
|
|
3be0e1c13a | ||
|
|
18c020535a | ||
|
|
8d1fcc06fd | ||
|
|
2b6a72ffb4 | ||
|
|
157d86c94f | ||
|
|
d41de06809 | ||
|
|
d730f21dc7 | ||
|
|
49dfaa20ab | ||
|
|
bfeb892cab | ||
|
|
4b56422abd | ||
|
|
53e3e2b66d | ||
|
|
834140f0a2 | ||
|
|
0d95d83ef9 | ||
|
|
54d373c963 | ||
|
|
1dfd68c691 | ||
|
|
df9213e812 | ||
|
|
03a078a3a0 | ||
|
|
11da025247 | ||
|
|
07a9da901f | ||
|
|
4ac3853be9 | ||
|
|
eae7a9978c | ||
|
|
bdd8572fbf | ||
|
|
07422dac29 | ||
|
|
088ae496cc | ||
|
|
c83a619082 | ||
|
|
ca7d1b111a | ||
|
|
3c507c1727 | ||
|
|
b111d24488 | ||
|
|
4dc8b44e81 | ||
|
|
27a9ad7bcb | ||
|
|
fbd4d512d5 | ||
|
|
0f85db6d36 | ||
|
|
0f78b5b315 | ||
|
|
78e3bb1acd | ||
|
|
c5e1c057ae | ||
|
|
f34a3c3c02 | ||
|
|
546a32e97a | ||
|
|
abd269949d | ||
|
|
0d5f76b19e | ||
|
|
bfa77baae1 | ||
|
|
a2a1aac384 | ||
|
|
43ede7ba26 | ||
|
|
bb8535cb3a | ||
|
|
883e9fdf62 | ||
|
|
c625766af1 | ||
|
|
23730ab28f | ||
|
|
0c8bfea2f7 | ||
|
|
0306732a3d | ||
|
|
6842cbfda4 | ||
|
|
ecb4cb31ad | ||
|
|
dd47430f19 | ||
|
|
74f27544f7 | ||
|
|
5868765087 | ||
|
|
545d64a2e5 | ||
|
|
c69dee4c96 | ||
|
|
b367001b95 | ||
|
|
120fc4ca42 | ||
|
|
e4756a523a | ||
|
|
46843a5efa | ||
|
|
6377736f43 | ||
|
|
afe97bcc96 | ||
|
|
8af6fedf8a | ||
|
|
d8042b25e4 | ||
|
|
f97e71d054 | ||
|
|
d066f0b94d | ||
|
|
e9d389e4f1 | ||
|
|
e90403dbbe | ||
|
|
3dc3581e6b | ||
|
|
ff82f70e9a | ||
|
|
560f462f7b | ||
|
|
23b2b5ba56 | ||
|
|
11cb8cbbdc | ||
|
|
41799b2663 | ||
|
|
2f842bcbdd | ||
|
|
336a8b5825 | ||
|
|
d2f54f5bd2 | ||
|
|
8c81c14c8d | ||
|
|
1f6d872fa5 | ||
|
|
ae1b9b8dd5 | ||
|
|
1e1706d371 | ||
|
|
5ccaa521cf | ||
|
|
90bb9870ab | ||
|
|
70ac719725 | ||
|
|
08d540a761 | ||
|
|
304a3804bc | ||
|
|
f7726e552a | ||
|
|
a1ac4e85ed | ||
|
|
f8e5370b0b | ||
|
|
fb560089b9 | ||
|
|
341f6c9f62 | ||
|
|
b2e97fe1d2 | ||
|
|
e73584fef7 | ||
|
|
45ad4bbcf1 | ||
|
|
096847ea07 | ||
|
|
faf6a37c9f | ||
|
|
d4ec1bda54 | ||
|
|
325b97b683 | ||
|
|
7ab065e8cd | ||
|
|
aea0670268 | ||
|
|
5560a99423 | ||
|
|
0c4e191f3b | ||
|
|
cb914e4729 | ||
|
|
ab027d6af6 | ||
|
|
6a8ee544e8 | ||
|
|
2bb38619ea | ||
|
|
4b352da402 | ||
|
|
75243b8e6a | ||
|
|
7df2915fbd | ||
|
|
6427a3846b | ||
|
|
5169ee91ea | ||
|
|
5917accdd2 | ||
|
|
4a5cb7f628 | ||
|
|
5dd24623f7 | ||
|
|
befb6f632f | ||
|
|
92e0f8349c | ||
|
|
ffbba01c41 | ||
|
|
5f9679655c | ||
|
|
6ded80d2c6 | ||
|
|
eb3c33b091 | ||
|
|
794216713a | ||
|
|
a2862e604c | ||
|
|
8429da3d2a | ||
|
|
381b0e78d5 | ||
|
|
2e63cd8116 | ||
|
|
52e0d84238 | ||
|
|
5725535715 | ||
|
|
05ed98aa0c | ||
|
|
fd021d4778 | ||
|
|
2b9f9fce86 | ||
|
|
81aac442f2 | ||
|
|
16e3af9b49 | ||
|
|
227bdd7d4c | ||
|
|
471a7903f6 | ||
|
|
37177e7207 | ||
|
|
5805104d13 | ||
|
|
e686a4f627 | ||
|
|
c7f80d86a8 | ||
|
|
19187583e1 | ||
|
|
f2c3b096a0 | ||
|
|
816d752dc8 | ||
|
|
0a880a2bf3 | ||
|
|
d6b3b0a3d3 | ||
|
|
ca38948e21 | ||
|
|
fe67c01e57 | ||
|
|
37053239c0 | ||
|
|
2bb5a4b11f | ||
|
|
cea3ee4ef9 | ||
|
|
90db52e5f5 | ||
|
|
3f020ec855 | ||
|
|
b1896733ca | ||
|
|
3d2155b60e | ||
|
|
a949422ac9 | ||
|
|
0243e5cbb8 | ||
|
|
0b12b398ba | ||
|
|
122577b11b | ||
|
|
ebdbfe0027 | ||
|
|
b680697af6 | ||
|
|
2e248744c0 | ||
|
|
82a6befce7 | ||
|
|
ccef65039a | ||
|
|
e4a670da5a | ||
|
|
c930b2ee60 | ||
|
|
4932e1dcb5 | ||
|
|
536281ec80 | ||
|
|
367cee593f | ||
|
|
99cf23df26 | ||
|
|
f49d4592a0 | ||
|
|
7f27544acb | ||
|
|
2aac44d95e | ||
|
|
8f921b8b08 | ||
|
|
dfe485b079 | ||
|
|
ad9096b5a8 | ||
|
|
b265fbf9a0 | ||
|
|
e60a513c88 | ||
|
|
1f8e731594 | ||
|
|
d69ef31bf9 | ||
|
|
9ae7c5efbc | ||
|
|
902bbf7dc4 | ||
|
|
d29ef0d7b1 | ||
|
|
f29f525d90 | ||
|
|
d2a3d9049f | ||
|
|
d308e20871 | ||
|
|
0cd6c53e0d | ||
|
|
5475b79cde | ||
|
|
8e24c655b0 | ||
|
|
bb5452ad26 | ||
|
|
ed6b7f1ab4 | ||
|
|
85b8e9b51f | ||
|
|
4453123944 | ||
|
|
3239c893ba | ||
|
|
17a0063b40 | ||
|
|
122ba385f7 | ||
|
|
75dc7af0ed | ||
|
|
cb15e28cef | ||
|
|
cbefa5f882 | ||
|
|
231f01dad2 | ||
|
|
c14ccdc21c | ||
|
|
fcf70c242e | ||
|
|
a0476be2c9 | ||
|
|
24a5407c8f | ||
|
|
66da72ccc2 | ||
|
|
6a342ae368 | ||
|
|
dd851edbdc | ||
|
|
e485a4a8ef | ||
|
|
026942dd72 | ||
|
|
237ebd6ec4 | ||
|
|
a4d6e69309 | ||
|
|
29e04dd8c8 | ||
|
|
5a8e271037 | ||
|
|
43e41f4980 | ||
|
|
fd5e0fd60f | ||
|
|
de000228cf | ||
|
|
a2de86c23e | ||
|
|
00c4a28d22 | ||
|
|
8e10f7af0e | ||
|
|
135a311c05 | ||
|
|
13bb5aa8dd | ||
|
|
a476416dc4 | ||
|
|
19768e1398 | ||
|
|
7c2d77a3ee | ||
|
|
2560757ea2 | ||
|
|
e290c128bf | ||
|
|
95a73704a2 | ||
|
|
b843b871f6 | ||
|
|
925676f136 | ||
|
|
d3f41f14c7 | ||
|
|
045ce73c83 | ||
|
|
932d000c9d | ||
|
|
84285ff985 | ||
|
|
8b06a735ac | ||
|
|
153ec268b7 | ||
|
|
92eaf5fbaa |
5
.github/codecov.yml
vendored
Normal file
5
.github/codecov.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
informational: true
|
||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -322,4 +322,4 @@ jobs:
|
||||
run: bundle exec rspec --profile --pattern "engines/*/spec/{,/*/**}/*_spec.rb,spec/features/admin/*/*_spec.rb,spec/lib/{,/*/**}/*_spec.rb"
|
||||
|
||||
- name: Codecov
|
||||
uses: codecov/codecov-action@v1.3.1
|
||||
uses: codecov/codecov-action@v1.5.0
|
||||
|
||||
@@ -1 +1 @@
|
||||
5.12.0
|
||||
14.16.1
|
||||
|
||||
@@ -334,7 +334,6 @@ Layout/LineLength:
|
||||
- spec/services/variant_units/option_value_namer_spec.rb
|
||||
- spec/spec_helper.rb
|
||||
- spec/support/cancan_helper.rb
|
||||
- spec/support/delayed_job_helper.rb
|
||||
- spec/support/matchers/delegate_matchers.rb
|
||||
- spec/support/matchers/select2_matchers.rb
|
||||
- spec/support/matchers/table_matchers.rb
|
||||
@@ -549,7 +548,6 @@ Metrics/BlockLength:
|
||||
- spec/models/tag_rule/discount_order_spec.rb
|
||||
- spec/requests/api/orders_spec.rb
|
||||
- spec/spec_helper.rb
|
||||
- spec/support/delayed_job_helper.rb
|
||||
- spec/support/matchers/select2_matchers.rb
|
||||
- spec/support/matchers/table_matchers.rb
|
||||
- spec/swagger_helper.rb
|
||||
|
||||
@@ -781,7 +781,6 @@ Style/ClassEqualityComparison:
|
||||
- 'app/controllers/spree/admin/payments_controller.rb'
|
||||
- 'app/models/tag_rule/discount_order.rb'
|
||||
- 'spec/lib/open_food_network/group_buy_report_spec.rb'
|
||||
- 'spec/support/delayed_job_helper.rb'
|
||||
|
||||
# Offense count: 3
|
||||
Style/ClassVars:
|
||||
@@ -1200,7 +1199,6 @@ Style/GuardClause:
|
||||
- 'lib/open_food_network/order_cycle_form_applicator.rb'
|
||||
- 'lib/open_food_network/rack_request_blocker.rb'
|
||||
- 'lib/spree/core/controller_helpers/respond_with.rb'
|
||||
- 'spec/support/delayed_job_helper.rb'
|
||||
- 'spec/support/request/distribution_helper.rb'
|
||||
- 'spec/support/request/shop_workflow.rb'
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.5.8
|
||||
2.5.9
|
||||
|
||||
26
Dockerfile
26
Dockerfile
@@ -7,23 +7,39 @@ 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
|
||||
ENV RBENV_ROOT /usr/local/src/rbenv
|
||||
ENV CONFIGURE_OPTS --disable-install-doc
|
||||
ENV BUNDLE_PATH /bundles
|
||||
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -6,8 +6,9 @@ This is a general guide to setting up an Open Food Network **development environ
|
||||
|
||||
The fastest way to make it work locally is to use Docker, you only need to setup git, see the [Docker setup guide](docker/README.md).
|
||||
Otherwise, for a local setup you will need:
|
||||
* Ruby 2.4.4 and bundler (check current Ruby version in [.ruby-version](https://github.com/openfoodfoundation/openfoodnetwork/blob/master/.ruby-version) file)
|
||||
* Ruby and bundler (check current Ruby version in [.ruby-version](https://github.com/openfoodfoundation/openfoodnetwork/blob/master/.ruby-version) file)
|
||||
* PostgreSQL database
|
||||
* Redis (for background jobs)
|
||||
* Chrome (for testing)
|
||||
|
||||
The following guides will provide OS-specific step-by-step instructions to get these requirements installed:
|
||||
@@ -47,7 +48,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:
|
||||
|
||||
@@ -78,8 +83,6 @@ Note: If your OS is not explicitly supported in the setup guides then not all te
|
||||
|
||||
Note: The time zone on your machine should match the one defined in `config/application.yml`.
|
||||
|
||||
The project is configured to use [Zeus][zeus] to reduce the pre-test startup time while Rails loads. See the [Zeus GitHub page][zeus] for usage instructions.
|
||||
|
||||
Once [npm dependencies are installed][karma], AngularJS tests can be run with:
|
||||
|
||||
./script/karma run
|
||||
@@ -119,7 +122,6 @@ If these commands succeed, you should be able to [continue the setup process](#g
|
||||
[ubuntu]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-Ubuntu
|
||||
[debian]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-Debian
|
||||
[wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki
|
||||
[zeus]: https://github.com/burke/zeus
|
||||
[rubocop]: https://rubocop.readthedocs.io/en/latest/
|
||||
[karma]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Karma
|
||||
[slack-dev]: https://openfoodnetwork.slack.com/messages/C2GQ45KNU
|
||||
|
||||
39
Gemfile
39
Gemfile
@@ -1,27 +1,27 @@
|
||||
# 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'
|
||||
gem 'rails', '~> 6.0.3.7'
|
||||
|
||||
gem 'activemerchant', '>= 1.78.0'
|
||||
gem 'angular-rails-templates', '>= 0.3.0'
|
||||
gem 'awesome_nested_set'
|
||||
gem 'ransack', '2.4.1'
|
||||
gem 'responders'
|
||||
gem 'sass', '<= 4.7.1'
|
||||
gem 'sass-rails', '< 6.0.0'
|
||||
gem 'sass', '~> 3.4.0' # this restriction originates from foundation-rails's version
|
||||
gem 'sass-rails', '< 5.1.0' # this restriction originates from the compass-rails's version
|
||||
|
||||
gem 'i18n'
|
||||
gem 'i18n-js', '~> 3.8.2'
|
||||
gem 'i18n-js', '~> 3.8.3'
|
||||
gem 'rails-i18n'
|
||||
gem 'rails_safe_tasks', '~> 1.0'
|
||||
|
||||
gem "activerecord-import"
|
||||
gem "db2fog", github: "openfoodfoundation/db2fog", branch: "rails-5"
|
||||
gem "fog-aws", ">= 0.6.0"
|
||||
gem "db2fog", github: "openfoodfoundation/db2fog", branch: "rails-6"
|
||||
gem "fog-aws", "~> 2.0" # db2fog does not support v3
|
||||
|
||||
gem "catalog", path: "./engines/catalog"
|
||||
gem 'dfc_provider', path: './engines/dfc_provider'
|
||||
@@ -50,10 +50,6 @@ gem 'devise-token_authenticatable'
|
||||
gem 'jwt', '~> 2.2'
|
||||
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'
|
||||
|
||||
gem 'andand'
|
||||
@@ -70,6 +66,7 @@ gem "active_model_serializers", "0.8.4"
|
||||
gem 'activerecord-session_store'
|
||||
gem 'acts-as-taggable-on', '~> 7.0'
|
||||
gem 'angularjs-file-upload-rails', '~> 2.4.1'
|
||||
gem 'bootsnap', require: false
|
||||
gem 'custom_error_message', github: 'jeremydurham/custom-err-msg'
|
||||
gem 'dalli'
|
||||
gem 'figaro'
|
||||
@@ -80,7 +77,12 @@ gem 'paper_trail', '~> 10.3.1'
|
||||
gem 'paperclip', '~> 3.4.1'
|
||||
gem 'rack-rewrite'
|
||||
gem 'rack-ssl', require: 'rack/ssl'
|
||||
gem 'roadie-rails', '~> 2.2.0'
|
||||
gem 'roadie-rails'
|
||||
|
||||
gem 'redis', '>= 4.0', require: ['redis', 'redis/connection/hiredis']
|
||||
gem 'hiredis'
|
||||
gem 'sidekiq'
|
||||
gem 'sidekiq-scheduler'
|
||||
|
||||
gem 'combine_pdf'
|
||||
gem 'wicked_pdf'
|
||||
@@ -108,7 +110,7 @@ gem 'foundation-rails', '= 5.5.2.1'
|
||||
gem 'jquery-migrate-rails'
|
||||
gem 'jquery-rails', '4.4.0'
|
||||
gem 'jquery-ui-rails', '~> 4.2'
|
||||
gem 'select2-rails', '~> 3.4.7'
|
||||
gem "select2-rails", github: "openfoodfoundation/select2-rails", branch: "v349_with_thor_v1"
|
||||
|
||||
gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz', branch: 'ofn-rails-4'
|
||||
|
||||
@@ -127,12 +129,11 @@ end
|
||||
|
||||
group :test, :development do
|
||||
# Pretty printed test output
|
||||
gem 'atomic'
|
||||
gem 'awesome_print'
|
||||
gem 'bullet'
|
||||
gem 'capybara'
|
||||
gem 'database_cleaner', require: false
|
||||
gem "factory_bot_rails", '6.1.0', require: false
|
||||
gem "factory_bot_rails", '6.2.0', require: false
|
||||
gem 'fuubar', '~> 2.5.1'
|
||||
gem 'json_spec', '~> 1.1.4'
|
||||
gem 'knapsack'
|
||||
@@ -148,17 +149,18 @@ group :test, :development do
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'byebug'
|
||||
gem 'codecov', require: false
|
||||
gem 'simplecov', require: false
|
||||
gem 'test-prof'
|
||||
gem 'webmock'
|
||||
gem 'rails-controller-testing'
|
||||
gem 'pdf-reader'
|
||||
# See spec/spec_helper.rb for instructions
|
||||
# gem 'perftools.rb'
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'byebug'
|
||||
gem 'debugger-linecache'
|
||||
gem 'pry'
|
||||
gem 'pry-byebug'
|
||||
@@ -169,10 +171,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
|
||||
|
||||
299
Gemfile.lock
299
Gemfile.lock
@@ -6,13 +6,13 @@ GIT
|
||||
|
||||
GIT
|
||||
remote: https://github.com/openfoodfoundation/db2fog.git
|
||||
revision: 8ceef362c64e6573d62d26db5ebb0c0f33cd3d61
|
||||
branch: rails-5
|
||||
revision: 5b63343847452f52aa42f7fc169d6ab3af57cda3
|
||||
branch: rails-6
|
||||
specs:
|
||||
db2fog (0.9.1)
|
||||
activerecord (>= 3.2.0, < 6.0)
|
||||
db2fog (0.9.2)
|
||||
activerecord (>= 3.2.0, < 7.0)
|
||||
fog-core (~> 1.0)
|
||||
rails (>= 3.2.0, < 6.0)
|
||||
rails (>= 3.2.0, < 7.0)
|
||||
|
||||
GIT
|
||||
remote: https://github.com/openfoodfoundation/ofn-qz.git
|
||||
@@ -21,6 +21,15 @@ GIT
|
||||
specs:
|
||||
ofn-qz (0.1.0)
|
||||
|
||||
GIT
|
||||
remote: https://github.com/openfoodfoundation/select2-rails.git
|
||||
revision: fc240e85fbdf1878ff3c39d972c0cd9a312f5ed4
|
||||
branch: v349_with_thor_v1
|
||||
specs:
|
||||
select2-rails (3.4.9)
|
||||
sass-rails
|
||||
thor (>= 0.14)
|
||||
|
||||
PATH
|
||||
remote: engines/catalog
|
||||
specs:
|
||||
@@ -47,48 +56,61 @@ PATH
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actioncable (5.2.6)
|
||||
actionpack (= 5.2.6)
|
||||
Ascii85 (1.1.0)
|
||||
actioncable (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailer (5.2.6)
|
||||
actionpack (= 5.2.6)
|
||||
actionview (= 5.2.6)
|
||||
activejob (= 5.2.6)
|
||||
actionmailbox (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
activejob (= 6.0.3.7)
|
||||
activerecord (= 6.0.3.7)
|
||||
activestorage (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
mail (>= 2.7.1)
|
||||
actionmailer (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
actionview (= 6.0.3.7)
|
||||
activejob (= 6.0.3.7)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (5.2.6)
|
||||
actionview (= 5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
actionpack (6.0.3.7)
|
||||
actionview (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
rack (~> 2.0, >= 2.0.8)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionpack-action_caching (1.2.1)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||
actionpack-action_caching (1.2.2)
|
||||
actionpack (>= 4.0.0)
|
||||
actionview (5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
actiontext (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
activerecord (= 6.0.3.7)
|
||||
activestorage (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||
active_model_serializers (0.8.4)
|
||||
activemodel (>= 3.0)
|
||||
activejob (5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
activejob (6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
globalid (>= 0.3.6)
|
||||
activemerchant (1.119.0)
|
||||
activemerchant (1.120.0)
|
||||
activesupport (>= 4.2)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
activemodel (5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
activerecord (5.2.6)
|
||||
activemodel (= 5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
arel (>= 9.0)
|
||||
activerecord-import (1.0.8)
|
||||
activemodel (6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
activerecord (6.0.3.7)
|
||||
activemodel (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
activerecord-import (1.1.0)
|
||||
activerecord (>= 3.2)
|
||||
activerecord-postgresql-adapter (0.0.1)
|
||||
pg
|
||||
@@ -98,21 +120,24 @@ GEM
|
||||
multi_json (~> 1.11, >= 1.11.2)
|
||||
rack (>= 2.0.8, < 3)
|
||||
railties (>= 5.2.4.1)
|
||||
activestorage (5.2.6)
|
||||
actionpack (= 5.2.6)
|
||||
activerecord (= 5.2.6)
|
||||
activestorage (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
activejob (= 6.0.3.7)
|
||||
activerecord (= 6.0.3.7)
|
||||
marcel (~> 1.0.0)
|
||||
activesupport (5.2.6)
|
||||
activesupport (6.0.3.7)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.2, >= 2.2.2)
|
||||
acts-as-taggable-on (7.0.0)
|
||||
activerecord (>= 5.0, < 6.2)
|
||||
acts_as_list (1.0.4)
|
||||
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)
|
||||
@@ -122,9 +147,7 @@ GEM
|
||||
railties (>= 3, < 7)
|
||||
angularjs-file-upload-rails (2.4.1)
|
||||
angularjs-rails (1.5.5)
|
||||
arel (9.0.0)
|
||||
ast (2.4.2)
|
||||
atomic (1.1.101)
|
||||
awesome_nested_set (3.4.0)
|
||||
activerecord (>= 4.0.0, < 7.0)
|
||||
awesome_print (1.9.2)
|
||||
@@ -134,6 +157,8 @@ GEM
|
||||
json (~> 1.4)
|
||||
nokogiri (~> 1)
|
||||
bcrypt (3.1.16)
|
||||
bootsnap (1.7.5)
|
||||
msgpack (~> 1.0)
|
||||
bugsnag (6.20.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.2.4)
|
||||
@@ -184,29 +209,24 @@ GEM
|
||||
compass (~> 1.0.0)
|
||||
sass-rails (< 5.1)
|
||||
sprockets (< 4.0)
|
||||
concurrent-ruby (1.1.8)
|
||||
concurrent-ruby (1.1.9)
|
||||
connection_pool (2.2.5)
|
||||
crack (0.4.5)
|
||||
rexml
|
||||
crass (1.0.6)
|
||||
css_parser (1.9.0)
|
||||
addressable
|
||||
daemons (1.4.0)
|
||||
dalli (2.7.11)
|
||||
database_cleaner (1.99.0)
|
||||
ddtrace (0.48.0)
|
||||
database_cleaner (2.0.1)
|
||||
database_cleaner-active_record (~> 2.0.0)
|
||||
database_cleaner-active_record (2.0.0)
|
||||
activerecord (>= 5.a)
|
||||
database_cleaner-core (~> 2.0.0)
|
||||
database_cleaner-core (2.0.1)
|
||||
ddtrace (0.50.0)
|
||||
ffi (~> 1.0)
|
||||
msgpack
|
||||
debugger-linecache (1.2.0)
|
||||
delayed_job (4.1.9)
|
||||
activesupport (>= 3.0, < 6.2)
|
||||
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)
|
||||
@@ -219,22 +239,28 @@ 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)
|
||||
excon (0.79.0)
|
||||
et-orbi (1.2.4)
|
||||
tzinfo
|
||||
excon (0.81.0)
|
||||
execjs (2.7.0)
|
||||
factory_bot (6.1.0)
|
||||
factory_bot (6.2.0)
|
||||
activesupport (>= 5.0.0)
|
||||
factory_bot_rails (6.1.0)
|
||||
factory_bot (~> 6.1.0)
|
||||
factory_bot_rails (6.2.0)
|
||||
factory_bot (~> 6.2.0)
|
||||
railties (>= 5.0.0)
|
||||
faraday (1.3.0)
|
||||
faraday (1.4.1)
|
||||
faraday-excon (~> 1.1)
|
||||
faraday-net_http (~> 1.0)
|
||||
faraday-net_http_persistent (~> 1.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ruby2_keywords
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-excon (1.1.0)
|
||||
faraday-net_http (1.0.1)
|
||||
faraday-net_http_persistent (1.1.0)
|
||||
ffaker (2.18.0)
|
||||
ffi (1.15.0)
|
||||
ffi (1.15.1)
|
||||
figaro (1.2.0)
|
||||
thor (>= 0.14.0, < 2)
|
||||
flipper (0.20.4)
|
||||
@@ -268,6 +294,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)
|
||||
@@ -284,10 +313,12 @@ 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)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-js (3.8.2)
|
||||
i18n-js (3.8.3)
|
||||
i18n (>= 0.6.6)
|
||||
immigrant (0.3.6)
|
||||
activerecord (>= 3.0)
|
||||
@@ -305,7 +336,7 @@ GEM
|
||||
json_spec (1.1.5)
|
||||
multi_json (~> 1.0)
|
||||
rspec (>= 2.0, < 4.0)
|
||||
jwt (2.2.2)
|
||||
jwt (2.2.3)
|
||||
kaminari (1.2.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.2.1)
|
||||
@@ -321,11 +352,11 @@ GEM
|
||||
kgio (2.11.3)
|
||||
knapsack (1.22.0)
|
||||
rake
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
launchy (2.5.0)
|
||||
addressable (~> 2.7)
|
||||
letter_opener (1.7.0)
|
||||
launchy (~> 2.2)
|
||||
libv8-node (15.14.0.0)
|
||||
libv8-node (15.14.0.1)
|
||||
loofah (2.9.1)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
@@ -335,12 +366,12 @@ GEM
|
||||
method_source (1.0.0)
|
||||
mime-types (3.3.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2020.1104)
|
||||
mime-types-data (3.2021.0225)
|
||||
mimemagic (0.4.3)
|
||||
nokogiri (~> 1)
|
||||
rake
|
||||
mini_mime (1.1.0)
|
||||
mini_portile2 (2.5.1)
|
||||
mini_portile2 (2.5.3)
|
||||
mini_racer (0.4.0)
|
||||
libv8-node (~> 15.14.0.0)
|
||||
minitest (5.14.4)
|
||||
@@ -352,10 +383,8 @@ 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.3)
|
||||
nokogiri (1.11.7)
|
||||
mini_portile2 (~> 2.5.0)
|
||||
racc (~> 1.4)
|
||||
oauth2 (1.4.7)
|
||||
@@ -384,15 +413,22 @@ GEM
|
||||
xml-simple
|
||||
paypal-sdk-merchant (1.117.2)
|
||||
paypal-sdk-core (~> 0.3.0)
|
||||
pdf-reader (2.5.0)
|
||||
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)
|
||||
pry (0.14.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
pry-byebug (3.9.0)
|
||||
pry-byebug (3.8.0)
|
||||
byebug (~> 11.0)
|
||||
pry (~> 0.13.0)
|
||||
pry (~> 0.10)
|
||||
public_suffix (4.0.6)
|
||||
raabro (1.4.0)
|
||||
racc (1.5.2)
|
||||
rack (2.2.3)
|
||||
rack-mini-profiler (2.3.2)
|
||||
@@ -404,18 +440,20 @@ GEM
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (5.2.6)
|
||||
actioncable (= 5.2.6)
|
||||
actionmailer (= 5.2.6)
|
||||
actionpack (= 5.2.6)
|
||||
actionview (= 5.2.6)
|
||||
activejob (= 5.2.6)
|
||||
activemodel (= 5.2.6)
|
||||
activerecord (= 5.2.6)
|
||||
activestorage (= 5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
rails (6.0.3.7)
|
||||
actioncable (= 6.0.3.7)
|
||||
actionmailbox (= 6.0.3.7)
|
||||
actionmailer (= 6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
actiontext (= 6.0.3.7)
|
||||
actionview (= 6.0.3.7)
|
||||
activejob (= 6.0.3.7)
|
||||
activemodel (= 6.0.3.7)
|
||||
activerecord (= 6.0.3.7)
|
||||
activestorage (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 5.2.6)
|
||||
railties (= 6.0.3.7)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-controller-testing (1.0.5)
|
||||
actionpack (>= 5.0.1.rc1)
|
||||
@@ -426,16 +464,16 @@ GEM
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.3.0)
|
||||
loofah (~> 2.3)
|
||||
rails-i18n (5.1.3)
|
||||
rails-i18n (6.0.0)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 5.0, < 6)
|
||||
railties (>= 6.0.0, < 7)
|
||||
rails_safe_tasks (1.0.0)
|
||||
railties (5.2.6)
|
||||
actionpack (= 5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
railties (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.19.0, < 2.0)
|
||||
thor (>= 0.20.3, < 2.0)
|
||||
rainbow (3.0.0)
|
||||
raindrops (0.19.1)
|
||||
rake (13.0.3)
|
||||
@@ -443,10 +481,11 @@ GEM
|
||||
activerecord (>= 5.2.4)
|
||||
activesupport (>= 5.2.4)
|
||||
i18n
|
||||
rb-fsevent (0.10.4)
|
||||
rb-fsevent (0.11.0)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
redcarpet (3.5.1)
|
||||
redis (4.2.5)
|
||||
regexp_parser (2.1.1)
|
||||
request_store (1.5.0)
|
||||
rack (>= 1.4)
|
||||
@@ -499,16 +538,16 @@ GEM
|
||||
rswag-ui (2.4.0)
|
||||
actionpack (>= 3.1, < 7.0)
|
||||
railties (>= 3.1, < 7.0)
|
||||
rubocop (1.14.0)
|
||||
rubocop (1.16.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.0.0.0)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml
|
||||
rubocop-ast (>= 1.5.0, < 2.0)
|
||||
rubocop-ast (>= 1.7.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.5.0)
|
||||
rubocop-ast (1.7.0)
|
||||
parser (>= 3.0.1.1)
|
||||
rubocop-rails (2.10.1)
|
||||
activesupport (>= 4.2.0)
|
||||
@@ -516,34 +555,39 @@ GEM
|
||||
rubocop (>= 1.7.0, < 2.0)
|
||||
ruby-progressbar (1.11.0)
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby2_keywords (0.0.2)
|
||||
ruby2_keywords (0.0.4)
|
||||
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)
|
||||
sass-rails (5.0.8)
|
||||
railties (>= 5.2.0)
|
||||
sass (~> 3.1)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (>= 1.1, < 3)
|
||||
select2-rails (3.4.9)
|
||||
sass-rails
|
||||
thor (~> 0.14)
|
||||
selenium-webdriver (3.142.7)
|
||||
childprocess (>= 0.5, < 4.0)
|
||||
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.1.0)
|
||||
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)
|
||||
simplecov_json_formatter (0.1.3)
|
||||
spring (2.1.1)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
@@ -562,15 +606,18 @@ GEM
|
||||
activerecord (>= 5.1)
|
||||
state_machines-activemodel (>= 0.8.0)
|
||||
stringex (2.8.5)
|
||||
stripe (5.30.0)
|
||||
stripe (5.33.0)
|
||||
temple (0.8.2)
|
||||
test-prof (1.0.3)
|
||||
test-unit (3.4.1)
|
||||
test-prof (1.0.5)
|
||||
test-unit (3.4.4)
|
||||
power_assert
|
||||
thor (0.20.3)
|
||||
thor (1.1.0)
|
||||
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)
|
||||
@@ -585,8 +632,8 @@ GEM
|
||||
unicorn-worker-killer (0.4.5)
|
||||
get_process_mem (~> 0)
|
||||
unicorn (>= 4, < 7)
|
||||
uniform_notifier (1.14.1)
|
||||
view_component (2.31.1)
|
||||
uniform_notifier (1.14.2)
|
||||
view_component (2.34.0)
|
||||
activesupport (>= 5.0.0, < 7.0)
|
||||
view_component_storybook (0.8.0)
|
||||
view_component (>= 2.2)
|
||||
@@ -596,11 +643,11 @@ GEM
|
||||
nokogiri (~> 1.6)
|
||||
rubyzip (>= 1.3.0)
|
||||
selenium-webdriver (>= 3.0, < 4.0)
|
||||
webmock (3.12.2)
|
||||
webmock (3.13.0)
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
websocket-driver (0.7.3)
|
||||
websocket-driver (0.7.4)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
whenever (1.0.0)
|
||||
@@ -611,6 +658,7 @@ GEM
|
||||
xml-simple (1.1.8)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
zeitwerk (2.4.2)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -629,10 +677,10 @@ DEPENDENCIES
|
||||
angular_rails_csrf
|
||||
angularjs-file-upload-rails (~> 2.4.1)
|
||||
angularjs-rails (= 1.5.5)
|
||||
atomic
|
||||
awesome_nested_set
|
||||
awesome_print
|
||||
aws-sdk (= 1.67.0)
|
||||
bootsnap
|
||||
bugsnag
|
||||
bullet
|
||||
byebug
|
||||
@@ -644,26 +692,22 @@ DEPENDENCIES
|
||||
combine_pdf
|
||||
compass-rails
|
||||
custom_error_message!
|
||||
daemons
|
||||
dalli
|
||||
database_cleaner
|
||||
db2fog!
|
||||
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.1.0)
|
||||
factory_bot_rails (= 6.2.0)
|
||||
ffaker
|
||||
figaro
|
||||
flipper
|
||||
flipper-active_record
|
||||
flipper-ui
|
||||
fog-aws (>= 0.6.0)
|
||||
fog-aws (~> 2.0)
|
||||
foundation-icons-sass-rails
|
||||
foundation-rails (= 5.5.2.1)
|
||||
fuubar (~> 2.5.1)
|
||||
@@ -672,8 +716,9 @@ DEPENDENCIES
|
||||
good_migrations
|
||||
haml
|
||||
highline (= 2.0.3)
|
||||
hiredis
|
||||
i18n
|
||||
i18n-js (~> 3.8.2)
|
||||
i18n-js (~> 3.8.3)
|
||||
immigrant
|
||||
jquery-migrate-rails
|
||||
jquery-rails (= 4.4.0)
|
||||
@@ -694,31 +739,35 @@ DEPENDENCIES
|
||||
paperclip (~> 3.4.1)
|
||||
paranoia (~> 2.4)
|
||||
paypal-sdk-merchant (= 1.117.2)
|
||||
pdf-reader
|
||||
pg (~> 1.2.3)
|
||||
pry
|
||||
pry-byebug
|
||||
rack-mini-profiler (< 3.0.0)
|
||||
rack-rewrite
|
||||
rack-ssl
|
||||
rails (~> 5.2)
|
||||
rails (~> 6.0.3.7)
|
||||
rails-controller-testing
|
||||
rails-i18n
|
||||
rails_safe_tasks (~> 1.0)
|
||||
ransack (= 2.4.1)
|
||||
redcarpet
|
||||
redis (>= 4.0)
|
||||
responders
|
||||
roadie-rails (~> 2.2.0)
|
||||
roadie-rails
|
||||
roo (~> 2.8.3)
|
||||
rspec-rails (>= 3.5.2)
|
||||
rspec-retry
|
||||
rswag
|
||||
rubocop
|
||||
rubocop-rails
|
||||
sass (<= 4.7.1)
|
||||
sass-rails (< 6.0.0)
|
||||
select2-rails (~> 3.4.7)
|
||||
sass (~> 3.4.0)
|
||||
sass-rails (< 5.1.0)
|
||||
select2-rails!
|
||||
selenium-webdriver
|
||||
shoulda-matchers
|
||||
sidekiq
|
||||
sidekiq-scheduler
|
||||
simplecov
|
||||
spring
|
||||
spring-commands-rspec
|
||||
@@ -741,7 +790,7 @@ DEPENDENCIES
|
||||
wkhtmltopdf-binary
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.5.8p224
|
||||
ruby 2.5.9p229
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.3
|
||||
|
||||
@@ -3,12 +3,18 @@ angular.module('admin.orderCycles', ['ngTagsInput', 'admin.indexUtils', 'admin.e
|
||||
require: "ngModel"
|
||||
link: (scope, element, attrs, ngModel) ->
|
||||
$timeout ->
|
||||
flatpickr(element, Object.assign({},
|
||||
fp = flatpickr(element, Object.assign({},
|
||||
window.FLATPICKR_DATETIME_DEFAULT, {
|
||||
onOpen: (selectedDates, dateStr, instance) ->
|
||||
instance.setDate(ngModel.$modelValue)
|
||||
instance.input.dispatchEvent(new Event('focus', { bubbles: true }));
|
||||
}));
|
||||
fp.minuteElement.addEventListener "keyup", (e) ->
|
||||
if !isNaN(event.target.value)
|
||||
fp.setDate(fp.selectedDates[0].setMinutes(e.target.value), true)
|
||||
fp.hourElement.addEventListener "keyup", (e) ->
|
||||
if !isNaN(event.target.value)
|
||||
fp.setDate(fp.selectedDates[0].setHours(e.target.value), true)
|
||||
|
||||
.directive 'ofnOnChange', ->
|
||||
(scope, element, attrs) ->
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
@@ -3,7 +3,7 @@ Darkswarm.controller "EditBoughtOrderController", ($scope, $resource, $timeout,
|
||||
$scope.removeEnabled = true
|
||||
|
||||
$scope.deleteLineItem = (id) ->
|
||||
if Cart.has_one_line_item()
|
||||
if Cart.isOnlyItemInOrder(id)
|
||||
Messages.error(t 'orders_cannot_remove_the_final_item')
|
||||
$scope.removeEnabled = false
|
||||
$timeout (->
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
Darkswarm.controller "ShopVariantCtrl", ($scope, $modal, Cart) ->
|
||||
$scope.$watchGroup [
|
||||
'variant.line_item.quantity',
|
||||
'variant.line_item.max_quantity'
|
||||
], (new_value, old_value) ->
|
||||
return if old_value[0] == null && new_value[0] == null
|
||||
$scope.updateCart = (line_item) ->
|
||||
Cart.adjust($scope.variant.line_item)
|
||||
|
||||
$scope.variant.line_item.quantity ||= 0
|
||||
@@ -44,10 +40,12 @@ Darkswarm.controller "ShopVariantCtrl", ($scope, $modal, Cart) ->
|
||||
$scope.add = (quantity) ->
|
||||
item = $scope.variant.line_item
|
||||
item.quantity = $scope.sanitizedQuantity() + quantity
|
||||
$scope.updateCart(item)
|
||||
|
||||
$scope.addMax = (quantity) ->
|
||||
item = $scope.variant.line_item
|
||||
item.max_quantity = $scope.sanitizedMaxQuantity() + quantity
|
||||
$scope.updateCart(item)
|
||||
|
||||
$scope.canAdd = (quantity) ->
|
||||
wantedQuantity = $scope.sanitizedQuantity() + quantity
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
Darkswarm.directive "shopVariantWithUnitPrice", ->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
templateUrl: 'shop_variant_with_unit_price.html'
|
||||
scope:
|
||||
variant: '='
|
||||
show_unit_price: '=showunitprice'
|
||||
controller: 'ShopVariantCtrl'
|
||||
@@ -115,8 +115,9 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo
|
||||
@line_items = []
|
||||
localStorageService.clearAll() # One day this will have to be moar GRANULAR
|
||||
|
||||
has_one_line_item: =>
|
||||
@line_items_finalised.length == 1
|
||||
isOnlyItemInOrder: (id) =>
|
||||
deletedItem = @line_items_finalised.find((item) -> item.id == id)
|
||||
@line_items_finalised.filter((item) -> item.order_id == deletedItem.order_id).length == 1
|
||||
|
||||
removeFinalisedLineItem: (id) =>
|
||||
@line_items_finalised = @line_items_finalised.filter (item) ->
|
||||
|
||||
@@ -10,7 +10,7 @@ Darkswarm.service "GmapsGeo", ->
|
||||
# console.log "Error: #{status}"
|
||||
geocode: (address, callback) ->
|
||||
geocoder = new google.maps.Geocoder()
|
||||
geocoder.geocode {'address': address, 'region': "<%= Spree::Country.find_by(id: Spree::Config[:default_country_id]).iso %>"}, callback
|
||||
geocoder.geocode {'address': address, 'region': "<%= DefaultCountry.code %>"}, callback
|
||||
|
||||
distanceBetween: (src, dst) ->
|
||||
google.maps.geometry.spherical.computeDistanceBetween @toLatLng(src), @toLatLng(dst)
|
||||
@@ -20,4 +20,4 @@ Darkswarm.service "GmapsGeo", ->
|
||||
if locatable.lat?
|
||||
locatable
|
||||
else
|
||||
new google.maps.LatLng locatable.latitude, locatable.longitude
|
||||
new google.maps.LatLng locatable.latitude, locatable.longitude
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
.div
|
||||
{{ variant.line_item.total_price | localizeCurrency }}
|
||||
|
||||
.unit-price{"ng-if": "show_unit_price"}
|
||||
.unit-price
|
||||
%question-mark-with-tooltip{"question-mark-with-tooltip": "_",
|
||||
"question-mark-with-tooltip-append-to-body": "true",
|
||||
"question-mark-with-tooltip-placement": "top",
|
||||
|
||||
@@ -8,9 +8,16 @@
|
||||
"price-breakdown-placement" => "bottom",
|
||||
"price-breakdown-animation" => true}
|
||||
{{ variant.price_with_fees | localizeCurrency }}
|
||||
.unit-price.variant-unit-price
|
||||
%question-mark-with-tooltip{"question-mark-with-tooltip" => "_",
|
||||
"question-mark-with-tooltip-append-to-body" => "true",
|
||||
"question-mark-with-tooltip-placement" => "top",
|
||||
"question-mark-with-tooltip-animation" => true,
|
||||
key: "'js.shopfront.unit_price_tooltip'"}
|
||||
{{ variant.unit_price_price | localizeCurrency }} / {{ variant.unit_price_unit }}
|
||||
|
||||
.medium-2.large-2.columns.total-price
|
||||
%span{"ng-class" => "{filled: variant.line_item.total_price}"}
|
||||
{{ variant.line_item.total_price | localizeCurrency }}
|
||||
|
||||
%ng-include{src: "'partials/shop_variant_no_group_buy.html'"}
|
||||
%ng-include{src: "'partials/shop_variant_with_group_buy.html'"}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
.variants.row
|
||||
.small-4.medium-4.large-5.columns.variant-name
|
||||
.inline{"ng-if" => "::variant.display_name"} {{ ::variant.display_name }}
|
||||
.variant-unit {{ ::variant.unit_to_display }}
|
||||
.small-3.medium-3.large-2.columns.variant-price
|
||||
%price-breakdown{"price-breakdown" => "_", variant: "variant",
|
||||
"price-breakdown-append-to-body" => "true",
|
||||
"price-breakdown-placement" => "bottom",
|
||||
"price-breakdown-animation" => true}
|
||||
{{ variant.price_with_fees | localizeCurrency }}
|
||||
.unit-price.variant-unit-price
|
||||
%question-mark-with-tooltip{"question-mark-with-tooltip" => "_",
|
||||
"question-mark-with-tooltip-append-to-body" => "true",
|
||||
"question-mark-with-tooltip-placement" => "top",
|
||||
"question-mark-with-tooltip-animation" => true,
|
||||
key: "'js.shopfront.unit_price_tooltip'"}
|
||||
{{ variant.unit_price_price | localizeCurrency }} / {{ variant.unit_price_unit }}
|
||||
|
||||
.medium-2.large-2.columns.total-price
|
||||
%span{"ng-class" => "{filled: variant.line_item.total_price}"}
|
||||
{{ variant.line_item.total_price | localizeCurrency }}
|
||||
%ng-include{src: "'partials/shop_variant_no_group_buy.html'"}
|
||||
%ng-include{src: "'partials/shop_variant_with_group_buy.html'"}
|
||||
6
app/assets/stylesheets/admin/terms_of_service_files.scss
Normal file
6
app/assets/stylesheets/admin/terms_of_service_files.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
.admin-current-terms-of-service {
|
||||
border: .1em solid $spree-blue;
|
||||
border-radius: .5em;
|
||||
margin: 1em 0;
|
||||
padding: 1em;
|
||||
}
|
||||
@@ -32,10 +32,7 @@ module Admin
|
||||
# See https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/locking/pessimistic.rb#L69
|
||||
# and https://www.postgresql.org/docs/current/static/sql-select.html#SQL-FOR-UPDATE-SHARE
|
||||
order.with_lock do
|
||||
if @line_item.update(line_item_params)
|
||||
order.update_line_item_fees! @line_item
|
||||
order.update_order_fees!
|
||||
order.update!
|
||||
if order.contents.update_item(@line_item, line_item_params)
|
||||
render body: nil, status: :no_content # No Content, does not trigger ng resource auto-update
|
||||
else
|
||||
render json: { errors: @line_item.errors }, status: :precondition_failed
|
||||
@@ -49,7 +46,7 @@ module Admin
|
||||
load_line_item
|
||||
authorize! :update, order
|
||||
|
||||
@line_item.destroy
|
||||
order.contents.remove(@line_item.variant)
|
||||
render body: nil, status: :no_content # No Content, does not trigger ng resource auto-update
|
||||
end
|
||||
|
||||
@@ -63,16 +60,9 @@ module Admin
|
||||
Spree::LineItem
|
||||
end
|
||||
|
||||
# Returns the appropriate serializer for this controller
|
||||
#
|
||||
# @return [Api::Admin::LineItemSerializer]
|
||||
def serializer(_ams_prefix)
|
||||
Api::Admin::LineItemSerializer
|
||||
end
|
||||
|
||||
def serialized_line_items
|
||||
ActiveModel::ArraySerializer.new(
|
||||
@line_items, each_serializer: serializer(nil)
|
||||
@line_items, each_serializer: Api::Admin::LineItemSerializer
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -28,9 +28,7 @@ module Admin
|
||||
def build_resource
|
||||
enterprise_group = super
|
||||
enterprise_group.address = Spree::Address.new
|
||||
enterprise_group.address.country = Spree::Country.find_by(
|
||||
id: Spree::Config[:default_country_id]
|
||||
)
|
||||
enterprise_group.address.country = DefaultCountry.country
|
||||
enterprise_group
|
||||
end
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ module Admin
|
||||
def build_resource
|
||||
enterprise = super
|
||||
enterprise.address ||= Spree::Address.new
|
||||
enterprise.address.country ||= Spree::Country.find_by(id: Spree::Config[:default_country_id])
|
||||
enterprise.address.country ||= DefaultCountry.country
|
||||
enterprise
|
||||
end
|
||||
|
||||
|
||||
40
app/controllers/admin/terms_of_service_files_controller.rb
Normal file
40
app/controllers/admin/terms_of_service_files_controller.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class TermsOfServiceFilesController < Spree::Admin::BaseController
|
||||
def show
|
||||
@current_file = TermsOfServiceFile.current
|
||||
@new_file = TermsOfServiceFile.new
|
||||
end
|
||||
|
||||
def new
|
||||
show
|
||||
render :show
|
||||
end
|
||||
|
||||
def create
|
||||
TermsOfServiceFile.create!(file_params)
|
||||
redirect_to main_app.admin_terms_of_service_files_path
|
||||
rescue ActionController::ParameterMissing
|
||||
flash[:error] = t(".select_file")
|
||||
redirect_to main_app.admin_terms_of_service_files_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
TermsOfServiceFile.current.destroy!
|
||||
redirect_to main_app.admin_terms_of_service_files_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Needed by Spree::Admin::BaseController#authorize_admin or it
|
||||
# tries to find a Spree model.
|
||||
def model_class
|
||||
TermsOfServiceFile
|
||||
end
|
||||
|
||||
def file_params
|
||||
params.require(:terms_of_service_file).permit(:attachment)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -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
|
||||
|
||||
@@ -31,10 +31,12 @@ module Api
|
||||
unlock = params[:shipment].delete(:unlock)
|
||||
|
||||
if unlock == 'yes'
|
||||
@shipment.fee_adjustment.open
|
||||
@shipment.fee_adjustment.fire_events(:open)
|
||||
end
|
||||
|
||||
@shipment.update(shipment_params[:shipment])
|
||||
if @shipment.update(shipment_params)
|
||||
@order.updater.update_totals_and_states
|
||||
end
|
||||
|
||||
if unlock == 'yes'
|
||||
@shipment.fee_adjustment.close
|
||||
@@ -79,7 +81,6 @@ module Api
|
||||
quantity = params[:quantity].to_i
|
||||
|
||||
@order.contents.remove(variant, quantity, @shipment)
|
||||
@order.recreate_all_fees!
|
||||
@shipment.reload if @shipment.persisted?
|
||||
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
@@ -94,7 +95,7 @@ module Api
|
||||
|
||||
def find_and_update_shipment
|
||||
@shipment = @order.shipments.find_by!(number: params[:id])
|
||||
@shipment.update(shipment_params[:shipment]) if shipment_params[:shipment].present?
|
||||
@shipment.update(shipment_params)
|
||||
@shipment.reload
|
||||
end
|
||||
|
||||
@@ -113,10 +114,9 @@ module Api
|
||||
end
|
||||
|
||||
def shipment_params
|
||||
params.permit(
|
||||
[:id, :order_id, :variant_id, :quantity,
|
||||
{ shipment: [:tracking, :selected_shipping_rate_id] }]
|
||||
)
|
||||
return {} unless params.has_key? :shipment
|
||||
|
||||
params.require(:shipment).permit(:tracking, :selected_shipping_rate_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,6 +26,7 @@ class ApplicationController < ActionController::Base
|
||||
helper 'footer_links'
|
||||
helper 'discourse'
|
||||
helper 'checkout'
|
||||
helper 'terms_and_conditions'
|
||||
|
||||
protect_from_forgery
|
||||
|
||||
@@ -153,7 +154,7 @@ class ApplicationController < ActionController::Base
|
||||
current_order.empty!
|
||||
current_order.set_order_cycle! nil
|
||||
flash[:info] = I18n.t('order_cycle_closed')
|
||||
redirect_to main_app.root_url
|
||||
redirect_to main_app.shop_path
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -3,33 +3,28 @@ class CartController < BaseController
|
||||
|
||||
def populate
|
||||
order = current_order(true)
|
||||
|
||||
cart_service = CartService.new(order)
|
||||
|
||||
cart_service.populate(params.slice(:variants, :quantity), true)
|
||||
if cart_service.valid?
|
||||
if cart_service.populate(params.slice(:variants, :quantity))
|
||||
order.cap_quantity_at_stock!
|
||||
order.recreate_all_fees!
|
||||
|
||||
variant_ids = variant_ids_in(cart_service.variants_h)
|
||||
|
||||
render json: { error: false,
|
||||
stock_levels: VariantsStockLevels.new.call(order, variant_ids) },
|
||||
status: :ok
|
||||
render json: { error: false, stock_levels: stock_levels(order) }, status: :ok
|
||||
else
|
||||
render json: { error: cart_service.errors.full_messages.join(",") },
|
||||
status: :precondition_failed
|
||||
end
|
||||
|
||||
populate_variant_attributes
|
||||
end
|
||||
|
||||
def variant_ids_in(variants_h)
|
||||
variants_h.map { |v| v[:variant_id].to_i }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def stock_levels(order)
|
||||
variants_in_cart = order.line_items.pluck(:variant_id)
|
||||
variants_in_request = raw_params[:variants]&.map(&:first) || []
|
||||
|
||||
VariantsStockLevels.new.call(order, (variants_in_cart + variants_in_request).uniq)
|
||||
end
|
||||
|
||||
def check_authorization
|
||||
session[:access_token] ||= params[:token]
|
||||
order = Spree::Order.find_by(number: params[:id]) || current_order
|
||||
@@ -40,26 +35,4 @@ class CartController < BaseController
|
||||
authorize! :create, Spree::Order
|
||||
end
|
||||
end
|
||||
|
||||
def populate_variant_attributes
|
||||
order = current_order.reload
|
||||
|
||||
populate_variant_attributes_from_variant(order) if params.key? :variant_attributes
|
||||
populate_variant_attributes_from_product(order) if params.key? :quantity
|
||||
end
|
||||
|
||||
def populate_variant_attributes_from_variant(order)
|
||||
params[:variant_attributes].each do |variant_id, attributes|
|
||||
permitted = attributes.permit(:quantity, :max_quantity).to_h.with_indifferent_access
|
||||
order.set_variant_attributes(Spree::Variant.find(variant_id), permitted)
|
||||
end
|
||||
end
|
||||
|
||||
def populate_variant_attributes_from_product(order)
|
||||
params[:products].each do |_product_id, variant_id|
|
||||
max_quantity = params[:max_quantity].to_i
|
||||
order.set_variant_attributes(Spree::Variant.find(variant_id),
|
||||
max_quantity: max_quantity)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -55,7 +55,7 @@ class CheckoutController < ::BaseController
|
||||
flash[:error] = I18n.t("checkout.failed")
|
||||
action_failed(e)
|
||||
ensure
|
||||
@order.update!
|
||||
@order.update_order!
|
||||
end
|
||||
|
||||
# Clears the cached order. Required for #current_order to return a new order
|
||||
|
||||
@@ -39,12 +39,8 @@ class LineItemsController < BaseController
|
||||
def destroy_with_lock(item)
|
||||
order = item.order
|
||||
order.with_lock do
|
||||
item.destroy
|
||||
order.update_shipping_fees!
|
||||
order.contents.remove(item.variant)
|
||||
order.update_payment_fees!
|
||||
order.update_order_fees!
|
||||
order.update!
|
||||
order.create_tax_charge!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ module Spree
|
||||
|
||||
def update_order
|
||||
@order.reload
|
||||
@order.update!
|
||||
@order.update_order!
|
||||
end
|
||||
|
||||
def collection
|
||||
|
||||
@@ -12,7 +12,7 @@ module Spree
|
||||
helper 'enterprise_fees'
|
||||
helper 'angular_form'
|
||||
|
||||
layout '/spree/layouts/admin'
|
||||
layout 'spree/layouts/admin'
|
||||
|
||||
include I18nHelper
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@ module Spree
|
||||
def edit
|
||||
@preferences_general = [:site_name, :default_seo_title, :default_meta_keywords,
|
||||
:default_meta_description, :site_url]
|
||||
@preferences_security = [:allow_ssl_in_production,
|
||||
:allow_ssl_in_staging, :allow_ssl_in_development_and_test]
|
||||
@preferences_security = [:allow_ssl_in_production, :allow_ssl_in_staging]
|
||||
@preferences_currency = [:display_currency, :hide_cents]
|
||||
end
|
||||
|
||||
|
||||
@@ -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|
|
||||
|
||||
@@ -9,6 +9,10 @@ module Spree
|
||||
before_action :load_payment, only: [:fire, :show]
|
||||
before_action :load_data
|
||||
before_action :can_transition_to_payment
|
||||
# We ensure that items are in stock before all screens if the order is in the Payment state.
|
||||
# This way, we don't allow someone to enter credit card details for an order only to be told
|
||||
# that it can't be processed.
|
||||
before_action :ensure_sufficient_stock_lines
|
||||
|
||||
respond_to :html
|
||||
|
||||
@@ -142,6 +146,20 @@ module Spree
|
||||
redirect_to spree.edit_admin_order_customer_url(@order)
|
||||
end
|
||||
|
||||
def ensure_sufficient_stock_lines
|
||||
return if !@order.payment? || @order.insufficient_stock_lines.blank?
|
||||
|
||||
flash[:error] = I18n.t("spree.orders.line_item.insufficient_stock",
|
||||
on_hand: "0 #{out_of_stock_item_names}")
|
||||
redirect_to spree.edit_admin_order_url(@order)
|
||||
end
|
||||
|
||||
def out_of_stock_item_names
|
||||
@order.insufficient_stock_lines.map do |line_item|
|
||||
line_item.variant.name
|
||||
end.join(", ")
|
||||
end
|
||||
|
||||
def load_order
|
||||
@order = Order.find_by!(number: params[:order_id])
|
||||
authorize! action, @order
|
||||
|
||||
@@ -14,7 +14,7 @@ module Spree
|
||||
respond_to :html
|
||||
respond_to :json
|
||||
|
||||
before_action :update_distribution, only: :update
|
||||
before_action :set_current_order, only: :update
|
||||
before_action :filter_order_params, only: :update
|
||||
before_action :enable_embedded_shopfront
|
||||
|
||||
@@ -27,13 +27,7 @@ module Spree
|
||||
def show
|
||||
@order = Spree::Order.find_by!(number: params[:id])
|
||||
|
||||
if params.key?("payment_intent")
|
||||
result = ProcessPaymentIntent.new(params["payment_intent"], @order).call!
|
||||
unless result.ok?
|
||||
flash[:error] = "#{I18n.t("payment_could_not_process")}. #{result.error}"
|
||||
end
|
||||
@order.reload
|
||||
end
|
||||
handle_stripe_response
|
||||
end
|
||||
|
||||
def empty
|
||||
@@ -44,17 +38,6 @@ module Spree
|
||||
redirect_to main_app.cart_path
|
||||
end
|
||||
|
||||
def check_authorization
|
||||
session[:access_token] ||= params[:token]
|
||||
order = Spree::Order.find_by(number: params[:id]) || current_order
|
||||
|
||||
if order
|
||||
authorize! :edit, order, session[:access_token]
|
||||
else
|
||||
authorize! :create, Spree::Order
|
||||
end
|
||||
end
|
||||
|
||||
# Patching to redirect to shop if order is empty
|
||||
def edit
|
||||
@order = current_order(true)
|
||||
@@ -68,7 +51,7 @@ module Spree
|
||||
associate_user
|
||||
|
||||
if @order.insufficient_stock_lines.present? || @unavailable_order_variants.present?
|
||||
flash[:error] = t("spree.orders.error_flash_for_unavailable_items")
|
||||
flash.now[:error] = t("spree.orders.error_flash_for_unavailable_items")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -83,14 +66,10 @@ module Spree
|
||||
|
||||
# This action is called either from the cart page when the order is not yet complete, or from
|
||||
# the edit order page (frontoffice) if the hub allows users to update completed orders.
|
||||
# This line item updating logic should probably be handled through CartService#populate.
|
||||
if @order.update(order_params)
|
||||
discard_empty_line_items
|
||||
|
||||
if @order.contents.update_cart(order_params)
|
||||
@order.recreate_all_fees! # Enterprise fees on line items and on the order itself
|
||||
|
||||
if @order.complete?
|
||||
@order.update_shipping_fees!
|
||||
@order.update_payment_fees!
|
||||
@order.create_tax_charge!
|
||||
end
|
||||
@@ -101,7 +80,7 @@ module Spree
|
||||
@order.next_transition.run_callbacks if @order.cart?
|
||||
redirect_to main_app.checkout_state_path(@order.checkout_steps.first)
|
||||
elsif @order.complete?
|
||||
redirect_to order_path(@order)
|
||||
redirect_to main_app.order_path(@order)
|
||||
else
|
||||
redirect_to main_app.cart_path
|
||||
end
|
||||
@@ -115,24 +94,46 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def update_distribution
|
||||
@order = current_order(true)
|
||||
def cancel
|
||||
@order = Spree::Order.find_by!(number: params[:id])
|
||||
authorize! :cancel, @order
|
||||
|
||||
if params[:commit] == 'Choose Hub'
|
||||
distributor = Enterprise.is_distributor.find params[:order][:distributor_id]
|
||||
@order.set_distributor! distributor
|
||||
|
||||
flash[:notice] = I18n.t(:order_choosing_hub_notice)
|
||||
redirect_to request.referer
|
||||
|
||||
elsif params[:commit] == 'Choose Order Cycle'
|
||||
@order.empty! # empty cart
|
||||
order_cycle = OrderCycle.active.find params[:order][:order_cycle_id]
|
||||
@order.set_order_cycle! order_cycle
|
||||
|
||||
flash[:notice] = I18n.t(:order_choosing_hub_notice)
|
||||
redirect_to request.referer
|
||||
if CustomerOrderCancellation.new(@order).call
|
||||
flash[:success] = I18n.t(:orders_your_order_has_been_cancelled)
|
||||
else
|
||||
flash[:error] = I18n.t(:orders_could_not_cancel)
|
||||
end
|
||||
redirect_to request.referer || main_app.order_path(@order)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_current_order
|
||||
@order = current_order(true)
|
||||
end
|
||||
|
||||
def check_authorization
|
||||
session[:access_token] ||= params[:token]
|
||||
order = Spree::Order.find_by(number: params[:id]) || current_order
|
||||
|
||||
if order
|
||||
authorize! :edit, order, session[:access_token]
|
||||
else
|
||||
authorize! :create, Spree::Order
|
||||
end
|
||||
end
|
||||
|
||||
# Stripe can redirect here after a payment is processed in the backoffice.
|
||||
# We verify if it was successful here and persist the changes.
|
||||
def handle_stripe_response
|
||||
return unless params.key?("payment_intent")
|
||||
|
||||
result = ProcessPaymentIntent.new(params["payment_intent"], @order).call!
|
||||
|
||||
unless result.ok?
|
||||
flash.now[:error] = "#{I18n.t("payment_could_not_process")}. #{result.error}"
|
||||
end
|
||||
@order.reload
|
||||
end
|
||||
|
||||
def filter_order_params
|
||||
@@ -148,20 +149,6 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def cancel
|
||||
@order = Spree::Order.find_by!(number: params[:id])
|
||||
authorize! :cancel, @order
|
||||
|
||||
if CustomerOrderCancellation.new(@order).call
|
||||
flash[:success] = I18n.t(:orders_your_order_has_been_cancelled)
|
||||
else
|
||||
flash[:error] = I18n.t(:orders_could_not_cancel)
|
||||
end
|
||||
redirect_to request.referer || order_path(@order)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def discard_empty_line_items
|
||||
@order.line_items = @order.line_items.select { |li| li.quantity > 0 }
|
||||
end
|
||||
@@ -197,7 +184,7 @@ module Spree
|
||||
|
||||
if items.empty?
|
||||
flash[:error] = I18n.t(:orders_cannot_remove_the_final_item)
|
||||
redirect_to order_path(order_to_update)
|
||||
redirect_to main_app.order_path(order_to_update)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ module Spree
|
||||
|
||||
def show
|
||||
@payments_requiring_action = PaymentsRequiringAction.new(spree_current_user).query
|
||||
@orders = orders_collection
|
||||
@orders = orders_collection.includes(:line_items)
|
||||
|
||||
customers = spree_current_user.customers
|
||||
@shops = Enterprise
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module TermsAndConditionsHelper
|
||||
def link_to_platform_terms
|
||||
link_to(t("terms_of_service"), TermsOfServiceFile.current_url, target: "_blank")
|
||||
end
|
||||
|
||||
def render_terms_and_conditions
|
||||
if platform_terms_required? && terms_and_conditions_activated?
|
||||
render("checkout/all_terms_and_conditions")
|
||||
@@ -19,12 +23,18 @@ module TermsAndConditionsHelper
|
||||
current_order.distributor.terms_and_conditions.file?
|
||||
end
|
||||
|
||||
def terms_and_conditions_already_accepted?
|
||||
customer_terms_and_conditions_accepted_at = spree_current_user&.
|
||||
customer_of(current_order.distributor)&.terms_and_conditions_accepted_at
|
||||
def all_terms_and_conditions_already_accepted?
|
||||
platform_tos_already_accepted? && terms_and_conditions_already_accepted?
|
||||
end
|
||||
|
||||
customer_terms_and_conditions_accepted_at.present? &&
|
||||
(customer_terms_and_conditions_accepted_at >
|
||||
current_order.distributor.terms_and_conditions_updated_at)
|
||||
def platform_tos_already_accepted?
|
||||
TermsOfService.tos_accepted?(spree_current_user&.customer_of(current_order.distributor))
|
||||
end
|
||||
|
||||
def terms_and_conditions_already_accepted?
|
||||
TermsOfService.tos_accepted?(
|
||||
spree_current_user&.customer_of(current_order.distributor),
|
||||
current_order.distributor
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ConfirmOrderJob < ActiveJob::Base
|
||||
def perform(order_id)
|
||||
Spree::OrderMailer.confirm_email_for_customer(order_id).deliver_now
|
||||
Spree::OrderMailer.confirm_email_for_shop(order_id).deliver_now
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@ module JobLogger
|
||||
|
||||
def self.logger
|
||||
@logger ||= begin
|
||||
logger = Delayed::Worker.logger.clone
|
||||
logger = Rails.logger.clone
|
||||
logger.formatter = Formatter.new
|
||||
logger
|
||||
end
|
||||
|
||||
@@ -90,13 +90,13 @@ class SubscriptionConfirmJob < ActiveJob::Base
|
||||
end
|
||||
|
||||
def send_confirmation_email(order)
|
||||
order.update!
|
||||
order.update_order!
|
||||
record_success(order)
|
||||
SubscriptionMailer.confirmation_email(order).deliver_now
|
||||
end
|
||||
|
||||
def send_failed_payment_email(order, error_message = nil)
|
||||
order.update!
|
||||
order.update_order!
|
||||
record_and_log_error(:failed_payment, order, error_message)
|
||||
SubscriptionMailer.failed_payment_email(order).deliver_now
|
||||
rescue StandardError => e
|
||||
|
||||
@@ -77,7 +77,7 @@ class SubscriptionPlacementJob < ActiveJob::Base
|
||||
|
||||
def handle_empty_order(order, changes)
|
||||
order.reload.all_adjustments.destroy_all
|
||||
order.update!
|
||||
order.update_order!
|
||||
send_empty_email(order, changes)
|
||||
end
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ module Spree
|
||||
# Inline stylesheets
|
||||
include Roadie::Rails::Automatic
|
||||
|
||||
helper TermsAndConditionsHelper
|
||||
|
||||
layout 'mailer'
|
||||
|
||||
def from_address
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -105,7 +105,7 @@ class Enterprise < ApplicationRecord
|
||||
after_touch :touch_distributors
|
||||
after_create :set_default_contact
|
||||
after_create :relate_to_owners_enterprises
|
||||
after_create :send_welcome_email
|
||||
after_create_commit :send_welcome_email
|
||||
|
||||
after_rollback :restore_permalink
|
||||
|
||||
@@ -121,7 +121,7 @@ class Enterprise < ApplicationRecord
|
||||
scope :not_ready_for_checkout, lambda {
|
||||
# When ready_for_checkout is empty, return all rows when there are no enterprises ready for
|
||||
# checkout.
|
||||
ready_enterprises = Enterprise.ready_for_checkout.
|
||||
ready_enterprises = Enterprise.default_scoped.ready_for_checkout.
|
||||
except(:select).
|
||||
select('DISTINCT enterprises.id')
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class Exchange < ApplicationRecord
|
||||
scope :by_enterprise_name, -> {
|
||||
joins('INNER JOIN enterprises AS sender ON (sender.id = exchanges.sender_id)').
|
||||
joins('INNER JOIN enterprises AS receiver ON (receiver.id = exchanges.receiver_id)').
|
||||
order("CASE WHEN exchanges.incoming='t' THEN sender.name ELSE receiver.name END")
|
||||
order(Arel.sql("CASE WHEN exchanges.incoming='t' THEN sender.name ELSE receiver.name END"))
|
||||
}
|
||||
|
||||
# Exchanges on order cycles that are dated and are upcoming or open are cached
|
||||
|
||||
@@ -24,7 +24,7 @@ module Spree
|
||||
|
||||
def self.default
|
||||
country = begin
|
||||
Spree::Country.find(Spree::Config[:default_country_id])
|
||||
DefaultCountry.country
|
||||
rescue StandardError
|
||||
Spree::Country.first
|
||||
end
|
||||
|
||||
@@ -96,7 +96,7 @@ module Spree
|
||||
# more than on line items at once via accepted_nested_attributes the order
|
||||
# object on the association would be in a old state and therefore the
|
||||
# adjustment calculations would not performed on proper values
|
||||
def update!(calculable = nil, force: false)
|
||||
def update_adjustment!(calculable = nil, force: false)
|
||||
return amount if immutable? && !force
|
||||
|
||||
if originator.present?
|
||||
@@ -127,11 +127,7 @@ module Spree
|
||||
end
|
||||
|
||||
def set_absolute_included_tax!(tax)
|
||||
# This rubocop issue can now fixed by renaming Adjustment#update! to something else,
|
||||
# then AR's update! can be used instead of update_attributes!
|
||||
# rubocop:disable Rails/ActiveRecordAliases
|
||||
update_attributes! included_tax: tax.round(2)
|
||||
# rubocop:enable Rails/ActiveRecordAliases
|
||||
update! included_tax: tax.round(2)
|
||||
end
|
||||
|
||||
def display_included_tax
|
||||
|
||||
@@ -33,7 +33,6 @@ module Spree
|
||||
preference :allow_backorder_shipping, :boolean, default: false
|
||||
preference :allow_checkout_on_gateway_error, :boolean, default: false
|
||||
preference :allow_guest_checkout, :boolean, default: true
|
||||
preference :allow_ssl_in_development_and_test, :boolean, default: false
|
||||
preference :allow_ssl_in_production, :boolean, default: true
|
||||
preference :allow_ssl_in_staging, :boolean, default: true
|
||||
# Replace with the name of a zone if you would like to limit the countries
|
||||
|
||||
@@ -87,7 +87,7 @@ module Spree
|
||||
)
|
||||
refund_transaction_response = provider.refund_transaction(refund_transaction)
|
||||
if refund_transaction_response.success?
|
||||
payment.source.update_attributes(
|
||||
payment.source.update(
|
||||
refunded_at: Time.now,
|
||||
refund_transaction_id: refund_transaction_response.RefundTransactionID,
|
||||
state: "refunded",
|
||||
|
||||
@@ -5,7 +5,6 @@ require 'stripe/credit_card_cloner'
|
||||
require 'stripe/authorize_response_patcher'
|
||||
require 'stripe/payment_intent_validator'
|
||||
require 'active_merchant/billing/gateways/stripe_payment_intents'
|
||||
require 'active_merchant/billing/gateways/stripe_decorator'
|
||||
|
||||
module Spree
|
||||
class Gateway
|
||||
@@ -112,6 +111,7 @@ module Spree
|
||||
options[:description] = "Spree Order ID: #{gateway_options[:order_id]}"
|
||||
options[:currency] = gateway_options[:currency]
|
||||
options[:stripe_account] = stripe_account_id
|
||||
options[:execute_threed] = true # Handle 3DS responses
|
||||
options
|
||||
end
|
||||
|
||||
@@ -129,7 +129,19 @@ module Spree
|
||||
payment = fetch_payment(creditcard, gateway_options)
|
||||
raise Stripe::StripeError, I18n.t(:no_pending_payments) unless payment&.response_code
|
||||
|
||||
Stripe::PaymentIntentValidator.new.call(payment.response_code, stripe_account_id)
|
||||
payment_intent_response = Stripe::PaymentIntentValidator.new.
|
||||
call(payment.response_code, stripe_account_id)
|
||||
|
||||
raise_if_not_in_capture_state(payment_intent_response)
|
||||
|
||||
payment.response_code
|
||||
end
|
||||
|
||||
def raise_if_not_in_capture_state(payment_intent_response)
|
||||
state = payment_intent_response.status
|
||||
return if state == 'requires_capture'
|
||||
|
||||
raise Stripe::StripeError, I18n.t(:invalid_payment_state, state: state)
|
||||
end
|
||||
|
||||
def fetch_payment(creditcard, gateway_options)
|
||||
|
||||
@@ -66,7 +66,7 @@ module Spree
|
||||
end
|
||||
|
||||
def update_order
|
||||
order.update!
|
||||
order.update_order!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,9 +17,9 @@ module Spree
|
||||
end
|
||||
|
||||
def update_adjustments
|
||||
adjustment_total = adjustments.additional.map(&:update!).compact.sum
|
||||
included_tax_total = tax_adjustments.inclusive.reload.map(&:update!).compact.sum
|
||||
additional_tax_total = tax_adjustments.additional.reload.map(&:update!).compact.sum
|
||||
adjustment_total = adjustments.additional.map(&:update_adjustment!).compact.sum
|
||||
included_tax_total = tax_adjustments.inclusive.reload.map(&:update_adjustment!).compact.sum
|
||||
additional_tax_total = tax_adjustments.additional.reload.map(&:update_adjustment!).compact.sum
|
||||
|
||||
item.update_columns(
|
||||
included_tax_total: included_tax_total,
|
||||
|
||||
@@ -65,10 +65,10 @@ module Spree
|
||||
# Find line items that are from order sorted by variant name and unit value
|
||||
scope :sorted_by_name_and_unit_value, -> {
|
||||
joins(variant: :product).
|
||||
reorder("
|
||||
reorder(Arel.sql("
|
||||
lower(spree_products.name) asc,
|
||||
lower(spree_variants.display_name) asc,
|
||||
spree_variants.unit_value asc")
|
||||
spree_variants.unit_value asc"))
|
||||
}
|
||||
|
||||
scope :from_order_cycle, lambda { |order_cycle|
|
||||
@@ -230,7 +230,6 @@ module Spree
|
||||
|
||||
# update the order totals, etc.
|
||||
order.create_tax_charge!
|
||||
order.update!
|
||||
end
|
||||
|
||||
def update_inventory_before_destroy
|
||||
|
||||
@@ -35,7 +35,7 @@ module Spree
|
||||
alias_attribute :shipping_address, :ship_address
|
||||
|
||||
has_many :state_changes, as: :stateful
|
||||
has_many :line_items, -> { order('created_at ASC') }, dependent: :destroy
|
||||
has_many :line_items, -> { order('created_at ASC') }, class_name: "Spree::LineItem", dependent: :destroy
|
||||
has_many :payments, dependent: :destroy
|
||||
has_many :return_authorizations, dependent: :destroy, inverse_of: :order
|
||||
has_many :adjustments, -> { order "#{Spree::Adjustment.table_name}.created_at ASC" },
|
||||
@@ -212,7 +212,7 @@ module Spree
|
||||
@updater ||= OrderManagement::Order::Updater.new(self)
|
||||
end
|
||||
|
||||
def update!
|
||||
def update_order!
|
||||
updater.update
|
||||
end
|
||||
|
||||
@@ -243,63 +243,11 @@ module Spree
|
||||
return_authorizations.any?(&:authorized?)
|
||||
end
|
||||
|
||||
# This is currently used when adding a variant to an order in the BackOffice.
|
||||
# Spree::OrderContents#add is equivalent but slightly different from add_variant below.
|
||||
# OrderContents should always be used when modifying an order's line items
|
||||
def contents
|
||||
@contents ||= Spree::OrderContents.new(self)
|
||||
end
|
||||
|
||||
# This is currently used when adding a variant to an order in the FrontOffice.
|
||||
# This add_variant is equivalent but slightly different from Spree::OrderContents#add above.
|
||||
# Spree::OrderContents#add is the more modern version in Spree history
|
||||
# but this add_variant has been customized for OFN FrontOffice.
|
||||
def add_variant(variant, quantity = 1, max_quantity = nil, currency = nil)
|
||||
line_items.reload
|
||||
current_item = find_line_item_by_variant(variant)
|
||||
|
||||
# Notify bugsnag if we get line items with a quantity of zero
|
||||
if quantity == 0
|
||||
Bugsnag.notify(RuntimeError.new("Zero Quantity Line Item"),
|
||||
current_item: current_item.as_json,
|
||||
line_items: line_items.map(&:id),
|
||||
variant: variant.as_json)
|
||||
end
|
||||
|
||||
if current_item
|
||||
current_item.quantity = quantity
|
||||
current_item.max_quantity = max_quantity
|
||||
|
||||
current_item.currency = currency unless currency.nil?
|
||||
current_item.save
|
||||
else
|
||||
current_item = Spree::LineItem.new(quantity: quantity, max_quantity: max_quantity)
|
||||
current_item.variant = variant
|
||||
if currency
|
||||
current_item.currency = currency unless currency.nil?
|
||||
current_item.price = variant.price_in(currency).amount
|
||||
else
|
||||
current_item.price = variant.price
|
||||
end
|
||||
line_items << current_item
|
||||
end
|
||||
|
||||
reload
|
||||
current_item
|
||||
end
|
||||
|
||||
def set_variant_attributes(variant, attributes)
|
||||
line_item = find_line_item_by_variant(variant)
|
||||
|
||||
return unless line_item
|
||||
|
||||
if attributes.key?(:max_quantity) && attributes[:max_quantity].to_i < line_item.quantity
|
||||
attributes[:max_quantity] = line_item.quantity
|
||||
end
|
||||
|
||||
line_item.assign_attributes(attributes)
|
||||
line_item.save!
|
||||
end
|
||||
|
||||
# Associates the specified user with the order.
|
||||
def associate_user!(user)
|
||||
self.user = user
|
||||
@@ -395,7 +343,8 @@ module Spree
|
||||
def deliver_order_confirmation_email
|
||||
return if subscription.present?
|
||||
|
||||
ConfirmOrderJob.perform_later(id)
|
||||
Spree::OrderMailer.confirm_email_for_customer(id).deliver_later
|
||||
Spree::OrderMailer.confirm_email_for_shop(id).deliver_later
|
||||
end
|
||||
|
||||
# Helper methods for checkout steps
|
||||
@@ -517,6 +466,16 @@ module Spree
|
||||
shipments
|
||||
end
|
||||
|
||||
# Clear shipments and move order back to address state unless compete. This is relevant where
|
||||
# an order is part-way through checkout and the user changes items in the cart; in that case
|
||||
# we need to reset the checkout flow to ensure the order is processed correctly.
|
||||
def ensure_updated_shipments
|
||||
if !self.completed? && shipments.any?
|
||||
shipments.destroy_all
|
||||
restart_checkout_flow
|
||||
end
|
||||
end
|
||||
|
||||
def refresh_shipment_rates
|
||||
shipments.map(&:refresh_rates)
|
||||
end
|
||||
@@ -580,12 +539,6 @@ module Spree
|
||||
save!
|
||||
end
|
||||
|
||||
def remove_variant(variant)
|
||||
line_items.reload
|
||||
current_item = find_line_item_by_variant(variant)
|
||||
current_item.andand.destroy
|
||||
end
|
||||
|
||||
def cap_quantity_at_stock!
|
||||
line_items.includes(variant: :stock_items).find_each(&:cap_quantity_at_stock!)
|
||||
end
|
||||
@@ -748,8 +701,8 @@ module Spree
|
||||
def update_adjustment!(adjustment)
|
||||
return if adjustment.finalized?
|
||||
|
||||
adjustment.update!(force: true)
|
||||
update!
|
||||
adjustment.update_adjustment!(force: true)
|
||||
updater.update_totals_and_states
|
||||
end
|
||||
|
||||
# object_params sets the payment amount to the order total, but it does this
|
||||
|
||||
@@ -130,6 +130,13 @@ module Spree
|
||||
steps << "complete" unless steps.include?("complete")
|
||||
steps
|
||||
end
|
||||
|
||||
def restart_checkout_flow
|
||||
update_columns(
|
||||
state: checkout_steps.first,
|
||||
updated_at: Time.zone.now,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,25 +11,79 @@ module Spree
|
||||
# Get current line item for variant if exists
|
||||
# Add variant qty to line_item
|
||||
def add(variant, quantity = 1, shipment = nil)
|
||||
line_item = order.find_line_item_by_variant(variant)
|
||||
add_to_line_item(line_item, variant, quantity, shipment)
|
||||
line_item = add_to_line_item(variant, quantity, shipment)
|
||||
update_shipment(shipment)
|
||||
update_order
|
||||
line_item
|
||||
end
|
||||
|
||||
# Get current line item for variant
|
||||
# Remove variant qty from line_item
|
||||
def remove(variant, quantity = 1, shipment = nil)
|
||||
line_item = order.find_line_item_by_variant(variant)
|
||||
def remove(variant, quantity = nil, shipment = nil)
|
||||
line_item = remove_from_line_item(variant, quantity, shipment)
|
||||
update_shipment(shipment)
|
||||
order.update_order_fees! if order.completed?
|
||||
update_order
|
||||
line_item
|
||||
end
|
||||
|
||||
unless line_item
|
||||
raise ActiveRecord::RecordNotFound, "Line item not found for variant #{variant.sku}"
|
||||
def update_or_create(variant, attributes)
|
||||
line_item = find_line_item_by_variant(variant)
|
||||
|
||||
if line_item
|
||||
line_item.update(attributes)
|
||||
else
|
||||
line_item = Spree::LineItem.new(attributes)
|
||||
line_item.variant = variant
|
||||
line_item.price = variant.price
|
||||
order.line_items << line_item
|
||||
end
|
||||
|
||||
remove_from_line_item(line_item, variant, quantity, shipment)
|
||||
order.reload
|
||||
line_item
|
||||
end
|
||||
|
||||
def update_cart(params)
|
||||
if order.update_attributes(params)
|
||||
discard_empty_line_items
|
||||
update_shipment
|
||||
update_order
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def update_item(line_item, params)
|
||||
if line_item.update_attributes(params)
|
||||
discard_empty_line_items
|
||||
order.update_line_item_fees! line_item
|
||||
order.update_order_fees! if order.completed?
|
||||
update_shipment
|
||||
update_order
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_to_line_item(line_item, variant, quantity, shipment = nil)
|
||||
def discard_empty_line_items
|
||||
order.line_items = order.line_items.select {|li| li.quantity.positive? }
|
||||
end
|
||||
|
||||
def update_shipment(target_shipment = nil)
|
||||
if order.completed? || target_shipment.present?
|
||||
order.update_shipping_fees!
|
||||
else
|
||||
order.ensure_updated_shipments
|
||||
end
|
||||
end
|
||||
|
||||
def add_to_line_item(variant, quantity, shipment = nil)
|
||||
line_item = find_line_item_by_variant(variant)
|
||||
|
||||
if line_item
|
||||
line_item.target_shipment = shipment
|
||||
line_item.quantity += quantity.to_i
|
||||
@@ -40,23 +94,37 @@ module Spree
|
||||
end
|
||||
|
||||
line_item.save
|
||||
order.reload
|
||||
line_item
|
||||
end
|
||||
|
||||
def remove_from_line_item(line_item, _variant, quantity, shipment = nil)
|
||||
line_item.quantity += -quantity
|
||||
def remove_from_line_item(variant, quantity, shipment = nil)
|
||||
line_item = find_line_item_by_variant(variant, true)
|
||||
|
||||
quantity.present? ? line_item.quantity += -quantity : line_item.quantity = 0
|
||||
line_item.target_shipment = shipment
|
||||
|
||||
if line_item.quantity == 0
|
||||
Spree::OrderInventory.new(order).verify(line_item, shipment)
|
||||
line_item.destroy
|
||||
else
|
||||
line_item.save!
|
||||
end
|
||||
|
||||
order.reload
|
||||
line_item
|
||||
end
|
||||
|
||||
def find_line_item_by_variant(variant, raise_error = false)
|
||||
line_item = order.find_line_item_by_variant(variant)
|
||||
|
||||
if !line_item.present? && raise_error
|
||||
raise ActiveRecord::RecordNotFound, "Line item not found for variant #{variant.sku}"
|
||||
end
|
||||
|
||||
line_item
|
||||
end
|
||||
|
||||
def update_order
|
||||
order.update_order!
|
||||
order.reload
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -50,6 +50,7 @@ module Spree
|
||||
scope :failed, -> { with_state('failed') }
|
||||
scope :valid, -> { where('state NOT IN (?)', %w(failed invalid)) }
|
||||
scope :authorization_action_required, -> { where.not(cvv_response_message: nil) }
|
||||
scope :with_payment_intent, ->(code) { where(response_code: code) }
|
||||
|
||||
# order state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
|
||||
state_machine initial: :checkout do
|
||||
@@ -205,7 +206,7 @@ module Spree
|
||||
end
|
||||
|
||||
def update_order
|
||||
order.update!
|
||||
OrderManagement::Order::Updater.new(order).after_payment_update(self)
|
||||
end
|
||||
|
||||
# Necessary because some payment gateways will refuse payments with
|
||||
|
||||
@@ -66,7 +66,7 @@ module Spree
|
||||
order.shipped_shipments.collect{ |s| s.inventory_units.to_a }.flatten
|
||||
end
|
||||
|
||||
# Used when Adjustment#update! wants to update the related adjustment
|
||||
# Used when Adjustment#update_adjustment! wants to update the related adjustment
|
||||
def compute_amount(*_args)
|
||||
-amount.abs
|
||||
end
|
||||
@@ -105,7 +105,7 @@ module Spree
|
||||
)
|
||||
|
||||
order.return if inventory_units.all?(&:returned?)
|
||||
order.update!
|
||||
order.update_order!
|
||||
end
|
||||
|
||||
def allow_receive?
|
||||
|
||||
@@ -160,10 +160,6 @@ module Spree
|
||||
Spree::Money.new(item_cost, currency: currency)
|
||||
end
|
||||
|
||||
def editable_by?(_user)
|
||||
!shipped?
|
||||
end
|
||||
|
||||
def update_amounts
|
||||
return unless fee_adjustment&.amount != cost
|
||||
|
||||
@@ -187,14 +183,6 @@ module Spree
|
||||
@scoper ||= OpenFoodNetwork::ScopeVariantToHub.new(order.distributor)
|
||||
end
|
||||
|
||||
def line_items
|
||||
if order.complete?
|
||||
order.line_items.select { |li| inventory_units.pluck(:variant_id).include?(li.variant_id) }
|
||||
else
|
||||
order.line_items
|
||||
end
|
||||
end
|
||||
|
||||
def finalize!
|
||||
InventoryUnit.finalize_units!(inventory_units)
|
||||
manifest.each { |item| manifest_unstock(item) }
|
||||
@@ -295,6 +283,15 @@ module Spree
|
||||
|
||||
private
|
||||
|
||||
def line_items
|
||||
if order.complete?
|
||||
inventory_unit_ids = inventory_units.pluck(:variant_id)
|
||||
order.line_items.select { |li| inventory_unit_ids.include?(li.variant_id) }
|
||||
else
|
||||
order.line_items
|
||||
end
|
||||
end
|
||||
|
||||
def manifest_unstock(item)
|
||||
stock_location.unstock item.variant, item.quantity, self
|
||||
end
|
||||
@@ -309,7 +306,7 @@ module Spree
|
||||
record = true
|
||||
while record
|
||||
random = "H#{Array.new(11) { rand(9) }.join}"
|
||||
record = self.class.find_by(number: random)
|
||||
record = self.class.default_scoped.find_by(number: random)
|
||||
end
|
||||
self.number = random
|
||||
end
|
||||
|
||||
@@ -50,7 +50,7 @@ module Spree
|
||||
category = TaxCategory.includes(:tax_rates).find_by(is_default: true)
|
||||
return 0 unless category
|
||||
|
||||
address ||= Address.new(country_id: Spree::Config[:default_country_id])
|
||||
address ||= Address.new(country_id: DefaultCountry.id)
|
||||
rate = category.tax_rates.detect { |tax_rate| tax_rate.zone.include? address }.try(:amount)
|
||||
|
||||
rate || 0
|
||||
|
||||
22
app/models/terms_of_service_file.rb
Normal file
22
app/models/terms_of_service_file.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class TermsOfServiceFile < ApplicationRecord
|
||||
has_attached_file :attachment
|
||||
|
||||
validates :attachment, presence: true
|
||||
|
||||
# The most recently uploaded file is the current one.
|
||||
def self.current
|
||||
order(:id).last
|
||||
end
|
||||
|
||||
def self.current_url
|
||||
current&.attachment&.url || Spree::Config.footer_tos_url
|
||||
end
|
||||
|
||||
# If no file has been uploaded, we don't know when the old terms have
|
||||
# been updated last. So we return the most recent possible update time.
|
||||
def self.updated_at
|
||||
current&.updated_at || Time.zone.now
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
class Api::LineItemSerializer < ActiveModel::Serializer
|
||||
attributes :id, :quantity, :max_quantity, :price
|
||||
attributes :id, :quantity, :max_quantity, :price, :order_id
|
||||
|
||||
has_one :variant, serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
@@ -22,7 +22,7 @@ module Api
|
||||
end
|
||||
|
||||
def item_count
|
||||
object.line_items.sum(:quantity)
|
||||
object.line_items.sum(&:quantity)
|
||||
end
|
||||
|
||||
def completed_at
|
||||
|
||||
@@ -3,10 +3,9 @@ require "open_food_network/scope_variant_to_hub"
|
||||
class Api::ProductSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :permalink, :meta_keywords
|
||||
attributes :group_buy, :notes, :description, :description_html
|
||||
attributes :properties_with_values, :price
|
||||
attributes :properties_with_values
|
||||
|
||||
has_many :variants, serializer: Api::VariantSerializer
|
||||
has_one :master, serializer: Api::VariantSerializer
|
||||
|
||||
has_one :primary_taxon, serializer: Api::TaxonSerializer
|
||||
has_many :taxons, serializer: Api::IdSerializer
|
||||
@@ -32,18 +31,6 @@ class Api::ProductSerializer < ActiveModel::Serializer
|
||||
options[:variants][object.id] || []
|
||||
end
|
||||
|
||||
def master
|
||||
options[:master_variants][object.id].andand.first
|
||||
end
|
||||
|
||||
def price
|
||||
if options[:enterprise_fee_calculator]
|
||||
object.master.price + options[:enterprise_fee_calculator].indexed_fees_for(object.master)
|
||||
else
|
||||
object.master.price_with_fees(options[:current_distributor], options[:current_order_cycle])
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sanitizer
|
||||
|
||||
@@ -3,23 +3,22 @@ require 'open_food_network/scope_variant_to_hub'
|
||||
# Previously Spree::OrderPopulator. Modified to work with max_quantity and variant overrides.
|
||||
|
||||
class CartService
|
||||
attr_accessor :order, :currency
|
||||
attr_reader :variants_h
|
||||
attr_accessor :order
|
||||
attr_reader :errors
|
||||
|
||||
def initialize(order)
|
||||
@order = order
|
||||
@currency = order.currency
|
||||
@errors = ActiveModel::Errors.new(self)
|
||||
end
|
||||
|
||||
def populate(from_hash, overwrite = false)
|
||||
def populate(from_hash)
|
||||
@distributor, @order_cycle = distributor_and_order_cycle
|
||||
|
||||
variants_data = read_variants_hash(from_hash)
|
||||
|
||||
@order.with_lock do
|
||||
variants_data = read_variants from_hash
|
||||
attempt_cart_add_variants variants_data
|
||||
overwrite_variants variants_data if overwrite
|
||||
overwrite_variants variants_data
|
||||
end
|
||||
valid?
|
||||
end
|
||||
@@ -34,10 +33,10 @@ class CartService
|
||||
loaded_variants = indexed_variants(variants_data)
|
||||
|
||||
variants_data.each do |variant_data|
|
||||
loaded_variant = loaded_variants[variant_data[:variant_id].to_i]
|
||||
loaded_variant = loaded_variants[variant_data[:variant_id]]
|
||||
|
||||
if loaded_variant.deleted?
|
||||
remove_deleted_variant(loaded_variant)
|
||||
if loaded_variant.deleted? || !variant_data[:quantity].positive?
|
||||
cart_remove(loaded_variant)
|
||||
next
|
||||
end
|
||||
|
||||
@@ -57,15 +56,7 @@ class CartService
|
||||
end
|
||||
end
|
||||
|
||||
def remove_deleted_variant(variant)
|
||||
line_item_for_variant(variant).andand.destroy
|
||||
end
|
||||
|
||||
def attempt_cart_add(variant, quantity, max_quantity = nil)
|
||||
quantity = quantity.to_i
|
||||
max_quantity = max_quantity.to_i if max_quantity
|
||||
return unless quantity > 0
|
||||
|
||||
scoper.scope(variant)
|
||||
return unless valid_variant?(variant)
|
||||
|
||||
@@ -73,27 +64,37 @@ class CartService
|
||||
end
|
||||
|
||||
def cart_add(variant, quantity, max_quantity)
|
||||
quantity_to_add, max_quantity_to_add = quantities_to_add(variant, quantity, max_quantity)
|
||||
if quantity_to_add > 0
|
||||
@order.add_variant(variant, quantity_to_add, max_quantity_to_add, currency)
|
||||
attributes = final_quantities(variant, quantity, max_quantity)
|
||||
|
||||
if attributes[:quantity].positive?
|
||||
@order.contents.update_or_create(variant, attributes)
|
||||
else
|
||||
@order.remove_variant variant
|
||||
cart_remove(variant)
|
||||
end
|
||||
end
|
||||
|
||||
def quantities_to_add(variant, quantity, max_quantity)
|
||||
def cart_remove(variant)
|
||||
begin
|
||||
order.contents.remove(variant)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
# Nothing to remove; no line items for this variant were found.
|
||||
end
|
||||
end
|
||||
|
||||
def final_quantities(variant, quantity, max_quantity)
|
||||
# If not enough stock is available, add as much as we can to the cart
|
||||
on_hand = variant.on_hand
|
||||
on_hand = [quantity, max_quantity].compact.max if variant.on_demand
|
||||
quantity_to_add = [quantity, on_hand].min
|
||||
max_quantity_to_add = max_quantity # max_quantity is not capped
|
||||
final_quantity = [quantity, on_hand].min
|
||||
final_max_quantity = max_quantity # max_quantity is not capped
|
||||
|
||||
[quantity_to_add, max_quantity_to_add]
|
||||
{ quantity: final_quantity, max_quantity: final_max_quantity }
|
||||
end
|
||||
|
||||
def overwrite_variants(variants)
|
||||
variants_removed(variants).each do |id|
|
||||
cart_remove(id)
|
||||
variants_removed(variants).each do |variant_id|
|
||||
variant = Spree::Variant.with_deleted.find(variant_id)
|
||||
cart_remove(variant)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -101,27 +102,25 @@ class CartService
|
||||
@scoper ||= OpenFoodNetwork::ScopeVariantToHub.new(@distributor)
|
||||
end
|
||||
|
||||
def read_variants(data)
|
||||
@variants_h = read_variants_hash(data)
|
||||
end
|
||||
|
||||
def read_variants_hash(data)
|
||||
variants_array = []
|
||||
(data[:variants] || []).each do |variant_id, quantity|
|
||||
if quantity.is_a?(ActionController::Parameters)
|
||||
variants_array.push({ variant_id: variant_id, quantity: quantity[:quantity], max_quantity: quantity[:max_quantity] })
|
||||
variants_array.push({
|
||||
variant_id: variant_id.to_i,
|
||||
quantity: quantity[:quantity].to_i,
|
||||
max_quantity: quantity[:max_quantity].to_i
|
||||
})
|
||||
else
|
||||
variants_array.push({ variant_id: variant_id, quantity: quantity })
|
||||
variants_array.push({
|
||||
variant_id: variant_id.to_i,
|
||||
quantity: quantity.to_i
|
||||
})
|
||||
end
|
||||
end
|
||||
variants_array
|
||||
end
|
||||
|
||||
def cart_remove(variant_id)
|
||||
variant = Spree::Variant.find(variant_id)
|
||||
@order.remove_variant(variant)
|
||||
end
|
||||
|
||||
def distributor_and_order_cycle
|
||||
[@order.distributor, @order.order_cycle]
|
||||
end
|
||||
@@ -131,7 +130,7 @@ class CartService
|
||||
li = line_item_for_variant loaded_variant
|
||||
|
||||
li_added = li.nil? && (variant_data[:quantity].to_i > 0 || variant_data[:max_quantity].to_i > 0)
|
||||
li_quantity_changed = li.present? && li.quantity.to_i != variant_data[:quantity].to_i
|
||||
li_quantity_changed = li.present? && li.quantity != variant_data[:quantity].to_i
|
||||
li_max_quantity_changed = li.present? && li.max_quantity.to_i != variant_data[:max_quantity].to_i
|
||||
|
||||
li_added || li_quantity_changed || li_max_quantity_changed
|
||||
|
||||
13
app/services/default_country.rb
Normal file
13
app/services/default_country.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class DefaultCountry
|
||||
def self.id
|
||||
country.id
|
||||
end
|
||||
|
||||
def self.code
|
||||
country.iso
|
||||
end
|
||||
|
||||
def self.country
|
||||
Spree::Country.find_by(iso: ENV["DEFAULT_COUNTRY_CODE"]) || Spree::Country.first
|
||||
end
|
||||
end
|
||||
@@ -2,9 +2,8 @@
|
||||
# by setting entries on the Spree Config
|
||||
# and initializing Spree:MailSettings that uses the Spree::Config.
|
||||
class MailConfiguration
|
||||
# @param entries [Hash] Spree Config entries
|
||||
def self.entries=(entries)
|
||||
entries.each do |name, value|
|
||||
def self.apply!
|
||||
configuration.each do |name, value|
|
||||
Spree::Config[name] = value
|
||||
end
|
||||
apply_mail_settings
|
||||
@@ -12,6 +11,21 @@ class MailConfiguration
|
||||
|
||||
private
|
||||
|
||||
def self.configuration
|
||||
{
|
||||
mail_host: ENV.fetch('MAIL_HOST'),
|
||||
mail_domain: ENV.fetch('MAIL_DOMAIN'),
|
||||
mail_port: ENV.fetch('MAIL_PORT'),
|
||||
mail_auth_type: ENV.fetch('MAIL_AUTH_TYPE', 'login'),
|
||||
smtp_username: ENV.fetch('SMTP_USERNAME'),
|
||||
smtp_password: ENV.fetch('SMTP_PASSWORD'),
|
||||
secure_connection_type: ENV.fetch('MAIL_SECURE_CONNECTION', 'None'),
|
||||
mails_from: ENV.fetch('MAILS_FROM', "no-reply@#{ENV.fetch('MAIL_DOMAIN')}"),
|
||||
mail_bcc: ENV.fetch('MAIL_BCC', ''),
|
||||
intercept_email: ''
|
||||
}
|
||||
end
|
||||
|
||||
def self.apply_mail_settings
|
||||
Spree::Core::MailSettings.init
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ class OrderCheckoutRestart
|
||||
clear_shipments
|
||||
clear_payments
|
||||
|
||||
order.reload.update!
|
||||
order.reload.update_order!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -19,12 +19,9 @@ class OrderFeesHandler
|
||||
|
||||
create_line_item_fees!
|
||||
create_order_fees!
|
||||
|
||||
order.updater.update_totals
|
||||
order.updater.persist_totals
|
||||
end
|
||||
|
||||
order.update!
|
||||
order.update_order!
|
||||
end
|
||||
|
||||
def create_line_item_fees!
|
||||
@@ -43,13 +40,13 @@ class OrderFeesHandler
|
||||
|
||||
def update_line_item_fees!(line_item)
|
||||
line_item.adjustments.enterprise_fee.each do |fee|
|
||||
fee.update!(line_item, force: true)
|
||||
fee.update_adjustment!(line_item, force: true)
|
||||
end
|
||||
end
|
||||
|
||||
def update_order_fees!
|
||||
order.adjustments.enterprise_fee.where(adjustable_type: 'Spree::Order').each do |fee|
|
||||
fee.update!(order, force: true)
|
||||
fee.update_adjustment!(order, force: true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ class OrderSyncer
|
||||
distributor_id: shop_id)
|
||||
update_associations_for(order)
|
||||
line_item_syncer.sync!(order)
|
||||
order.update_order!
|
||||
order.save
|
||||
end
|
||||
end
|
||||
|
||||
@@ -44,7 +44,7 @@ module Permissions
|
||||
def filtered_orders(orders)
|
||||
return orders unless filter_orders?
|
||||
|
||||
orders.complete.not_state(:canceled).search(search_params).result
|
||||
orders.complete.not_state(:canceled).ransack(search_params).result
|
||||
end
|
||||
|
||||
def filter_orders?
|
||||
|
||||
@@ -23,21 +23,20 @@ class ProcessPaymentIntent
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(payment_intent, order, last_payment = nil)
|
||||
def initialize(payment_intent, order)
|
||||
@payment_intent = payment_intent
|
||||
@order = order
|
||||
@last_payment = last_payment.presence || OrderPaymentFinder.new(order).last_payment
|
||||
@payment = order.payments.pending.with_payment_intent(payment_intent).first
|
||||
end
|
||||
|
||||
def call!
|
||||
validate_intent!
|
||||
return Result.new(ok: false) unless valid?
|
||||
return Result.new(ok: false) unless payment.present? && ready_for_capture?
|
||||
return Result.new(ok: true) if already_processed?
|
||||
|
||||
OrderWorkflow.new(order).next
|
||||
process_payment
|
||||
|
||||
if last_payment.can_complete?
|
||||
last_payment.complete!
|
||||
last_payment.mark_as_processed
|
||||
if payment.reload.completed?
|
||||
payment.mark_as_processed
|
||||
|
||||
Result.new(ok: true)
|
||||
else
|
||||
@@ -50,18 +49,29 @@ class ProcessPaymentIntent
|
||||
|
||||
private
|
||||
|
||||
attr_reader :order, :payment_intent, :last_payment
|
||||
attr_reader :order, :payment_intent, :payment
|
||||
|
||||
def valid?
|
||||
order.present? && matches_last_payment?
|
||||
def process_payment
|
||||
if order.state == "payment"
|
||||
# Moves the order to completed, which calls #process_payments!
|
||||
OrderWorkflow.new(order).next
|
||||
else
|
||||
order.process_payments!
|
||||
end
|
||||
end
|
||||
|
||||
def validate_intent!
|
||||
Stripe::PaymentIntentValidator.new.call(payment_intent, stripe_account_id)
|
||||
def ready_for_capture?
|
||||
payment_intent_status == 'requires_capture'
|
||||
end
|
||||
|
||||
def matches_last_payment?
|
||||
last_payment&.state == "pending" && last_payment&.response_code == payment_intent
|
||||
def already_processed?
|
||||
payment_intent_status == 'succeeded'
|
||||
end
|
||||
|
||||
def payment_intent_status
|
||||
@payment_intent_status ||= Stripe::PaymentIntentValidator.new.
|
||||
call(payment_intent, stripe_account_id).
|
||||
status
|
||||
end
|
||||
|
||||
def stripe_account_id
|
||||
@@ -69,6 +79,6 @@ class ProcessPaymentIntent
|
||||
end
|
||||
|
||||
def preferred_enterprise_id
|
||||
last_payment.payment_method.preferred_enterprise_id
|
||||
payment.payment_method.preferred_enterprise_id
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,7 +19,6 @@ class ProductsRenderer
|
||||
current_order_cycle: order_cycle,
|
||||
current_distributor: distributor,
|
||||
variants: variants_for_shop_by_id,
|
||||
master_variants: master_variants_for_shop_by_id,
|
||||
enterprise_fee_calculator: enterprise_fee_calculator).to_json
|
||||
end
|
||||
|
||||
@@ -31,7 +30,9 @@ class ProductsRenderer
|
||||
return unless order_cycle
|
||||
|
||||
@products ||= begin
|
||||
results = distributed_products.products_relation.order(taxon_order)
|
||||
results = distributed_products.
|
||||
products_relation.
|
||||
order(Arel.sql(taxon_order))
|
||||
|
||||
filter_and_paginate(results).
|
||||
each { |product| product_scoper.scope(product) } # Scope results with variant_overrides
|
||||
@@ -84,10 +85,6 @@ class ProductsRenderer
|
||||
index_by_product_id variants_for_shop.reject(&:is_master)
|
||||
end
|
||||
|
||||
def master_variants_for_shop_by_id
|
||||
index_by_product_id variants_for_shop.select(&:is_master)
|
||||
end
|
||||
|
||||
def index_by_product_id(variants)
|
||||
variants.each_with_object({}) do |v, vs|
|
||||
vs[v.product_id] ||= []
|
||||
|
||||
@@ -77,6 +77,6 @@ class TaxRateFinder
|
||||
approximation = (included_tax / (amount - included_tax))
|
||||
return [] if approximation.infinite? || approximation.zero? || approximation.nan?
|
||||
|
||||
[Spree::TaxRate.order("ABS(amount - #{approximation})").first]
|
||||
[Spree::TaxRate.order(Arel.sql("ABS(amount - #{approximation})")).first]
|
||||
end
|
||||
end
|
||||
|
||||
11
app/services/terms_of_service.rb
Normal file
11
app/services/terms_of_service.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class TermsOfService
|
||||
def self.tos_accepted?(customer, distributor = nil)
|
||||
return false unless accepted_at = customer&.terms_and_conditions_accepted_at
|
||||
|
||||
if distributor
|
||||
accepted_at > distributor.terms_and_conditions_updated_at
|
||||
else
|
||||
accepted_at > TermsOfServiceFile.updated_at
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@
|
||||
= "admin.enterprises"
|
||||
|
||||
= admin_inject_available_countries(module: 'admin.enterprises')
|
||||
= admin_inject_json "admin.enterprises", "defaultCountryID", Spree::Config[:default_country_id]
|
||||
= admin_inject_json "admin.enterprises", "defaultCountryID", DefaultCountry.id
|
||||
|
||||
-# Form
|
||||
|
||||
|
||||
16
app/views/admin/terms_of_service_files/show.html.haml
Normal file
16
app/views/admin/terms_of_service_files/show.html.haml
Normal file
@@ -0,0 +1,16 @@
|
||||
- content_for :page_title do
|
||||
= t(".title")
|
||||
|
||||
.admin-current-terms-of-service
|
||||
- if @current_file
|
||||
%p= t(".current_terms_html", tos_link: link_to(t(".terms_of_service"), @current_file.attachment.url), datetime: @current_file.updated_at)
|
||||
%p= link_to t(".delete"), main_app.admin_terms_of_service_files_path, method: "delete", data: { confirm: t(".confirm_delete") }
|
||||
- else
|
||||
%p
|
||||
= t(".no_files")
|
||||
= t(".using_default_terms_html", tos_link: link_to_platform_terms)
|
||||
|
||||
= form_for [main_app, :admin, @new_file] do |f|
|
||||
= f.label :attachment
|
||||
= f.file_field :attachment
|
||||
= f.submit
|
||||
@@ -1,4 +1,4 @@
|
||||
%p
|
||||
%input{ type: 'checkbox', id: 'accept_terms', ng: { model: "terms_and_conditions_accepted", init: "terms_and_conditions_accepted=false" } }
|
||||
%input{ type: 'checkbox', id: 'accept_terms', ng: { model: "terms_and_conditions_accepted", init: "terms_and_conditions_accepted = #{all_terms_and_conditions_already_accepted?}" } }
|
||||
%label.small{for: "accept_terms"}
|
||||
= t('.message_html', terms_and_conditions_link: link_to( t(".terms_and_conditions"), current_order.distributor.terms_and_conditions.url, target: '_blank'), tos_link: link_to(t(".terms_of_service"), Spree::Config.footer_tos_url, target: "_blank"))
|
||||
= t('.message_html', terms_and_conditions_link: link_to( t(".terms_and_conditions"), current_order.distributor.terms_and_conditions.url, target: '_blank'), tos_link: link_to_platform_terms)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
= validated_input t(:postcode), "order.bill_address.zipcode"
|
||||
|
||||
.small-6.columns.right
|
||||
= validated_select t(:country), "order.bill_address.country_id", {}, {"ng-init" => "order.bill_address.country_id = order.bill_address.country_id || #{Spree::Config[:default_country_id]}", "ng-options" => "c.id as c.name for c in countries"}
|
||||
= validated_select t(:country), "order.bill_address.country_id", {}, {"ng-init" => "order.bill_address.country_id = order.bill_address.country_id || #{DefaultCountry.id}", "ng-options" => "c.id as c.name for c in countries"}
|
||||
|
||||
.row
|
||||
.small-12.columns.text-right
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%p
|
||||
%input{ type: "checkbox", id: "platform_tos_accepted", ng: { model: "platform_tos_accepted", init: "platform_tos_accepted = false" } }
|
||||
%input{ type: "checkbox", id: "platform_tos_accepted", ng: { model: "platform_tos_accepted", init: "platform_tos_accepted = #{platform_tos_already_accepted?}" } }
|
||||
%label.small{for: "platform_tos_accepted"}
|
||||
= t(".message_html", tos_link: link_to(t(".terms_of_service"), Spree::Config.footer_tos_url, target: "_blank"))
|
||||
= t(".message_html", tos_link: link_to_platform_terms)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
.small-6.columns
|
||||
= validated_input t(:postcode), "order.ship_address.zipcode"
|
||||
.small-6.columns.right
|
||||
= validated_select t(:country), "order.ship_address.country_id", {}, {"ng-init" => "order.ship_address.country_id = order.ship_address.country_id || #{Spree::Config[:default_country_id]}", "ng-options" => "c.id as c.name for c in countries"}
|
||||
= validated_select t(:country), "order.ship_address.country_id", {}, {"ng-init" => "order.ship_address.country_id = order.ship_address.country_id || #{DefaultCountry.id}", "ng-options" => "c.id as c.name for c in countries"}
|
||||
.row
|
||||
.small-6.columns
|
||||
= validated_input t(:phone), "order.ship_address.phone"
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
%tr
|
||||
%td{:align => "center"}
|
||||
%p
|
||||
%a{:href => "#{ URI.join(main_app.root_url, Spree::Config.footer_tos_url).to_s }", :target => "_blank"}
|
||||
= t :terms_of_service
|
||||
= link_to_platform_terms
|
||||
|
|
||||
%a{:href => "#{ main_app.root_url }"}
|
||||
= Spree::Config[:site_name]
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
.small-12.medium-8.large-8.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_country' }= t(".country_field")
|
||||
%select.chunky{ id: 'enterprise_country', name: 'country', required: true, ng: { init: "setDefaultCountry(#{Spree::Config[:default_country_id]})", model: 'enterprise.country', options: 'c as c.name for c in countries' } }
|
||||
%select.chunky{ id: 'enterprise_country', name: 'country', required: true, ng: { init: "setDefaultCountry(#{DefaultCountry.id})", model: 'enterprise.country', options: 'c as c.name for c in countries' } }
|
||||
%span.error{ ng: { show: "details.country.$error.required && submitted" } }
|
||||
= t(".country_field_error")
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
.small-12.medium-6.columns{'ng-hide' => '!tos_required' }
|
||||
%p.tos-message
|
||||
#{t(:enterprise_tos_message)}
|
||||
%a{href: Spree::Config.footer_tos_url, target: "_blank" } #{t(:enterprise_tos_link_text)}
|
||||
= link_to_platform_terms
|
||||
%p.tos-checkbox
|
||||
%input{ type: 'checkbox', name: 'accept_terms', id: 'accept_terms', ng: { model: "tos_accepted" } }
|
||||
%label{for: "accept_terms"} #{t(:enterprise_tos_agree)}
|
||||
|
||||
@@ -100,8 +100,7 @@
|
||||
.small-12.medium-5.columns.text-left
|
||||
%p.text-small
|
||||
= t '.footer_legal_call'
|
||||
%a{href: Spree::Config.footer_tos_url, target: "_blank"}
|
||||
= t '.footer_legal_tos'
|
||||
= link_to_platform_terms
|
||||
|
|
||||
= t '.footer_legal_visit'
|
||||
%a{href:"https://github.com/openfoodfoundation/openfoodnetwork", target: "_blank"} GitHub
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
- if Rails.env.test?
|
||||
%script{type: "text/javascript"}
|
||||
= render file: "spec/support/fixtures/stripejs-mock.js"
|
||||
= raw render file: "spec/support/fixtures/stripejs-mock.js"
|
||||
- else
|
||||
%script{src: "https://js.stripe.com/v3/", type: "text/javascript"}
|
||||
|
||||
@@ -23,17 +23,16 @@
|
||||
%span.quantity {{ line_item.quantity }}
|
||||
%td
|
||||
.total-price.text-right {{ line_item.total_price | localizeCurrency }}
|
||||
- if feature? :unit_price, spree_current_user
|
||||
.unit-price
|
||||
%div{:style => "margin-right: 5px"}
|
||||
%question-mark-with-tooltip{"question-mark-with-tooltip" => "_",
|
||||
"question-mark-with-tooltip-append-to-body" => "true",
|
||||
"question-mark-with-tooltip-placement" => "top",
|
||||
"question-mark-with-tooltip-animation" => true,
|
||||
key: "'js.shopfront.unit_price_tooltip'",
|
||||
context: "'cart-sidebar'"}
|
||||
.options-text
|
||||
{{ line_item.variant.unit_price_price | localizeCurrency }} / {{ line_item.variant.unit_price_unit }}
|
||||
.unit-price
|
||||
%div{:style => "margin-right: 5px"}
|
||||
%question-mark-with-tooltip{"question-mark-with-tooltip" => "_",
|
||||
"question-mark-with-tooltip-append-to-body" => "true",
|
||||
"question-mark-with-tooltip-placement" => "top",
|
||||
"question-mark-with-tooltip-animation" => true,
|
||||
key: "'js.shopfront.unit_price_tooltip'",
|
||||
context: "'cart-sidebar'"}
|
||||
.options-text
|
||||
{{ line_item.variant.unit_price_price | localizeCurrency }} / {{ line_item.variant.unit_price_unit }}
|
||||
|
||||
.cart-empty{"ng-show" => "Cart.line_items.length == 0"}
|
||||
%p
|
||||
|
||||
@@ -13,10 +13,7 @@
|
||||
%product.animate-repeat{"ng-controller" => "ProductNodeCtrl", "ng-repeat" => "product in Products.products track by product.id", "id" => "product-{{ product.id }}"}
|
||||
= render "shop/products/summary"
|
||||
.shop-variants
|
||||
- if feature? :unit_price, spree_current_user
|
||||
%shop-variant-with-unit-price{showunitprice: 'true', variant: 'variant', "ng-repeat" => "variant in product.variants | orderBy: ['name_to_display','unit_value'] track by variant.id", "id" => "variant-{{ variant.id }}", "ng-class" => "{'out-of-stock': !variant.on_demand && variant.on_hand == 0}"}
|
||||
- else
|
||||
%shop-variant{variant: 'variant', "ng-repeat" => "variant in product.variants | orderBy: ['name_to_display','unit_value'] track by variant.id", "id" => "variant-{{ variant.id }}", "ng-class" => "{'out-of-stock': !variant.on_demand && variant.on_hand == 0}"}
|
||||
%shop-variant{variant: 'variant', "ng-repeat" => "variant in product.variants | orderBy: ['name_to_display','unit_value'] track by variant.id", "id" => "variant-{{ variant.id }}", "ng-class" => "{'out-of-stock': !variant.on_demand && variant.on_hand == 0}"}
|
||||
%product{"ng-show" => "Products.loading"}
|
||||
.summary
|
||||
.small-12.columns.text-center
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
= label_tag(key, Spree.t(key)) + tag(:br) if type == :boolean
|
||||
%fieldset.legal.no-border-bottom
|
||||
%legend{:align => "center"}= t('.legal_settings')
|
||||
.field
|
||||
= label_tag(:footer_tos_url, t('.footer_tos_url')) + tag(:br)
|
||||
= preference_field_tag(:footer_tos_url, Spree::Config[:footer_tos_url], type: Spree::Config.preference_type(:footer_tos_url))
|
||||
.field
|
||||
= preference_field_tag(:enterprises_require_tos, Spree::Config[:enterprises_require_tos], :type => Spree::Config.preference_type(:enterprises_require_tos))
|
||||
= label_tag(:enterprises_require_tos, t('.enterprises_require_tos')) + tag(:br)
|
||||
|
||||
@@ -26,4 +26,4 @@
|
||||
var shipments = [];
|
||||
- @order.shipments.each do |shipment|
|
||||
shipments.push(#{shipment.to_json(:root => false, :include => [:inventory_units, :stock_location]).html_safe});
|
||||
= render :partial => 'spree/admin/shared/update_order_state', :handlers => [:erb]
|
||||
= render :partial => 'spree/admin/shared/update_order_state', :handlers => [:erb], :formats => [:js]
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
%th.final_weight_volume{ 'ng-show' => 'columns.final_weight_volume.visible' }
|
||||
= t("admin.orders.bulk_management.weight_volume")
|
||||
%th.price{ 'ng-show' => 'columns.price.visible' }
|
||||
= "#{t('admin.price')} (#{currency_symbol})"
|
||||
= "#{t('admin.price')} (#{Spree::Money.currency_symbol})"
|
||||
%th.actions
|
||||
%th.actions
|
||||
= t("admin.orders.bulk_management.ask")
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
%span.centered.three.columns
|
||||
= t "spree_admin_enterprises_fees"
|
||||
%div.sixteen.columns.alpha.list
|
||||
- @enterprises.each do |enterprise|
|
||||
= render 'enterprise_row', { enterprise: enterprise }
|
||||
= render partial: 'enterprise_row', collection: @enterprises, as: :enterprise
|
||||
|
||||
%a.sixteen.columns.alpha.button.bottom.blue{ href: "#{main_app.admin_enterprises_path}" }
|
||||
= t "spree_admin_overview_enterprises_footer"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
%br
|
||||
%select.fullwidth{ id: 'category_filter', 'ofn-select2-min-search' => 5, ng: {model: 'q.categoryFilter', options: 'taxon.id as taxon.name for taxon in taxons'} }
|
||||
.filter_select.three.columns
|
||||
%label{ for: 'import_filter' } Import Date
|
||||
%label{ for: 'import_filter' }= t 'import_date'
|
||||
%br
|
||||
%select.fullwidth{ id: 'import_date_filter', 'ofn-select2-min-search' => 5, ng: {model: 'q.importDateFilter', init: "importDates = #{@import_dates}; showLatestImport = #{@show_latest_import}", options: 'date.id as date.name for date in importDates'} }
|
||||
|
||||
|
||||
@@ -52,20 +52,19 @@
|
||||
%br/
|
||||
= f.text_field :price, { "class" => "fullwidth", "ng-model" => "product.price" }
|
||||
= f.error_message_on :price
|
||||
- if feature? :unit_price, spree_current_user
|
||||
.four.columns{ ng: { app: 'ofn.admin'}}
|
||||
= f.field_container :unit_price do
|
||||
%div{style: "display: flex"}
|
||||
= f.label :unit_price, t(".unit_price")
|
||||
%question-mark-with-tooltip{"question-mark-with-tooltip" => "_",
|
||||
"question-mark-with-tooltip-append-to-body" => "true",
|
||||
"question-mark-with-tooltip-placement" => "top",
|
||||
"question-mark-with-tooltip-animation" => true,
|
||||
key: "'js.admin.unit_price_tooltip'"}
|
||||
%input{ "type" => "text", "id" => "product_unit_price", "name" => "product[unit_price]",
|
||||
"class" => 'fullwidth', "disabled" => true, "ng-model" => "unit_price"}
|
||||
%div{style: "color: black"}
|
||||
= t(".unit_price_legend")
|
||||
.four.columns{ ng: { app: 'ofn.admin'}}
|
||||
= f.field_container :unit_price do
|
||||
%div{style: "display: flex"}
|
||||
= f.label :unit_price, t(".unit_price")
|
||||
%question-mark-with-tooltip{"question-mark-with-tooltip" => "_",
|
||||
"question-mark-with-tooltip-append-to-body" => "true",
|
||||
"question-mark-with-tooltip-placement" => "top",
|
||||
"question-mark-with-tooltip-animation" => true,
|
||||
key: "'js.admin.unit_price_tooltip'"}
|
||||
%input{ "type" => "text", "id" => "product_unit_price", "name" => "product[unit_price]",
|
||||
"class" => 'fullwidth', "disabled" => true, "ng-model" => "unit_price"}
|
||||
%div{style: "color: black"}
|
||||
= t(".unit_price_legend")
|
||||
.sixteen.columns.alpha
|
||||
.three.columns
|
||||
- if Spree::TaxCategory.any?
|
||||
|
||||
@@ -5,14 +5,15 @@
|
||||
%nav.menu
|
||||
%ul.sidebar
|
||||
= configurations_sidebar_menu_item Spree.t(:general_settings), edit_admin_general_settings_path
|
||||
= configurations_sidebar_menu_item t(".terms_of_service"), main_app.admin_terms_of_service_files_path
|
||||
= configurations_sidebar_menu_item Spree.t(:mail_method_settings), edit_admin_mail_methods_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
|
||||
= configurations_sidebar_menu_item Spree.t(:tax_settings), edit_admin_tax_settings_path
|
||||
= configurations_sidebar_menu_item Spree.t(:zones), admin_zones_path
|
||||
= configurations_sidebar_menu_item Spree.t(:countries), admin_countries_path
|
||||
- if Spree::Config[:default_country_id]
|
||||
= configurations_sidebar_menu_item Spree.t(:states), admin_country_states_path(Spree::Config[:default_country_id])
|
||||
- if DefaultCountry.id
|
||||
= configurations_sidebar_menu_item Spree.t(:states), admin_country_states_path(DefaultCountry.id)
|
||||
= configurations_sidebar_menu_item Spree.t(:payment_methods), admin_payment_methods_path
|
||||
= configurations_sidebar_menu_item Spree.t(:taxonomies), admin_taxonomies_path
|
||||
= configurations_sidebar_menu_item Spree.t(:shipping_methods), admin_shipping_methods_path
|
||||
|
||||
@@ -34,22 +34,21 @@
|
||||
.field
|
||||
= f.label :price, t('.price')
|
||||
= f.text_field :price, class: 'fullwidth', "ng-model" => "variant.price", "ng-init" => "variant.price = '#{number_to_currency(@variant.price, unit: '')}'"
|
||||
- if feature? :unit_price, spree_current_user
|
||||
.field
|
||||
= hidden_field_tag 'product_variant_unit', @product.variant_unit
|
||||
= hidden_field_tag 'product_variant_unit_name', @product.variant_unit_name
|
||||
= f.field_container :unit_price do
|
||||
%div{style: "display: flex"}
|
||||
= f.label :unit_price, t(".unit_price"), {style: "display: inline-block"}
|
||||
%question-mark-with-tooltip{"question-mark-with-tooltip" => "_",
|
||||
"question-mark-with-tooltip-append-to-body" => "true",
|
||||
"question-mark-with-tooltip-placement" => "top",
|
||||
"question-mark-with-tooltip-animation" => true,
|
||||
key: "'js.admin.unit_price_tooltip'"}
|
||||
%input{ "type" => "text", "id" => "variant_unit_price", "name" => "variant[unit_price]",
|
||||
"class" => 'fullwidth', "disabled" => true, "ng-model" => "unit_price"}
|
||||
%div{style: "color: black"}
|
||||
= t("spree.admin.products.new.unit_price_legend")
|
||||
.field
|
||||
= hidden_field_tag 'product_variant_unit', @product.variant_unit
|
||||
= hidden_field_tag 'product_variant_unit_name', @product.variant_unit_name
|
||||
= f.field_container :unit_price do
|
||||
%div{style: "display: flex"}
|
||||
= f.label :unit_price, t(".unit_price"), {style: "display: inline-block"}
|
||||
%question-mark-with-tooltip{"question-mark-with-tooltip" => "_",
|
||||
"question-mark-with-tooltip-append-to-body" => "true",
|
||||
"question-mark-with-tooltip-placement" => "top",
|
||||
"question-mark-with-tooltip-animation" => true,
|
||||
key: "'js.admin.unit_price_tooltip'"}
|
||||
%input{ "type" => "text", "id" => "variant_unit_price", "name" => "variant[unit_price]",
|
||||
"class" => 'fullwidth', "disabled" => true, "ng-model" => "unit_price"}
|
||||
%div{style: "color: black"}
|
||||
= t("spree.admin.products.new.unit_price_legend")
|
||||
%div{ 'set-on-demand' => '' }
|
||||
.field.checkbox
|
||||
%label
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user