mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Compare commits
524 Commits
v1.8.6
...
v1.8.13-tr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1a2a66d21 | ||
|
|
0117e2e8b5 | ||
|
|
2650dc209e | ||
|
|
58d7d8f016 | ||
|
|
1fbb4b25d1 | ||
|
|
b43b92dcfd | ||
|
|
649c25622a | ||
|
|
1f2820f6d4 | ||
|
|
22f018f2bc | ||
|
|
8c5ac4cb23 | ||
|
|
b9ff5674af | ||
|
|
f0968109c6 | ||
|
|
eeb41ccfdd | ||
|
|
587a53d36d | ||
|
|
ec7b7e0391 | ||
|
|
7f982c0c90 | ||
|
|
6c71ef8760 | ||
|
|
936355d54b | ||
|
|
07620c2e62 | ||
|
|
686a8f3af9 | ||
|
|
199bfe531e | ||
|
|
e4627fe0d0 | ||
|
|
ec6a365227 | ||
|
|
c6f6f5bc55 | ||
|
|
5166a3d958 | ||
|
|
9429695e15 | ||
|
|
f396d30747 | ||
|
|
2637574c93 | ||
|
|
d2ba4650e5 | ||
|
|
3adb13e62c | ||
|
|
f69d86ab8f | ||
|
|
7c0feab08f | ||
|
|
ea784d6362 | ||
|
|
6e57f917d2 | ||
|
|
ba97f61c9e | ||
|
|
c5eca68d79 | ||
|
|
92814162dc | ||
|
|
44374e8499 | ||
|
|
2ca04bb84e | ||
|
|
66a85bb99f | ||
|
|
9f6931ba18 | ||
|
|
8fe6800151 | ||
|
|
e86122cb3e | ||
|
|
7641dcc1be | ||
|
|
8648070a05 | ||
|
|
5200937165 | ||
|
|
6215777986 | ||
|
|
0eb4c7f7ba | ||
|
|
782a812596 | ||
|
|
113f6565be | ||
|
|
b1452f097d | ||
|
|
6384b5abb3 | ||
|
|
2c14ed848f | ||
|
|
5dfac10599 | ||
|
|
250062bd2f | ||
|
|
3f2299e52e | ||
|
|
327753b7ca | ||
|
|
ba447b547d | ||
|
|
8ebd49ec0f | ||
|
|
155a2574bb | ||
|
|
b8c2e54194 | ||
|
|
9f243e6d3c | ||
|
|
ece8d8b518 | ||
|
|
0624c49a4f | ||
|
|
71742a80b5 | ||
|
|
f4b1667005 | ||
|
|
e5c9845b10 | ||
|
|
d3fc89f42a | ||
|
|
9c6454b47a | ||
|
|
7d2484c8bf | ||
|
|
9723c8b82b | ||
|
|
8b2b51d511 | ||
|
|
872a150c7d | ||
|
|
3a0c0fd638 | ||
|
|
739d06cf03 | ||
|
|
9fa7a30c7e | ||
|
|
ba0b17e168 | ||
|
|
5caaec8ef3 | ||
|
|
9971c9f923 | ||
|
|
974099747b | ||
|
|
1920ee7e88 | ||
|
|
55b2c19b64 | ||
|
|
60060a7017 | ||
|
|
ef488133e8 | ||
|
|
5c66a2fc9d | ||
|
|
5f8890e963 | ||
|
|
58c463497a | ||
|
|
3bb6d68adf | ||
|
|
705295049e | ||
|
|
a07fd854f6 | ||
|
|
b2bae242d9 | ||
|
|
1a57a0b3ca | ||
|
|
a0595bc45a | ||
|
|
8853340fa1 | ||
|
|
bde3fa4ce6 | ||
|
|
cee24dcca7 | ||
|
|
c1789c4833 | ||
|
|
6fbf902562 | ||
|
|
dc0da6f7b7 | ||
|
|
385847d7da | ||
|
|
9d7f63db42 | ||
|
|
d0c6292e9d | ||
|
|
994023ec10 | ||
|
|
1028b49719 | ||
|
|
b7f99c3185 | ||
|
|
ce85027b79 | ||
|
|
94b6a61665 | ||
|
|
f84acf44f3 | ||
|
|
386d651678 | ||
|
|
23a6e2dd8f | ||
|
|
6c69eebcbf | ||
|
|
d8a158c56d | ||
|
|
dfda30f4cb | ||
|
|
d26970d04c | ||
|
|
63e453e2c7 | ||
|
|
c7ed27286a | ||
|
|
e5340cb53a | ||
|
|
7079952f6b | ||
|
|
f79dcaba15 | ||
|
|
33a1d97d5e | ||
|
|
28ea23965b | ||
|
|
fbdbbb980f | ||
|
|
fc5b339e2a | ||
|
|
4acb3f1962 | ||
|
|
7bb58342fc | ||
|
|
b277ff03ea | ||
|
|
5061d0c4cd | ||
|
|
931a5be162 | ||
|
|
e437cba155 | ||
|
|
ec53d9df7a | ||
|
|
3330e9b219 | ||
|
|
884743ce97 | ||
|
|
b482d1e57c | ||
|
|
78f5002be5 | ||
|
|
a42799dff4 | ||
|
|
1196cd7df4 | ||
|
|
3c1eae1f47 | ||
|
|
ba27d63f9c | ||
|
|
0083733c4c | ||
|
|
a1ffc869f3 | ||
|
|
7a07e8fa16 | ||
|
|
699da16049 | ||
|
|
18c7b03f3d | ||
|
|
8b560e6cee | ||
|
|
7974ac45f2 | ||
|
|
41b5cf10dd | ||
|
|
b6955cb98c | ||
|
|
6c36c269c8 | ||
|
|
b879ea5a96 | ||
|
|
a6ed4a2c6a | ||
|
|
6972822c49 | ||
|
|
db63f30a76 | ||
|
|
848193434b | ||
|
|
570f0344da | ||
|
|
38c25c412f | ||
|
|
3b4ffe1f70 | ||
|
|
4699c654fc | ||
|
|
c1c5d00f45 | ||
|
|
220693f4e3 | ||
|
|
fcce858ea4 | ||
|
|
1f9698f7a2 | ||
|
|
1766da9d60 | ||
|
|
15ee62aaa8 | ||
|
|
6fc4a297a0 | ||
|
|
74d8dc48b4 | ||
|
|
b6f4ce373e | ||
|
|
c9f186f48f | ||
|
|
daab0dfd7a | ||
|
|
22b5dafad2 | ||
|
|
110f74eee8 | ||
|
|
61cb78fc93 | ||
|
|
38d3b446cc | ||
|
|
e47e10d267 | ||
|
|
77c8c85775 | ||
|
|
fab6d70832 | ||
|
|
9586666248 | ||
|
|
f5ab9a3445 | ||
|
|
1ac8c85113 | ||
|
|
56c2350d36 | ||
|
|
6eafed00f5 | ||
|
|
74661c0b77 | ||
|
|
c4fbcb19d0 | ||
|
|
08e391856c | ||
|
|
8c8b40c5a8 | ||
|
|
c3eda435eb | ||
|
|
5eadb33db9 | ||
|
|
f977a05b08 | ||
|
|
217eda8362 | ||
|
|
579f3bf90a | ||
|
|
348ab81c42 | ||
|
|
3df629bc6e | ||
|
|
07b2f0a7c2 | ||
|
|
c0445d46f3 | ||
|
|
6c90b4e6d0 | ||
|
|
e79a23a554 | ||
|
|
314ccc2f27 | ||
|
|
68c8759af1 | ||
|
|
314e9a4f15 | ||
|
|
0029a1b6cf | ||
|
|
bfcde72855 | ||
|
|
3d0ada803f | ||
|
|
840c936a6f | ||
|
|
7ea74ccf4a | ||
|
|
b55036e165 | ||
|
|
47011e11ff | ||
|
|
ae28d7a96b | ||
|
|
0dd8959bf7 | ||
|
|
316b0915e4 | ||
|
|
e21bfd95f4 | ||
|
|
893331c7bb | ||
|
|
b94bcd697f | ||
|
|
b0ff7ca767 | ||
|
|
493a537f2c | ||
|
|
cda43f075b | ||
|
|
5d9f92eaa7 | ||
|
|
c6afa1849c | ||
|
|
eec3a21c89 | ||
|
|
768240a5ba | ||
|
|
5af8668560 | ||
|
|
630b8a2577 | ||
|
|
12a6f652ad | ||
|
|
db4a528ba3 | ||
|
|
479c7ba24b | ||
|
|
1f08729df3 | ||
|
|
811671661e | ||
|
|
936df71d0d | ||
|
|
f3f6714472 | ||
|
|
3bce2eb7b5 | ||
|
|
bf05866f92 | ||
|
|
219ad4a3a7 | ||
|
|
a7d8028d5a | ||
|
|
d49469a3e6 | ||
|
|
4835ef067f | ||
|
|
4112c3cc75 | ||
|
|
0fe4030d71 | ||
|
|
e8d2d4d96f | ||
|
|
88c3f414fb | ||
|
|
c0d6b68233 | ||
|
|
65f62c42b9 | ||
|
|
fe7bd5e2cd | ||
|
|
e1b40142b8 | ||
|
|
963b4617a9 | ||
|
|
95ddfc4e40 | ||
|
|
01746ed470 | ||
|
|
f25e3bc6f7 | ||
|
|
e63f1c2991 | ||
|
|
29e2886b05 | ||
|
|
a97bcf74de | ||
|
|
1e6f4aa73d | ||
|
|
7c7933f8bb | ||
|
|
dc69c6e825 | ||
|
|
41e91765ca | ||
|
|
19569f9316 | ||
|
|
d91c3d1241 | ||
|
|
b302deb7a3 | ||
|
|
2fae467e9a | ||
|
|
6a5e4bb592 | ||
|
|
c72d17dc83 | ||
|
|
78ffdec693 | ||
|
|
49c19a1d6a | ||
|
|
e854eb0426 | ||
|
|
4a9c17cb28 | ||
|
|
0d1547f439 | ||
|
|
fa5ed529cb | ||
|
|
accb3076e9 | ||
|
|
a4e4e1ec68 | ||
|
|
507e12adba | ||
|
|
4809237ecc | ||
|
|
81877fedb6 | ||
|
|
1f2c6f2a85 | ||
|
|
4fe5e60967 | ||
|
|
f4eb9cb790 | ||
|
|
775f9b3ada | ||
|
|
188b33921c | ||
|
|
20c033317f | ||
|
|
e7a5d063ac | ||
|
|
1fda781d7e | ||
|
|
45fc801a08 | ||
|
|
5fa45c0716 | ||
|
|
21337a5b50 | ||
|
|
ec36a843cf | ||
|
|
e99dbaf4d8 | ||
|
|
c83ad2ecc4 | ||
|
|
80d8d18eb2 | ||
|
|
903d1afb53 | ||
|
|
cd55d2e2ff | ||
|
|
05cf8c4351 | ||
|
|
b04d815408 | ||
|
|
7b370a2eb6 | ||
|
|
5808b601b8 | ||
|
|
fdcd3dc3e3 | ||
|
|
c4bd085393 | ||
|
|
0e91d01412 | ||
|
|
fcb9e9fa56 | ||
|
|
3591354cb1 | ||
|
|
b38eab11eb | ||
|
|
c43dea60b7 | ||
|
|
268bea25d0 | ||
|
|
e94ae20b31 | ||
|
|
a94961c0a7 | ||
|
|
0d5fde919b | ||
|
|
429ef4e2ba | ||
|
|
e8999d23e1 | ||
|
|
209c9242d9 | ||
|
|
6defb09d2e | ||
|
|
2774c09d7a | ||
|
|
c62a044598 | ||
|
|
f73fbe7f23 | ||
|
|
5e1e4c1d19 | ||
|
|
cc5a335fb7 | ||
|
|
91fc3f33a0 | ||
|
|
648753b412 | ||
|
|
24fcc3dd34 | ||
|
|
14fb40a996 | ||
|
|
f4511fc74d | ||
|
|
3d0f192490 | ||
|
|
6b7cdf3a37 | ||
|
|
052d6c6b02 | ||
|
|
6e5c878491 | ||
|
|
c0c6cd1a60 | ||
|
|
2ad433590d | ||
|
|
2cb3da56ab | ||
|
|
8582e6d6b4 | ||
|
|
170101cbfe | ||
|
|
8107f49373 | ||
|
|
7ef0964af2 | ||
|
|
18472ea8c3 | ||
|
|
36e0f45a89 | ||
|
|
bea0b2b1e5 | ||
|
|
9a69951136 | ||
|
|
e19bab1aa2 | ||
|
|
8e2a111a0b | ||
|
|
70707969f3 | ||
|
|
2fe25c6219 | ||
|
|
cc1ef5b28b | ||
|
|
3fc2070b2c | ||
|
|
d22f5678be | ||
|
|
0429906eed | ||
|
|
88a09da325 | ||
|
|
963f0d601f | ||
|
|
8570471c00 | ||
|
|
7925af30d6 | ||
|
|
6f59751582 | ||
|
|
2d2792225a | ||
|
|
a079a64cbe | ||
|
|
656be690a3 | ||
|
|
167045f695 | ||
|
|
dbe968afbb | ||
|
|
179b995fa0 | ||
|
|
4791086207 | ||
|
|
be6b09a6e0 | ||
|
|
f235099859 | ||
|
|
ff8ca521ff | ||
|
|
98f7d52493 | ||
|
|
4815405839 | ||
|
|
42a6e35185 | ||
|
|
408a57479e | ||
|
|
beaf54107c | ||
|
|
e45d1d42b4 | ||
|
|
bc442c7819 | ||
|
|
6a361f2d7b | ||
|
|
a62998e5f1 | ||
|
|
ebcb8ff3e7 | ||
|
|
da8c107331 | ||
|
|
5870927518 | ||
|
|
e008a154e5 | ||
|
|
a2d01b5144 | ||
|
|
8afd5c509b | ||
|
|
311f72e4cb | ||
|
|
78563a7d75 | ||
|
|
9284dd9b63 | ||
|
|
92981e4fcd | ||
|
|
9235727d45 | ||
|
|
fc4ead9b05 | ||
|
|
b8622e95b7 | ||
|
|
f8341dccd4 | ||
|
|
b8ed7789f0 | ||
|
|
6d19613ecc | ||
|
|
0d56cbf169 | ||
|
|
67730e82c3 | ||
|
|
940ca7ade1 | ||
|
|
05f9747f15 | ||
|
|
27903ab744 | ||
|
|
931e528e14 | ||
|
|
6bed94a09b | ||
|
|
165b437f31 | ||
|
|
b526307ad1 | ||
|
|
a7bfddfcb5 | ||
|
|
52e4722dcb | ||
|
|
017916b193 | ||
|
|
02e5ba4dfd | ||
|
|
651626eb4f | ||
|
|
20d01c3047 | ||
|
|
a391b6f076 | ||
|
|
ade73f66c8 | ||
|
|
44970a13bb | ||
|
|
d80f080af5 | ||
|
|
6ec7276cfc | ||
|
|
2444d3b547 | ||
|
|
e899633aff | ||
|
|
a9f01c0f0d | ||
|
|
e021afdd8a | ||
|
|
88dea0f2b8 | ||
|
|
5150025641 | ||
|
|
fc400741b4 | ||
|
|
5cb2194f5e | ||
|
|
64f6a794fc | ||
|
|
764c95488c | ||
|
|
6cabba4cd8 | ||
|
|
bd1cd527d3 | ||
|
|
d17f9dc504 | ||
|
|
f62c583130 | ||
|
|
b1e27e0dad | ||
|
|
6ae1272281 | ||
|
|
e0cb6ed60a | ||
|
|
8aeec74fed | ||
|
|
7cd7e7367b | ||
|
|
4f4fe90db4 | ||
|
|
7a7cd3a937 | ||
|
|
bfc01e7c89 | ||
|
|
bc5672b5eb | ||
|
|
d77f775c4c | ||
|
|
7531c8cbc9 | ||
|
|
38fe0afc03 | ||
|
|
252f876827 | ||
|
|
6d9bae8ef9 | ||
|
|
0b2281dfe2 | ||
|
|
72cff0688a | ||
|
|
9793450ed0 | ||
|
|
c8f0502e71 | ||
|
|
b075ed373a | ||
|
|
eef308c4f6 | ||
|
|
70225afa13 | ||
|
|
0a67876815 | ||
|
|
b59e5ad248 | ||
|
|
287e0b5b55 | ||
|
|
c6a1560845 | ||
|
|
45dc1341d3 | ||
|
|
7d7197da58 | ||
|
|
066f42070a | ||
|
|
cad3464f56 | ||
|
|
bbcaef20a8 | ||
|
|
43726a0b23 | ||
|
|
6e6efea328 | ||
|
|
a2a6ce1b3e | ||
|
|
3a69c958ef | ||
|
|
14ee7a06ae | ||
|
|
6cd8289b27 | ||
|
|
d0509b54bf | ||
|
|
ee905cad5f | ||
|
|
01efb63ad3 | ||
|
|
7981feefa1 | ||
|
|
d4fd66461e | ||
|
|
071ba5285d | ||
|
|
6795237a2d | ||
|
|
57363e2da5 | ||
|
|
da9a3ce9f3 | ||
|
|
c4318030d3 | ||
|
|
44a301edb1 | ||
|
|
dabac50128 | ||
|
|
6030e9a294 | ||
|
|
9b656eaf4f | ||
|
|
22080a9a08 | ||
|
|
d93fe3cf2c | ||
|
|
1ea4f4274c | ||
|
|
bd11c6ce14 | ||
|
|
e8848451a5 | ||
|
|
f4f38b4183 | ||
|
|
27283c50b8 | ||
|
|
3e77534dcf | ||
|
|
5e214a32b3 | ||
|
|
7498b7f098 | ||
|
|
268c8dbcdd | ||
|
|
dbbd52cace | ||
|
|
1770a67cd9 | ||
|
|
3678d4d018 | ||
|
|
3de69987e6 | ||
|
|
cbbb047fc1 | ||
|
|
338d3cbc38 | ||
|
|
4c438ff101 | ||
|
|
631b19084a | ||
|
|
63e815c7fc | ||
|
|
b7e9ffc9da | ||
|
|
d8ce0e7d58 | ||
|
|
a115f2a268 | ||
|
|
c0c8b07add | ||
|
|
5913004e14 | ||
|
|
f4034b1065 | ||
|
|
db93b74490 | ||
|
|
d574b8943b | ||
|
|
46fcf7b62e | ||
|
|
3e565ad7cb | ||
|
|
0e01350107 | ||
|
|
7d79fffa33 | ||
|
|
4117b32ebd | ||
|
|
7a68cc7da1 | ||
|
|
20e6b703d9 | ||
|
|
a1535d6c04 | ||
|
|
f33df883a0 | ||
|
|
48acf80c85 | ||
|
|
d8f8c0df16 | ||
|
|
8ce917a422 | ||
|
|
6546d2763b | ||
|
|
d3a3b2da9a | ||
|
|
fdd6400cb8 | ||
|
|
225e436293 | ||
|
|
0e354f8fc1 | ||
|
|
a6a0bdb063 | ||
|
|
6753320336 | ||
|
|
a3b91dabe5 | ||
|
|
257441c9be | ||
|
|
1497d2c3bb | ||
|
|
8f0bc367d0 | ||
|
|
764219b9ed | ||
|
|
7f7ee25e27 | ||
|
|
1765ba0422 | ||
|
|
32d2adc8a2 | ||
|
|
d890770104 | ||
|
|
376c4c3e0e | ||
|
|
a0b740f52d | ||
|
|
0d4c4f20df | ||
|
|
ab707cf312 | ||
|
|
9989b76b7d | ||
|
|
04a714426f |
@@ -1,11 +1,9 @@
|
||||
engines:
|
||||
rubocop:
|
||||
enabled: true
|
||||
exclude_fingerprints:
|
||||
- ac41db8d4ec4cbf508c353d9b65a024f
|
||||
- 8e3b6322aef5be9f38700b3fd0cd347e
|
||||
channel: rubocop-0-48
|
||||
scss-lint:
|
||||
enabled: true
|
||||
enabled: false
|
||||
ratings:
|
||||
paths:
|
||||
- app/**
|
||||
|
||||
28
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
28
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#### What? Why?
|
||||
|
||||
[Explain why is this change needed and the solution you propose. Provide
|
||||
context for others to understand it]
|
||||
|
||||
#### What should we test?
|
||||
|
||||
[List which features should be tested and how]
|
||||
|
||||
#### Release notes
|
||||
|
||||
[In case this should be present in the release notes, please write them or
|
||||
remove this section otherwise]
|
||||
|
||||
#### How is this related to the Spree upgrade?
|
||||
|
||||
[Any known conflicts with the Spree Upgrade? explain them or remove this section
|
||||
otherwise]
|
||||
|
||||
#### Discourse thread
|
||||
|
||||
[Is there a discussion about this in Discourse? add the link if so or remove
|
||||
this section otherwise]
|
||||
|
||||
#### Dependencies
|
||||
|
||||
[Does this PR depend on another one? add the link of so or remove this section
|
||||
otherwise]
|
||||
166
.rubocop.yml
166
.rubocop.yml
@@ -1,4 +1,9 @@
|
||||
inherit_from:
|
||||
- .rubocop_todo.yml
|
||||
|
||||
AllCops:
|
||||
TargetRubyVersion: 2.1
|
||||
TargetRailsVersion: 3.2
|
||||
Include:
|
||||
- '**/Rakefile'
|
||||
- '**/config.ru'
|
||||
@@ -6,24 +11,169 @@ AllCops:
|
||||
- 'db/**/*'
|
||||
- 'config/**/*'
|
||||
- 'script/**/*'
|
||||
- 'spec/**/*'
|
||||
- 'vendor/**/*'
|
||||
- 'node_modules/**/*'
|
||||
- !ruby/regexp /old_and_unused\.rb$/
|
||||
|
||||
Documentation:
|
||||
# OFN SETTINGS
|
||||
# Cop settings that have been agreed upon by the OFN community
|
||||
|
||||
Rails:
|
||||
Enabled: true
|
||||
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
||||
Style/EmptyLinesAroundClassBody:
|
||||
Style/StringLiterals:
|
||||
Enabled: false
|
||||
|
||||
Style/BracesAroundHashParameters:
|
||||
Layout/MultilineMethodCallIndentation:
|
||||
Enabled: true
|
||||
EnforcedStyle: indented
|
||||
|
||||
# TEMPORARY/CONTESTED SETTINGS
|
||||
# These are still to be decided upon, but recommended for inclusion by
|
||||
# oeoeaio after scrutinising offenses the codebase
|
||||
|
||||
# Don't think this is a big issue, mostly picking up RPSEC scope definitions
|
||||
# with lamdas and RSpec '.to change{}' blocks
|
||||
Lint/AmbiguousBlockAssociation:
|
||||
Enabled: false
|
||||
|
||||
|
||||
# Heaps of offences (> 100) in specs, mostly in situations where two or more
|
||||
# instances of a model are required, but only one is referenced. Difficult to
|
||||
# fix without making the spec look messy or rewriting it.
|
||||
# Should definitely fix at some point.
|
||||
Lint/UselessAssignment:
|
||||
Exclude:
|
||||
- spec/**/*
|
||||
|
||||
# AFAIK, there is no good alternative to dynamic matchers until we upgrade
|
||||
# to Rails 4 and can use #find_by. If there is a better approach, let's do it.
|
||||
Rails/DynamicFindBy:
|
||||
Enabled: false
|
||||
|
||||
# This should be the programmer's discretion, perhaps we should review all of
|
||||
# the uses of it an make specific exceptions though.
|
||||
Rails/SkipsModelValidations:
|
||||
Enabled: false
|
||||
|
||||
# Relaxed.Ruby.Style SETTINGS
|
||||
# These styles are a starting point for the conversation around conventions
|
||||
# They should be removed or tweaked and moved above as decisions are made
|
||||
# NOTE: Cops which did not fail at the time of writing were removed
|
||||
|
||||
Layout/DotPosition:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styledotposition
|
||||
|
||||
Layout/SpaceBeforeBlockBraces:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylespacebeforeblockbraces
|
||||
|
||||
Layout/SpaceInsideParens:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylespaceinsideparens
|
||||
|
||||
Style/Alias:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylealias
|
||||
|
||||
Style/BlockDelimiters:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styleblockdelimiters
|
||||
|
||||
Style/CommentAnnotation:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylecommentannotation
|
||||
|
||||
Style/DoubleNegation:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styledoublenegation
|
||||
|
||||
Style/FormatString:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styleformatstring
|
||||
|
||||
Style/IfUnlessModifier:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styleifunlessmodifier
|
||||
|
||||
Style/Lambda:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylelambda
|
||||
|
||||
Style/MultilineBlockChain:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylemultilineblockchain
|
||||
|
||||
Style/NegatedIf:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylenegatedif
|
||||
|
||||
Style/NegatedWhile:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylenegatedwhile
|
||||
|
||||
Style/ParallelAssignment:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styleparallelassignment
|
||||
|
||||
Style/PercentLiteralDelimiters:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylepercentliteraldelimiters
|
||||
|
||||
Style/Semicolon:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylesemicolon
|
||||
|
||||
Style/SingleLineMethods:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylesinglelinemethods
|
||||
|
||||
Style/TrailingCommaInArguments:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styletrailingcommainarguments
|
||||
|
||||
Style/TrailingCommaInLiteral:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styletrailingcommainliteral
|
||||
|
||||
Style/WordArray:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylewordarray
|
||||
|
||||
Lint/AmbiguousRegexpLiteral:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#lintambiguousregexpliteral
|
||||
|
||||
Lint/AssignmentInCondition:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#lintassignmentincondition
|
||||
|
||||
Metrics/AbcSize:
|
||||
Enabled: false
|
||||
|
||||
Metrics/BlockNesting:
|
||||
Enabled: false
|
||||
|
||||
Metrics/ClassLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/ModuleLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/CyclomaticComplexity:
|
||||
Enabled: false
|
||||
|
||||
Metrics/LineLength:
|
||||
Enabled: false
|
||||
Max: 120
|
||||
|
||||
MethodLength:
|
||||
Metrics/MethodLength:
|
||||
Enabled: false
|
||||
|
||||
StringLiterals:
|
||||
Metrics/ParameterLists:
|
||||
Enabled: false
|
||||
|
||||
Metrics/PerceivedComplexity:
|
||||
Enabled: false
|
||||
|
||||
2202
.rubocop_todo.yml
Normal file
2202
.rubocop_todo.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,9 @@ env:
|
||||
- CI_NODE_INDEX=3
|
||||
- CI_NODE_INDEX=4 KARMA="true" GITHUB_DEPLOY="true"
|
||||
|
||||
before_install:
|
||||
- ./script/upgrade_bundler.sh
|
||||
|
||||
before_script:
|
||||
- cp config/database.travis.yml config/database.yml
|
||||
- cp config/application.yml.example config/application.yml
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
See this here post on raising a github issue:
|
||||
https://community.openfoodnetwork.org/t/how-to-raise-a-github-issue/912
|
||||
|
||||
# Contributing
|
||||
|
||||
We love pull requests from everyone. Here are some instructions for
|
||||
|
||||
16
Gemfile
16
Gemfile
@@ -4,12 +4,13 @@ ruby "2.1.5"
|
||||
gem 'rails', '3.2.21'
|
||||
gem 'rails-i18n', '~> 3.0.0'
|
||||
gem 'i18n', '~> 0.6.11'
|
||||
gem 'i18n-js', '~> 3.0.0'
|
||||
|
||||
# Patched version. See http://rubysec.com/advisories/CVE-2015-5312/.
|
||||
gem 'nokogiri', '>= 1.6.7.1'
|
||||
|
||||
gem 'pg'
|
||||
gem 'spree', github: 'openfoodfoundation/spree', branch: '1-3-stable'
|
||||
gem 'spree', github: 'openfoodfoundation/spree', branch: 'spree-upgrade-step1c'
|
||||
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
|
||||
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '1-3-stable'
|
||||
|
||||
@@ -50,7 +51,7 @@ gem 'gmaps4rails'
|
||||
gem 'spinjs-rails'
|
||||
gem 'rack-ssl', :require => 'rack/ssl'
|
||||
gem 'custom_error_message', :github => 'jeremydurham/custom-err-msg'
|
||||
gem 'angularjs-file-upload-rails', '~> 1.1.0'
|
||||
gem 'angularjs-file-upload-rails', '~> 1.1.6'
|
||||
gem 'roadie-rails', '~> 1.0.3'
|
||||
gem 'figaro'
|
||||
gem 'blockenspiel'
|
||||
@@ -63,6 +64,7 @@ gem 'wkhtmltopdf-binary'
|
||||
|
||||
gem 'foreigner'
|
||||
gem 'immigrant'
|
||||
gem 'roo', '~> 2.7.0'
|
||||
|
||||
gem 'whenever', require: false
|
||||
|
||||
@@ -87,8 +89,10 @@ gem "foundation-rails"
|
||||
gem 'foundation_rails_helper', github: 'willrjmarshall/foundation_rails_helper', branch: "rails3"
|
||||
|
||||
gem 'jquery-rails'
|
||||
gem 'jquery-migrate-rails'
|
||||
gem 'css_splitter'
|
||||
|
||||
gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz'
|
||||
|
||||
group :test, :development do
|
||||
# Pretty printed test output
|
||||
@@ -112,7 +116,6 @@ end
|
||||
|
||||
group :test do
|
||||
gem 'webmock'
|
||||
|
||||
# See spec/spec_helper.rb for instructions
|
||||
#gem 'perftools.rb'
|
||||
end
|
||||
@@ -124,7 +127,12 @@ group :development do
|
||||
gem 'guard-livereload'
|
||||
gem 'rack-livereload'
|
||||
gem 'guard-rails'
|
||||
gem 'guard-zeus'
|
||||
gem 'guard-rspec'
|
||||
gem 'parallel_tests'
|
||||
gem 'rubocop', '>= 0.49.1'
|
||||
|
||||
# 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'
|
||||
end
|
||||
|
||||
157
Gemfile.lock
157
Gemfile.lock
@@ -22,46 +22,56 @@ GIT
|
||||
spree_core (~> 1.3.4)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree.git
|
||||
revision: 6e3edfe40a5de8eba0095b2c5f3db9ea54c3afda
|
||||
branch: 1-3-stable
|
||||
remote: git://github.com/openfoodfoundation/ofn-qz.git
|
||||
revision: 024680ccea429b2e5428d7b964fa67c52add34ec
|
||||
specs:
|
||||
spree (1.3.6.beta)
|
||||
spree_api (= 1.3.6.beta)
|
||||
spree_cmd (= 1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree_promo (= 1.3.6.beta)
|
||||
spree_sample (= 1.3.6.beta)
|
||||
spree_api (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
ofn-qz (0.1.0)
|
||||
railties (~> 3.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree.git
|
||||
revision: a4c439570b77afa50f9e36299811f293232bd281
|
||||
branch: spree-upgrade-step1c
|
||||
specs:
|
||||
spree (1.3.99)
|
||||
spree_api (= 1.3.99)
|
||||
spree_cmd (= 1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
spree_dash (= 1.3.99)
|
||||
spree_promo (= 1.3.99)
|
||||
spree_sample (= 1.3.99)
|
||||
spree_api (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
versioncake (= 0.4.0)
|
||||
spree_cmd (1.3.6.beta)
|
||||
spree_cmd (1.3.99)
|
||||
thor (>= 0.14.6)
|
||||
spree_core (1.3.6.beta)
|
||||
activemerchant (~> 1.34)
|
||||
spree_core (1.3.99)
|
||||
activemerchant (~> 1.50.0)
|
||||
acts_as_list (= 0.1.4)
|
||||
awesome_nested_set (= 2.1.5)
|
||||
aws-sdk (~> 1.11.1)
|
||||
cancan (= 1.6.8)
|
||||
deface (>= 0.9.0)
|
||||
ffaker (~> 1.15.0)
|
||||
highline (= 1.6.18)
|
||||
jquery-rails (~> 2.2.0)
|
||||
highline (= 1.6.11)
|
||||
jquery-rails (~> 2.0)
|
||||
json (>= 1.5.5)
|
||||
kaminari (= 0.14.1)
|
||||
money (= 5.1.1)
|
||||
kaminari (= 0.13.0)
|
||||
money (= 5.0.0)
|
||||
paperclip (~> 3.0)
|
||||
rabl (= 0.7.2)
|
||||
rails (~> 3.2.16)
|
||||
rails (~> 3.2.13)
|
||||
ransack (= 0.7.2)
|
||||
select2-rails (= 3.5.9.3)
|
||||
state_machine (= 1.1.2)
|
||||
select2-rails (~> 3.2)
|
||||
state_machine (= 1.2.0)
|
||||
stringex (~> 1.3.2)
|
||||
truncate_html (~> 0.5.5)
|
||||
spree_promo (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree_sample (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree_dash (1.3.99)
|
||||
httparty (~> 0.8.1)
|
||||
spree_core (= 1.3.99)
|
||||
spree_promo (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
spree_sample (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/deface.git
|
||||
@@ -123,8 +133,8 @@ GEM
|
||||
sprockets (~> 2.2.1)
|
||||
active_model_serializers (0.8.3)
|
||||
activemodel (>= 3.0)
|
||||
activemerchant (1.57.0)
|
||||
activesupport (>= 3.2.14, < 5.1)
|
||||
activemerchant (1.50.0)
|
||||
activesupport (>= 3.2.14, < 5.0.0)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
@@ -151,10 +161,11 @@ GEM
|
||||
railties (>= 3.1)
|
||||
sprockets (~> 2)
|
||||
tilt
|
||||
angularjs-file-upload-rails (1.1.0)
|
||||
angularjs-file-upload-rails (1.1.6)
|
||||
angularjs-rails (1.5.5)
|
||||
ansi (1.4.2)
|
||||
arel (3.0.3)
|
||||
ast (2.3.0)
|
||||
atomic (1.1.99)
|
||||
awesome_nested_set (2.1.5)
|
||||
activerecord (>= 3.0.0)
|
||||
@@ -167,9 +178,7 @@ GEM
|
||||
bcrypt-ruby (3.1.5)
|
||||
bcrypt (>= 3.1.3)
|
||||
blockenspiel (0.4.5)
|
||||
bugsnag (1.5.2)
|
||||
httparty (>= 0.6, < 1.0)
|
||||
multi_json (~> 1.0)
|
||||
bugsnag (4.1.0)
|
||||
builder (3.0.4)
|
||||
byebug (2.7.0)
|
||||
columnize (~> 0.3)
|
||||
@@ -189,7 +198,7 @@ GEM
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
cliver (0.3.2)
|
||||
cocaine (0.5.7)
|
||||
cocaine (0.5.8)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.0.9)
|
||||
coffee-rails (3.2.2)
|
||||
@@ -249,7 +258,7 @@ GEM
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0.5.3)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.0.8)
|
||||
eventmachine (1.2.3)
|
||||
excon (0.45.4)
|
||||
execjs (2.6.0)
|
||||
factory_girl (3.3.0)
|
||||
@@ -399,34 +408,35 @@ GEM
|
||||
guard-rspec (4.0.4)
|
||||
guard (>= 2.1.1)
|
||||
rspec (~> 2.14)
|
||||
guard-zeus (0.0.1)
|
||||
guard
|
||||
zeus
|
||||
haml (4.0.4)
|
||||
tilt
|
||||
highline (1.6.18)
|
||||
highline (1.6.11)
|
||||
hike (1.2.3)
|
||||
http_parser.rb (0.5.3)
|
||||
httparty (0.13.1)
|
||||
json (~> 1.8)
|
||||
multi_xml (>= 0.5.2)
|
||||
httparty (0.8.3)
|
||||
multi_json (~> 1.0)
|
||||
multi_xml
|
||||
i18n (0.6.11)
|
||||
i18n-js (3.0.0)
|
||||
i18n (~> 0.6, >= 0.6.6)
|
||||
immigrant (0.1.6)
|
||||
activerecord (>= 3.0)
|
||||
foreigner (>= 1.2.1)
|
||||
inflecto (0.0.2)
|
||||
ipaddress (0.8.0)
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.2.2)
|
||||
jquery-migrate-rails (1.2.1)
|
||||
jquery-rails (2.3.0)
|
||||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.3)
|
||||
json_spec (1.1.1)
|
||||
multi_json (~> 1.0)
|
||||
rspec (~> 2.0)
|
||||
kaminari (0.14.1)
|
||||
kaminari (0.13.0)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
railties (>= 3.0.0)
|
||||
kgio (2.9.3)
|
||||
knapsack (1.5.1)
|
||||
rake
|
||||
@@ -449,8 +459,9 @@ GEM
|
||||
mini_portile2 (2.0.0)
|
||||
momentjs-rails (2.5.1)
|
||||
railties (>= 3.1)
|
||||
money (5.1.1)
|
||||
i18n (~> 0.6.0)
|
||||
money (5.0.0)
|
||||
i18n (~> 0.4)
|
||||
json
|
||||
multi_json (1.12.1)
|
||||
multi_xml (0.5.5)
|
||||
newrelic_rpm (3.12.0.288)
|
||||
@@ -466,9 +477,11 @@ GEM
|
||||
activesupport (>= 3.0.0)
|
||||
cocaine (~> 0.5.3)
|
||||
mime-types
|
||||
parallel (1.4.1)
|
||||
parallel_tests (1.3.7)
|
||||
parallel (1.11.2)
|
||||
parallel_tests (2.14.1)
|
||||
parallel
|
||||
parser (2.4.0.0)
|
||||
ast (~> 2.2)
|
||||
paypal-sdk-core (0.2.10)
|
||||
multi_json (~> 1.0)
|
||||
xml-simple
|
||||
@@ -483,6 +496,7 @@ GEM
|
||||
polyamorous (0.5.0)
|
||||
activerecord (~> 3.0)
|
||||
polyglot (0.3.5)
|
||||
powerpack (0.1.1)
|
||||
pry (0.9.12.2)
|
||||
coderay (~> 1.0.5)
|
||||
method_source (~> 0.8)
|
||||
@@ -494,7 +508,7 @@ GEM
|
||||
activesupport (>= 2.3.14)
|
||||
multi_json (~> 1.0)
|
||||
rack (1.4.7)
|
||||
rack-cache (1.2)
|
||||
rack-cache (1.6.1)
|
||||
rack (>= 0.4)
|
||||
rack-livereload (0.3.15)
|
||||
rack
|
||||
@@ -520,8 +534,10 @@ GEM
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
rainbow (2.2.2)
|
||||
rake
|
||||
raindrops (0.13.0)
|
||||
rake (10.4.2)
|
||||
rake (11.3.0)
|
||||
ransack (0.7.2)
|
||||
actionpack (~> 3.0)
|
||||
activerecord (~> 3.0)
|
||||
@@ -547,6 +563,9 @@ GEM
|
||||
roadie-rails (1.0.3)
|
||||
rails (>= 3.0, < 4.2)
|
||||
roadie (~> 3.0)
|
||||
roo (2.7.1)
|
||||
nokogiri (~> 1)
|
||||
rubyzip (~> 1.1, < 2.0.0)
|
||||
rspec (2.14.1)
|
||||
rspec-core (~> 2.14.0)
|
||||
rspec-expectations (~> 2.14.0)
|
||||
@@ -564,14 +583,22 @@ GEM
|
||||
rspec-mocks (~> 2.14.0)
|
||||
rspec-retry (0.4.2)
|
||||
rspec-core
|
||||
ruby-progressbar (1.7.1)
|
||||
rubocop (0.49.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.3.3.1, < 3.0)
|
||||
powerpack (~> 0.1)
|
||||
rainbow (>= 1.99.1, < 3.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
ruby-progressbar (1.8.1)
|
||||
rubyzip (1.2.0)
|
||||
safe_yaml (0.9.5)
|
||||
sass (3.3.14)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
select2-rails (3.5.9.3)
|
||||
select2-rails (3.5.10)
|
||||
thor (~> 0.14)
|
||||
shoulda-matchers (1.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
@@ -583,14 +610,14 @@ GEM
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
state_machine (1.1.2)
|
||||
state_machine (1.2.0)
|
||||
stringex (1.3.3)
|
||||
therubyracer (0.12.0)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thor (0.19.1)
|
||||
tilt (1.4.1)
|
||||
timecop (0.6.2.2)
|
||||
timecop (0.8.1)
|
||||
timers (1.1.0)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
@@ -601,10 +628,11 @@ GEM
|
||||
sprockets (>= 2.0.0)
|
||||
turn (0.8.3)
|
||||
ansi
|
||||
tzinfo (0.3.44)
|
||||
tzinfo (0.3.49)
|
||||
uglifier (2.7.1)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
unicode-display_width (1.3.0)
|
||||
unicorn (4.9.0)
|
||||
kgio (~> 2.6)
|
||||
rack
|
||||
@@ -628,14 +656,11 @@ GEM
|
||||
whenever (0.9.2)
|
||||
activesupport (>= 2.3.4)
|
||||
chronic (>= 0.6.3)
|
||||
wicked_pdf (0.11.0)
|
||||
rails
|
||||
wkhtmltopdf-binary (0.9.9.3)
|
||||
wicked_pdf (1.1.0)
|
||||
wkhtmltopdf-binary (0.12.3.1)
|
||||
xml-simple (1.1.4)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
zeus (0.15.4)
|
||||
method_source (>= 0.6.7)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -645,7 +670,7 @@ DEPENDENCIES
|
||||
acts-as-taggable-on (~> 3.4)
|
||||
andand
|
||||
angular-rails-templates (~> 0.2.0)
|
||||
angularjs-file-upload-rails (~> 1.1.0)
|
||||
angularjs-file-upload-rails (~> 1.1.6)
|
||||
angularjs-rails (= 1.5.5)
|
||||
atomic
|
||||
awesome_print
|
||||
@@ -665,6 +690,7 @@ DEPENDENCIES
|
||||
deface!
|
||||
delayed_job_active_record
|
||||
diffy
|
||||
eventmachine (>= 1.2.3)
|
||||
factory_girl_rails
|
||||
figaro
|
||||
foreigner
|
||||
@@ -678,10 +704,11 @@ DEPENDENCIES
|
||||
guard-livereload
|
||||
guard-rails
|
||||
guard-rspec
|
||||
guard-zeus
|
||||
haml
|
||||
i18n (~> 0.6.11)
|
||||
i18n-js (~> 3.0.0)
|
||||
immigrant
|
||||
jquery-migrate-rails
|
||||
jquery-rails
|
||||
json_spec
|
||||
knapsack
|
||||
@@ -689,6 +716,7 @@ DEPENDENCIES
|
||||
momentjs-rails
|
||||
newrelic_rpm
|
||||
nokogiri (>= 1.6.7.1)
|
||||
ofn-qz!
|
||||
oj
|
||||
paper_trail (~> 3.0.8)
|
||||
paperclip
|
||||
@@ -704,8 +732,10 @@ DEPENDENCIES
|
||||
redcarpet
|
||||
representative_view
|
||||
roadie-rails (~> 1.0.3)
|
||||
roo (~> 2.7.0)
|
||||
rspec-rails
|
||||
rspec-retry
|
||||
rubocop (>= 0.49.1)
|
||||
sass (~> 3.3)
|
||||
sass-rails (~> 3.2.3)
|
||||
shoulda-matchers
|
||||
@@ -728,5 +758,8 @@ DEPENDENCIES
|
||||
wicked_pdf
|
||||
wkhtmltopdf-binary
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.1.5p273
|
||||
|
||||
BUNDLED WITH
|
||||
1.12.5
|
||||
1.15.2
|
||||
|
||||
@@ -47,4 +47,3 @@ end
|
||||
#watch(%r{^spec/acceptance/(.+)\.feature$})
|
||||
#watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
||||
#end
|
||||
|
||||
|
||||
12
README.md
12
README.md
@@ -54,6 +54,7 @@ First, check your dependencies: Ensure that you have Ruby 2.1.5 installed:
|
||||
Install the project's gem dependencies:
|
||||
|
||||
cd openfoodnetwork
|
||||
./script/upgrade_bundler.sh
|
||||
bundle install
|
||||
|
||||
Configure the site:
|
||||
@@ -98,6 +99,17 @@ The site is configured to use
|
||||
startup time while Rails loads. See the Zeus github page for
|
||||
usage instructions.
|
||||
|
||||
Once [npm dependencies are
|
||||
installed](https://github.com/openfoodfoundation/openfoodnetwork/wiki/Karma), AngularJS tests can be run with:
|
||||
|
||||
./script/karma run
|
||||
|
||||
If you want karma to automatically rerun the tests on file modification, use:
|
||||
|
||||
./script/karma start
|
||||
|
||||
### Multilingual
|
||||
Do not forget to run `rake tmp:cache:clear` after locales are updated to reload I18n js translations.
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
//= require jquery
|
||||
//= require jquery-migrate-min
|
||||
//= require jquery_ujs
|
||||
//= require jquery-ui
|
||||
//= require shared/jquery-ui-timepicker-addon
|
||||
@@ -36,6 +37,7 @@
|
||||
//= require ./order_cycles/order_cycles
|
||||
//= require ./payment_methods/payment_methods
|
||||
//= require ./products/products
|
||||
//= require ./resources/resources
|
||||
//= require ./shipping_methods/shipping_methods
|
||||
//= require ./side_menu/side_menu
|
||||
//= require ./tag_rules/tag_rules
|
||||
@@ -46,7 +48,7 @@
|
||||
//= require textAngular-rangy.min.js
|
||||
//= require textAngular-sanitize.min.js
|
||||
//= require textAngular.min.js
|
||||
//= require darkswarm/i18n.js
|
||||
//= require i18n/translations
|
||||
//= require darkswarm/i18n.translate.js
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
|
||||
|
||||
$scope.producers = producers
|
||||
$scope.taxons = Taxons.taxons
|
||||
$scope.taxons = Taxons.all
|
||||
$scope.tax_categories = tax_categories
|
||||
$scope.filterProducers = [{id: "0", name: ""}].concat $scope.producers
|
||||
$scope.filterTaxons = [{id: "0", name: ""}].concat $scope.taxons
|
||||
|
||||
@@ -14,8 +14,8 @@ angular.module("admin.businessModelConfiguration").controller "BusinessModelConf
|
||||
$scope.cappedBill()
|
||||
|
||||
$scope.capReached = ->
|
||||
return "No" if !$scope.cap? || Number($scope.cap) == 0
|
||||
if $scope.bill() >= Number($scope.cap) then "Yes" else "No"
|
||||
return t('no') if !$scope.cap? || Number($scope.cap) == 0
|
||||
if $scope.bill() >= Number($scope.cap) then t('yes') else t('no')
|
||||
|
||||
$scope.includedTax = ->
|
||||
return 0 if !$scope.taxRate? || Number($scope.taxRate) == 0
|
||||
|
||||
@@ -3,8 +3,8 @@ angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filt
|
||||
$scope.availableCountries = availableCountries
|
||||
$scope.RequestMonitor = RequestMonitor
|
||||
$scope.submitAll = pendingChanges.submitAll
|
||||
$scope.add = Customers.add
|
||||
$scope.customerLimit = 20
|
||||
$scope.customers = Customers.all
|
||||
$scope.columns = Columns.columns
|
||||
|
||||
$scope.confirmRefresh = (event) ->
|
||||
@@ -16,7 +16,6 @@ angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filt
|
||||
Customers.index({enterprise_id: $scope.shop_id}).then (data) ->
|
||||
pendingChanges.removeAll()
|
||||
$scope.customers_form.$setPristine()
|
||||
$scope.customers = data
|
||||
|
||||
$scope.shop_id = shops[0].id if shops.length == 1
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ angular.module("admin.customers").directive 'newCustomerDialog', ($compile, $tem
|
||||
if response.data.errors
|
||||
scope.errors.push(error) for error in response.data.errors
|
||||
else
|
||||
scope.errors.push("Sorry! Could not create '#{scope.email}'")
|
||||
scope.errors.push(t('js.customers.could_not_create') + " '#{scope.email}'")
|
||||
return
|
||||
|
||||
# Compile modal template
|
||||
@@ -35,4 +35,4 @@ angular.module("admin.customers").directive 'newCustomerDialog', ($compile, $tem
|
||||
if CurrentShop.shop.id
|
||||
template.dialog('open')
|
||||
else
|
||||
alert('Please select a shop first')
|
||||
alert(t('js.customers.select_shop'))
|
||||
|
||||
@@ -2,7 +2,7 @@ angular.module('admin.enterpriseFees').directive 'spreeDeleteResource', ->
|
||||
(scope, element, attrs) ->
|
||||
if scope.enterprise_fee.id
|
||||
url = '/admin/enterprise_fees/' + scope.enterprise_fee.id
|
||||
html = '<a href="' + url + '" class="delete-resource icon_link icon-trash no-text" data-action="remove" data-confirm="Are you sure?" url="' + url + '"></a>'
|
||||
html = '<a href="' + url + '" class="delete-resource icon_link icon-trash no-text" data-action="remove" data-confirm="' + t('are_you_sure') + '" url="' + url + '"></a>'
|
||||
#var html = '<a href="'+url+'" class="delete-resource" data-confirm="Are you sure?"><img alt="Delete" src="/assets/admin/icons/delete.png" /> Delete</a>';
|
||||
element.append html
|
||||
return
|
||||
|
||||
@@ -11,7 +11,7 @@ angular.module("admin.enterprises")
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.$watch 'enterprise_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t('admin.unsaved_changes') if newValue
|
||||
|
||||
$scope.setFormDirty = ->
|
||||
$scope.$apply ->
|
||||
@@ -24,13 +24,12 @@ angular.module("admin.enterprises")
|
||||
$scope.navClear()
|
||||
enterprise_form.submit()
|
||||
|
||||
|
||||
# Provide a callback for generating warning messages displayed before leaving the page. This is passed in
|
||||
# from a directive "nav-check" in the page - if we pass it here it will be called in the test suite,
|
||||
# and on all new uses of this contoller, and we might not want that .
|
||||
# and on all new uses of this contoller, and we might not want that.
|
||||
enterpriseNavCallback = ->
|
||||
if $scope.Enterprise.$dirty
|
||||
"Your changes to the enterprise are not saved yet."
|
||||
if $scope.enterprise_form.$dirty
|
||||
t('admin.unsaved_confirm_leave')
|
||||
|
||||
# Register the NavigationCheck callback
|
||||
NavigationCheck.register(enterpriseNavCallback)
|
||||
@@ -39,6 +38,8 @@ angular.module("admin.enterprises")
|
||||
if manager.id?
|
||||
for i, user of $scope.Enterprise.users when user.id == manager.id
|
||||
$scope.Enterprise.users.splice i, 1
|
||||
if $scope.enterprise_form?
|
||||
$scope.enterprise_form.$setDirty()
|
||||
|
||||
$scope.addManager = (manager) ->
|
||||
if manager.id? and manager.email?
|
||||
|
||||
@@ -30,27 +30,27 @@ angular.module("admin.enterprises").controller 'enterprisesCtrl', ($scope, $q, E
|
||||
$scope.producerTextFor = (enterprise) ->
|
||||
switch enterprise.is_primary_producer
|
||||
when true
|
||||
"Producer"
|
||||
t('js.enterprises.producer')
|
||||
else
|
||||
"Non-Producer"
|
||||
t('js.enterprises.non_producer')
|
||||
|
||||
$scope.packageTextFor = (enterprise) ->
|
||||
switch enterprise.is_primary_producer
|
||||
when true
|
||||
switch enterprise.sells
|
||||
when "none"
|
||||
"Profile"
|
||||
t('js.profile')
|
||||
when "own"
|
||||
"Shop"
|
||||
t('js.shop')
|
||||
when "any"
|
||||
"Hub"
|
||||
t('js.hub')
|
||||
else
|
||||
"Choose"
|
||||
t('js.choose')
|
||||
else
|
||||
switch enterprise.sells
|
||||
when "none"
|
||||
"Profile"
|
||||
t('js.profile')
|
||||
when "any"
|
||||
"Hub"
|
||||
t('js.hub')
|
||||
else
|
||||
"Choose"
|
||||
t('js.choose')
|
||||
|
||||
@@ -14,7 +14,7 @@ angular.module("admin.enterprises").controller 'indexPanelCtrl', ($scope, Enterp
|
||||
, (response) ->
|
||||
$scope.saving = false
|
||||
if response.status == 422 && response.data.errors?
|
||||
message = 'Please resolve the following errors:\n'
|
||||
message = t('js.resolve_errors') + ':\n'
|
||||
for attr, msg of response.data.errors
|
||||
message += "#{attr} #{msg}\n"
|
||||
alert(message)
|
||||
|
||||
@@ -6,7 +6,6 @@ angular.module("admin.enterprises")
|
||||
|
||||
$scope.menu.setItems [
|
||||
{ name: 'primary_details', label: t('primary_details'), icon_class: "icon-home" }
|
||||
{ name: 'users', label: t('users'), icon_class: "icon-user" }
|
||||
{ name: 'address', label: t('address'), icon_class: "icon-map-marker" }
|
||||
{ name: 'contact', label: t('contact'), icon_class: "icon-phone" }
|
||||
{ name: 'social', label: t('social'), icon_class: "icon-twitter" }
|
||||
@@ -20,11 +19,11 @@ angular.module("admin.enterprises")
|
||||
{ name: 'inventory_settings', label: t('inventory_settings'), icon_class: "icon-list-ol", show: "enterpriseIsShop()" }
|
||||
{ name: 'tag_rules', label: t('tag_rules'), icon_class: "icon-random", show: "enterpriseIsShop()" }
|
||||
{ name: 'shop_preferences', label: t('shop_preferences'), icon_class: "icon-shopping-cart", show: "enterpriseIsShop()" }
|
||||
{ name: 'users', label: t('users'), icon_class: "icon-user" }
|
||||
]
|
||||
|
||||
$scope.select(0)
|
||||
|
||||
|
||||
$scope.showItem = (item) ->
|
||||
if item.show?
|
||||
$parse(item.show)($scope)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
angular.module('admin.enterprises').directive 'enterpriseSwitcher', (NavigationCheck) ->
|
||||
restrict: 'A'
|
||||
require: 'ngModel'
|
||||
link: (scope, element, attr, ngModel) ->
|
||||
initial = element[0].getAttribute('data-initial')
|
||||
|
||||
element.on 'change', ->
|
||||
if not NavigationCheck.confirmLeave()
|
||||
# Reset the current dropdown selection if staying on page
|
||||
ngModel.$setViewValue initial
|
||||
ngModel.$render()
|
||||
element.select2 'val', initial
|
||||
return
|
||||
|
||||
NavigationCheck.clear() # Don't ask twice if leaving
|
||||
window.location = element[0].querySelector('option[selected]').getAttribute('data-url')
|
||||
@@ -19,16 +19,16 @@ angular.module("admin.enterprises").factory 'PermalinkChecker', ($q, $http) ->
|
||||
if data.length > @MAX_PERMALINK_LENGTH || !data.match(/^[\w-]+$/)
|
||||
deferredRequest.resolve
|
||||
permalink: permalink
|
||||
available: "Error"
|
||||
available: t('js.error')
|
||||
else
|
||||
deferredRequest.resolve
|
||||
permalink: data
|
||||
available: "Available"
|
||||
available: t('available')
|
||||
).error (data,status) =>
|
||||
if status == 409
|
||||
deferredRequest.resolve
|
||||
permalink: data
|
||||
available: "Unavailable"
|
||||
available: t('js.unavailable')
|
||||
else
|
||||
# Something went wrong or request was aborted
|
||||
deferredRequest.reject()
|
||||
|
||||
@@ -3,19 +3,42 @@ angular.module("admin.indexUtils").directive "ofnSelect2", ($sanitize, $timeout,
|
||||
restrict: 'C'
|
||||
scope:
|
||||
data: "="
|
||||
minSearch: "@?"
|
||||
text: "@?"
|
||||
minSearch: "@"
|
||||
text: "@"
|
||||
blank: "=?"
|
||||
filter: "=?"
|
||||
onSelecting: "=?"
|
||||
multiple: '@'
|
||||
link: (scope, element, attrs, ngModel) ->
|
||||
$timeout ->
|
||||
scope.text ||= 'name'
|
||||
scope.filter ||= -> true
|
||||
scope.text ?= 'name'
|
||||
scope.multiple ?= false
|
||||
scope.filter ?= -> true
|
||||
|
||||
if scope.data.$promise
|
||||
scope.data.$promise.then -> init()
|
||||
else
|
||||
init()
|
||||
|
||||
element.on "select2-opening", scope.onSelecting || angular.noop
|
||||
|
||||
attrs.$observe 'disabled', (value) ->
|
||||
element.select2('enable', !value)
|
||||
|
||||
ngModel.$formatters.push (value) ->
|
||||
element.select2('val', value)
|
||||
value
|
||||
|
||||
ngModel.$parsers.push (value) ->
|
||||
return value.split(",") if scope.multiple
|
||||
value
|
||||
|
||||
init = ->
|
||||
scope.data.unshift(scope.blank) if scope.blank? && typeof scope.blank is "object"
|
||||
|
||||
item.name = $sanitize(item.name) for item in scope.data
|
||||
element.select2
|
||||
multiple: scope.multiple
|
||||
minimumResultsForSearch: scope.minSearch || 0
|
||||
data: ->
|
||||
filtered = $filter('filter')(scope.data,scope.filter)
|
||||
@@ -24,12 +47,3 @@ angular.module("admin.indexUtils").directive "ofnSelect2", ($sanitize, $timeout,
|
||||
item[scope.text]
|
||||
formatResult: (item) ->
|
||||
item[scope.text]
|
||||
|
||||
element.on "select2-opening", scope.onSelecting || angular.noop
|
||||
|
||||
attrs.$observe 'disabled', (value) ->
|
||||
element.select2('enable', !value)
|
||||
|
||||
ngModel.$formatters.push (value) ->
|
||||
element.select2('val', value)
|
||||
value
|
||||
|
||||
@@ -1 +1 @@
|
||||
angular.module("admin.indexUtils", ['ngResource', 'ngSanitize', 'templates', 'admin.utils']).config ($httpProvider) ->
|
||||
angular.module("admin.indexUtils", ['admin.resources', 'ngSanitize', 'templates', 'admin.utils']).config ($httpProvider) ->
|
||||
@@ -3,7 +3,8 @@ angular.module("admin.indexUtils").factory 'Dereferencer', ->
|
||||
dereference: (array, data)->
|
||||
if array
|
||||
for object, i in array
|
||||
array[i] = data[object.id]
|
||||
match = data[object.id]
|
||||
array[i] = match if match?
|
||||
|
||||
dereferenceAttr: (array, attr, data)->
|
||||
if array
|
||||
|
||||
@@ -21,16 +21,16 @@ angular.module("admin.indexUtils").factory "pendingChanges", ($q, resources, Sta
|
||||
submitAll: (form=null) =>
|
||||
all = []
|
||||
@errors = []
|
||||
StatusMessage.display('progress', "Saving...")
|
||||
StatusMessage.display('progress', t('js.saving'))
|
||||
for id, objectChanges of @pendingChanges
|
||||
for attrName, change of objectChanges
|
||||
all.push @submit(change)
|
||||
$q.all(all).then =>
|
||||
if @errors.length == 0
|
||||
StatusMessage.display('success', "All changes saved successfully")
|
||||
StatusMessage.display('success', t('js.all_changes_saved_successfully'))
|
||||
form.$setPristine() if form?
|
||||
else
|
||||
StatusMessage.display('failure', "Oh no! I was unable to save your changes")
|
||||
StatusMessage.display('failure', t('js.oh_no'))
|
||||
all
|
||||
|
||||
submit: (change) ->
|
||||
|
||||
@@ -10,7 +10,7 @@ angular.module("admin.indexUtils").factory "SpreeApiAuth", ($q, $http, SpreeApiK
|
||||
deferred.resolve()
|
||||
|
||||
.error (response) ->
|
||||
error = response?.error || "You are unauthorised to access this page."
|
||||
error = response?.error || t('js.unauthorized')
|
||||
deferred.reject(error)
|
||||
|
||||
deferred.promise
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, blankOption, VariantUnitManager, RequestMonitor) ->
|
||||
angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, VariantUnitManager, RequestMonitor) ->
|
||||
$scope.initialized = false
|
||||
$scope.RequestMonitor = RequestMonitor
|
||||
$scope.filteredLineItems = []
|
||||
@@ -15,31 +15,31 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
LineItems.allSaved() || confirm(t("unsaved_changes_warning"))
|
||||
|
||||
$scope.resetSelectFilters = ->
|
||||
$scope.distributorFilter = blankOption().id
|
||||
$scope.supplierFilter = blankOption().id
|
||||
$scope.orderCycleFilter = blankOption().id
|
||||
$scope.distributorFilter = 0
|
||||
$scope.supplierFilter = 0
|
||||
$scope.orderCycleFilter = 0
|
||||
$scope.quickSearch = ""
|
||||
|
||||
$scope.refreshData = ->
|
||||
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == "0"
|
||||
$scope.startDate = OrderCycles.orderCyclesByID[$scope.orderCycleFilter].first_order
|
||||
$scope.endDate = OrderCycles.orderCyclesByID[$scope.orderCycleFilter].last_order
|
||||
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == 0
|
||||
$scope.startDate = OrderCycles.byID[$scope.orderCycleFilter].first_order
|
||||
$scope.endDate = OrderCycles.byID[$scope.orderCycleFilter].last_order
|
||||
|
||||
RequestMonitor.load $scope.orders = Orders.index("q[state_not_eq]": "canceled", "q[completed_at_not_null]": "true", "q[completed_at_gt]": "#{parseDate($scope.startDate)}", "q[completed_at_lt]": "#{parseDate($scope.endDate)}")
|
||||
RequestMonitor.load $scope.lineItems = LineItems.index("q[order][state_not_eq]": "canceled", "q[order][completed_at_not_null]": "true", "q[order][completed_at_gt]": "#{parseDate($scope.startDate)}", "q[order][completed_at_lt]": "#{parseDate($scope.endDate)}")
|
||||
|
||||
unless $scope.initialized
|
||||
RequestMonitor.load $scope.distributors = Enterprises.index(includeBlank: true, action: "for_line_items", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
|
||||
RequestMonitor.load $scope.orderCycles = OrderCycles.index(includeBlank: true, ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{daysFromToday(-90)}")
|
||||
RequestMonitor.load $scope.suppliers = Enterprises.index(includeBlank: true, action: "for_line_items", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
|
||||
RequestMonitor.load $scope.distributors = Enterprises.index(action: "for_line_items", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
|
||||
RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{daysFromToday(-90)}")
|
||||
RequestMonitor.load $scope.suppliers = Enterprises.index(action: "for_line_items", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
|
||||
|
||||
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.distributors.$promise, $scope.orderCycles.$promise]).then ->
|
||||
Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.enterprisesByID
|
||||
Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.orderCyclesByID
|
||||
Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.byID
|
||||
Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.byID
|
||||
|
||||
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.suppliers.$promise, $scope.lineItems.$promise]).then ->
|
||||
Dereferencer.dereferenceAttr $scope.lineItems, "supplier", Enterprises.enterprisesByID
|
||||
Dereferencer.dereferenceAttr $scope.lineItems, "order", Orders.ordersByID
|
||||
Dereferencer.dereferenceAttr $scope.lineItems, "supplier", Enterprises.byID
|
||||
Dereferencer.dereferenceAttr $scope.lineItems, "order", Orders.byID
|
||||
$scope.bulk_order_form.$setPristine()
|
||||
StatusMessage.clear()
|
||||
unless $scope.initialized
|
||||
@@ -51,13 +51,13 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
|
||||
$scope.$watch 'bulk_order_form.$dirty', (newVal, oldVal) ->
|
||||
if newVal == true
|
||||
StatusMessage.display 'notice', "You have unsaved changes"
|
||||
StatusMessage.display 'notice', t('js.unsaved_changes')
|
||||
|
||||
$scope.submit = ->
|
||||
if $scope.bulk_order_form.$valid
|
||||
StatusMessage.display 'progress', "Saving..."
|
||||
StatusMessage.display 'progress', t('js.saving')
|
||||
$q.all(LineItems.saveAll()).then(->
|
||||
StatusMessage.display 'success', "All changes saved"
|
||||
StatusMessage.display 'success', t('js.all_changes_saved')
|
||||
$scope.bulk_order_form.$setPristine()
|
||||
).catch ->
|
||||
StatusMessage.display 'failure', t "unsaved_changes_error"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
angular.module("admin.lineItems").filter "selectFilter", (blankOption, RequestMonitor) ->
|
||||
angular.module("admin.lineItems").filter "selectFilter", (RequestMonitor) ->
|
||||
return (lineItems,selectedSupplier,selectedDistributor,selectedOrderCycle) ->
|
||||
filtered = []
|
||||
unless RequestMonitor.loading
|
||||
filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,"0") || lineItem.supplier.id == selectedSupplier) &&
|
||||
(angular.equals(selectedDistributor,"0") || lineItem.order.distributor.id == selectedDistributor) &&
|
||||
(angular.equals(selectedOrderCycle,"0") || lineItem.order.order_cycle.id == selectedOrderCycle)
|
||||
filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,0) || lineItem.supplier.id == selectedSupplier) &&
|
||||
(angular.equals(selectedDistributor,0) || lineItem.order.distributor.id == selectedDistributor) &&
|
||||
(angular.equals(selectedOrderCycle,0) || lineItem.order.order_cycle.id == selectedOrderCycle)
|
||||
filtered
|
||||
|
||||
@@ -12,7 +12,10 @@ angular.module('admin.orderCycles')
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||
@@ -81,7 +84,7 @@ angular.module('admin.orderCycles')
|
||||
|
||||
$scope.submit = ($event, destination) ->
|
||||
$event.preventDefault()
|
||||
StatusMessage.display 'progress', "Saving..."
|
||||
StatusMessage.display 'progress', t('js.saving')
|
||||
OrderCycle.create(destination)
|
||||
|
||||
$scope.cancel = (destination) ->
|
||||
|
||||
@@ -13,7 +13,10 @@ angular.module('admin.orderCycles')
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||
@@ -68,6 +71,7 @@ angular.module('admin.orderCycles')
|
||||
$scope.removeCoordinatorFee = ($event, index) ->
|
||||
$event.preventDefault()
|
||||
OrderCycle.removeCoordinatorFee(index)
|
||||
$scope.order_cycle_form.$dirty = true
|
||||
|
||||
$scope.addExchangeFee = ($event, exchange) ->
|
||||
$event.preventDefault()
|
||||
@@ -76,17 +80,18 @@ angular.module('admin.orderCycles')
|
||||
$scope.removeExchangeFee = ($event, exchange, index) ->
|
||||
$event.preventDefault()
|
||||
OrderCycle.removeExchangeFee(exchange, index)
|
||||
$scope.order_cycle_form.$dirty = true
|
||||
|
||||
$scope.removeDistributionOfVariant = (variant_id) ->
|
||||
OrderCycle.removeDistributionOfVariant(variant_id)
|
||||
|
||||
$scope.submit = (destination) ->
|
||||
$event.preventDefault()
|
||||
StatusMessage.display 'progress', "Saving..."
|
||||
StatusMessage.display 'progress', t('js.saving')
|
||||
|
||||
$scope.submit = ($event, destination) ->
|
||||
$event.preventDefault()
|
||||
StatusMessage.display 'progress', "Saving..."
|
||||
StatusMessage.display 'progress', t('js.saving')
|
||||
OrderCycle.update(destination, $scope.order_cycle_form)
|
||||
|
||||
$scope.cancel = (destination) ->
|
||||
|
||||
@@ -8,7 +8,10 @@ angular.module('admin.orderCycles').controller "AdminSimpleCreateOrderCycleCtrl"
|
||||
$scope.enterprise_fees = EnterpriseFee.index(coordinator_id: ocInstance.coordinator_id)
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.init = (enterprises) ->
|
||||
enterprise = enterprises[Object.keys(enterprises)[0]]
|
||||
@@ -46,7 +49,7 @@ angular.module('admin.orderCycles').controller "AdminSimpleCreateOrderCycleCtrl"
|
||||
|
||||
$scope.submit = ($event, destination) ->
|
||||
$event.preventDefault()
|
||||
StatusMessage.display 'progress', "Saving..."
|
||||
StatusMessage.display 'progress', t('js.saving')
|
||||
OrderCycle.mirrorIncomingToOutgoingProducts()
|
||||
OrderCycle.create(destination)
|
||||
|
||||
|
||||
@@ -10,7 +10,10 @@ angular.module('admin.orderCycles').controller "AdminSimpleEditOrderCycleCtrl",
|
||||
$scope.init()
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||
@@ -39,7 +42,7 @@ angular.module('admin.orderCycles').controller "AdminSimpleEditOrderCycleCtrl",
|
||||
|
||||
$scope.submit = ($event, destination) ->
|
||||
$event.preventDefault()
|
||||
StatusMessage.display 'progress', "Saving..."
|
||||
StatusMessage.display 'progress', t('js.saving')
|
||||
OrderCycle.mirrorIncomingToOutgoingProducts()
|
||||
OrderCycle.update(destination, $scope.order_cycle_form)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module('admin.orderCycles', ['ngResource', 'admin.utils', 'admin.indexUtils', 'ngTagsInput'])
|
||||
angular.module('admin.orderCycles', ['admin.utils', 'admin.indexUtils', 'ngTagsInput'])
|
||||
|
||||
.config ($httpProvider) ->
|
||||
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
|
||||
|
||||
@@ -165,13 +165,13 @@ angular.module('admin.orderCycles').factory 'OrderCycle', ($resource, $window, S
|
||||
if destination?
|
||||
$window.location = destination
|
||||
else
|
||||
StatusMessage.display 'success', 'Your order cycle has been updated.'
|
||||
StatusMessage.display 'success', t('js.order_cycles.update_success')
|
||||
else
|
||||
console.log('Failed to update order cycle')
|
||||
|
||||
confirmNoDistributors: ->
|
||||
if @order_cycle.outgoing_exchanges.length == 0
|
||||
confirm 'There are no distributors in this order cycle. This order cycle will not be visible to customers until you add one. Would you like to continue saving this order cycle?'
|
||||
confirm t('js.order_cycles.no_distributors')
|
||||
else
|
||||
true
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
angular.module("admin.paymentMethods").controller "paymentMethodsCtrl", ($scope, PaymentMethods) ->
|
||||
$scope.findPaymentMethodByID = (id) ->
|
||||
$scope.PaymentMethod = PaymentMethods.findByID(id)
|
||||
$scope.PaymentMethod = PaymentMethods.byID[id]
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
angular.module("admin.paymentMethods")
|
||||
.factory "PaymentMethods", (paymentMethods) ->
|
||||
new class PaymentMethods
|
||||
paymentMethods: paymentMethods
|
||||
|
||||
findByID: (id) ->
|
||||
for paymentMethod in @paymentMethods
|
||||
return paymentMethod if paymentMethod.id is id
|
||||
@@ -0,0 +1,5 @@
|
||||
angular.module("ofn.admin").controller "DropdownPanelsCtrl", ($scope) ->
|
||||
$scope.active = false
|
||||
|
||||
$scope.togglePanel = ->
|
||||
$scope.active = !$scope.active
|
||||
@@ -0,0 +1,14 @@
|
||||
angular.module("ofn.admin").controller "ImportOptionsFormCtrl", ($scope, $rootScope, ProductImportService) ->
|
||||
|
||||
$scope.toggleResetAbsent = () ->
|
||||
confirmed = confirm t('js.product_import.confirmation') if $scope.resetAbsent
|
||||
|
||||
if confirmed or !$scope.resetAbsent
|
||||
ProductImportService.updateResetAbsent($scope.supplierId, $scope.resetCount, $scope.resetAbsent)
|
||||
else
|
||||
$scope.resetAbsent = false
|
||||
|
||||
$scope.resetTotal = ProductImportService.resetTotal
|
||||
|
||||
$rootScope.$watch 'resetTotal', (newValue) ->
|
||||
$scope.resetTotal = newValue if newValue || newValue == 0
|
||||
@@ -0,0 +1,15 @@
|
||||
angular.module("ofn.admin").factory "ProductImportService", ($rootScope) ->
|
||||
new class ProductImportService
|
||||
suppliers: {}
|
||||
resetTotal: 0
|
||||
|
||||
updateResetAbsent: (supplierId, resetCount, resetAbsent) ->
|
||||
if resetAbsent
|
||||
@suppliers[supplierId] = resetCount
|
||||
@resetTotal += resetCount
|
||||
else
|
||||
@suppliers[supplierId] = null
|
||||
@resetTotal -= resetCount
|
||||
|
||||
$rootScope.resetTotal = @resetTotal
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
angular.module("admin.products").controller "editUnitsCtrl", ($scope, VariantUnitManager) ->
|
||||
|
||||
$scope.product =
|
||||
variant_unit: angular.element('#variant_unit').val()
|
||||
variant_unit_scale: angular.element('#variant_unit_scale').val()
|
||||
|
||||
$scope.variant_unit_options = VariantUnitManager.variantUnitOptions()
|
||||
|
||||
if $scope.product.variant_unit == 'items'
|
||||
$scope.variant_unit_with_scale = 'items'
|
||||
else
|
||||
$scope.variant_unit_with_scale = $scope.product.variant_unit + '_' + $scope.product.variant_unit_scale
|
||||
|
||||
$scope.setFields = ->
|
||||
if $scope.variant_unit_with_scale == 'items'
|
||||
variant_unit = 'items'
|
||||
variant_unit_scale = null
|
||||
else
|
||||
options = $scope.variant_unit_with_scale.split('_')
|
||||
variant_unit = options[0]
|
||||
variant_unit_scale = options[1]
|
||||
|
||||
$scope.product.variant_unit = variant_unit
|
||||
$scope.product.variant_unit_scale = variant_unit_scale
|
||||
@@ -0,0 +1,14 @@
|
||||
angular.module("admin.products").controller "variantUnitsCtrl", ($scope, VariantUnitManager, $timeout) ->
|
||||
|
||||
$scope.unitName = (scale, type) ->
|
||||
VariantUnitManager.getUnitName(scale, type)
|
||||
|
||||
$scope.scale = angular.element('#product_variant_unit_scale').val()
|
||||
|
||||
$scope.updateValue = ->
|
||||
unit_value_human = angular.element('#unit_value_human').val()
|
||||
$scope.unit_value = unit_value_human * $scope.scale
|
||||
|
||||
variant_unit_value = angular.element('#variant_unit_value').val()
|
||||
$scope.unit_value_human = variant_unit_value / $scope.scale
|
||||
$timeout -> $scope.updateValue()
|
||||
@@ -1 +1 @@
|
||||
angular.module("admin.products", [])
|
||||
angular.module("admin.products", ["textAngular", "admin.utils"])
|
||||
@@ -0,0 +1 @@
|
||||
angular.module("admin.resources", ['ngResource'])
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.customers").factory 'CustomerResource', ($resource) ->
|
||||
angular.module("admin.resources").factory 'CustomerResource', ($resource) ->
|
||||
$resource('/admin/customers/:id.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.enterprises").factory 'EnterpriseResource', ($resource) ->
|
||||
angular.module("admin.resources").factory 'EnterpriseResource', ($resource) ->
|
||||
ignoredAttrs = ->
|
||||
["$$hashKey", "producer", "package", "producerError", "packageError", "status"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.lineItems").factory 'LineItemResource', ($resource) ->
|
||||
angular.module("admin.resources").factory 'LineItemResource', ($resource) ->
|
||||
$resource('/admin/:orders/:order_number/line_items/:id.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.orderCycles").factory 'OrderCycleResource', ($resource) ->
|
||||
angular.module("admin.resources").factory 'OrderCycleResource', ($resource) ->
|
||||
$resource('/admin/order_cycles/:id/:action.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.orders").factory 'OrderResource', ($resource) ->
|
||||
angular.module("admin.resources").factory 'OrderResource', ($resource) ->
|
||||
$resource('/admin/orders/:id/:action.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
@@ -1,31 +1,43 @@
|
||||
angular.module("admin.customers").factory "Customers", ($q, InfoDialog, RequestMonitor, CustomerResource, CurrentShop) ->
|
||||
angular.module("admin.resources").factory "Customers", ($q, InfoDialog, RequestMonitor, CustomerResource, CurrentShop) ->
|
||||
new class Customers
|
||||
customers: []
|
||||
all: []
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
add: (email) ->
|
||||
params =
|
||||
enterprise_id: CurrentShop.shop.id
|
||||
email: email
|
||||
CustomerResource.create params, (customer) =>
|
||||
@customers.unshift customer if customer.id
|
||||
if customer.id
|
||||
@all.unshift customer
|
||||
@byID[customer.id] = customer
|
||||
@pristineByID[customer.id] = angular.copy(customer)
|
||||
|
||||
remove: (customer) ->
|
||||
params = id: customer.id
|
||||
CustomerResource.destroy params, =>
|
||||
i = @customers.indexOf customer
|
||||
@customers.splice i, 1 unless i < 0
|
||||
i = @all.indexOf customer
|
||||
@all.splice i, 1 unless i < 0
|
||||
, (response) =>
|
||||
errors = response.data.errors
|
||||
if errors?
|
||||
InfoDialog.open 'error', errors[0]
|
||||
else
|
||||
InfoDialog.open 'error', "Could not delete customer: #{customer.email}"
|
||||
InfoDialog.open 'error', t('js.resources.could_not_delete_customer') + ": #{customer.email}"
|
||||
|
||||
index: (params) ->
|
||||
request = CustomerResource.index(params, (data) => @customers = data)
|
||||
@clear()
|
||||
request = CustomerResource.index(params, (data) => @load(data))
|
||||
RequestMonitor.load(request.$promise)
|
||||
request.$promise
|
||||
|
||||
load: (customers) ->
|
||||
for customer in customers
|
||||
@all.push customer
|
||||
@byID[customer.id] = customer
|
||||
@pristineByID[customer.id] = angular.copy(customer)
|
||||
|
||||
update: (address, customer, addressType) ->
|
||||
params =
|
||||
id: customer.id
|
||||
@@ -33,3 +45,5 @@ angular.module("admin.customers").factory "Customers", ($q, InfoDialog, RequestM
|
||||
"#{addressType}_attributes": address
|
||||
CustomerResource.update params
|
||||
|
||||
clear: ->
|
||||
@all.length = 0
|
||||
@@ -1,21 +1,18 @@
|
||||
angular.module("admin.enterprises").factory 'Enterprises', ($q, EnterpriseResource, blankOption) ->
|
||||
angular.module("admin.resources").factory 'Enterprises', ($q, EnterpriseResource) ->
|
||||
new class Enterprises
|
||||
enterprisesByID: {}
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
index: (params={}, callback=null) ->
|
||||
includeBlank = !!params['includeBlank']
|
||||
delete params['includeBlank']
|
||||
EnterpriseResource.index(params, (data) =>
|
||||
for enterprise in data
|
||||
@enterprisesByID[enterprise.id] = enterprise
|
||||
@pristineByID[enterprise.id] = angular.copy(enterprise)
|
||||
|
||||
EnterpriseResource.index params, (data) =>
|
||||
@load(data)
|
||||
(callback || angular.noop)(data)
|
||||
|
||||
data.unshift(blankOption()) if includeBlank
|
||||
data
|
||||
)
|
||||
|
||||
load: (enterprises) ->
|
||||
for enterprise in enterprises
|
||||
@byID[enterprise.id] = enterprise
|
||||
@pristineByID[enterprise.id] = angular.copy(enterprise)
|
||||
|
||||
save: (enterprise) ->
|
||||
deferred = $q.defer()
|
||||
@@ -1,23 +1,25 @@
|
||||
angular.module("admin.lineItems").factory 'LineItems', ($q, LineItemResource) ->
|
||||
angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) ->
|
||||
new class LineItems
|
||||
lineItemsByID: {}
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
index: (params={}, callback=null) ->
|
||||
LineItemResource.index params, (data) =>
|
||||
@resetData()
|
||||
for lineItem in data
|
||||
@lineItemsByID[lineItem.id] = lineItem
|
||||
@pristineByID[lineItem.id] = angular.copy(lineItem)
|
||||
|
||||
@load(data)
|
||||
(callback || angular.noop)(data)
|
||||
|
||||
resetData: ->
|
||||
@lineItemsByID = {}
|
||||
@byID = {}
|
||||
@pristineByID = {}
|
||||
|
||||
load: (lineItems) ->
|
||||
@resetData()
|
||||
for lineItem in lineItems
|
||||
@byID[lineItem.id] = lineItem
|
||||
@pristineByID[lineItem.id] = angular.copy(lineItem)
|
||||
|
||||
saveAll: ->
|
||||
for id, lineItem of @lineItemsByID
|
||||
for id, lineItem of @byID
|
||||
lineItem.errors = {} # removes errors when line_item has been returned to original state
|
||||
@save(lineItem) if !@isSaved(lineItem)
|
||||
|
||||
@@ -34,7 +36,7 @@ angular.module("admin.lineItems").factory 'LineItems', ($q, LineItemResource) ->
|
||||
deferred.promise
|
||||
|
||||
allSaved: ->
|
||||
for id, lineItem of @lineItemsByID
|
||||
for id, lineItem of @byID
|
||||
return false unless @isSaved(lineItem)
|
||||
true
|
||||
|
||||
@@ -54,7 +56,7 @@ angular.module("admin.lineItems").factory 'LineItems', ($q, LineItemResource) ->
|
||||
deferred = $q.defer()
|
||||
lineItem.$delete({id: lineItem.id, orders: "orders", order_number: lineItem.order.number})
|
||||
.then( (data) =>
|
||||
delete @lineItemsByID[lineItem.id]
|
||||
delete @byID[lineItem.id]
|
||||
delete @pristineByID[lineItem.id]
|
||||
(callback || angular.noop)(data)
|
||||
deferred.resolve(data)
|
||||
@@ -1,21 +1,24 @@
|
||||
angular.module("admin.orderCycles").factory 'OrderCycles', ($q, OrderCycleResource, blankOption) ->
|
||||
angular.module("admin.resources").factory 'OrderCycles', ($q, $injector, OrderCycleResource) ->
|
||||
new class OrderCycles
|
||||
orderCyclesByID: {}
|
||||
all: []
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
constructor: ->
|
||||
if $injector.has('orderCycles')
|
||||
@load($injector.get('orderCycles'))
|
||||
|
||||
index: (params={}, callback=null) ->
|
||||
includeBlank = !!params['includeBlank']
|
||||
delete params['includeBlank']
|
||||
OrderCycleResource.index(params, (data) =>
|
||||
for orderCycle in data
|
||||
@orderCyclesByID[orderCycle.id] = orderCycle
|
||||
@pristineByID[orderCycle.id] = angular.copy(orderCycle)
|
||||
|
||||
OrderCycleResource.index params, (data) =>
|
||||
@load(data)
|
||||
(callback || angular.noop)(data)
|
||||
|
||||
data.unshift(blankOption()) if includeBlank
|
||||
data
|
||||
)
|
||||
|
||||
load: (orderCycles) ->
|
||||
for orderCycle in orderCycles
|
||||
@all.push orderCycle
|
||||
@byID[orderCycle.id] = orderCycle
|
||||
@pristineByID[orderCycle.id] = angular.copy(orderCycle)
|
||||
|
||||
save: (order_cycle) ->
|
||||
deferred = $q.defer()
|
||||
@@ -1,16 +1,18 @@
|
||||
angular.module("admin.orders").factory 'Orders', ($q, OrderResource) ->
|
||||
angular.module("admin.resources").factory 'Orders', ($q, OrderResource) ->
|
||||
new class Orders
|
||||
ordersByID: {}
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
index: (params={}, callback=null) ->
|
||||
OrderResource.index params, (data) =>
|
||||
for order in data
|
||||
@ordersByID[order.id] = order
|
||||
@pristineByID[order.id] = angular.copy(order)
|
||||
|
||||
@load(data)
|
||||
(callback || angular.noop)(data)
|
||||
|
||||
load: (orders) ->
|
||||
for order in orders
|
||||
@byID[order.id] = order
|
||||
@pristineByID[order.id] = angular.copy(order)
|
||||
|
||||
save: (order) ->
|
||||
deferred = $q.defer()
|
||||
order.$update({id: order.number})
|
||||
@@ -0,0 +1,16 @@
|
||||
angular.module("admin.resources")
|
||||
.factory "PaymentMethods", ($injector) ->
|
||||
new class PaymentMethods
|
||||
paymentMethods: []
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
constructor: ->
|
||||
if $injector.has('paymentMethods')
|
||||
@load($injector.get('paymentMethods'))
|
||||
|
||||
load: (paymentMethods) ->
|
||||
for paymentMethod in paymentMethods
|
||||
@paymentMethods.push paymentMethod
|
||||
@byID[paymentMethod.id] = paymentMethod
|
||||
@pristineByID[paymentMethod.id] = angular.copy(paymentMethod)
|
||||
@@ -0,0 +1,16 @@
|
||||
angular.module("admin.resources")
|
||||
.factory "ShippingMethods", ($injector) ->
|
||||
new class ShippingMethods
|
||||
shippingMethods: []
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
constructor: ->
|
||||
if $injector.has('shippingMethods')
|
||||
@load($injector.get('shippingMethods'))
|
||||
|
||||
load: (shippingMethods) ->
|
||||
for shippingMethod in shippingMethods
|
||||
@shippingMethods.push shippingMethod
|
||||
@byID[shippingMethod.id] = shippingMethod
|
||||
@pristineByID[shippingMethod.id] = angular.copy(shippingMethod)
|
||||
@@ -1,6 +1,6 @@
|
||||
angular.module("ofn.admin").factory "ofnConfirmHandler", (pendingChanges, $compile, $q) ->
|
||||
return (scope, callback) ->
|
||||
template = "<div id='dialog-div' style='padding: 10px'><h6>Unsaved changes currently exist, save now or ignore?</h6></div>"
|
||||
template = "<div id='dialog-div' style='padding: 10px'><h6>" + t('js.services.unsaved_changes_message') + "</h6></div>"
|
||||
dialogDiv = $compile(template)(scope)
|
||||
return ->
|
||||
if pendingChanges.changeCount(pendingChanges.pendingChanges) > 0
|
||||
|
||||
@@ -26,7 +26,7 @@ angular.module("ofn.admin").factory 'EnterpriseRelationships', ($http, enterpris
|
||||
|
||||
permission_presentation: (permission) ->
|
||||
switch permission
|
||||
when "add_to_order_cycle" then "add to order cycle"
|
||||
when "manage_products" then "manage products"
|
||||
when "edit_profile" then "edit profile"
|
||||
when "create_variant_overrides" then "add products to inventory"
|
||||
when "add_to_order_cycle" then t('js.services.add_to_order_cycle')
|
||||
when "manage_products" then t('js.services.manage_products')
|
||||
when "edit_profile" then t('js.services.edit_profile')
|
||||
when "create_variant_overrides" then t('js.services.add_products_to_inventory')
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
angular.module("admin.shippingMethods").controller "shippingMethodsCtrl", ($scope, ShippingMethods) ->
|
||||
$scope.findShippingMethodByID = (id) ->
|
||||
$scope.ShippingMethod = ShippingMethods.findByID(id)
|
||||
$scope.ShippingMethod = ShippingMethods.byID[id]
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
angular.module("admin.shippingMethods")
|
||||
.factory "ShippingMethods", (shippingMethods) ->
|
||||
new class ShippingMethods
|
||||
shippingMethods: shippingMethods
|
||||
|
||||
findByID: (id) ->
|
||||
for shippingMethod in @shippingMethods
|
||||
return shippingMethod if shippingMethod.id is id
|
||||
@@ -2,7 +2,7 @@ angular.module("admin.tagRules").controller "TagRulesCtrl", ($scope, $http, $fil
|
||||
$scope.tagGroups = enterprise.tag_groups
|
||||
$scope.defaultTagGroup = enterprise.default_tag_group
|
||||
|
||||
$scope.visibilityOptions = [ { id: "visible", name: "VISIBLE" }, { id: "hidden", name: "NOT VISIBLE" } ]
|
||||
$scope.visibilityOptions = [ { id: "visible", name: t('js.tag_rules.visible') }, { id: "hidden", name: t('js.tag_rules.not_visible') } ]
|
||||
|
||||
$scope.updateRuleCounts = ->
|
||||
index = $scope.defaultTagGroup.rules.length
|
||||
@@ -38,7 +38,6 @@ angular.module("admin.tagRules").controller "TagRulesCtrl", ($scope, $http, $fil
|
||||
newRule.peferred_exchange_tags = []
|
||||
newRule.preferred_matched_order_cycles_visibility = "visible"
|
||||
tagGroup.rules.push(newRule)
|
||||
$scope.enterprise_form.$setDirty()
|
||||
$scope.updateRuleCounts()
|
||||
|
||||
$scope.addNewTag = ->
|
||||
@@ -58,3 +57,4 @@ angular.module("admin.tagRules").controller "TagRulesCtrl", ($scope, $http, $fil
|
||||
.success ->
|
||||
tagGroup.rules.splice(index, 1)
|
||||
$scope.updateRuleCounts()
|
||||
$scope.enterprise_form.$setDirty()
|
||||
|
||||
@@ -9,10 +9,10 @@ angular.module("admin.tagRules").directive 'newTagRuleDialog', ($compile, $templ
|
||||
|
||||
scope.ruleTypes = [
|
||||
# { id: "DiscountOrder", name: 'Apply a discount to orders' }
|
||||
{ id: "FilterProducts", name: 'Show or Hide variants in my shopfront' }
|
||||
{ id: "FilterShippingMethods", name: 'Show or Hide shipping methods at checkout' }
|
||||
{ id: "FilterPaymentMethods", name: 'Show or Hide payment methods at checkout' }
|
||||
{ id: "FilterOrderCycles", name: 'Show or Hide order cycles in my shopfront' }
|
||||
{ id: "FilterProducts", name: t('js.tag_rules.show_hide_variants') }
|
||||
{ id: "FilterShippingMethods", name: t('js.tag_rules.show_hide_shipping') }
|
||||
{ id: "FilterPaymentMethods", name: t('js.tag_rules.show_hide_payment') }
|
||||
{ id: "FilterOrderCycles", name: t('js.tag_rules.show_hide_order_cycles') }
|
||||
]
|
||||
|
||||
scope.ruleType = scope.ruleTypes[0].id
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
angular.module("admin.taxons").factory "Taxons", (taxons, $filter) ->
|
||||
new class Taxons
|
||||
taxons: taxons
|
||||
taxonsByID: {}
|
||||
all: []
|
||||
byID: {}
|
||||
|
||||
constructor: ->
|
||||
for taxon in @taxons
|
||||
@taxonsByID[taxon.id] = taxon
|
||||
for taxon in taxons
|
||||
@all.push taxon
|
||||
@byID[taxon.id] = taxon
|
||||
|
||||
# For finding a single Taxon
|
||||
findByID: (id) ->
|
||||
@taxonsByID[id]
|
||||
@byID[id]
|
||||
|
||||
# For finding multiple Taxons represented by comma delimited string
|
||||
findByIDs: (ids) ->
|
||||
@taxonsByID[taxon_id] for taxon_id in ids.split(",") when @taxonsByID[taxon_id]
|
||||
@byID[taxon_id] for taxon_id in ids.split(",") when @byID[taxon_id]
|
||||
|
||||
findByTerm: (term) ->
|
||||
$filter('filter')(@taxons, term)
|
||||
$filter('filter')(@all, term)
|
||||
|
||||
@@ -30,8 +30,16 @@ show_flash_error = function(message) {
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$('a.close').click(function(event){
|
||||
event.preventDefault();
|
||||
$(this).parent().slideUp(250);
|
||||
});
|
||||
$('a.close').click(function(event){
|
||||
event.preventDefault();
|
||||
$(this).parent().slideUp(250);
|
||||
});
|
||||
|
||||
// Spree locates hidden with prev(), which with our current version of jQuery
|
||||
// does not locate the hidden field, resulting in the delete failing. This
|
||||
// handler updates the hidden field, fixing the problem.
|
||||
$('body').on('click', 'a.remove_fields', function() {
|
||||
$(this).next("input[type=hidden]").val("1");
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
angular.module("admin.utils").directive "textangularStrip", () ->
|
||||
restrict: 'CA'
|
||||
link: (scope, element, attrs) ->
|
||||
scope.stripFormatting = ($html) ->
|
||||
return String($html).replace(/<[^>]+>/gm, '')
|
||||
@@ -1,2 +0,0 @@
|
||||
angular.module("admin.utils").value "blankOption", ->
|
||||
{ id: "0", name: "All" }
|
||||
@@ -10,7 +10,6 @@ angular.module("admin.utils")
|
||||
|
||||
$rootScope.$on "$locationChangeStart", @locationChangeStartHandler
|
||||
|
||||
|
||||
# Action for regular browser navigation.
|
||||
onBeforeUnloadHandler: ($event) =>
|
||||
message = @getMessage()
|
||||
@@ -21,13 +20,17 @@ angular.module("admin.utils")
|
||||
|
||||
# Action for angular navigation.
|
||||
locationChangeStartHandler: ($event) =>
|
||||
message = @getMessage()
|
||||
if message and not $window.confirm(message)
|
||||
if not @confirmLeave()
|
||||
$event.stopPropagation() if $event.stopPropagation
|
||||
$event.preventDefault() if $event.preventDefault
|
||||
$event.cancelBubble = true
|
||||
$event.returnValue = false
|
||||
|
||||
# Check if leaving is okay
|
||||
confirmLeave: =>
|
||||
message = @getMessage()
|
||||
!message or $window.confirm(message)
|
||||
|
||||
# Runs callback functions to retreive most recently added non-empty message.
|
||||
getMessage: ->
|
||||
message = null
|
||||
|
||||
@@ -11,6 +11,14 @@ angular.module("admin.utils").factory "StatusMessage", ($timeout) ->
|
||||
text: ""
|
||||
style: {}
|
||||
|
||||
invalidMessage: ""
|
||||
|
||||
setValidation: (isValid) ->
|
||||
if isValid
|
||||
StatusMessage.invalidMessage = ''
|
||||
else
|
||||
StatusMessage.invalidMessage = t("admin.form_invalid")
|
||||
|
||||
active: ->
|
||||
@statusMessage.text != ''
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl",
|
||||
$scope.currentView = -> Views.currentView
|
||||
|
||||
$scope.views = Views.setViews
|
||||
inventory: { name: "Inventory Products", visible: true }
|
||||
hidden: { name: "Hidden Products", visible: false }
|
||||
new: { name: "New Products", visible: false }
|
||||
inventory: { name: t('js.variant_overrides.inventory_products'), visible: true }
|
||||
hidden: { name: t('js.variant_overrides.hidden_products'), visible: false }
|
||||
new: { name: t('js.variant_overrides.new_products'), visible: false }
|
||||
|
||||
$scope.bulkActions = [ name: "Reset Stock Levels To Defaults", callback: 'resetStock' ]
|
||||
$scope.bulkActions = [ name: t('js.variant_overrides.reset_stock_levels'), callback: 'resetStock' ]
|
||||
|
||||
$scope.columns = Columns.columns
|
||||
|
||||
@@ -52,22 +52,22 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl",
|
||||
|
||||
$scope.displayDirty = ->
|
||||
if DirtyVariantOverrides.count() > 0
|
||||
num = if DirtyVariantOverrides.count() == 1 then "one override" else "#{DirtyVariantOverrides.count()} overrides"
|
||||
StatusMessage.display 'notice', "Changes to #{num} remain unsaved."
|
||||
num = if DirtyVariantOverrides.count() == 1 then t('js.variant_overrides.one_override') else "#{DirtyVariantOverrides.count()} " + t('js.variant_overrides.overrides')
|
||||
StatusMessage.display 'notice', t('js.variant_overrides.changes_to') + ' ' + num + ' ' + t('js.variant_overrides.remain_unsaved')
|
||||
else
|
||||
StatusMessage.clear()
|
||||
|
||||
$scope.update = ->
|
||||
if DirtyVariantOverrides.count() == 0
|
||||
StatusMessage.display 'alert', 'No changes to save.'
|
||||
StatusMessage.display 'alert', t('js.variant_overrides.no_changes_to_save')
|
||||
else
|
||||
StatusMessage.display 'progress', 'Saving...'
|
||||
StatusMessage.display 'progress', t('js.saving')
|
||||
DirtyVariantOverrides.save()
|
||||
.success (updatedVos) ->
|
||||
DirtyVariantOverrides.clear()
|
||||
VariantOverrides.updateIds updatedVos
|
||||
$scope.variant_overrides_form.$setPristine()
|
||||
StatusMessage.display 'success', 'Changes saved.'
|
||||
StatusMessage.display 'success', t('js.changes_saved')
|
||||
VariantOverrides.updateData updatedVos # Refresh page data
|
||||
.error (data, status) ->
|
||||
StatusMessage.display 'failure', $scope.updateError(data, status)
|
||||
@@ -75,32 +75,32 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl",
|
||||
|
||||
$scope.updateError = (data, status) ->
|
||||
if status == 401
|
||||
"I couldn't get authorisation to save those changes, so they remain unsaved."
|
||||
t('js.variant_overrides.no_authorisation')
|
||||
|
||||
else if status == 400 && data.errors?
|
||||
errors = []
|
||||
for field, field_errors of data.errors
|
||||
errors = errors.concat field_errors
|
||||
errors = errors.join ', '
|
||||
"I had some trouble saving: #{errors}"
|
||||
t('js.variant_overrides.some_trouble', {errors: errors})
|
||||
else
|
||||
"Oh no! I was unable to save your changes."
|
||||
t('js.oh_no')
|
||||
|
||||
$scope.resetStock = ->
|
||||
if DirtyVariantOverrides.count() > 0
|
||||
StatusMessage.display 'alert', 'Save changes first.'
|
||||
StatusMessage.display 'alert', t('js.save_changes_first')
|
||||
$timeout ->
|
||||
$scope.displayDirty()
|
||||
, 3000 # 3 second delay
|
||||
else
|
||||
return unless $scope.hub_id?
|
||||
StatusMessage.display 'progress', 'Changing on hand stock levels...'
|
||||
StatusMessage.display 'progress', t('js.variant_overrides.changing_on_hand_stock')
|
||||
$http
|
||||
method: "POST"
|
||||
url: "/admin/variant_overrides/bulk_reset"
|
||||
data: { hub_id: $scope.hub_id }
|
||||
.success (updatedVos) ->
|
||||
VariantOverrides.updateData updatedVos
|
||||
StatusMessage.display 'success', 'Stocks reset to defaults.'
|
||||
StatusMessage.display 'success', t('js.variant_overrides.stock_reset')
|
||||
.error (data, status) ->
|
||||
$timeout -> StatusMessage.display 'failure', $scope.updateError(data, status)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#= require ../shared/angular-local-storage.js
|
||||
#= require ../shared/angular-slideables.js
|
||||
#= require angularjs-file-upload
|
||||
|
||||
#= require i18n/translations
|
||||
|
||||
#= require angular-rails-templates
|
||||
#= require_tree ../templates
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
$ ->
|
||||
if ($ 'form#update-cart').is('*')
|
||||
($ 'form#update-cart a.delete').show().one 'click', ->
|
||||
($ this).parents('.line-item').first().find('input.line_item_quantity').val 0
|
||||
($ this).parents('form').first().submit()
|
||||
if $('form#update-cart').is('*') || $('form#update-order').is('*')
|
||||
$('form#update-cart a.delete, form#update-order a.delete').show().one 'click', ->
|
||||
$(this).parents('.line-item').first().find('input.line_item_quantity').val 0
|
||||
$(this).parents('form').first().submit()
|
||||
false
|
||||
|
||||
($ 'form#update-cart').submit ->
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
Darkswarm.controller "EditBoughtOrderController", ($scope, $resource, Cart) ->
|
||||
$scope.showBought = false
|
||||
|
||||
$scope.deleteLineItem = (id) ->
|
||||
params = {id: id}
|
||||
success = (response) ->
|
||||
$(".line-item-" + id).remove()
|
||||
Cart.removeFinalisedLineItem(id)
|
||||
fail = (error) ->
|
||||
console.log error
|
||||
|
||||
$resource("/line_items/:id").delete(params, success, fail)
|
||||
@@ -10,7 +10,7 @@ Darkswarm.controller "OrderCycleCtrl", ($scope, $timeout, OrderCycle) ->
|
||||
$("#order_cycle_id").trigger("openTrigger")
|
||||
|
||||
|
||||
Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Products, Variants, Cart) ->
|
||||
Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Products, Variants, Cart, ChangeableOrdersAlert) ->
|
||||
# Track previous order cycle id for use with revertOrderCycle()
|
||||
$scope.previous_order_cycle_id = OrderCycle.order_cycle.order_cycle_id
|
||||
$scope.$watch 'order_cycle.order_cycle_id', (newValue, oldValue)->
|
||||
@@ -30,3 +30,5 @@ Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Prod
|
||||
Variants.clear()
|
||||
Cart.clear()
|
||||
Products.update()
|
||||
Cart.reloadFinalisedLineItems()
|
||||
ChangeableOrdersAlert.reload()
|
||||
|
||||
@@ -5,7 +5,20 @@ Darkswarm.controller "RegistrationCtrl", ($scope, RegistrationService, Enterpris
|
||||
|
||||
$scope.steps = ['details', 'contact', 'type', 'about', 'images', 'social']
|
||||
|
||||
$scope.countries = availableCountries
|
||||
# Filter countries without states since the form requires a state to be selected.
|
||||
# Consider changing the form to require a state only if a country requires them (Spree option).
|
||||
# Invalid countries still need to be filtered (better server-side).
|
||||
$scope.countries = availableCountries.filter (country) ->
|
||||
country.states.length > 0
|
||||
|
||||
$scope.countriesById = $scope.countries.reduce (obj, country) ->
|
||||
obj[country.id] = country
|
||||
obj
|
||||
, {}
|
||||
|
||||
$scope.setDefaultCountry = (id) ->
|
||||
country = $scope.countriesById[id]
|
||||
$scope.enterprise.country = country if country
|
||||
|
||||
$scope.countryHasStates = ->
|
||||
$scope.enterprise.country.states.length > 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.controller "ShoppingTabsCtrl", ($scope, $controller, Navigation) ->
|
||||
Darkswarm.controller "ShoppingTabsCtrl", ($scope, $controller, Navigation, $location) ->
|
||||
angular.extend this, $controller('TabsCtrl', {$scope: $scope})
|
||||
|
||||
$scope.tabs =
|
||||
@@ -6,3 +6,7 @@ Darkswarm.controller "ShoppingTabsCtrl", ($scope, $controller, Navigation) ->
|
||||
producers: { active: Navigation.isActive('/producers') }
|
||||
contact: { active: Navigation.isActive('/contact') }
|
||||
groups: { active: Navigation.isActive('/groups') }
|
||||
|
||||
$scope.$on '$locationChangeStart', (event, url) ->
|
||||
tab = $location.path().replace(/^\//, '')
|
||||
$scope.tabs[tab]?.active = true
|
||||
|
||||
@@ -11,8 +11,7 @@ window.Darkswarm = angular.module("Darkswarm", ["ngResource",
|
||||
'angularFileUpload',
|
||||
'angularSlideables'
|
||||
]).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) ->
|
||||
$httpProvider.defaults.headers.post['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
|
||||
$httpProvider.defaults.headers.put['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
|
||||
$httpProvider.defaults.headers['common']['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
|
||||
$httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest'
|
||||
$httpProvider.defaults.headers.common.Accept = "application/json, text/javascript, */*"
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
Darkswarm.directive "changeableOrdersAlert", (ChangeableOrdersAlert) ->
|
||||
restrict: "C"
|
||||
scope: true
|
||||
link: (scope, element, attrs) ->
|
||||
scope.alert = ChangeableOrdersAlert
|
||||
@@ -0,0 +1,9 @@
|
||||
Darkswarm.directive "confirmLinkClick", ($window) ->
|
||||
restrict: 'A'
|
||||
scope:
|
||||
confirmMsg: '@confirmLinkClick'
|
||||
link: (scope, elem, attr) ->
|
||||
elem.bind 'click', (event) ->
|
||||
unless confirm(scope.confirmMsg)
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
@@ -15,7 +15,7 @@ Darkswarm.directive 'mapOsmTiles', ($timeout) ->
|
||||
if x < 0
|
||||
x = tilesPerGlobe + x
|
||||
# Wrap y (latitude) in a like manner if you want to enable vertical infinite scroll
|
||||
'http://tile.openstreetmap.org/' + zoom + '/' + x + '/' + coord.y + '.png'
|
||||
'https://a.tile.openstreetmap.org/' + zoom + '/' + x + '/' + coord.y + '.png'
|
||||
tileSize: new google.maps.Size(256, 256)
|
||||
name: 'OpenStreetMap'
|
||||
maxZoom: 18
|
||||
|
||||
@@ -6,7 +6,11 @@ Darkswarm.directive "ofnOnHand", ->
|
||||
# In cases where this field gets its value from the HTML element rather than the model,
|
||||
# initialise the model with the HTML value.
|
||||
if scope.$eval(attr.ngModel) == undefined
|
||||
ngModel.$setViewValue elem.val()
|
||||
# Don't dirty the model when we do this
|
||||
setDirty = ngModel.$setDirty
|
||||
ngModel.$setDirty = angular.noop
|
||||
ngModel.$setViewValue(elem.val())
|
||||
ngModel.$setDirty = setDirty
|
||||
|
||||
ngModel.$parsers.push (viewValue) ->
|
||||
on_hand = parseInt(attr.ofnOnHand)
|
||||
|
||||
@@ -4,5 +4,5 @@ Darkswarm.filter 'products', (Matcher) ->
|
||||
text ?= ""
|
||||
return products if text == ""
|
||||
products.filter (product) =>
|
||||
propertiesToMatch = [product.name, product.supplier.name, product.primary_taxon.name]
|
||||
Matcher.match propertiesToMatch, text
|
||||
propertiesToMatch = [product.name, product.variant_names, product.supplier.name, product.primary_taxon.name]
|
||||
Matcher.matchBeginning propertiesToMatch, text
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
Darkswarm.filter 'properties', ->
|
||||
# Filter anything that responds to object.supplied_properties
|
||||
(objects, ids) ->
|
||||
(objects, ids, source) ->
|
||||
objects ||= []
|
||||
ids ?= []
|
||||
|
||||
source ||= 'properties'
|
||||
return [] unless source in ['properties', 'supplied_properties', 'distributed_properties']
|
||||
|
||||
if ids.length == 0
|
||||
# No properties selected, pass all objects through.
|
||||
objects
|
||||
else
|
||||
objects.filter (obj) ->
|
||||
properties = obj.supplied_properties || obj.properties
|
||||
properties = obj[source]
|
||||
properties.some (property) ->
|
||||
property.id in ids
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Darkswarm.filter 'propertiesOf', ->
|
||||
(objects) ->
|
||||
(objects, source) ->
|
||||
source ||= 'properties'
|
||||
return {} unless source in ['properties', 'supplied_properties', 'distributed_properties']
|
||||
|
||||
properties = {}
|
||||
for object in objects
|
||||
if object.supplied_properties?
|
||||
for property in object.supplied_properties
|
||||
properties[property.id] = property
|
||||
else
|
||||
for property in object.properties
|
||||
if object[source]?
|
||||
for property in object[source]
|
||||
properties[property.id] = property
|
||||
|
||||
properties
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<%# Defines a global I18n object containing the language of the current locale %>
|
||||
<%
|
||||
# Invalidate this asset if locale changes.
|
||||
Dir[Rails.root.join('config', 'locales', "#{I18n.default_locale}.yml").to_s].each do |f|
|
||||
depend_on(f)
|
||||
end
|
||||
%>
|
||||
<%- I18n.backend.send(:init_translations) unless I18n.backend.initialized? %>
|
||||
window.I18n = <%= I18n.backend.send(:translations)[I18n.default_locale].with_indifferent_access.to_json.html_safe %>
|
||||
@@ -1,17 +1,11 @@
|
||||
# Old aliases before i18n-js was introduced.
|
||||
# TODO - delete it after everything is moved to i18n-js
|
||||
|
||||
# Declares the translation function t.
|
||||
# You can use translate('login') or t('login') in Javascript.
|
||||
window.translate = (key, options = {}) ->
|
||||
unless 'I18n' of window
|
||||
console.log 'The I18n object is undefined. Cannot translate text.'
|
||||
return key
|
||||
dict = I18n
|
||||
parts = key.split '.'
|
||||
while (parts.length)
|
||||
part = parts.shift()
|
||||
return key unless part of dict
|
||||
dict = dict[part]
|
||||
text = dict
|
||||
for name, value of options
|
||||
text = text.split("%{#{name}}").join(value)
|
||||
text
|
||||
I18n.t(key, options)
|
||||
window.t = window.translate
|
||||
|
||||
@@ -25,9 +25,7 @@ Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redir
|
||||
isActive: Navigation.isActive
|
||||
|
||||
close: ->
|
||||
if location.pathname in ["/", "/checkout"]
|
||||
Navigation.navigate "/"
|
||||
else
|
||||
if location.pathname in ["/register", "/register/auth"]
|
||||
Loading.message = t 'going_back_to_home_page'
|
||||
location.hash = ""
|
||||
location.pathname = "/"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $rootScope, localStorageService)->
|
||||
Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $rootScope, $resource, localStorageService) ->
|
||||
# Handles syncing of current cart/order state to server
|
||||
new class Cart
|
||||
dirty: false
|
||||
@@ -6,11 +6,15 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo
|
||||
update_enqueued: false
|
||||
order: CurrentOrder.order
|
||||
line_items: CurrentOrder.order?.line_items || []
|
||||
line_items_finalised: CurrentOrder.order?.finalised_line_items || []
|
||||
|
||||
constructor: ->
|
||||
for line_item in @line_items
|
||||
line_item.variant.line_item = line_item
|
||||
Variants.register line_item.variant
|
||||
for line_item in @line_items_finalised
|
||||
line_item.variant.line_item = line_item
|
||||
Variants.extend line_item.variant
|
||||
|
||||
adjust: (line_item) =>
|
||||
line_item.total_price = line_item.variant.price_with_fees * line_item.quantity
|
||||
@@ -115,3 +119,15 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo
|
||||
clear: ->
|
||||
@line_items = []
|
||||
localStorageService.clearAll() # One day this will have to be moar GRANULAR
|
||||
|
||||
removeFinalisedLineItem: (id) =>
|
||||
@line_items_finalised = @line_items_finalised.filter (item) ->
|
||||
item.id != id
|
||||
|
||||
reloadFinalisedLineItems: =>
|
||||
@line_items_finalised = []
|
||||
$resource("/line_items/bought").query (items) =>
|
||||
for line_item in items
|
||||
line_item.variant.line_item = line_item
|
||||
Variants.extend line_item.variant
|
||||
@line_items_finalised = items
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
Darkswarm.factory 'ChangeableOrdersAlert', ($http) ->
|
||||
new class ChangeableOrdersAlert
|
||||
html: ''
|
||||
visible: true
|
||||
|
||||
constructor: ->
|
||||
@reload()
|
||||
|
||||
reload: ->
|
||||
$http.get('/shop/changeable_orders_alert').then (response) =>
|
||||
@html = response.data.trim()
|
||||
|
||||
close: =>
|
||||
@visible = false
|
||||
@@ -1,7 +1,14 @@
|
||||
Darkswarm.factory "Matcher", ->
|
||||
# Match text fragment in an array of strings.
|
||||
new class Matcher
|
||||
|
||||
# Match text fragment in an array of strings.
|
||||
match: (properties, text)->
|
||||
properties.some (prop)->
|
||||
prop ||= ""
|
||||
prop.toLowerCase().indexOf(text.toLowerCase()) != -1
|
||||
|
||||
# Return true if text occurs at the beginning of any word present in an array of strings
|
||||
matchBeginning: (properties, text) ->
|
||||
text = text.trim()
|
||||
regexp = new RegExp("(?:^|[\\s-])#{text}", "i")
|
||||
properties.some (prop) -> (prop || "").search(regexp) >= 0
|
||||
|
||||
@@ -3,10 +3,12 @@ Darkswarm.factory 'Orders', (orders_by_distributor, currencyConfig, CurrentHub,
|
||||
constructor: ->
|
||||
# Populate Orders.orders from json in page.
|
||||
@orders_by_distributor = orders_by_distributor
|
||||
@changeable_orders = []
|
||||
@currency_symbol = currencyConfig.symbol
|
||||
|
||||
for distributor in @orders_by_distributor
|
||||
@updateRunningBalance(distributor.distributed_orders)
|
||||
@findChangeableOrders(distributor.distributed_orders)
|
||||
@updateRunningBalance(distributor.distributed_orders)
|
||||
|
||||
|
||||
updateRunningBalance: (orders) ->
|
||||
@@ -14,3 +16,7 @@ Darkswarm.factory 'Orders', (orders_by_distributor, currencyConfig, CurrentHub,
|
||||
balances = orders.slice(i,orders.length).map (o) -> parseFloat(o.outstanding_balance)
|
||||
running_balance = balances.reduce (a,b) -> a+b
|
||||
order.running_balance = running_balance.toFixed(2)
|
||||
|
||||
findChangeableOrders: (orders) ->
|
||||
for order in orders when order.changes_allowed
|
||||
@changeable_orders.push(order)
|
||||
|
||||
@@ -25,7 +25,6 @@ Darkswarm.factory 'Products', ($resource, Enterprises, Dereferencer, Taxons, Pro
|
||||
prices = (v.price for v in product.variants)
|
||||
product.price = Math.min.apply(null, prices)
|
||||
product.hasVariants = product.variants?.length > 0
|
||||
|
||||
product.primaryImage = product.images[0]?.small_url if product.images
|
||||
product.primaryImageOrMissing = product.primaryImage || "/assets/noimage/small.png"
|
||||
product.largeImage = product.images[0]?.large_url if product.images
|
||||
@@ -43,7 +42,10 @@ Darkswarm.factory 'Products', ($resource, Enterprises, Dereferencer, Taxons, Pro
|
||||
registerVariants: ->
|
||||
for product in @products
|
||||
if product.variants
|
||||
product.variant_names = ""
|
||||
product.variants = for variant in product.variants
|
||||
variant = Variants.register variant
|
||||
if product.name != variant.name_to_display
|
||||
product.variant_names += variant.name_to_display + " "
|
||||
variant.product = product
|
||||
variant
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
{{ message }}
|
||||
.action-buttons.text-center
|
||||
%button{ ng: { click: "close()" } }
|
||||
OK
|
||||
= t(:ok)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.ofn-drop-down
|
||||
%span
|
||||
%i.icon-check
|
||||
Actions
|
||||
= t('admin.actions')
|
||||
%i{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
|
||||
%div.menu{ 'ng-show' => "expanded" }
|
||||
%a.menu_item{ 'ng-repeat' => "link in links", href: '{{link.url}}', target: "{{link.target || '_self'}}", data: { method: "{{ link.method || 'get' }}", confirm: "{{link.confirm}}" } }
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
#tag-rule-help
|
||||
.margin-bottom-30.text-center
|
||||
.text-big Tag Rules
|
||||
.text-big
|
||||
= t('js.admin.modals.tag_rule_help.title')
|
||||
|
||||
.margin-bottom-30
|
||||
.text-normal Overview
|
||||
%p Tag rules provide a way to describe which items are visible or otherwise to which customers. Items can be Shipping Methods, Payment Methods, Products and Order Cycles.
|
||||
.text-normal= t('js.admin.modals.tag_rule_help.overview')
|
||||
%p= t('js.admin.modals.tag_rule_help.overview_text')
|
||||
|
||||
.margin-bottom-30
|
||||
.text-normal 'By Default...' Rules
|
||||
%p Default rules allow you to hide items so that they are not visible by default. This behaviour can then be overriden by non-default rules for customers with particular tags.
|
||||
.text-normal= t('js.admin.modals.tag_rule_help.by_default_rules')
|
||||
%p= t('js.admin.modals.tag_rule_help.by_default_rules_text')
|
||||
|
||||
.margin-bottom-30
|
||||
.text-normal 'Customers Tagged...' Rules
|
||||
%p By creating rules related to a specific customer tag, you can override the default behaviour (whether it be to show or to hide items) for customers with the specified tag.
|
||||
.text-normal= t('js.admin.modals.tag_rule_help.customer_tagged_rules')
|
||||
%p= t('js.admin.modals.tag_rule_help.customer_tagged_rules_text')
|
||||
|
||||
.text-center
|
||||
%input.button.red.icon-plus{ type: 'button', value: 'Got it', ng: { click: 'close()' } }
|
||||
%input.button.red.icon-plus{ type: 'button', value: t('js.admin.modals.got_it'), ng: { click: 'close()' } }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#new-tag-rule-dialog
|
||||
.text-normal.margin-bottom-30.text-center
|
||||
Select a rule type:
|
||||
= t('js.admin.new_tag_rule_dialog.select_rule_type')
|
||||
|
||||
.text-center.margin-bottom-30
|
||||
-# %select.fullwidth{ 'select2-min-search' => 5, 'ng-model' => 'newRuleType', 'ng-options' => 'ruleType.id as ruleType.name for ruleType in availableRuleTypes' }
|
||||
|
||||
@@ -2,130 +2,128 @@
|
||||
.alpha.eight.columns
|
||||
%div{ ng: { if: "!enterprise.is_primary_producer", switch: "enterprise.sells" } }
|
||||
.info{ ng: { switch: { when: "none" } } }
|
||||
%h3 Hub Profile
|
||||
%h3= t('js.admin.panels.enterprise_package.hub_profile')
|
||||
|
||||
%p
|
||||
%strong COST: ALWAYS FREE
|
||||
%strong= t('js.admin.panels.enterprise_package.hub_profile_cost')
|
||||
|
||||
%p People can find and contact you on the Open Food Network. Your enterprise will be visible on the map, and will be searchable in listings.
|
||||
%p= t('js.admin.panels.enterprise_package.hub_profile_text1')
|
||||
|
||||
%p Having a profile, and making connections within your local food system through the Open Food Network will always be free.
|
||||
%p= t('js.admin.panels.enterprise_package.hub_profile_text2')
|
||||
|
||||
.info{ ng: { switch: { when: "any" } } }
|
||||
%h3 Hub Shop
|
||||
%h3= t('js.admin.panels.enterprise_package.hub_shop')
|
||||
|
||||
%p
|
||||
%strong
|
||||
%monthly-pricing-description{ joiner: "comma" }
|
||||
|
||||
%p Your enterprise is the backbone of your local food system. You aggregate produce from other enterprises and can sell it through your shop on the Open Food Network.
|
||||
%p= t('js.admin.panels.enterprise_package.hub_shop_text1')
|
||||
|
||||
%p Hubs can take many forms, whether they be a food co-op, a buying group, a veggie-box program, or a local grocery store.
|
||||
%p= t('js.admin.panels.enterprise_package.hub_shop_text2')
|
||||
|
||||
%p If you also want to sell your own products, you will need to switch this enterprise to be a producer.
|
||||
%p= t('js.admin.panels.enterprise_package.hub_shop_text3')
|
||||
|
||||
.info{ ng: { switch: { default: true } } }
|
||||
%h3
|
||||
Please Choose a Package
|
||||
= t('js.admin.panels.enterprise_package.choose_package')
|
||||
%i.icon-arrow-right
|
||||
|
||||
%p
|
||||
%strong Your enterprise will not be fully activated until a package is selected from the options on the left.
|
||||
%strong= t('js.admin.panels.enterprise_package.choose_package_text1')
|
||||
|
||||
%p
|
||||
Click on an option to see more detailed information about each package, and hit the red SAVE button when you are done!
|
||||
|
||||
|
||||
= t('js.admin.panels.enterprise_package.choose_package_text2')
|
||||
|
||||
%div{ ng: { if: "enterprise.is_primary_producer", switch: "enterprise.sells" } }
|
||||
.info{ ng: { switch: { when: "none" } } }
|
||||
%h3 Profile Only
|
||||
%h3= t('js.admin.panels.enterprise_package.profile_only')
|
||||
|
||||
%p
|
||||
%strong COST: ALWAYS FREE
|
||||
%strong= t('js.admin.panels.enterprise_package.profile_only_cost')
|
||||
|
||||
%p A profile makes you visible and contactable to others and is a way to share your story.
|
||||
%p= t('js.admin.panels.enterprise_package.profile_only_text1')
|
||||
|
||||
%p If you prefer to focus on producing food, and want to leave the work of selling it to someone else, you won't require a shop on the Open Food Network.
|
||||
%p= t('js.admin.panels.enterprise_package.profile_only_text2')
|
||||
|
||||
%p Add your products to Open Food Network, allowing hubs to stock your products in their stores.
|
||||
%p= t('js.admin.panels.enterprise_package.profile_only_text3')
|
||||
|
||||
.info{ ng: { switch: { when: "own" } } }
|
||||
%h3 Producer Shop
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_shop')
|
||||
|
||||
%p
|
||||
%strong
|
||||
%monthly-pricing-description{ joiner: "comma" }
|
||||
|
||||
%p Sell your products directly to customers through your very own Open Food Network shopfront.
|
||||
%p= t('js.admin.panels.enterprise_package.producer_shop_text1')
|
||||
|
||||
%p A Producer Shop is for your produce only, if you want to sell produce grown/produced off site, please select 'Producer Hub'.
|
||||
%p= t('js.admin.panels.enterprise_package.producer_shop_text2')
|
||||
|
||||
.info{ ng: { switch: { when: "any" } } }
|
||||
%h3 Producer Hub
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_hub')
|
||||
|
||||
%p
|
||||
%strong
|
||||
%monthly-pricing-description{ joiner: "comma" }
|
||||
|
||||
%p Your enterprise is the backbone of your local food system. You can sell your own produce as well as produce aggregated from other enterprises through your shopfront on the Open Food Network.
|
||||
%p= t('js.admin.panels.enterprise_package.producer_hub_text1')
|
||||
|
||||
%p Producer Hubs can take many forms, whether they be a CSA, a veggie-box program, or a food co-op with a rooftop garden.
|
||||
%p= t('js.admin.panels.enterprise_package.producer_hub_text2')
|
||||
|
||||
%p The Open Food Network aims to support as many hub models as possible, so no matter your situation, we want to provide the tools you need to run your organisation or local food business.
|
||||
%p= t('js.admin.panels.enterprise_package.producer_hub_text3')
|
||||
|
||||
.info{ ng: { switch: { default: true } } }
|
||||
%h3
|
||||
Please Choose a Package
|
||||
= t('js.admin.panels.enterprise_package.choose_package')
|
||||
%i.icon-arrow-right
|
||||
|
||||
%p
|
||||
%strong Your producer enterprise will not be fully activated until a package is selected from the options on the left.
|
||||
%strong= t('js.admin.panels.enterprise_package.choose_package_text1')
|
||||
|
||||
%p
|
||||
Click on an option to see more detailed information about each package, and hit the red SAVE button when you are done!
|
||||
= t('js.admin.panels.enterprise_package.choose_package_text2')
|
||||
|
||||
.omega.eight.columns{ ng: { switch: "enterprise.is_primary_producer" } }
|
||||
%div{ ng: { switch: { when: "false" } } }
|
||||
%a.button.selector.hub-profile{ ng: { click: "enterprise.owned && (enterprise.sells='none')", class: "{selected: enterprise.sells=='none', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 Profile Only
|
||||
%p Get a listing
|
||||
.bottom ALWAYS FREE
|
||||
%h3= t('js.admin.panels.enterprise_package.profile_only')
|
||||
%p= t('js.admin.panels.enterprise_package.get_listing')
|
||||
.bottom= t('js.admin.panels.enterprise_package.always_free')
|
||||
%a.button.selector.hub{ ng: { click: "enterprise.owned && (enterprise.sells='any')", class: "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 Hub Shop
|
||||
%p Sell produce from others
|
||||
%h3= t('js.admin.panels.enterprise_package.hub_shop')
|
||||
%p= t('js.admin.panels.enterprise_package.sell_produce_others')
|
||||
.bottom
|
||||
%monthly-pricing-description{ joiner: "newline" }
|
||||
|
||||
%div{ ng: { switch: { when: "true" } } }
|
||||
%a.button.selector.producer-profile{ ng: { click: "enterprise.owned && (enterprise.sells='none')", class: "{selected: enterprise.sells=='none', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 Profile Only
|
||||
%p Get a listing
|
||||
.bottom ALWAYS FREE
|
||||
%h3= t('js.admin.panels.enterprise_package.profile_only')
|
||||
%p= t('js.admin.panels.enterprise_package.get_listing')
|
||||
.bottom= t('js.admin.panels.enterprise_package.always_free')
|
||||
%a.button.selector.producer-shop{ ng: { click: "enterprise.owned && (enterprise.sells='own')", class: "{selected: enterprise.sells=='own', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 Producer Shop
|
||||
%p Sell your own produce
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_shop')
|
||||
%p= t('js.admin.panels.enterprise_package.sell_own_produce')
|
||||
.bottom
|
||||
%monthly-pricing-description{ joiner: "newline" }
|
||||
|
||||
%a.button.selector.producer-hub{ ng: { click: "enterprise.owned && (enterprise.sells='any')", class: "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 Producer Hub
|
||||
%p Sell produce from self and others
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_hub')
|
||||
%p= t('js.admin.panels.enterprise_package.sell_both')
|
||||
.bottom
|
||||
%monthly-pricing-description{ joiner: "newline" }
|
||||
|
||||
%a.button.update.fullwidth{ ng: { show: "enterprise.owned", class: "{disabled: saved() && !saving, saving: saving}", click: "save()" } }
|
||||
%span{ ng: {hide: "saved() || saving" } }
|
||||
SAVE
|
||||
= t('js.admin.panels.save')
|
||||
%i.icon-save
|
||||
%span{ ng: {show: "saved() && !saving" } }
|
||||
SAVED
|
||||
= t('js.admin.panels.saved')
|
||||
%i.icon-ok-sign
|
||||
%span{ ng: {show: "saving" } }
|
||||
SAVING
|
||||
= t('js.admin.panels.saving')
|
||||
%i.icon-refresh
|
||||
|
||||
@@ -1,39 +1,37 @@
|
||||
.row.enterprise_producer_panel{ ng: { controller: 'indexProducerPanelCtrl' } }
|
||||
|
||||
.alpha.eight.columns
|
||||
.info{ ng: { show: "enterprise.is_primary_producer==true" } }
|
||||
%h3 Producer
|
||||
%p Producers make yummy things to eat &/or drink. You're a producer if you grow it, raise it, brew it, bake it, ferment it, milk it or mould it.
|
||||
|
||||
%p Producers can also perform other functions, such as aggregating food from other enterprises and selling it through a shop on the Open Food Network.
|
||||
%h3= t('js.admin.panels.enterprise_producer.producer')
|
||||
%p= t('js.admin.panels.enterprise_producer.producer_text1')
|
||||
|
||||
%p= t('js.admin.panels.enterprise_producer.producer_text2')
|
||||
|
||||
.info{ ng: { show: "enterprise.is_primary_producer==false" } }
|
||||
%h3 Non-Producer
|
||||
%p Non-producers do not produce any food themselves, meaning that they cannot create their own products for sale through the Open Food Network.
|
||||
%h3= t('js.admin.panels.enterprise_producer.non_producer')
|
||||
%p= t('js.admin.panels.enterprise_producer.non_producer_text1')
|
||||
|
||||
%p Instead, non-producers specialise in linking producers to the end eater, whether it be by aggregating, grading, packing, selling or delivering food.
|
||||
%p= t('js.admin.panels.enterprise_producer.non_producer_text2')
|
||||
|
||||
.omega.eight.columns
|
||||
%a.button.selector.producer{ ng: { click: 'enterprise.owned && changeToProducer()', class: "{selected: enterprise.is_primary_producer==true, disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 PRODUCER
|
||||
%p Producers of food
|
||||
.bottom eg. GROWERS, BAKERS, BREWERS, MAKERS
|
||||
%h3= t('js.admin.panels.enterprise_producer.producer')
|
||||
%p= t('js.admin.panels.enterprise_producer.producer_desc')
|
||||
.bottom= t('js.admin.panels.enterprise_producer.producer_example')
|
||||
|
||||
%a.button.selector.non-producer{ ng: { click: 'enterprise.owned && changeToNonProducer()', class: "{selected: enterprise.is_primary_producer==false, disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 Non-Producer
|
||||
%p All other food enterprises
|
||||
.bottom eg. Grocery stores, Food co-ops, Buying groups
|
||||
%h3= t('js.admin.panels.enterprise_producer.non_producer')
|
||||
%p= t('js.admin.panels.enterprise_producer.non_producer_desc')
|
||||
.bottom= t('js.admin.panels.enterprise_producer.non_producer_example')
|
||||
|
||||
%a.button.update.fullwidth{ ng: { show: "enterprise.owned", class: "{disabled: saved() && !saving, saving: saving}", click: "save()" } }
|
||||
%span{ ng: {hide: "saved() || saving" } }
|
||||
SAVE
|
||||
= t('js.admin.panels.save')
|
||||
%i.icon-save
|
||||
%span{ ng: {show: "saved() && !saving" } }
|
||||
SAVED
|
||||
= t('js.admin.panels.saved')
|
||||
%i.icon-ok-sign
|
||||
%span{ ng: {show: "saving" } }
|
||||
SAVING
|
||||
= t('js.admin.panels.saving')
|
||||
%i.icon-refresh
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
.row.enterprise_status_panel{ ng: { controller: 'indexStatusPanelCtrl' } }
|
||||
.alpha.omega.sixteen.columns
|
||||
|
||||
%h4.status-ok.text-center{ ng: { show: "issues.length == 0 && warnings.length == 0" } }
|
||||
%i.icon-ok-sign
|
||||
{{ object.name }} is set up and ready to go!
|
||||
= t('js.admin.panels.enterprise_status.status_title', name: '{{ object.name }}')
|
||||
|
||||
%table{ ng: { show: "issues.length > 0 || warnings.length > 0" } }
|
||||
%thead
|
||||
%th.severity
|
||||
Severity
|
||||
= t('js.admin.panels.enterprise_status.severity')
|
||||
%th.description
|
||||
Description
|
||||
= t('js.admin.panels.enterprise_status.description')
|
||||
%th.resolve
|
||||
Resolve
|
||||
= t('js.admin.panels.enterprise_status.resolve')
|
||||
%tr{ ng: { repeat: "issue in issues"} }
|
||||
%td.severity
|
||||
%i.icon-warning-sign.issue
|
||||
|
||||
@@ -7,16 +7,13 @@
|
||||
'ng-model' => 'exchange.select_all_variants',
|
||||
'ng-change' => 'setExchangeVariants(exchange, incomingExchangeVariantsFor(exchange.enterprise_id), exchange.select_all_variants)',
|
||||
'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_select_all_variants' }
|
||||
Select all
|
||||
= t('admin.select_all')
|
||||
|
||||
.exchange-products
|
||||
-# Scope product list based on permissions the current user has to view variants in this exchange
|
||||
.exchange-product{'ng-repeat' => 'product in supplied_products | filter:productSuppliedToOrderCycle | visibleProducts:exchange:order_cycle.visible_variants_for_outgoing_exchanges | orderBy:"name"' }
|
||||
.exchange-product-details
|
||||
%label
|
||||
-# MASTER_VARIANTS: No longer required
|
||||
-# = check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants.length > 0', 'ng-model' => 'exchange.variants[product.master_id]', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}',
|
||||
-# 'ng-disabled' => 'product.variants.length > 0 || !order_cycle.editable_variants_for_outgoing_exchanges.hasOwnProperty(exchange.enterprise_id) || order_cycle.editable_variants_for_outgoing_exchanges[exchange.enterprise_id].indexOf(product.master_id) < 0'
|
||||
%img{'ng-src' => '{{ product.image_url }}'}
|
||||
.name {{ product.name }}
|
||||
.supplier {{ product.supplier_name }}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
'ng-model' => 'exchange.select_all_variants',
|
||||
'ng-change' => 'setExchangeVariants(exchange, suppliedVariants(exchange.enterprise_id), exchange.select_all_variants)',
|
||||
'id' => 'order_cycle_incoming_exchange_{{ $index }}_select_all_variants' }
|
||||
Select all
|
||||
= t('admin.select_all')
|
||||
|
||||
.exchange-products
|
||||
-# No need to scope product list based on permissions, because if an incoming exchange is visible,
|
||||
@@ -36,7 +36,7 @@
|
||||
'ofn-sync-distributions' => '{{ product.master_id }}',
|
||||
'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}',
|
||||
'ng-disabled' => '!order_cycle.editable_variants_for_incoming_exchanges.hasOwnProperty(exchange.enterprise_id) || order_cycle.editable_variants_for_incoming_exchanges[exchange.enterprise_id].indexOf(product.master_id) < 0' }
|
||||
Obsolete master
|
||||
= t('admin.obsolete_master')
|
||||
|
||||
.exchange-product-variant{'ng-repeat' => 'variant in product.variants'}
|
||||
%label
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user