mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Compare commits
255 Commits
v1.8.10
...
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 | ||
|
|
a97bcf74de | ||
|
|
1e6f4aa73d | ||
|
|
7c7933f8bb | ||
|
|
dc69c6e825 | ||
|
|
41e91765ca | ||
|
|
19569f9316 | ||
|
|
6a5e4bb592 | ||
|
|
507e12adba | ||
|
|
5fa45c0716 |
@@ -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
|
||||
|
||||
9
Gemfile
9
Gemfile
@@ -4,6 +4,7 @@ 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'
|
||||
@@ -115,7 +116,6 @@ end
|
||||
|
||||
group :test do
|
||||
gem 'webmock'
|
||||
|
||||
# See spec/spec_helper.rb for instructions
|
||||
#gem 'perftools.rb'
|
||||
end
|
||||
@@ -127,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
|
||||
|
||||
37
Gemfile.lock
37
Gemfile.lock
@@ -165,6 +165,7 @@ GEM
|
||||
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)
|
||||
@@ -257,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)
|
||||
@@ -407,9 +408,6 @@ 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.11)
|
||||
@@ -419,6 +417,8 @@ GEM
|
||||
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)
|
||||
@@ -477,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
|
||||
@@ -494,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)
|
||||
@@ -531,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 (11.1.2)
|
||||
rake (11.3.0)
|
||||
ransack (0.7.2)
|
||||
actionpack (~> 3.0)
|
||||
activerecord (~> 3.0)
|
||||
@@ -578,7 +583,14 @@ 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)
|
||||
@@ -620,6 +632,7 @@ GEM
|
||||
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
|
||||
@@ -648,8 +661,6 @@ GEM
|
||||
xml-simple (1.1.4)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
zeus (0.15.4)
|
||||
method_source (>= 0.6.7)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -679,6 +690,7 @@ DEPENDENCIES
|
||||
deface!
|
||||
delayed_job_active_record
|
||||
diffy
|
||||
eventmachine (>= 1.2.3)
|
||||
factory_girl_rails
|
||||
figaro
|
||||
foreigner
|
||||
@@ -692,9 +704,9 @@ 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
|
||||
@@ -723,6 +735,7 @@ DEPENDENCIES
|
||||
roo (~> 2.7.0)
|
||||
rspec-rails
|
||||
rspec-retry
|
||||
rubocop (>= 0.49.1)
|
||||
sass (~> 3.3)
|
||||
sass-rails (~> 3.2.3)
|
||||
shoulda-matchers
|
||||
@@ -749,4 +762,4 @@ RUBY VERSION
|
||||
ruby 2.1.5p273
|
||||
|
||||
BUNDLED WITH
|
||||
1.14.3
|
||||
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
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -107,6 +108,9 @@ 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
|
||||
|
||||
* Andrew Spinks (http://github.com/andrewspinks)
|
||||
|
||||
@@ -48,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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -84,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) ->
|
||||
|
||||
@@ -87,11 +87,11 @@ angular.module('admin.orderCycles')
|
||||
|
||||
$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) ->
|
||||
|
||||
@@ -49,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)
|
||||
|
||||
|
||||
@@ -42,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)
|
||||
|
||||
|
||||
@@ -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,8 +1,7 @@
|
||||
angular.module("ofn.admin").controller "ImportOptionsFormCtrl", ($scope, $rootScope, ProductImportService) ->
|
||||
|
||||
$scope.toggleResetAbsent = () ->
|
||||
confirmed = confirm 'This will set stock level to zero on all products for this \n' +
|
||||
'enterprise that are not present in the uploaded file.' if $scope.resetAbsent
|
||||
confirmed = confirm t('js.product_import.confirmation') if $scope.resetAbsent
|
||||
|
||||
if confirmed or !$scope.resetAbsent
|
||||
ProductImportService.updateResetAbsent($scope.supplierId, $scope.resetCount, $scope.resetAbsent)
|
||||
|
||||
@@ -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()
|
||||
@@ -24,7 +24,7 @@ angular.module("admin.resources").factory "Customers", ($q, InfoDialog, RequestM
|
||||
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) ->
|
||||
@clear()
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
@@ -57,4 +57,4 @@ angular.module("admin.tagRules").controller "TagRulesCtrl", ($scope, $http, $fil
|
||||
.success ->
|
||||
tagGroup.rules.splice(index, 1)
|
||||
$scope.updateRuleCounts()
|
||||
$scope.enterprise_form.$setDirty()
|
||||
$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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
|
||||
@@ -5,4 +5,4 @@ Darkswarm.filter 'products', (Matcher) ->
|
||||
return products if text == ""
|
||||
products.filter (product) =>
|
||||
propertiesToMatch = [product.name, product.variant_names, product.supplier.name, product.primary_taxon.name]
|
||||
Matcher.match propertiesToMatch, text
|
||||
Matcher.matchBeginning propertiesToMatch, text
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -42,9 +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
|
||||
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)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
'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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.row.exchange-tags
|
||||
.sixteen.columns.alpha.omega
|
||||
%span.text-normal Tags
|
||||
%span.text-normal
|
||||
= t('admin.tags')
|
||||
%br
|
||||
%tags-with-translation.fullwidth{ object: 'object' }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%div{ ng: { show: "data.length > limit" } }
|
||||
%input{ type: 'button', value: t(:show_more), ng: { click: 'limit = limit + increment' } }
|
||||
or
|
||||
%input{ type: 'button', value: t(:show_more_with_more, num: '{{ data.length - limit }}'), ng: { click: 'limit = data.length' } }
|
||||
%input{ type: 'button', value: t(:show_all_with_more, num: '{{ data.length - limit }}'), ng: { click: 'limit = data.length' } }
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_order_cycles_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_order_cycles_visibility]",
|
||||
ng: { value: "'hidden'", if: "rule.is_default" } }
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } } not visible
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } }
|
||||
=t(:not_visible)
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_payment_methods_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_payment_methods_visibility]",
|
||||
ng: { value: "'hidden'", if: "rule.is_default" } }
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } } not visible
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } }
|
||||
= t(:not_visible)
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_variants_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_variants_visibility]",
|
||||
ng: { value: "'hidden'", if: "rule.is_default" } }
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } } not visible
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } }
|
||||
= t(:not_visible)
|
||||
|
||||
@@ -7,4 +7,6 @@
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_shipping_methods_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_shipping_methods_visibility]",
|
||||
ng: { value: "'hidden'", if: "rule.is_default" } }
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } } not visible
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } }
|
||||
= t(:not_visible)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
%span.filter-shopfront.property-selectors.pad-top
|
||||
%ul.inline-block
|
||||
%li{"ng-repeat" => "property in enterprise.supplied_properties"}
|
||||
%a.button.tiny{"ng-bind" => "property.presentation"}
|
||||
%a.button.tiny.disabled{"ng-bind" => "property.presentation"}
|
||||
|
||||
.about-container.pad-top
|
||||
%img.enterprise-logo{"ng-src" => "{{::enterprise.logo}}", "ng-if" => "::enterprise.logo"}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%li.more
|
||||
%a.dropdown{ data: { dropdown: "{{ 'show-more-' + selectorName }}" }, ng: { class: "{active: selectedOverFlowSelectors().length > 0}" } }
|
||||
%span
|
||||
+ {{ overFlowSelectors().length }} more
|
||||
= t('js.more_items', count: "{{ overFlowSelectors().length }}")
|
||||
%i.ofn-i_052-point-down
|
||||
.f-dropdown.text-right.content{ ng: { attr: { id: "{{ 'show-more-' + selectorName }}" } } }
|
||||
%ul
|
||||
|
||||
3
app/assets/stylesheets/admin/enterprises.css.scss
Normal file
3
app/assets/stylesheets/admin/enterprises.css.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
form[name="enterprise_form"] div.row.warning {
|
||||
color: #DA7F52;
|
||||
}
|
||||
@@ -28,8 +28,8 @@ text-angular .ta-editor {
|
||||
left: 275px;
|
||||
}
|
||||
|
||||
span.error, div.error {
|
||||
color: #DA5354;
|
||||
span.error, div.error:not(.flash) {
|
||||
color: #DA5354;
|
||||
}
|
||||
|
||||
/* Fix conflict between Spree and elRTE's styles */
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
height: 100px
|
||||
width: 100px
|
||||
margin-right: 12px
|
||||
|
||||
|
||||
location
|
||||
@include headingFont
|
||||
@media all and (max-width: 768px)
|
||||
@@ -30,7 +30,7 @@
|
||||
margin-top: 0
|
||||
@media all and (max-width: 768px)
|
||||
margin-bottom: 8px
|
||||
|
||||
|
||||
|
||||
ordercycle
|
||||
text-align: right
|
||||
@@ -47,24 +47,26 @@
|
||||
p
|
||||
max-width: 100%
|
||||
float: right
|
||||
form.custom
|
||||
form.custom
|
||||
text-align: right
|
||||
& > strong
|
||||
line-height: 2.5
|
||||
font-size: 1.29em
|
||||
padding-right: 14px
|
||||
@media all and (max-width: 768px)
|
||||
select
|
||||
select
|
||||
width: inherit
|
||||
display: inline-block
|
||||
border-width: 1px
|
||||
border-color: #999
|
||||
color: #666
|
||||
font-size: 1em
|
||||
font-size: 1em
|
||||
margin-bottom: 0
|
||||
padding: 8px 20px 8px 12px
|
||||
@media all and (max-width: 768px)
|
||||
font-size: 0.875em
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0)
|
||||
font-size: 16px
|
||||
closing
|
||||
@include headingFont
|
||||
@media all and (max-width: 768px)
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
@import "branding";
|
||||
@import "mixins";
|
||||
|
||||
.account-summary {
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
|
||||
.orders {
|
||||
@include sidepaddingSm;
|
||||
|
||||
@include panepadding;
|
||||
|
||||
padding-top: 10px;
|
||||
|
||||
h3 {
|
||||
padding-top: 2em;
|
||||
}
|
||||
margin-top: 50px;
|
||||
margin-bottom: 100px;
|
||||
|
||||
a {
|
||||
color: $clr-brick;
|
||||
@@ -26,6 +24,12 @@
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.active_table_row {
|
||||
h3 {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
i.ofn-i_059-producer, i.ofn-i_060-producer-reversed {
|
||||
font-size: 3rem;
|
||||
display: inline-block;
|
||||
@@ -61,6 +65,7 @@
|
||||
.transaction-group {}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-radius: 0.5em 0.5em 0 0;
|
||||
|
||||
tr:nth-of-type(even) {
|
||||
|
||||
@@ -33,7 +33,9 @@
|
||||
|
||||
@-webkit-keyframes slideOutUp {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
@@ -46,10 +48,18 @@
|
||||
|
||||
@keyframes slideOutUp {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateY(0);
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: translateY(-20px);
|
||||
-ms-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeIn {
|
||||
|
||||
@@ -6,23 +6,25 @@
|
||||
background-color: #e1f0f5
|
||||
padding: 1em
|
||||
width: 100%
|
||||
border: none
|
||||
color: inherit
|
||||
|
||||
checkout
|
||||
display: block
|
||||
|
||||
@media all and (max-width: 640px)
|
||||
&.row .row
|
||||
@media all and (max-width: 640px)
|
||||
&.row .row
|
||||
margin-left: 0
|
||||
margin-right: 0
|
||||
|
||||
|
||||
orderdetails
|
||||
.button, table
|
||||
width: 100%
|
||||
@media all and (max-width: 640px)
|
||||
@media all and (max-width: 640px)
|
||||
form.edit_order
|
||||
border: 1px solid $disabled-bright
|
||||
margin-bottom: 2rem
|
||||
|
||||
|
||||
#details, #billing, #shipping, #payment
|
||||
border: 0
|
||||
margin: 1em 0
|
||||
@@ -34,20 +36,20 @@ checkout
|
||||
margin: 0
|
||||
padding: 0.65em
|
||||
background: #f7f7f7
|
||||
|
||||
.label
|
||||
|
||||
.label
|
||||
font-size: 1em
|
||||
padding: 0.3rem 0.35rem 0.275rem
|
||||
|
||||
// Logic to turn on & off the alerts for success against each fieldset
|
||||
|
||||
label, label.alert, label.success, &.valid label.alert, &.dirty label.success
|
||||
label, label.alert, label.success, &.valid label.alert, &.dirty label.success
|
||||
display: none
|
||||
|
||||
&.dirty label.alert
|
||||
&.dirty label.alert
|
||||
display: inline
|
||||
&.dirty.valid label.alert
|
||||
display: none
|
||||
&.dirty.valid label.alert
|
||||
display: none
|
||||
&.valid label.success
|
||||
display: inline
|
||||
|
||||
@@ -60,7 +62,7 @@ checkout
|
||||
text-align: left
|
||||
|
||||
// Logic to swap out up / down accordion icons
|
||||
//Foundation overrides
|
||||
//Foundation overrides
|
||||
dd > a
|
||||
@include csstrans
|
||||
background: $disabled-light !important
|
||||
@@ -68,7 +70,7 @@ checkout
|
||||
dd > a:hover
|
||||
background: $disabled-v-dark !important
|
||||
color: white
|
||||
|
||||
|
||||
dd
|
||||
span.accordion-up
|
||||
display: none
|
||||
@@ -79,4 +81,3 @@ checkout
|
||||
display: inline
|
||||
span.accordion-down
|
||||
display: none
|
||||
|
||||
|
||||
71
app/assets/stylesheets/darkswarm/embedded_shopfront.css.scss
Normal file
71
app/assets/stylesheets/darkswarm/embedded_shopfront.css.scss
Normal file
@@ -0,0 +1,71 @@
|
||||
body.embedded {
|
||||
nav.top-bar {
|
||||
ul.left, ul.center, ul.right li.current_hub {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul.right {
|
||||
width: auto !important;
|
||||
li {
|
||||
float: left;
|
||||
line-height: 4.6875rem;
|
||||
height: 4.6875rem;
|
||||
vertical-align: top;
|
||||
}
|
||||
li.powered-by {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
&.show-for-large-up {
|
||||
display: inherit !important;
|
||||
}
|
||||
&.show-for-medium-down {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
nav.top-bar ul.right li.powered-by {
|
||||
display: none;
|
||||
margin-right: 0.4rem;
|
||||
opacity: 0.6;
|
||||
|
||||
img {
|
||||
height: 1.8em;
|
||||
margin: 0px 0.4em 0.4em 0px;
|
||||
}
|
||||
span, a {
|
||||
font-family: "Oswald", sans-serif;
|
||||
font-size: 1rem;
|
||||
font-weight: 300;
|
||||
color: #555;
|
||||
padding: 0 !important;
|
||||
}
|
||||
a:hover {
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.blocked-cookies {
|
||||
text-align: center;
|
||||
margin-bottom: 0 !important;
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a.button.allow {
|
||||
background-color: rgba(0,0,0,0.25);
|
||||
margin-bottom: 0.4em;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0,0,0,0.35);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -117,6 +117,13 @@ nav {
|
||||
padding: 9px 0 0 9px;
|
||||
}
|
||||
|
||||
.top-bar .ofn-logo img {
|
||||
height: auto;
|
||||
width: auto;
|
||||
max-height: 51px;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.left-off-canvas-menu {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
@mixin panepadding {
|
||||
padding-top: 100px;
|
||||
padding-bottom: 100px;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
padding-top: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin paneWhiteText {
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
color: $clr-turquoise;
|
||||
}
|
||||
|
||||
.vertical-align-middle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
a {
|
||||
&:hover, &:active, &:focus {
|
||||
color: $clr-turquoise-bright;
|
||||
|
||||
@@ -110,6 +110,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.alert-box.changeable-orders-alert {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.alert-box.shopfront-message {
|
||||
border: 2px solid $clr-turquoise;
|
||||
border-radius: 5px;
|
||||
|
||||
@@ -72,11 +72,35 @@
|
||||
|
||||
// Shopping cart
|
||||
#cart-detail {
|
||||
.cart-item-delete {
|
||||
a.delete {
|
||||
.cart-item-delete, .bought-item-delete {
|
||||
a {
|
||||
font-size: 1.125em;
|
||||
}
|
||||
}
|
||||
|
||||
.out-of-stock {
|
||||
color: $clr-brick;
|
||||
}
|
||||
|
||||
button, .button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.toggle-bought {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
tr.bought td {
|
||||
color: $med-grey;
|
||||
|
||||
h5 {
|
||||
color: $med-grey;
|
||||
}
|
||||
|
||||
.already-confirmed {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-thumb-image {
|
||||
@@ -90,9 +114,3 @@
|
||||
height: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
#edit-cart {
|
||||
button, .button {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ class Admin::AccountsAndBillingSettingsController < Spree::Admin::BaseController
|
||||
|
||||
def start_job
|
||||
if @update_account_invoices_job || @finalize_account_invoices_job
|
||||
flash[:error] = "A task is already running, please wait until it has finished"
|
||||
flash[:error] = I18n.t(:accounts_and_billing_task_already_running_error)
|
||||
else
|
||||
new_job = "#{params[:job][:name]}".camelize.constantize.new
|
||||
Delayed::Job.enqueue new_job
|
||||
flash[:success] = "Task Queued"
|
||||
flash[:success] = I18n.t(:accounts_and_billing_start_task_notice)
|
||||
end
|
||||
|
||||
redirect_to_edit
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
module Admin
|
||||
class ContentsController < Spree::Admin::BaseController
|
||||
def edit
|
||||
@preference_sections = [{name: 'Header', preferences: [:logo, :logo_mobile, :logo_mobile_svg]},
|
||||
{name: 'Home page', preferences: [:home_hero, :home_show_stats]},
|
||||
{name: 'Producer signup page', preferences: [:producer_signup_pricing_table_html, :producer_signup_case_studies_html, :producer_signup_detail_html]},
|
||||
{name: 'Hub signup page', preferences: [:hub_signup_pricing_table_html, :hub_signup_case_studies_html, :hub_signup_detail_html]},
|
||||
{name: 'Group signup page', preferences: [:group_signup_pricing_table_html, :group_signup_case_studies_html, :group_signup_detail_html]},
|
||||
{name: 'Footer and External Links', preferences: [:footer_logo,
|
||||
@preference_sections = [{name: I18n.t('admin.contents.edit.header'), preferences: [:logo, :logo_mobile, :logo_mobile_svg]},
|
||||
{name: I18n.t('admin.contents.edit.home_page'), preferences: [:home_hero, :home_show_stats]},
|
||||
{name: I18n.t('admin.contents.edit.producer_signup_page'), preferences: [:producer_signup_pricing_table_html, :producer_signup_case_studies_html, :producer_signup_detail_html]},
|
||||
{name: I18n.t('admin.contents.edit.hub_signup_page'), preferences: [:hub_signup_pricing_table_html, :hub_signup_case_studies_html, :hub_signup_detail_html]},
|
||||
{name: I18n.t('admin.contents.edit.group_signup_page'), preferences: [:group_signup_pricing_table_html, :group_signup_case_studies_html, :group_signup_detail_html]},
|
||||
{name: I18n.t('admin.contents.edit.footer_and_external_links'), preferences: [:footer_logo,
|
||||
:footer_facebook_url, :footer_twitter_url, :footer_instagram_url, :footer_linkedin_url, :footer_googleplus_url, :footer_pinterest_url,
|
||||
:footer_email, :community_forum_url, :footer_links_md, :footer_about_url, :footer_tos_url]}]
|
||||
end
|
||||
@@ -21,7 +21,7 @@ module Admin
|
||||
# Save any uploaded images
|
||||
ContentConfig.save
|
||||
|
||||
flash[:success] = t(:successfully_updated, :resource => "Your content")
|
||||
flash[:success] = t(:successfully_updated, :resource => I18n.t('admin.contents.edit.your_content'))
|
||||
|
||||
redirect_to main_app.edit_admin_content_path
|
||||
end
|
||||
|
||||
@@ -35,7 +35,7 @@ module Admin
|
||||
if params.key? :enterprise_id
|
||||
redirect_path = main_app.admin_enterprise_fees_path(enterprise_id: params[:enterprise_id])
|
||||
end
|
||||
redirect_to redirect_path, :notice => 'Your enterprise fees have been updated.'
|
||||
redirect_to redirect_path, :notice => I18n.t(:enterprise_fees_update_notice)
|
||||
|
||||
else
|
||||
render :index
|
||||
@@ -49,7 +49,7 @@ module Admin
|
||||
product_distribution = ProductDistribution.where(:enterprise_fee_id => @object).first
|
||||
if product_distribution
|
||||
p = product_distribution.product
|
||||
error = "That enterprise fee cannot be deleted as it is referenced by a product distribution: #{p.id} - #{p.name}."
|
||||
error = I18n.t(:enterprise_fees_destroy_error, id: p.id, name: p.name)
|
||||
|
||||
respond_with(@object) do |format|
|
||||
format.html do
|
||||
|
||||
@@ -52,7 +52,6 @@ module Admin
|
||||
@owner_email = @enterprise_group.andand.owner.andand.email || ""
|
||||
end
|
||||
|
||||
|
||||
def collection
|
||||
EnterpriseGroup.by_position
|
||||
end
|
||||
|
||||
@@ -57,7 +57,7 @@ module Admin
|
||||
|
||||
def register
|
||||
if params[:sells] == 'unspecified'
|
||||
flash[:error] = "Please select a package"
|
||||
flash[:error] = I18n.t(:enterprise_register_package_error)
|
||||
return render :welcome, layout: "spree/layouts/bare_admin"
|
||||
end
|
||||
|
||||
@@ -68,10 +68,10 @@ module Admin
|
||||
end
|
||||
|
||||
if @enterprise.update_attributes(attributes)
|
||||
flash[:success] = "Congratulations! Registration for #{@enterprise.name} is complete!"
|
||||
flash[:success] = I18n.t(:enterprise_register_success_notice, enterprise: @enterprise.name)
|
||||
redirect_to admin_path
|
||||
else
|
||||
flash[:error] = "Could not complete registration for #{@enterprise.name}"
|
||||
flash[:error] = I18n.t(:enterprise_register_error, enterprise: @enterprise.name)
|
||||
render :welcome, layout: "spree/layouts/bare_admin"
|
||||
end
|
||||
end
|
||||
@@ -80,19 +80,19 @@ module Admin
|
||||
@enterprise_set = EnterpriseSet.new(collection, params[:enterprise_set])
|
||||
touched_enterprises = @enterprise_set.collection.select(&:changed?)
|
||||
if @enterprise_set.save
|
||||
flash[:success] = "Enterprises updated successfully"
|
||||
flash[:success] = I18n.t(:enterprise_bulk_update_success_notice)
|
||||
|
||||
# 18-3-2015: It seems that the form for this action sometimes loads bogus values for
|
||||
# the 'sells' field, and submitting that form results in a bunch of enterprises with
|
||||
# values that have mysteriously changed. This statement is here to help debug that
|
||||
# issue, and should be removed (along with its display in index.html.haml) when the
|
||||
# issue has been resolved.
|
||||
flash[:action] = "Updated #{pluralize(touched_enterprises.count, 'enterprise')}: #{touched_enterprises.map(&:name).join(', ')}"
|
||||
flash[:action] = "#{I18n.t(:updated)} #{pluralize(touched_enterprises.count, 'enterprise')}: #{touched_enterprises.map(&:name).join(', ')}"
|
||||
|
||||
redirect_to main_app.admin_enterprises_path
|
||||
else
|
||||
@enterprise_set.collection.select! { |e| touched_enterprises.include? e }
|
||||
flash[:error] = 'Update failed'
|
||||
flash[:error] = I18n.t(:enterprise_bulk_update_error)
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,7 +45,7 @@ module Admin
|
||||
if @order_cycle.save
|
||||
OpenFoodNetwork::OrderCycleFormApplicator.new(@order_cycle, spree_current_user).go!
|
||||
|
||||
flash[:notice] = 'Your order cycle has been created.'
|
||||
flash[:notice] = I18n.t(:order_cycles_create_notice)
|
||||
format.html { redirect_to admin_order_cycles_path }
|
||||
format.json { render :json => {:success => true} }
|
||||
else
|
||||
@@ -64,7 +64,7 @@ module Admin
|
||||
# Only update apply exchange information if it is actually submmitted
|
||||
OpenFoodNetwork::OrderCycleFormApplicator.new(@order_cycle, spree_current_user).go!
|
||||
end
|
||||
flash[:notice] = 'Your order cycle has been updated.' if params[:reloading] == '1'
|
||||
flash[:notice] = I18n.t(:order_cycles_update_notice) if params[:reloading] == '1'
|
||||
format.html { redirect_to main_app.edit_admin_order_cycle_path(@order_cycle) }
|
||||
format.json { render :json => {:success => true} }
|
||||
else
|
||||
@@ -76,7 +76,7 @@ module Admin
|
||||
def bulk_update
|
||||
@order_cycle_set = params[:order_cycle_set] && OrderCycleSet.new(params[:order_cycle_set])
|
||||
if @order_cycle_set.andand.save
|
||||
redirect_to main_app.admin_order_cycles_path, :notice => 'Order cycles have been updated.'
|
||||
redirect_to main_app.admin_order_cycles_path, notice: I18n.t(:order_cycles_bulk_update_notice)
|
||||
else
|
||||
render :index
|
||||
end
|
||||
@@ -85,14 +85,14 @@ module Admin
|
||||
def clone
|
||||
@order_cycle = OrderCycle.find params[:id]
|
||||
@order_cycle.clone!
|
||||
redirect_to main_app.admin_order_cycles_path, :notice => "Your order cycle #{@order_cycle.name} has been cloned."
|
||||
redirect_to main_app.admin_order_cycles_path, notice: I18n.t(:order_cycles_clone_notice, name: @order_cycle.name)
|
||||
end
|
||||
|
||||
# Send notifications to all producers who are part of the order cycle
|
||||
def notify_producers
|
||||
Delayed::Job.enqueue OrderCycleNotificationJob.new(params[:id].to_i)
|
||||
|
||||
redirect_to main_app.admin_order_cycles_path, :notice => 'Emails to be sent to producers have been queued for sending.'
|
||||
redirect_to main_app.admin_order_cycles_path, notice: I18n.t(:order_cycles_email_to_producers_notice)
|
||||
end
|
||||
|
||||
|
||||
@@ -100,10 +100,10 @@ module Admin
|
||||
def collection
|
||||
ocs = if params[:as] == "distributor"
|
||||
OrderCycle.ransack(params[:q]).result.
|
||||
involving_managed_distributors_of(spree_current_user).order('updated_at DESC')
|
||||
involving_managed_distributors_of(spree_current_user).order('updated_at DESC')
|
||||
elsif params[:as] == "producer"
|
||||
OrderCycle.ransack(params[:q]).result.
|
||||
involving_managed_producers_of(spree_current_user).order('updated_at DESC')
|
||||
involving_managed_producers_of(spree_current_user).order('updated_at DESC')
|
||||
else
|
||||
OrderCycle.ransack(params[:q]).result.accessible_by(spree_current_user)
|
||||
end
|
||||
@@ -115,7 +115,7 @@ module Admin
|
||||
end
|
||||
|
||||
def collection_actions
|
||||
[:index]
|
||||
[:index, :bulk_update]
|
||||
end
|
||||
|
||||
private
|
||||
@@ -138,12 +138,12 @@ module Admin
|
||||
available_coordinators = permitted_coordinating_enterprises_for(@order_cycle).select(&:confirmed?)
|
||||
case available_coordinators.count
|
||||
when 0
|
||||
flash[:error] = "None of your enterprises have permission to coordinate an order cycle"
|
||||
flash[:error] = I18n.t(:order_cycles_no_permission_to_coordinate_error)
|
||||
redirect_to main_app.admin_order_cycles_path
|
||||
when 1
|
||||
@order_cycle.coordinator = available_coordinators.first
|
||||
else
|
||||
flash[:error] = "You don't have permission to create an order cycle coordinated by that enterprise" if params[:coordinator_id]
|
||||
flash[:error] = I18n.t(:order_cycles_no_permission_to_create_error) if params[:coordinator_id]
|
||||
render :set_coordinator
|
||||
end
|
||||
end
|
||||
@@ -153,7 +153,7 @@ module Admin
|
||||
yield
|
||||
rescue ActiveRecord::InvalidForeignKey
|
||||
redirect_to main_app.admin_order_cycles_url
|
||||
flash[:error] = "That order cycle has been selected by a customer and cannot be deleted. To prevent customers from accessing it, please close it instead."
|
||||
flash[:error] = I18n.t(:order_cycles_no_permission_to_delete_error)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -179,9 +179,5 @@ module Admin
|
||||
def ams_prefix_whitelist
|
||||
[:basic]
|
||||
end
|
||||
|
||||
def collection_actions
|
||||
[:index, :bulk_update]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,7 +25,7 @@ class Admin::ProductImportController < Spree::Admin::BaseController
|
||||
|
||||
def validate_upload_presence
|
||||
unless params[:file] || (params[:filepath] && File.exist?(params[:filepath]))
|
||||
redirect_to '/admin/product_import', notice: 'File not found or could not be opened'
|
||||
redirect_to '/admin/product_import', notice: I18n.t(:product_import_file_not_found_notice)
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -39,7 +39,7 @@ class Admin::ProductImportController < Spree::Admin::BaseController
|
||||
|
||||
def check_spreadsheet_has_data(importer)
|
||||
unless importer.item_count
|
||||
redirect_to '/admin/product_import', notice: 'No data found in spreadsheet'
|
||||
redirect_to '/admin/product_import', notice: I18n.t(:product_import_no_data_in_spreadsheet_notice)
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -59,4 +59,4 @@ class Admin::ProductImportController < Spree::Admin::BaseController
|
||||
def model_class
|
||||
ProductImporter
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,7 +4,6 @@ module Admin
|
||||
"#{controller_name.classify}".constantize
|
||||
end
|
||||
|
||||
|
||||
# URL helpers
|
||||
def new_object_url(options = {})
|
||||
if parent_data.present?
|
||||
|
||||
@@ -12,7 +12,6 @@ module Admin
|
||||
def index
|
||||
end
|
||||
|
||||
|
||||
def bulk_update
|
||||
# Ensure we're authorised to update all variant overrides
|
||||
@vo_set.collection.each { |vo| authorize! :update, vo }
|
||||
|
||||
@@ -11,10 +11,10 @@ module Api
|
||||
def accessible
|
||||
@order_cycles = if params[:as] == "distributor"
|
||||
OrderCycle.ransack(params[:q]).result.
|
||||
involving_managed_distributors_of(current_api_user).order('updated_at DESC')
|
||||
involving_managed_distributors_of(current_api_user).order('updated_at DESC')
|
||||
elsif params[:as] == "producer"
|
||||
OrderCycle.ransack(params[:q]).result.
|
||||
involving_managed_producers_of(current_api_user).order('updated_at DESC')
|
||||
involving_managed_producers_of(current_api_user).order('updated_at DESC')
|
||||
else
|
||||
OrderCycle.ransack(params[:q]).result.accessible_by(current_api_user)
|
||||
end
|
||||
|
||||
@@ -3,6 +3,8 @@ require 'open_food_network/referer_parser'
|
||||
class ApplicationController < ActionController::Base
|
||||
protect_from_forgery
|
||||
|
||||
prepend_before_filter :restrict_iframes
|
||||
|
||||
include EnterprisesHelper
|
||||
helper CssSplitter::ApplicationHelper
|
||||
|
||||
@@ -18,13 +20,74 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
end
|
||||
|
||||
def shopfront_session
|
||||
session[:safari_fix] = true
|
||||
render 'shop/shopfront_session', layout: false
|
||||
end
|
||||
|
||||
def enable_embedded_styles
|
||||
session[:embedded_shopfront] = true
|
||||
render json: {}, status: 200
|
||||
end
|
||||
|
||||
def disable_embedded_styles
|
||||
session.delete :embedded_shopfront
|
||||
session.delete :shopfront_redirect
|
||||
render json: {}, status: 200
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def after_sign_in_path_for(resource_or_scope)
|
||||
return session[:shopfront_redirect] if session[:shopfront_redirect]
|
||||
stored_location_for(resource_or_scope) || signed_in_root_path(resource_or_scope)
|
||||
end
|
||||
|
||||
def after_sign_out_path_for(_resource_or_scope)
|
||||
session[:shopfront_redirect] ? session[:shopfront_redirect] : root_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def restrict_iframes
|
||||
response.headers['X-Frame-Options'] = 'DENY'
|
||||
response.headers['Content-Security-Policy'] = "frame-ancestors 'none'"
|
||||
end
|
||||
|
||||
def enable_embedded_shopfront
|
||||
whitelist = Spree::Config[:embedded_shopfronts_whitelist]
|
||||
return unless Spree::Config[:enable_embedded_shopfronts] && whitelist.present?
|
||||
return if request.referer && URI(request.referer).scheme != 'https' && !Rails.env.test?
|
||||
|
||||
response.headers.delete 'X-Frame-Options'
|
||||
response.headers['Content-Security-Policy'] = "frame-ancestors #{whitelist}"
|
||||
|
||||
check_embedded_request
|
||||
set_embedded_layout
|
||||
end
|
||||
|
||||
def check_embedded_request
|
||||
return unless params[:embedded_shopfront]
|
||||
|
||||
# Show embedded shopfront CSS
|
||||
session[:embedded_shopfront] = true
|
||||
|
||||
# Get shopfront slug and set redirect path
|
||||
if params[:controller] == 'enterprises' && params[:action] == 'shop' && params[:id]
|
||||
slug = params[:id]
|
||||
session[:shopfront_redirect] = '/' + slug + '/shop?embedded_shopfront=true'
|
||||
end
|
||||
end
|
||||
|
||||
def set_embedded_layout
|
||||
return unless session[:embedded_shopfront]
|
||||
@shopfront_layout = 'embedded'
|
||||
end
|
||||
|
||||
def action
|
||||
params[:action].to_sym
|
||||
end
|
||||
|
||||
|
||||
def require_distributor_chosen
|
||||
unless @distributor = current_distributor
|
||||
redirect_to spree.root_path
|
||||
@@ -62,7 +125,6 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# All render calls within the block will be performed with the specified format
|
||||
# Useful for rendering html within a JSON response, particularly if the specified
|
||||
# template or partial then goes on to render further partials without specifying
|
||||
|
||||
@@ -8,6 +8,7 @@ class BaseController < ApplicationController
|
||||
include Spree::Core::ControllerHelpers::Order
|
||||
include Spree::Core::ControllerHelpers::RespondWith
|
||||
|
||||
include I18nHelper
|
||||
include EnterprisesHelper
|
||||
include OrderCyclesHelper
|
||||
|
||||
@@ -17,9 +18,9 @@ class BaseController < ApplicationController
|
||||
# include Spree::ProductsHelper so that method is available on the controller
|
||||
include Spree::ProductsHelper
|
||||
|
||||
before_filter :set_locale
|
||||
before_filter :check_order_cycle_expiry
|
||||
|
||||
|
||||
private
|
||||
|
||||
def set_order_cycles
|
||||
@@ -29,7 +30,7 @@ class BaseController < ApplicationController
|
||||
end
|
||||
|
||||
@order_cycles = OrderCycle.with_distributor(@distributor).active
|
||||
.order(@distributor.preferred_shopfront_order_cycle_order)
|
||||
.order(@distributor.preferred_shopfront_order_cycle_order)
|
||||
|
||||
applicator = OpenFoodNetwork::TagRuleApplicator.new(@distributor, "FilterOrderCycles", current_customer.andand.tag_list)
|
||||
applicator.filter!(@order_cycles)
|
||||
|
||||
@@ -9,6 +9,7 @@ class CheckoutController < Spree::CheckoutController
|
||||
prepend_before_filter :require_distributor_chosen
|
||||
|
||||
skip_before_filter :check_registration
|
||||
before_filter :enable_embedded_shopfront
|
||||
|
||||
include OrderCyclesHelper
|
||||
include EnterprisesHelper
|
||||
@@ -88,7 +89,7 @@ class CheckoutController < Spree::CheckoutController
|
||||
|
||||
def check_order_for_phantom_fees
|
||||
phantom_fees = @order.adjustments.joins('LEFT OUTER JOIN spree_line_items ON spree_line_items.id = spree_adjustments.source_id').
|
||||
where("originator_type = 'EnterpriseFee' AND source_type = 'Spree::LineItem' AND spree_line_items.id IS NULL")
|
||||
where("originator_type = 'EnterpriseFee' AND source_type = 'Spree::LineItem' AND spree_line_items.id IS NULL")
|
||||
|
||||
if phantom_fees.any?
|
||||
Bugsnag.notify(RuntimeError.new("Phantom Fees"), {
|
||||
@@ -123,7 +124,6 @@ class CheckoutController < Spree::CheckoutController
|
||||
false
|
||||
end
|
||||
|
||||
|
||||
def update_failed
|
||||
clear_ship_address
|
||||
respond_to do |format|
|
||||
@@ -168,8 +168,8 @@ class CheckoutController < Spree::CheckoutController
|
||||
|
||||
customer_preferred_bill_address, customer_preferred_ship_address = @order.customer.bill_address, @order.customer.ship_address if @order.customer
|
||||
|
||||
@order.bill_address ||= customer_preferred_bill_address ||= preferred_bill_address || last_used_bill_address || Spree::Address.default
|
||||
@order.ship_address ||= customer_preferred_ship_address ||= preferred_ship_address || last_used_ship_address || Spree::Address.default
|
||||
@order.bill_address ||= customer_preferred_bill_address || preferred_bill_address || last_used_bill_address || Spree::Address.default
|
||||
@order.ship_address ||= customer_preferred_ship_address || preferred_ship_address || last_used_ship_address || Spree::Address.default
|
||||
end
|
||||
|
||||
def after_payment
|
||||
|
||||
@@ -30,7 +30,6 @@ class DiscourseSsoController < ApplicationController
|
||||
|
||||
def sso_url
|
||||
secret = discourse_sso_secret!
|
||||
discourse_url = discourse_url!
|
||||
sso = Discourse::SingleSignOn.parse(request.query_string, secret)
|
||||
sso.email = spree_current_user.email
|
||||
sso.username = spree_current_user.login
|
||||
|
||||
@@ -10,6 +10,7 @@ class EnterprisesController < BaseController
|
||||
before_filter :check_stock_levels, only: :shop
|
||||
|
||||
before_filter :clean_permalink, only: :check_permalink
|
||||
before_filter :enable_embedded_shopfront
|
||||
|
||||
respond_to :js, only: :permalink_checker
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
class HomeController < BaseController
|
||||
layout 'darkswarm'
|
||||
|
||||
before_filter :enable_embedded_shopfront
|
||||
|
||||
def index
|
||||
if ContentConfig.home_show_stats
|
||||
@num_distributors = Enterprise.is_distributor.activated.visible.count
|
||||
|
||||
48
app/controllers/line_items_controller.rb
Normal file
48
app/controllers/line_items_controller.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
class LineItemsController < BaseController
|
||||
respond_to :json
|
||||
|
||||
before_filter :load_line_item, only: :destroy
|
||||
|
||||
def bought
|
||||
respond_with bought_items, each_serializer: Api::LineItemSerializer
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :destroy, @line_item
|
||||
destroy_with_lock @line_item
|
||||
respond_with(@line_item)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_line_item
|
||||
@line_item = Spree::LineItem.find_by_id(params[:id])
|
||||
not_found unless @line_item
|
||||
end
|
||||
|
||||
# List all items the user already ordered in the current order cycle
|
||||
def bought_items
|
||||
return [] unless current_order_cycle && spree_current_user && current_distributor
|
||||
current_order_cycle.items_bought_by_user(spree_current_user, current_distributor)
|
||||
end
|
||||
|
||||
def unauthorized
|
||||
status = spree_current_user ? 403 : 401
|
||||
render nothing: true, status: status and return
|
||||
end
|
||||
|
||||
def not_found
|
||||
render nothing: true, status: 404 and return
|
||||
end
|
||||
|
||||
def destroy_with_lock(item)
|
||||
order = item.order
|
||||
order.with_lock do
|
||||
item.destroy
|
||||
order.update_shipping_fees!
|
||||
order.update_payment_fees!
|
||||
order.update_distribution_charge!
|
||||
order.create_tax_charge!
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,8 @@
|
||||
class ProducersController < BaseController
|
||||
layout 'darkswarm'
|
||||
|
||||
before_filter :enable_embedded_shopfront
|
||||
|
||||
def index
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,8 +2,8 @@ require 'open_food_network/cached_products_renderer'
|
||||
|
||||
class ShopController < BaseController
|
||||
layout "darkswarm"
|
||||
before_filter :require_distributor_chosen
|
||||
before_filter :set_order_cycles
|
||||
before_filter :require_distributor_chosen, :set_order_cycles, except: :changeable_orders_alert
|
||||
before_filter :enable_embedded_shopfront
|
||||
|
||||
def show
|
||||
redirect_to main_app.enterprise_shop_path(current_distributor)
|
||||
@@ -37,6 +37,10 @@ class ShopController < BaseController
|
||||
end
|
||||
end
|
||||
|
||||
def changeable_orders_alert
|
||||
render layout: false
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filtered_json(products_json)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
class ShopsController < BaseController
|
||||
layout 'darkswarm'
|
||||
|
||||
before_filter :enable_embedded_shopfront
|
||||
|
||||
def index
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,12 +23,11 @@ module Spree
|
||||
@tax_rate_id = tr_yielding_matching_tax || tr_valid_for_order
|
||||
|
||||
if tr_yielding_matching_tax.nil?
|
||||
@adjustment.errors.add :tax_rate_id, "^Please check that the tax rate for this adjustment is correct."
|
||||
@adjustment.errors.add :tax_rate_id, I18n.t(:adjustments_tax_rate_error)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def set_included_tax
|
||||
if params[:tax_rate_id].present?
|
||||
tax_rate = TaxRate.find params[:tax_rate_id]
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
require 'spree/core/controller_helpers/respond_with_decorator'
|
||||
|
||||
Spree::Admin::BaseController.class_eval do
|
||||
include I18nHelper
|
||||
|
||||
before_filter :set_locale
|
||||
before_filter :warn_invalid_order_cycles
|
||||
|
||||
# Warn the user when they have an active order cycle with hubs that are not ready
|
||||
@@ -51,13 +54,9 @@ Spree::Admin::BaseController.class_eval do
|
||||
distributor_names = distributors.map(&:name).join ', '
|
||||
|
||||
if distributors.count > 1
|
||||
"The hubs #{distributor_names} are listed in an active order cycle, " +
|
||||
"but do not have valid shipping and payment methods. " +
|
||||
"Until you set these up, customers will not be able to shop at these hubs."
|
||||
I18n.t(:active_distributors_not_ready_for_checkout_message_plural, distributor_names: distributor_names)
|
||||
else
|
||||
"The hub #{distributor_names} is listed in an active order cycle, " +
|
||||
"but does not have valid shipping and payment methods. " +
|
||||
"Until you set these up, customers will not be able to shop at this hub."
|
||||
I18n.t(:active_distributors_not_ready_for_checkout_message_singular, distributor_names: distributor_names)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ Spree::Admin::OrdersController.class_eval do
|
||||
|
||||
before_filter :load_distribution_choices, only: [:new, :edit, :update]
|
||||
|
||||
# Ensure that the distributor is set for an order when
|
||||
before_filter :ensure_distribution, only: :new
|
||||
|
||||
# After updating an order, the fees should be updated as well
|
||||
# Currently, adding or deleting line items does not trigger updating the
|
||||
# fees! This is a quick fix for that.
|
||||
@@ -109,9 +112,9 @@ Spree::Admin::OrdersController.class_eval do
|
||||
|
||||
# Replaced this search to filter orders to only show those distributed by current user (or all for admin user)
|
||||
@search.result.includes([:user, :shipments, :payments]).
|
||||
distributed_by_user(spree_current_user).
|
||||
page(params[:page]).
|
||||
per(params[:per_page] || Spree::Config[:orders_per_page])
|
||||
distributed_by_user(spree_current_user).
|
||||
page(params[:page]).
|
||||
per(params[:per_page] || Spree::Config[:orders_per_page])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -131,4 +134,16 @@ Spree::Admin::OrdersController.class_eval do
|
||||
ocs.closed +
|
||||
ocs.undated
|
||||
end
|
||||
|
||||
def ensure_distribution
|
||||
unless @order
|
||||
@order = Spree::Order.new
|
||||
@order.generate_order_number
|
||||
@order.save!
|
||||
end
|
||||
unless @order.distribution_set?
|
||||
render 'set_distribution', locals: { order: @order }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -18,55 +18,40 @@ Spree::Admin::ReportsController.class_eval do
|
||||
|
||||
include Spree::ReportsHelper
|
||||
|
||||
REPORT_TYPES = {
|
||||
orders_and_fulfillment: [
|
||||
['Order Cycle Supplier Totals',:order_cycle_supplier_totals],
|
||||
['Order Cycle Supplier Totals by Distributor',:order_cycle_supplier_totals_by_distributor],
|
||||
['Order Cycle Distributor Totals by Supplier',:order_cycle_distributor_totals_by_supplier],
|
||||
['Order Cycle Customer Totals',:order_cycle_customer_totals]
|
||||
],
|
||||
products_and_inventory: [
|
||||
['All products', :all_products],
|
||||
['Inventory (on hand)', :inventory],
|
||||
['LettuceShare', :lettuce_share]
|
||||
],
|
||||
customers: [
|
||||
["Mailing List", :mailing_list],
|
||||
["Addresses", :addresses]
|
||||
],
|
||||
order_cycle_management: [
|
||||
["Payment Methods Report", :payment_methods],
|
||||
["Delivery Report", :delivery]
|
||||
],
|
||||
sales_tax: [
|
||||
["Tax Types", :tax_types],
|
||||
["Tax Rates", :tax_rates]
|
||||
],
|
||||
packing: [
|
||||
["Pack By Customer", :pack_by_customer],
|
||||
["Pack By Supplier", :pack_by_supplier]
|
||||
]
|
||||
}
|
||||
|
||||
# Fetches user's distributors, suppliers and order_cycles
|
||||
before_filter :load_data, only: [:customers, :products_and_inventory, :order_cycle_management, :packing]
|
||||
|
||||
# Render a partial for orders and fulfillment description
|
||||
respond_override :index => { :html => { :success => lambda {
|
||||
@reports[:orders_and_fulfillment][:description] =
|
||||
render_to_string(partial: 'orders_and_fulfillment_description', layout: false, locals: {report_types: REPORT_TYPES[:orders_and_fulfillment]}).html_safe
|
||||
@reports[:products_and_inventory][:description] =
|
||||
render_to_string(partial: 'products_and_inventory_description', layout: false, locals: {report_types: REPORT_TYPES[:products_and_inventory]}).html_safe
|
||||
@reports[:customers][:description] =
|
||||
render_to_string(partial: 'customers_description', layout: false, locals: {report_types: REPORT_TYPES[:customers]}).html_safe
|
||||
@reports[:order_cycle_management][:description] =
|
||||
render_to_string(partial: 'order_cycle_management_description', layout: false, locals: {report_types: REPORT_TYPES[:order_cycle_management]}).html_safe
|
||||
@reports[:packing][:description] =
|
||||
render_to_string(partial: 'packing_description', layout: false, locals: {report_types: REPORT_TYPES[:packing]}).html_safe
|
||||
@reports[:sales_tax][:description] =
|
||||
render_to_string(partial: 'sales_tax_description', layout: false, locals: {report_types: REPORT_TYPES[:sales_tax]}).html_safe
|
||||
} } }
|
||||
|
||||
def report_types
|
||||
{
|
||||
orders_and_fulfillment: [
|
||||
[I18n.t('admin.reports.supplier_totals'), :order_cycle_supplier_totals],
|
||||
[I18n.t('admin.reports.supplier_totals_by_distributor'), :order_cycle_supplier_totals_by_distributor],
|
||||
[I18n.t('admin.reports.totals_by_supplier'), :order_cycle_distributor_totals_by_supplier],
|
||||
[I18n.t('admin.reports.customer_totals'), :order_cycle_customer_totals]
|
||||
],
|
||||
products_and_inventory: [
|
||||
[I18n.t('admin.reports.all_products'), :all_products],
|
||||
[I18n.t('admin.reports.inventory'), :inventory],
|
||||
[I18n.t('admin.reports.lettuce_share'), :lettuce_share]
|
||||
],
|
||||
customers: [
|
||||
[I18n.t('admin.reports.mailing_list'), :mailing_list],
|
||||
[I18n.t('admin.reports.addresses'), :addresses]
|
||||
],
|
||||
order_cycle_management: [
|
||||
[I18n.t('admin.reports.payment_methods'), :payment_methods],
|
||||
[I18n.t('admin.reports.delivery'), :delivery]
|
||||
],
|
||||
sales_tax: [
|
||||
[I18n.t('admin.reports.tax_types'), :tax_types],
|
||||
[I18n.t('admin.reports.tax_rates'), :tax_rates]
|
||||
],
|
||||
packing: [
|
||||
[I18n.t('admin.reports.pack_by_customer'), :pack_by_customer],
|
||||
[I18n.t('admin.reports.pack_by_supplier'), :pack_by_supplier]
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
# Overide spree reports list.
|
||||
def index
|
||||
@@ -76,7 +61,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
|
||||
# This action is short because we refactored it like bosses
|
||||
def customers
|
||||
@report_types = REPORT_TYPES[:customers]
|
||||
@report_types = report_types[:customers]
|
||||
@report_type = params[:report_type]
|
||||
@report = OpenFoodNetwork::CustomersReport.new spree_current_user, params
|
||||
render_report(@report.header, @report.table, params[:csv], "customers_#{timestamp}.csv")
|
||||
@@ -95,13 +80,12 @@ Spree::Admin::ReportsController.class_eval do
|
||||
@suppliers = my_suppliers | my_distributors.map { |d| Spree::Product.in_distributor(d) }.flatten.map(&:supplier).uniq
|
||||
@order_cycles = OrderCycle.active_or_complete.accessible_by(spree_current_user).order('orders_close_at DESC')
|
||||
|
||||
@report_types = REPORT_TYPES[:order_cycle_management]
|
||||
@report_types = report_types[:order_cycle_management]
|
||||
@report_type = params[:report_type]
|
||||
|
||||
# -- Build Report with Order Grouper
|
||||
@report = OpenFoodNetwork::OrderCycleManagementReport.new spree_current_user, params
|
||||
@table = @report.table_items
|
||||
csv_file_name = "#{params[:report_type]}_#{timestamp}.csv"
|
||||
|
||||
render_report(@report.header, @table, params[:csv], "order_cycle_management_#{timestamp}.csv")
|
||||
end
|
||||
@@ -119,14 +103,13 @@ Spree::Admin::ReportsController.class_eval do
|
||||
# My suppliers and any suppliers supplying products I distribute
|
||||
@suppliers = my_suppliers | my_distributors.map { |d| Spree::Product.in_distributor(d) }.flatten.map(&:supplier).uniq
|
||||
@order_cycles = OrderCycle.active_or_complete.accessible_by(spree_current_user).order('orders_close_at DESC')
|
||||
@report_types = REPORT_TYPES[:packing]
|
||||
@report_types = report_types[:packing]
|
||||
@report_type = params[:report_type]
|
||||
|
||||
# -- Build Report with Order Grouper
|
||||
@report = OpenFoodNetwork::PackingReport.new spree_current_user, params
|
||||
order_grouper = OpenFoodNetwork::OrderGrouper.new @report.rules, @report.columns
|
||||
@table = order_grouper.table(@report.table_items)
|
||||
csv_file_name = "#{params[:report_type]}_#{timestamp}.csv"
|
||||
|
||||
render_report(@report.header, @table, params[:csv], "packing_#{timestamp}.csv")
|
||||
end
|
||||
@@ -145,9 +128,9 @@ Spree::Admin::ReportsController.class_eval do
|
||||
orders.select{ |order| orders_with_hidden_details.include? order }.each do |order|
|
||||
# TODO We should really be hiding customer code here too, but until we
|
||||
# have an actual association between order and customer, it's a bit tricky
|
||||
order.bill_address.andand.assign_attributes(firstname: "HIDDEN", lastname: "", phone: "", address1: "", address2: "", city: "", zipcode: "", state: nil)
|
||||
order.ship_address.andand.assign_attributes(firstname: "HIDDEN", lastname: "", phone: "", address1: "", address2: "", city: "", zipcode: "", state: nil)
|
||||
order.assign_attributes(email: "HIDDEN")
|
||||
order.bill_address.andand.assign_attributes(firstname: I18n.t('admin.reports.hidden'), lastname: "", phone: "", address1: "", address2: "", city: "", zipcode: "", state: nil)
|
||||
order.ship_address.andand.assign_attributes(firstname: I18n.t('admin.reports.hidden'), lastname: "", phone: "", address1: "", address2: "", city: "", zipcode: "", state: nil)
|
||||
order.assign_attributes(email: I18n.t('admin.reports.hidden'))
|
||||
end
|
||||
|
||||
@report = OpenFoodNetwork::OrderAndDistributorReport.new orders
|
||||
@@ -226,12 +209,12 @@ Spree::Admin::ReportsController.class_eval do
|
||||
@suppliers = permissions.visible_enterprises_for_order_reports.is_primary_producer
|
||||
|
||||
@order_cycles = OrderCycle.active_or_complete.
|
||||
involving_managed_distributors_of(spree_current_user).order('orders_close_at DESC')
|
||||
involving_managed_distributors_of(spree_current_user).order('orders_close_at DESC')
|
||||
|
||||
@report_types = REPORT_TYPES[:orders_and_fulfillment]
|
||||
@report_types = report_types[:orders_and_fulfillment]
|
||||
@report_type = params[:report_type]
|
||||
|
||||
@include_blank = 'All'
|
||||
@include_blank = I18n.t(:all)
|
||||
|
||||
# -- Build Report with Order Grouper
|
||||
@report = OpenFoodNetwork::OrdersAndFulfillmentsReport.new spree_current_user, params
|
||||
@@ -244,7 +227,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
end
|
||||
|
||||
def products_and_inventory
|
||||
@report_types = REPORT_TYPES[:products_and_inventory]
|
||||
@report_types = report_types[:products_and_inventory]
|
||||
if params[:report_type] != 'lettuce_share'
|
||||
@report = OpenFoodNetwork::ProductsAndInventoryReport.new spree_current_user, params
|
||||
else
|
||||
@@ -254,7 +237,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
end
|
||||
|
||||
def users_and_enterprises
|
||||
# @report_types = REPORT_TYPES[:users_and_enterprises]
|
||||
# @report_types = report_types[:users_and_enterprises]
|
||||
@report = OpenFoodNetwork::UsersAndEnterprisesReport.new params
|
||||
render_report(@report.header, @report.table, params[:csv], "users_and_enterprises_#{timestamp}.csv")
|
||||
end
|
||||
@@ -273,7 +256,6 @@ Spree::Admin::ReportsController.class_eval do
|
||||
render_report(@report.header, @report.table, params[:csv], "xero_invoices_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
|
||||
def render_report(header, table, create_csv, csv_file_name)
|
||||
unless create_csv
|
||||
render :html => table
|
||||
@@ -316,19 +298,33 @@ Spree::Admin::ReportsController.class_eval do
|
||||
|
||||
def authorized_reports
|
||||
reports = {
|
||||
:orders_and_distributors => {:name => "Orders And Distributors", :description => "Orders with distributor details"},
|
||||
:bulk_coop => {:name => "Bulk Co-Op", :description => "Reports for Bulk Co-Op orders"},
|
||||
:payments => {:name => "Payment Reports", :description => "Reports for Payments"},
|
||||
:orders_and_fulfillment => {:name => "Orders & Fulfillment Reports", :description => ''},
|
||||
:customers => {:name => "Customers", :description => 'Customer details'},
|
||||
:products_and_inventory => {:name => "Products & Inventory", :description => ''},
|
||||
:sales_total => { :name => "Sales Total", :description => "Sales Total For All Orders" },
|
||||
:users_and_enterprises => { :name => "Users & Enterprises", :description => "Enterprise Ownership & Status" },
|
||||
:order_cycle_management => {:name => "Order Cycle Management", :description => ''},
|
||||
:sales_tax => { :name => "Sales Tax", :description => "Sales Tax For Orders" },
|
||||
:xero_invoices => { :name => "Xero Invoices", :description => 'Invoices for import into Xero' },
|
||||
:packing => { :name => "Packing Reports", :description => '' }
|
||||
:orders_and_distributors => {:name => I18n.t('admin.reports.orders_and_distributors.name'), :description => I18n.t('admin.reports.orders_and_distributors.description')},
|
||||
:bulk_coop => {:name => I18n.t('admin.reports.bulk_coop.name'), :description => I18n.t('admin.reports.bulk_coop.description')},
|
||||
:payments => {:name => I18n.t('admin.reports.payments.name'), :description => I18n.t('admin.reports.payments.description')},
|
||||
:orders_and_fulfillment => {:name => I18n.t('admin.reports.orders_and_fulfillment.name'), :description => ''},
|
||||
:customers => {:name => I18n.t('admin.reports.customers.name'), :description => ''},
|
||||
:products_and_inventory => {:name => I18n.t('admin.reports.products_and_inventory.name'), :description => ''},
|
||||
:sales_total => {:name => I18n.t('admin.reports.sales_total.name'), :description => I18n.t('admin.reports.sales_total.description')},
|
||||
:users_and_enterprises => {:name => I18n.t('admin.reports.users_and_enterprises.name'), :description => I18n.t('admin.reports.users_and_enterprises.description')},
|
||||
:order_cycle_management => {:name => I18n.t('admin.reports.order_cycle_management.name'), :description => ''},
|
||||
:sales_tax => {:name => I18n.t('admin.reports.sales_tax.name'), :description => ''},
|
||||
:xero_invoices => {:name => I18n.t('admin.reports.xero_invoices.name'), :description => I18n.t('admin.reports.xero_invoices.description')},
|
||||
:packing => {:name => I18n.t('admin.reports.packing.name'), :description => ''}
|
||||
}
|
||||
|
||||
reports[:orders_and_fulfillment][:description] =
|
||||
render_to_string(partial: 'orders_and_fulfillment_description', layout: false, locals: {report_types: report_types[:orders_and_fulfillment]}).html_safe
|
||||
reports[:products_and_inventory][:description] =
|
||||
render_to_string(partial: 'products_and_inventory_description', layout: false, locals: {report_types: report_types[:products_and_inventory]}).html_safe
|
||||
reports[:customers][:description] =
|
||||
render_to_string(partial: 'customers_description', layout: false, locals: {report_types: report_types[:customers]}).html_safe
|
||||
reports[:order_cycle_management][:description] =
|
||||
render_to_string(partial: 'order_cycle_management_description', layout: false, locals: {report_types: report_types[:order_cycle_management]}).html_safe
|
||||
reports[:packing][:description] =
|
||||
render_to_string(partial: 'packing_description', layout: false, locals: {report_types: report_types[:packing]}).html_safe
|
||||
reports[:sales_tax][:description] =
|
||||
render_to_string(partial: 'sales_tax_description', layout: false, locals: {report_types: report_types[:sales_tax]}).html_safe
|
||||
|
||||
# Return only reports the user is authorized to view.
|
||||
reports.select { |action| can? action, :report }
|
||||
end
|
||||
|
||||
@@ -19,7 +19,7 @@ Spree::Admin::SearchController.class_eval do
|
||||
def customers
|
||||
if spree_current_user.enterprises.pluck(:id).include? params[:distributor_id].to_i
|
||||
@customers = Customer.ransack({m: 'or', email_start: params[:q], name_start: params[:q]})
|
||||
.result.where(enterprise_id: params[:distributor_id])
|
||||
.result.where(enterprise_id: params[:distributor_id])
|
||||
else
|
||||
@customers = []
|
||||
end
|
||||
|
||||
@@ -38,7 +38,7 @@ module Spree
|
||||
def do_not_destroy_referenced_shipping_methods
|
||||
order = Order.where(:shipping_method_id => @object).first
|
||||
if order
|
||||
flash[:error] = "That shipping method cannot be deleted as it is referenced by an order: #{order.number}."
|
||||
flash[:error] = I18n.t(:shipping_method_destroy_error, number: order.number)
|
||||
redirect_to collection_url and return
|
||||
end
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user