Compare commits

...

205 Commits
v1.10 ... v1.11

Author SHA1 Message Date
Pau Perez
0634735288 Adjust Codeclimate config to ignore Rails patch
Since it is a file copied from Rails 4, we want to keep it in its
original state and not refactor it.
2018-02-07 16:21:16 +11:00
Pau Perez
719c45b408 Apply Rails 4 patch at boot time not only specs
This makes this patch available also for things like database-related
rake tasks. It moves the patch to an initializer.
2018-02-07 16:21:16 +11:00
Maikel Linke
b70edd5424 Enabling non-privileged postgres users to run specs
Addressing issue #245.

A combination of fixtures and foreign key constraints requires the postgres
user to be superuser. Otherwise an attempt to disable constraints fails.
This got fixed in Rails 4 and this patch brings the same behaviour back to
Rails 3. It will allow us to run the specs with a nosuperuser postgres user.

See:
 - https://github.com/matthuhiggins/foreigner/issues/61
 - 9bb27f7ffe
2018-02-07 16:21:16 +11:00
Aaron Hursh
a6498c2f96 Removed ng-disabled conditional from submit button on admin customers index. 2018-02-07 15:09:07 +11:00
Rob Harrington
56be7b1d46 Fix spec to handle non-deterministic ordering 2018-02-07 11:45:48 +11:00
Rob Harrington
b2f3477261 Change unused creation_date translation key back to confirmation_date
See 22eae753fe for original change
2018-02-07 11:42:38 +11:00
Matt-Yorkley
14b73149be Remove stale form validation messages when showing new confirmation sent message 2018-02-07 10:41:54 +11:00
Matt-Yorkley
0ab7d95607 Remove mention of confirmation email from enterprise creation wizard 2018-02-07 10:41:53 +11:00
Matt-Yorkley
ee08dcfeb4 Use owner as contact if user record doesn't exist 2018-02-07 10:41:53 +11:00
Matt-Yorkley
b893dea810 Make sure userSelect directive uses our Admin::UserSerializer instead of base Spree api view 2018-02-07 10:41:53 +11:00
Matt-Yorkley
ec5ce45850 Change confirmation email wording 2018-02-07 10:41:53 +11:00
Matt-Yorkley
9afb97fa0f Show contact email without full permissions 2018-02-07 10:41:53 +11:00
Matt-Yorkley
676abe0ced Remove serialized contact attributes 2018-02-07 10:41:53 +11:00
Matt-Yorkley
73d38cb91b Re-add text version of confirmation email for accessibility 2018-02-07 10:41:53 +11:00
Matt-Yorkley
fffae46a63 Remove enterpriseRoles from enterprsies controller 2018-02-07 10:41:53 +11:00
Matt-Yorkley
6ed91cab1f Remove old translation keys 2018-02-07 10:41:53 +11:00
Matt-Yorkley
cc5d0c35dd Refactor enterprise contact user assignment 2018-02-07 10:41:53 +11:00
Matt-Yorkley
c34570154c Use contact model in printed tickets 2018-02-07 10:41:53 +11:00
Matt-Yorkley
a5940e1641 Fix user controller spec 2018-02-07 10:41:53 +11:00
Matt-Yorkley
39f0c5b5b0 Rename contact name field and revert contact name specs 2018-02-07 10:41:53 +11:00
Matt-Yorkley
abb5adec43 Enterprise managers UI specs 2018-02-07 10:41:53 +11:00
Matt-Yorkley
525cb4826f Code review refactoring 2018-02-07 10:41:53 +11:00
Matt-Yorkley
fde0aba96c Feedback when user changes email addess 2018-02-07 10:41:53 +11:00
Matt-Yorkley
ff18fd25f1 Adjust Discourse login for user confirmations 2018-02-07 10:41:53 +11:00
Matt-Yorkley
9248ac05ac Adjustments for failing specs 2018-02-07 10:41:53 +11:00
Matt-Yorkley
a066c6391d Adjust injection data namespacing 2018-02-07 10:41:53 +11:00
Matt-Yorkley
4d11485283 Use receives_notifications flag for enterprise contact 2018-02-07 10:41:53 +11:00
Matt-Yorkley
9e270690ef Remove enterprise email
A user with the same email address is receiving notifications now.
If the email address is invalid, the owner receives notifications.
2018-02-07 10:41:53 +11:00
Matt-Yorkley
15b781b271 Update enterprise managers and contact role 2018-02-07 10:41:52 +11:00
Matt-Yorkley
5dc8f21b7b Show confirmed status in enterprise managers UI 2018-02-07 10:41:52 +11:00
Matt-Yorkley
9ccb3ee80b Add receives_notifications flag to enterprise_roles 2018-02-07 10:41:52 +11:00
Matt-Yorkley
27de66b055 Owner's permissions can't be deleted 2018-02-07 10:41:52 +11:00
Matt-Yorkley
ba98c7e2c5 Rewrite enterprise contact functionality 2018-02-07 10:41:52 +11:00
Matt-Yorkley
22eae753fe Remove enterprise confirmations 2018-02-07 10:41:52 +11:00
Pierre de Lacroix
d832d850fe Revert removed translations for Enterprise mails 2018-02-07 10:41:52 +11:00
Matt-Yorkley
aead867ea0 Set all current users to confirmed 2018-02-07 10:41:51 +11:00
Matt-Yorkley
97f5022bdd Show signup message in modal wihout redirect 2018-02-07 10:41:51 +11:00
Matt-Yorkley
0cb7a555d3 Adjust confirmation template 2018-02-07 10:41:51 +11:00
Maikel Linke
52b7872a55 Simplify conditionals 2018-02-07 10:41:51 +11:00
Matt-Yorkley
522aaee1a3 Update login modal for resending confirmations 2018-02-07 10:41:51 +11:00
Matt-Yorkley
179cf6e484 Tidy up confirmation migrations 2018-02-07 10:41:51 +11:00
Matt-Yorkley
28ded1f0c2 Adjust user signup feedback 2018-02-07 10:41:51 +11:00
Pierre de Lacroix
7d971fc39d Add UserConfirmationsController spec 2018-02-07 10:41:51 +11:00
Pierre de Lacroix
4f0b20e8ad Better tests 2018-02-07 10:41:51 +11:00
Pierre de Lacroix
a6f2ee1367 Add migration to confirm already confirmed email addresses 2018-02-07 10:41:51 +11:00
Pierre de Lacroix
eb1c598a6c Fix tests 2018-02-07 10:41:51 +11:00
Pierre de Lacroix
4706bf0528 Remove changes on FR locale file 2018-02-07 10:41:51 +11:00
Matt-Yorkley
969b6caa96 Code cleanup 2018-02-07 10:41:51 +11:00
Matt-Yorkley
69ea1e6d26 Set test users to confirmed by default 2018-02-07 10:41:51 +11:00
Pierre de Lacroix
91704d9df7 Create user confirmation email 2018-02-07 10:41:51 +11:00
Pierre de Lacroix
dbbc2ddb1c Add confirmable email to user model 2018-02-07 10:41:51 +11:00
Pau Pérez Fabregat
99729457cc Merge pull request #2063 from coopdevs/autocorrect-cop
Autocorrect rubocop Layout/BlockEndNewline cop
2018-02-05 08:50:58 +01:00
Pau Pérez Fabregat
5a58294bc6 Merge pull request #2042 from erose357/master
addresses issue #1275
2018-02-02 13:41:23 +01:00
Enrico Stano
398b3bbd8b Merge pull request #1960 from coopdevs/remove-warning
Fix payment_method_decorator boot-time warning
2018-02-02 10:43:51 +01:00
Pau Perez
6cb038c362 Autocorrect rubocop Layout/BlockEndNewline cop 2018-02-01 09:52:53 +01:00
Pau Pérez Fabregat
cc40948783 Merge pull request #2051 from coopdevs/regenerate-knapsack-report
Regenerate Knapsack report
2018-01-31 15:04:30 +01:00
Enrico Stano
00bdcd3948 Merge pull request #2045 from coopdevs/use-symbol-hash-syntax
Enable HashSyntax rubocop cop with symbol style
2018-01-31 09:30:06 +01:00
Matt-Yorkley
c860ffc176 Adjust use of non-translatable open/closed icons 2018-01-24 15:33:26 +11:00
Pau Perez
8664411880 Disable knapsack report generation again
No need to enable it to regenerate the report again until Knapsack
itself tells us.
2018-01-23 09:21:56 +01:00
Pau Perez
f17f1008e3 Update knapsack report file with latest CI values 2018-01-23 09:21:10 +01:00
Pau Perez
a2828f3b9a Regenerate Knapsack report
It's already asking for it in the CI output
2018-01-23 08:06:53 +01:00
Pau Perez
cbfdfb43e3 Enable HashSyntax rubocop cop with symbol style
This enforces the ruby 1.9 symbol hash syntax and consistency among the
style of the keys.

  # bad
  {:a => 1, :b => 2}
  {c: 2, 'd' => 3} # should just use hash rockets

  # good
  {a: 1, b: 2}
  {:c => 3, 'd' => 4}

The .rubocop-todo.yml is also updated to keep track of the existing
violations.
2018-01-20 12:50:50 +01:00
Matt-Yorkley
23e672aef9 Add updated globe icon to mobile view 2018-01-19 10:56:11 +00:00
Matt-Yorkley
6d9cc7e29d Fix account page locale 2018-01-18 10:22:40 +11:00
Matt-Yorkley
8a47788a09 Remake OFN icon font 2018-01-18 10:22:40 +11:00
Matt-Yorkley
afed5ab666 Refector spec 2018-01-18 10:22:40 +11:00
Matt-Yorkley
357eda8c19 Adjustments for failing specs 2018-01-18 10:22:40 +11:00
Matt-Yorkley
f18401d183 Language switcher frontend 2018-01-18 10:22:40 +11:00
Matt-Yorkley
4ea91d14f9 Template I18n changes 2018-01-17 12:03:27 +11:00
Pau Perez
f57661b13f Fix payment_method_decorator boot-time warning
Removes the annoying message "warning: already initialized constant
Spree::PaymentMethod::DISPLAY" that appears 4 times when booting the
app.

We are declaring said constant exactly as our Spree version does so
there's no point on repeating work.
2018-01-15 12:50:05 +01:00
Pau Pérez Fabregat
ad25c1d1b2 Merge pull request #2033 from coopdevs/add-setup-script
Add setup script
2018-01-15 12:05:19 +01:00
Pau Perez
87af5dcee5 Point to rbenv and nodenv from setup script
Show the appropriate links when the Ruby and Node dependencies are not
met. This will make it easier for newcomers to install them.
2018-01-12 08:22:50 +01:00
Pau Perez
106871b956 Check node version and install npm packages 2018-01-11 14:14:08 +01:00
Pau Perez
4d25abcfce Add setup script
It aims to aid new open source contributors on setting up their dev
env by means of a single command with meaningful output.

Although ofn-install ansible scripts also work for development we don't
want to add too much burden to those single-time beginner contributions.
2018-01-11 14:14:08 +01:00
Rob Harrington
2ccdf3c97a Use upstream and origin as remote names
Also fixed a couple of typos
2018-01-11 14:30:08 +11:00
Rob Harrington
89bd9c8038 Update CONTRIBUTIONS.md to reflect current processes 2018-01-11 14:30:08 +11:00
Enrico Stano
88627dc837 Merge pull request #2038 from boveus/master
Update README.md
2018-01-10 12:17:21 +01:00
Brandon Stewart
8ca57b0705 Update README.md 2018-01-09 14:02:27 -07:00
Brandon Stewart
c7db283e8c Update README.md 2018-01-09 14:00:07 -07:00
erose357
83ca3b7b8b Adds a css rule to target the logo in .footer-local and padding between the logo and open source info at the bottom 2018-01-09 12:54:41 -07:00
Brandon Stewart
830699d2b8 Update README.md 2018-01-09 10:29:02 -07:00
Brandon Stewart
f822e658c4 Update README.md 2018-01-09 10:23:51 -07:00
Brandon Stewart
8817a1afb7 Update README.md 2018-01-09 10:23:30 -07:00
Brandon Stewart
693adf181e Update README.md 2018-01-09 10:21:24 -07:00
Brandon Stewart
f269f13b09 Update README.md 2018-01-08 11:50:44 -07:00
Matt-Yorkley
9845258a25 Merge pull request #2035 from Matt-Yorkley/uk/rubocop_fix
Update rubocop.yml
2018-01-05 20:16:44 +00:00
Enrico Stano
edbed2c8d3 Merge pull request #1984 from coopdevs/fix/api-key-taxons
Disable api auth as there is no Spree api key set
2018-01-05 10:31:36 +01:00
Matt-Yorkley
8e0f2d2500 Merge pull request #2037 from Matt-Yorkley/uk/codeclimate_checks
Codeclimate yml update
2018-01-05 01:37:06 +00:00
Matt-Yorkley
e022504c26 Codeclimate yml update 2018-01-04 17:10:55 +00:00
Matt-Yorkley
62e4cbd052 Update rubocop.yml 2018-01-04 16:01:06 +00:00
Enrico Stano
70ae59550d Merge pull request #2032 from Matt-Yorkley/uk/codeclimate_migrations
Adjust codeclimate engine for migrations folder
2018-01-03 13:48:47 +01:00
Lynne
f74af8fa2d Merge pull request #2034 from lin-d-hop/translations-uk
Manual uk translation update
2018-01-03 06:00:07 +01:00
lin-d-hop
82d1b57005 Not updated from transifex so manually commiting 2018-01-03 03:40:04 +00:00
Lynne
c32aacc1b3 Delete en-GB.yml
Superseded by en_GB.yml
2018-01-03 03:29:52 +00:00
Matt-Yorkley
523b4045bf Adjust codeclimate engine for migrations folder 2018-01-02 13:54:41 +00:00
Enrico Stano
8e4e273b7c Merge pull request #1994 from openfoodfoundation/transifex
Transifex
2017-12-22 16:36:44 +11:00
Enrico Stano
816297e22f Merge pull request #2022 from ltrls/add-order-print-ticket-feature-test
Add feature test for the Spree::Admin::OrdersController print_ticket action
2017-12-22 15:07:17 +11:00
Pau Perez
72889b5c36 Stub current_user instead of api key's user 2017-12-21 10:24:29 +11:00
Pau Perez
0f0216fe79 Upgrade spree to get our latest patch 2017-12-21 10:24:29 +11:00
Pierre de Lacroix
42433d1ad4 Add feature test for the Spree::Admin::OrdersController print_ticket action 2017-12-20 23:01:18 +01:00
Pau Perez
52533fc04c Rely on Spree's default value for requires_auth 2017-12-20 17:25:23 +11:00
Pau Perez
bb0223877c Remove unused arguments and reduce object creation 2017-12-20 17:25:23 +11:00
Pau Perez
5eb1fcddbb Remove dependency on TestingSupport by inlining 2017-12-20 17:25:23 +11:00
Pau Perez
c646eb3939 Disable api auth as there is no Spree api key set
Although Spree::Api::Config[:requires_authentication] is set to false by
default for some unknown reason if not done explicitly Spree still
returns it as false.

This amends the change done in a87c89c83d,
which introduced the bug. As there is no Spree api key set the auth
fails when getting taxons.
2017-12-20 17:25:23 +11:00
Enrico Stano
a313c99370 Merge pull request #2005 from coopdevs/upgrade-spree-fork-version
Upgrade spree's fork to latest commit
2017-12-20 17:23:48 +11:00
Enrico Stano
0f84d9f02e Merge pull request #2004 from coopdevs/is-this-needed
Remove unused Enterprise scopes
2017-12-20 16:59:15 +11:00
Enrico Stano
900a9c6145 Merge pull request #2000 from coopdevs/issue-template-improvement
Mention screenshot in the issue template
2017-12-20 16:48:54 +11:00
Pau Perez
5b33cbe9aa Upgrade spree's fork to latest commit
Needed to get
3289b5e31c
2017-12-20 16:37:14 +11:00
Enrico Stano
114ce3b764 Merge pull request #1940 from coopdevs/improve-readability-shop
Improve readability of shop's code
2017-12-20 16:28:53 +11:00
Enrico Stano
660d3f326f Remove unused Enterprise scopes 2017-12-20 16:00:35 +11:00
Pau Perez
b8d51ae0de Mention screenshot in the issue template
For things like translations it's enough sharing a screenshot when
reporting a bug. See
https://github.com/openfoodfoundation/openfoodnetwork/issues/1999
2017-12-20 10:16:53 +11:00
Enrico Stano
0bdda6387a Merge pull request #1996 from coopdevs/add-issue-template
Create issue template
2017-12-19 18:00:04 +11:00
Pau Perez
4fbdbb1aa2 Link to placeholder feature template
We'll write the template later on
2017-12-19 15:26:21 +11:00
Pau Perez
72ddcb4fff Create issue template
It assumes most of the times issues will be reported to keep track of
bugs.
2017-12-19 11:07:29 +11:00
Transifex-Openfoodnetwork
50ef2de5f9 Updating translations for config/locales/fr.yml 2017-12-15 20:06:43 +11:00
Transifex-Openfoodnetwork
55d3ee1af0 Updating translations for config/locales/pt.yml 2017-12-13 21:19:42 +11:00
Transifex-Openfoodnetwork
422166441e Updating translations for config/locales/en_US.yml 2017-12-09 02:29:48 +11:00
Transifex-Openfoodnetwork
9d3f85628c Updating translations for config/locales/nb.yml 2017-12-08 18:44:22 +11:00
Pierre de Lacroix
669d9c3c66 Fix translations on account page 2017-12-06 15:21:19 +11:00
Enrico Stano
dcb406d246 Merge pull request #1986 from andypalmer/github_protocol_warning
Change github definition to remove insecure protocol warning.
2017-12-04 21:49:05 +11:00
Andy Palmer
cadad28b0c Change github definition to remove insecure protocol warning. Consistently use 1.9.3 hash syntax 2017-12-04 16:50:36 +11:00
Enrico Stano
01b0a033fd Merge pull request #1904 from oeoeaio/spree-test-config
Use Spree's approach for preventing config caching when testing
2017-12-04 15:57:11 +11:00
Pierre de Lacroix
0fb66ab258 Fix CodeClimate issues 2017-12-01 13:37:30 +11:00
Pierre de Lacroix
a49c21cfd1 Add instance switch to enable number localization 2017-12-01 13:37:24 +11:00
Pierre de Lacroix
f67a8c1f2d Add tests 2017-12-01 13:37:24 +11:00
Pierre de Lacroix
f4624ead42 Make all products reload when updating in bulk edit 2017-12-01 13:37:24 +11:00
Pierre de Lacroix
2cd570383f Use localize_number in models 2017-12-01 13:37:24 +11:00
Pierre de Lacroix
920900b619 Add Spree::LocalizedNumber module 2017-12-01 13:37:24 +11:00
Pau Perez
e98d934a67 Include localization files as documented in gem
I followed the Usage help in
https://github.com/derekprior/momentjs-rails.
2017-11-29 10:13:05 +11:00
leandroalemao
31a846b9c3 Refactor _i18n_script.html.haml file and add new momentjs internationalisation files 2017-11-29 10:13:05 +11:00
leandroalemao
5eaea28401 Switch momentjs internationalisation according to I18n locale 2017-11-29 10:13:05 +11:00
Pierre de Lacroix
50ef902adb Add missing tooltip in products' bulk edit page 2017-11-23 11:31:41 +11:00
Pierre de Lacroix
75b6a078c6 Add missing translation 2017-11-23 11:31:41 +11:00
Pierre de Lacroix
c0c93c172e Add tooltips in products bulk edit page 2017-11-23 11:31:41 +11:00
Pau Perez
ed18244070 Remove TODO in favour of an issue in Github
It has become the issue
https://github.com/openfoodfoundation/openfoodnetwork/issues/1961
2017-11-23 11:12:17 +11:00
Pierre de Lacroix
e13063e0c6 Fix before_filter for Spree::Admin::OrdersController#print_ticket 2017-11-23 11:01:41 +11:00
Rob Harrington
6c38997010 Fix 1664: product tag rules not working
Caused by a combination of: fe7bd5e2cd and 38d3b446cc

Have added/tweaked specs to prevent this from happening again
2017-11-15 10:26:24 +11:00
Pau Perez
0e01c0d69b Turn TODO into issue #1957
TODOs that live in the code can't be prioritized and tend to be
forgotten.
2017-11-15 09:44:11 +11:00
Pau Perez
caab3ea74d Add spree user as admin of Enterprise 2 in seed 2017-11-15 09:42:21 +11:00
Lynne
c543dff2e1 Merge pull request #1956 from coopdevs/improve-pr-template
Add special keyword syntax to close issue from PR
2017-11-14 14:16:08 +01:00
Pau Perez
92badfd88c Add special keyword syntax to close issue from PR
We want the issue to be closed when the PR gets merged but we always
forget to add the "magic" comment as described in
https://help.github.com/articles/closing-issues-using-keywords/.
2017-11-14 09:02:52 +01:00
Lynne
dca64e6939 Merge pull request #1944 from lin-d-hop/master
Adding UK About pages to menus
2017-11-10 16:33:58 +01:00
Saimon Moore
a9c4d27d5e Undo i18n_fallbacks change to production.rb 2017-11-10 12:30:24 +11:00
Saimon Moore
610c2f9519 Ensure en is an I18n fallback in all environments
Since `en` is considered as the main fallback for all locales
ensure that it is present in all environments.

Note: Setting `config.i18n.fallbacks` to `true` means use the default locale
which means that if a particular instance is not using an `en` based locale
(the parent `en` locale is automatically derived as a fallback) then `en` will
not be available as a fallback.
2017-11-10 12:30:24 +11:00
Saimon Moore
05d757e7c4 Ensure we have min i18n fallbacks
This setting defines which locales will be exported to the frontend.
In general, ofn currently functions under a single locale
(which is also the default locale) but all translations are made from
the `en` locale.

The current process of ensuring translations are translated and make
their way into code is manual and prone to issues so occasionally
translations for keys in the default locale of a particular instance
are not deployed and the UI displays `missing translation` messages.

In these cases, it is far friendlier for the user to see fallbacks to
`en` rather than these errors so this commit ensure that at the very
least apart from the current default locale, `en` is also made available
and as such will be exported to the frontend so that it's translations
are available as a fallback in JS land.

I18n fallback config was already enabled in both frontend and backend.
Until now, available locales may not have been set (determined by the
`AVAILABLE_LOCALES` env var) and the translations for `en` not therefore
be present in the frontend for fallback to actually work.

This commit will ensure that a fallback to `en` is always possible in the
case of missing translations.
2017-11-10 12:30:24 +11:00
Maxim Colls
31a2453882 Bootstrap angular module in new_variant form 2017-11-10 09:37:36 +11:00
Rob Harrington
5febd0a0d6 Restructure flaky customer spec 2017-11-10 08:47:12 +11:00
Rob Harrington
694f1e9b25 Update knapsack report 2017-11-10 08:47:12 +11:00
Andy Palmer
131bf842a9 Update matchers to non-deprecated protocol 2017-11-10 08:47:12 +11:00
Andy Palmer
8ec1c2e04a No longer use expensive page.evaluate_script for imperative methods 2017-11-10 08:47:12 +11:00
Andy Palmer
e94dc257a1 We actually need to restart the driver, not the session 2017-11-10 08:47:12 +11:00
Andy Palmer
3bd4fc59d4 We reset the phantom js driver after each context to prevent it memory leaking and dying 2017-11-10 08:47:12 +11:00
Andy Palmer
7b8463b03a PhantomJS no longer crashes due to too specific selector 2017-11-10 08:47:12 +11:00
Rob Harrington
00e7fc1c0d Bump capybara version 2017-11-10 08:47:12 +11:00
Rob Harrington
2ca20ad701 Bump poltergeist version to 1.16.0 2017-11-10 08:47:12 +11:00
Maikel Linke
775da82072 Add waiting conditions to spec 2017-11-10 08:47:12 +11:00
Maikel Linke
162b392004 Use expect syntax, correct spec description 2017-11-10 08:47:12 +11:00
Maikel Linke
26bedf0523 Make title matcher more robust 2017-11-10 08:47:12 +11:00
Maikel Linke
ff3ee62509 Remove old comment 2017-11-10 08:47:12 +11:00
Maikel Linke
9c2a78adf2 Avoid warnings, use expect syntax 2017-11-10 08:47:12 +11:00
Maikel Linke
5a767ba3ef Avoid warning, use new syntax 2017-11-10 08:47:12 +11:00
Rob Harrington
691d642721 Use url helper instead of string to define expected url 2017-11-10 08:47:12 +11:00
Rob Harrington
7dbfc3740d Revert "Add workaround to pass Spree core tests in Travis"
This reverts commit 9cdec737078caa6eb5a90480cabb6ca477ab597b.
2017-11-10 08:47:12 +11:00
Rob Harrington
b2897d7feb Reset Spree::Config.allow_backorders to original value in spec 2017-11-10 08:47:12 +11:00
Julius Pabrinkis
b18177c215 Add workaround to pass Spree core tests in Travis 2017-11-10 08:47:12 +11:00
Julius Pabrinkis
cec0a8c2e7 Specify page object for Capybara#find methods 2017-11-10 08:47:12 +11:00
Julius Pabrinkis
412de318ed Manually disable backorders in failing features 2017-11-10 08:47:12 +11:00
Julius Pabrinkis
92cc7a4648 Another try for failing feature 2017-11-10 08:47:12 +11:00
Julius Pabrinkis
96c0481e17 Fix intermittently failing product distribution feature 2017-11-10 08:47:12 +11:00
Julius Pabrinkis
5dd7ddc288 Refactor base controller with new rspec syntax 2017-11-10 08:47:12 +11:00
Julius Pabrinkis
ea91a82f30 Try to fix shopping cart failing feauture in Travis 2017-11-10 08:47:12 +11:00
Julius Pabrinkis
8e10269b50 Try to fix intermittently failing test for product distribution 2017-11-10 08:47:12 +11:00
Julius Pabrinkis
dae74666c5 Add missing 'type: :request' for request spec 2017-11-10 08:47:12 +11:00
Julius Pabrinkis
94e31e35ba Fix Spree::Admin::BaseController related issues 2017-11-10 08:47:12 +11:00
Rob Harrington
c835b4eb1a Replacing stub_model objects with actual factory generated instances 2017-11-10 08:47:12 +11:00
Rob Harrington
ef9e43fbd3 Replacing mock_model objects with instance_doubles 2017-11-10 08:47:12 +11:00
Rob Harrington
f083433854 Explicitly specifying 'type: :helper' for all helper specs 2017-11-10 08:47:12 +11:00
Rob Harrington
9052b1c3db A few updates to spec where 'be true' and 'be false' didn't cut it 2017-11-10 08:47:12 +11:00
Rob Harrington
59578a73af Changing all references to 'be_true' and 'be_false' to 'be true' and 'be false'
See next commit for changes where this substitution was broken
2017-11-10 08:47:12 +11:00
Rob Harrington
c691e260cf Rspec matcher enqueue_job for Delayed::Job supports block expectations 2017-11-10 08:47:12 +11:00
Rob Harrington
82072c8970 Explicitly specifying 'type: :controller' for all controller specs 2017-11-10 08:47:12 +11:00
Rob Harrington
d0c52ac176 Updating outdated guard gems 2017-11-10 08:47:12 +11:00
Rob Harrington
6811a62568 Updating RSpec Gems 2017-11-10 08:47:12 +11:00
Buildkite
8653d03969 Merge remote-tracking branch 'origin/master' into HEAD 2017-11-09 13:49:39 +00:00
lin-d-hop
90d5a04368 Adding UK About pages to menus 2017-11-09 11:06:58 +00:00
Pau Perez
84e4ebef08 Do not notify Bugsnag of a cache miss
It's not the responsibility of a error tracking software to track
neither cache misses nor logs. That is what log monitoring is for.
2017-11-09 10:22:31 +01:00
Pau Perez
98603c4042 Do not test private methods 2017-11-09 10:22:31 +01:00
Pau Perez
26a4ee0171 Do not stub object under test 2017-11-09 10:22:31 +01:00
Pau Perez
4f03a2d25c Remove unnecessary require 2017-11-09 10:22:31 +01:00
Pau Perez
6a830a3843 Isolate ArraySerializer case in injection helper
This makes this special case with the ArraySerializer stand out so that
the reader notices it.
2017-11-09 10:22:30 +01:00
Pau Perez
3ffd049135 Remove commented out code 2017-11-09 10:22:30 +01:00
Rob Harrington
e6d1b38b82 Remove upgrade_bundler script by reverting 250062bd2, 3f2299e52 and 5dfac10599 2017-11-09 19:46:41 +11:00
Rob Harrington
f8a892faf2 Remove upgrade_bundler script by reverting 250062bd2, 3f2299e52 and 5dfac10599 2017-11-09 18:24:22 +11:00
Pierre de Lacroix
54e141489a Add noindex meta tag for invisible shops and staging environment 2017-11-09 12:04:27 +11:00
Pau Perez
e64fd1d308 Lower log level in prod to :info so we can debug
Otherwise, there are no log lines for any request, which makes it
impossible to find out anything about the app in production.

Obviously this increases the size of the log files but this has to be
  dealt with log rotation. The data is our most important asset.
2017-11-09 11:13:32 +11:00
Matt-Yorkley
01647c3df9 Disable allow_backorders by default in test environment 2017-11-02 17:43:46 +11:00
Rob Harrington
cd6d7c76f6 Fix spec that requires preference persistence 2017-11-02 17:43:04 +11:00
Rob Harrington
efa71c4ac8 Use Spree's approach for handling config when testing 2017-11-02 17:43:04 +11:00
Rob Harrington
d4eb27a4ed Fix race condition in shipping method order spec 2017-11-01 16:37:12 +11:00
Duende13
eca18ba6ee Test to control order of shipping methods by name 2017-11-01 15:30:42 +11:00
Duende13
31fa49feed Added orderBy 'name' to the list of shipping methods offered. 2017-11-01 15:30:42 +11:00
yasirazgar
b68aafdb72 1799 - adding missing translations in new shipping methods page 2017-11-01 10:50:21 +11:00
Andy Palmer
fd09a63e48 Imperative specs as per review comments 2017-10-24 17:56:04 +11:00
Andy Palmer
afc50863cd Replace Deface with update to overridden template 2017-10-24 17:39:34 +11:00
Andy Palmer
fea2240c39 Disabled product links in cart for openfoodfoundation/openfoodnetwork#1075 2017-10-24 14:56:35 +11:00
299 changed files with 5388 additions and 2165 deletions

View File

@@ -1,14 +1,36 @@
engines:
version: "2"
plugins:
rubocop:
enabled: true
channel: rubocop-0-48
channel: "rubocop-0-48"
scss-lint:
enabled: false
ratings:
paths:
- app/**
- lib/**
- "**.rb"
exclude_paths:
- spec/**/*
- vendor/**/*
duplication:
enabled: true
exclude_patterns:
- "db/**"
- "config/initializers/active_record_postgresql_referential_integrity_patch.rb"
checks:
argument-count:
enabled: false
complex-logic:
enabled: true
file-lines:
enabled: false
method-complexity:
enabled: false
method-count:
enabled: false
method-lines:
enabled: false
nested-control-flow:
enabled: true
return-statements:
enabled: true
similar-code:
enabled: true
identical-code:
enabled: true
exclude_patterns:
- "spec/**/*"
- "vendor/**/*"

42
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,42 @@
<!--- If what you want to file is not a bug, please use the [Feature
template](https://github.com/openfoodfoundation/openfoodnetwork/wiki/Feature-template)
instead -->
<!--- Provide a general summary of the issue in the Title above -->
## Description
<!--- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
## Expected Behavior
<!--- Tell us what should happen -->
## Actual Behavior
<!--- Tell us what happens instead -->
## Steps to Reproduce
<!--- Provide an unambiguous set of steps to reproduce this bug -->
<!--- Include code to reproduce, if relevant -->
1.
2.
3.
4.
## Animated Gif/Screenshot
<!-- Provide a screenshot or brief animated gif reproducing the bug. Linux users can use
[Peek](https://github.com/phw/peek#ubuntu) while Mac users can use [Recordit](http://recordit.co/) -->
## Context
<!--- How has this bug affected you? What were you trying to accomplish? -->
## Severity
<!--- Use the [Bug severity
guideline](https://github.com/openfoodfoundation/openfoodnetwork/wiki/Bug-severity) to assign one to this bug -->
## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* Version used:
* Browser name and version:
* Operating System and version (desktop or mobile):
## Possible Fix
<!--- Not obligatory, but suggest a fix or reason for the bug -->

View File

@@ -1,5 +1,7 @@
#### What? Why?
Closes #[the issue number this PR is related to]
[Explain why is this change needed and the solution you propose. Provide
context for others to understand it]

View File

@@ -27,6 +27,10 @@ Style/Documentation:
Style/StringLiterals:
Enabled: false
Style/HashSyntax:
Enabled: true
EnforcedStyle: ruby19_no_mixed_keys
Layout/MultilineMethodCallIndentation:
Enabled: true
EnforcedStyle: indented
@@ -53,6 +57,10 @@ Lint/UselessAssignment:
Rails/DynamicFindBy:
Enabled: false
# Same as above, #find_by is not available until Rails 4
Rails/FindBy:
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:

File diff suppressed because it is too large Load Diff

View File

@@ -22,9 +22,6 @@ 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
@@ -43,7 +40,6 @@ before_script:
script:
- 'if [ "$KARMA" = "true" ]; then bundle exec rake karma:run; else echo "Skipping karma run"; fi'
#- "KNAPSACK_GENERATE_REPORT=true bundle exec rspec spec"
- "bundle exec rake 'knapsack:rspec[--tag ~performance]'"
after_success:

View File

@@ -1,36 +1,68 @@
See this here post on raising a github issue:
https://community.openfoodnetwork.org/t/how-to-raise-a-github-issue/912
# Contributing
We love pull requests from everyone. Any contribution is valuable, but there are two issue streams that we especially love people to work on:
We love pull requests from everyone. Here are some instructions for
contributing code to Open Food Network. See the [developer wiki](https://github.com/openfoodfoundation/openfoodnetwork/wiki) for more information.
1) Our delivery backlog, is managed via a ZenHub board (ZenHub extensions are available for most major browsers). We use a Kanban-style approach, whereby devs pick issues from the top of the backlog which has been organised according to current priorities. If you have some time and are interested in working on some issues from the backlog, please make yourself known on the [#dev](https://openfoodnetwork.slack.com/messages/C2GQ45KNU) channel on Slack and we can direct you to the most appropriate issue to pick up.
Fork, then clone the repo:
2) Our list of bugs and other self-contained issues that we consider to be a good starting point for new contributors, or devs who arent able to commit to seeing a whole feature through. These issues are marked with the `# good first issue` label.
git clone git@github.com:your-username/openfoodnetwork.git
## Set up
Follow the instructions in README.markdown to set up your machine.
Set up your local development environment by following the appropriate guide from the `Development environment setup` section in the [developer wiki](https://github.com/openfoodfoundation/openfoodnetwork/wiki).
Make sure the tests pass:
Add an `upstream` remote that points to the main repo:
rspec spec
cd ~/location-of-your-local-ofn-repo
git remote add upstream https://github.com/openfoodfoundation/openfoodnetwork
Make your change. Add tests for your change. Make the tests pass:
If you haven't already done so, fork this repo using the `Fork` button in the top-right corner of this screen. Then ensure that your fork is listed as the `origin` remote on your local machine.
rspec spec
git remote set-url origin https://github.com/your-username/openfoodnetwork
Push to your fork and [submit a pull request][pr].
Fetch the latest version of `master` from `upstream` (ie. the main repo):
[pr]: https://github.com/openfoodfoundation/openfoodnetwork/compare/
git fetch upstream master
At this point you're waiting on us. We may suggest some changes or
improvements or alternatives.
Create a new branch on your local machine for (based on `upstream/master`):
To increase the chance that your pull request is swiftly accepted:
git checkout -b branch-name-here --no-track upstream/master
If you want to run the whole test suite, we recommend using a free CI service to run your tests in parallel. Running the whole suite locally in series is likely to take > 40 minutes. [TravisCI][travis] and [SemaphoreCI][semaphore] both work great in our experience. Either way, make sure the tests pass on your new branch:
bundle exec rspec spec
## Making a change
Make your changes to the codebase. We recommend using TDD. Add a test, make changes and get the test suite back to green.
bundle exec rspec spec
Once the tests are passing you can commit your changes. See [Making a great commit][great-commit] for more tips.
git add .
git commit -m "Add a concise commit message describing your change here"
Push your changes to a branch on your fork:
git push origin branch-name-here
## Submitting a Pull Request
Use the GitHub UI to submit a [new pull request][pr] against upstream/master. To increase the chances that your pull request is swiftly accepted please have a look at our guide to [[making a great pull request]].
TL;DR:
* Write tests
* Make sure the whole test suite is passing
* Keep your PR small, with a single focus
* Maintain a clean commit history
* Use a style consistent with the rest of the codebase
* Before submitting, [rebase your work][rebase] on the current master branch
From here, your pull request will progress through the [Review, Test, Merge & Deploy process][process].
[pr]: https://github.com/openfoodfoundation/openfoodnetwork/compare/
[great-pr]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Making-a-great-pull-request
[great-commit]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Making-a-great-commit
[process]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/The-process-of-review%2C-test%2C-merge-and-deploy
[rebase]: https://www.atlassian.com/git/tutorials/merging-vs-rebasing/workflow-walkthrough
[travis]: https://travis-ci.org/
[semaphore]: https://semaphoreci.com/

34
Gemfile
View File

@@ -1,5 +1,6 @@
source 'https://rubygems.org'
ruby "2.1.5"
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
gem 'rails', '3.2.21'
gem 'rails-i18n', '~> 3.0.0'
@@ -10,15 +11,15 @@ gem 'i18n-js', '~> 3.0.0'
gem 'nokogiri', '>= 1.6.7.1'
gem 'pg'
gem 'spree', github: 'openfoodfoundation/spree', branch: 'step-6a', ref: '5a76d45'
gem 'spree', github: 'openfoodfoundation/spree', branch: 'step-6a', ref: '86bf87f1b1e1b299edc8cd10a2486e44ba0a3987'
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
gem 'spree_auth_devise', github: 'openfoodfoundation/spree_auth_devise', branch: 'spree-upgrade-intermediate'
# Our branch contains two changes
# - Pass customer email and phone number to PayPal (merged to upstream master)
# - Change type of password from string to password to hide it in the form
gem 'spree_paypal_express', :github => "openfoodfoundation/better_spree_paypal_express", :branch => "spree-upgrade-intermediate"
#gem 'spree_paypal_express', :github => "spree-contrib/better_spree_paypal_express", :branch => "1-3-stable"
gem 'spree_paypal_express', github: "openfoodfoundation/better_spree_paypal_express", branch: "spree-upgrade-intermediate"
#gem 'spree_paypal_express', github: "spree-contrib/better_spree_paypal_express", branch: "1-3-stable"
gem 'stripe', '~> 3.3.1'
gem 'activemerchant', '~> 1.71.0'
@@ -30,7 +31,7 @@ gem 'daemons'
# Fix bug in simple_form preventing collection_check_boxes usage within form_for block
# When merged, revert to upstream gem
gem 'simple_form', :github => 'RohanM/simple_form'
gem 'simple_form', github: 'RohanM/simple_form'
gem 'unicorn'
gem 'angularjs-rails', '1.5.5'
@@ -48,14 +49,14 @@ gem 'representative_view'
gem 'rabl'
gem "active_model_serializers"
gem 'oj'
gem 'deface', :github => 'spree/deface', :ref => '1110a13'
gem 'deface', github: 'spree/deface', ref: '1110a13'
gem 'paperclip'
gem 'dalli'
gem 'geocoder'
gem 'gmaps4rails'
gem 'spinjs-rails'
gem 'rack-ssl', :require => 'rack/ssl'
gem 'custom_error_message', :github => 'jeremydurham/custom-err-msg'
gem 'rack-ssl', require: 'rack/ssl'
gem 'custom_error_message', github: 'jeremydurham/custom-err-msg'
gem 'angularjs-file-upload-rails', '~> 1.1.6'
gem 'roadie-rails', '~> 1.0.3'
gem 'figaro'
@@ -101,19 +102,19 @@ gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz'
group :test, :development do
# Pretty printed test output
gem 'turn', '~> 0.8.3', :require => false
gem 'fuubar'
gem 'rspec-rails'
gem 'turn', '~> 0.8.3', require: false
gem 'fuubar', '~> 2.2.0'
gem 'rspec-rails', ">= 3.5.2"
gem 'shoulda-matchers'
gem 'factory_girl_rails', :require => false
gem 'capybara'
gem 'database_cleaner', '0.7.1', :require => false
gem 'factory_girl_rails', require: false
gem 'capybara', '>= 2.15.4'
gem 'database_cleaner', '0.7.1', require: false
gem 'awesome_print'
gem 'letter_opener'
gem 'timecop'
gem 'poltergeist'
gem 'poltergeist', '>= 1.16.0'
gem 'rspec-retry'
gem 'json_spec'
gem 'json_spec', '~> 1.1.4'
gem 'unicorn-rails'
gem 'atomic'
gem 'knapsack'
@@ -130,10 +131,11 @@ group :development do
gem 'pry-byebug', '>= 3.4.3'
gem 'debugger-linecache'
gem 'guard'
gem 'listen', '3.0.8' # 3.1.0 requires ruby 2.2
gem 'guard-livereload'
gem 'rack-livereload'
gem 'guard-rails'
gem 'guard-rspec'
gem 'guard-rspec', '~> 4.7.3'
gem 'parallel_tests'
gem 'rubocop', '>= 0.49.1'

View File

@@ -1,5 +1,5 @@
GIT
remote: git://github.com/RohanM/simple_form.git
remote: https://github.com/RohanM/simple_form.git
revision: 45f08a213b40f3d4bda5f5398db841137587160a
specs:
simple_form (2.0.2)
@@ -7,13 +7,13 @@ GIT
activemodel (~> 3.0)
GIT
remote: git://github.com/jeremydurham/custom-err-msg.git
remote: https://github.com/jeremydurham/custom-err-msg.git
revision: 3a8ec9dddc7a5b0aab7c69a6060596de300c68f4
specs:
custom_error_message (1.1.1)
GIT
remote: git://github.com/openfoodfoundation/better_spree_paypal_express.git
remote: https://github.com/openfoodfoundation/better_spree_paypal_express.git
revision: 8d95f4544c682634812becaf50999fba0cd04df0
branch: spree-upgrade-intermediate
specs:
@@ -22,16 +22,16 @@ GIT
spree_core (~> 1.3.99)
GIT
remote: git://github.com/openfoodfoundation/ofn-qz.git
remote: https://github.com/openfoodfoundation/ofn-qz.git
revision: 024680ccea429b2e5428d7b964fa67c52add34ec
specs:
ofn-qz (0.1.0)
railties (~> 3.1)
GIT
remote: git://github.com/openfoodfoundation/spree.git
revision: 5a76d456ff70aea7aae3d25156558d71eb7febf2
ref: 5a76d45
remote: https://github.com/openfoodfoundation/spree.git
revision: 86bf87f1b1e1b299edc8cd10a2486e44ba0a3987
ref: 86bf87f1b1e1b299edc8cd10a2486e44ba0a3987
branch: step-6a
specs:
spree (1.3.99)
@@ -91,7 +91,7 @@ GIT
spree_core (= 1.3.99)
GIT
remote: git://github.com/openfoodfoundation/spree_auth_devise.git
remote: https://github.com/openfoodfoundation/spree_auth_devise.git
revision: da9eecefc6fe13dedf4c6f3febec79caad839ec3
branch: spree-upgrade-intermediate
specs:
@@ -103,7 +103,7 @@ GIT
spree_frontend (~> 1.3.6)
GIT
remote: git://github.com/spree/deface.git
remote: https://github.com/spree/deface.git
revision: 1110a1336252109bce7f98f9182042e0bc2930ae
ref: 1110a13
specs:
@@ -113,7 +113,7 @@ GIT
rails (>= 3.1)
GIT
remote: git://github.com/spree/spree_i18n.git
remote: https://github.com/spree/spree_i18n.git
revision: 752eb67204e9c5a4e22b62591a8fd55fe2285e43
branch: 1-3-stable
specs:
@@ -123,7 +123,7 @@ GIT
spree_core (>= 1.1)
GIT
remote: git://github.com/willrjmarshall/foundation_rails_helper.git
remote: https://github.com/willrjmarshall/foundation_rails_helper.git
revision: 4d5d53fdc4b1fb71e66524d298c5c635de82cfbb
branch: rails3
specs:
@@ -173,7 +173,8 @@ GEM
acts-as-taggable-on (3.5.0)
activerecord (>= 3.2, < 5)
acts_as_list (0.1.9)
addressable (2.4.0)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
andand (1.3.3)
angular-rails-templates (0.2.0)
railties (>= 3.1)
@@ -200,15 +201,13 @@ GEM
builder (3.0.4)
byebug (9.0.6)
cancan (1.6.8)
capybara (2.7.1)
capybara (2.15.4)
addressable
mime-types (>= 1.16)
mini_mime (>= 0.1.3)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
celluloid (0.15.2)
timers (~> 1.1.0)
chronic (0.10.2)
chunky_png (1.3.4)
climate_control (0.1.0)
@@ -266,11 +265,11 @@ GEM
warden (~> 1.2.1)
devise-encryptable (0.1.2)
devise (>= 2.1.0)
diff-lcs (1.2.4)
diff-lcs (1.3)
diffy (3.1.0)
em-websocket (0.5.0)
em-websocket (0.5.1)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.5.3)
http_parser.rb (~> 0.6.0)
erubis (2.7.0)
eventmachine (1.2.3)
excon (0.45.4)
@@ -283,7 +282,7 @@ GEM
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
ffaker (1.15.0)
ffi (1.9.3)
ffi (1.9.18)
figaro (0.7.0)
bundler (~> 1.0)
rails (>= 3, < 5)
@@ -404,31 +403,38 @@ GEM
foundation-rails (5.5.0.0)
railties (>= 3.1.0)
sass (>= 3.2.0, < 3.4)
fuubar (1.3.3)
rspec (>= 2.14.0, < 3.1.0)
fuubar (2.2.0)
rspec-core (~> 3.0)
ruby-progressbar (~> 1.4)
geocoder (1.1.8)
gmaps4rails (1.5.6)
guard (2.2.4)
guard (2.14.1)
formatador (>= 0.2.4)
listen (~> 2.1)
listen (>= 2.7, < 4.0)
lumberjack (~> 1.0)
nenv (~> 0.1)
notiffany (~> 0.0)
pry (>= 0.9.12)
shellany (~> 0.0)
thor (>= 0.18.1)
guard-livereload (2.0.1)
guard-compat (1.2.1)
guard-livereload (2.5.2)
em-websocket (~> 0.5)
guard (~> 2.0)
guard (~> 2.8)
guard-compat (~> 1.0)
multi_json (~> 1.8)
guard-rails (0.4.7)
guard (>= 0.2.2)
guard-rspec (4.0.4)
guard (>= 2.1.1)
rspec (~> 2.14)
guard-rails (0.7.2)
guard (~> 2.11)
guard-compat (~> 1.0)
guard-rspec (4.7.3)
guard (~> 2.1)
guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0)
haml (4.0.4)
tilt
highline (1.6.15)
hike (1.2.3)
http_parser.rb (0.5.3)
http_parser.rb (0.6.0)
httparty (0.9.0)
multi_json (~> 1.0)
multi_xml
@@ -446,9 +452,9 @@ GEM
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
json (1.8.6)
json_spec (1.1.1)
json_spec (1.1.5)
multi_json (~> 1.0)
rspec (~> 2.0)
rspec (>= 2.0, < 4.0)
jwt (1.5.4)
kaminari (0.13.0)
actionpack (>= 3.0.0)
@@ -463,16 +469,16 @@ GEM
letter_opener (1.0.0)
launchy (>= 2.0.4)
libv8 (3.16.14.11)
listen (2.2.0)
celluloid (>= 0.15.2)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
lumberjack (1.0.4)
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
lumberjack (1.0.12)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
method_source (0.9.0)
mime-types (1.25.1)
mini_mime (0.1.4)
mini_portile2 (2.1.0)
momentjs-rails (2.5.1)
railties (>= 3.1)
@@ -481,9 +487,13 @@ GEM
multi_json (1.12.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
nenv (0.3.0)
newrelic_rpm (3.12.0.288)
nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0)
notiffany (0.1.1)
nenv (~> 0.1)
shellany (~> 0.0)
oauth2 (1.2.0)
faraday (>= 0.8, < 0.10)
jwt (~> 1.0)
@@ -511,28 +521,28 @@ GEM
paypal-sdk-merchant (1.106.1)
paypal-sdk-core (~> 0.2.3)
pg (0.13.2)
poltergeist (1.9.0)
poltergeist (1.16.0)
capybara (~> 2.1)
cliver (~> 0.3.1)
multi_json (~> 1.0)
websocket-driver (>= 0.2.0)
polyamorous (0.5.0)
activerecord (~> 3.0)
polyglot (0.3.5)
powerpack (0.1.1)
pry (0.11.1)
pry (0.11.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-byebug (3.4.3)
byebug (>= 9.0, < 9.1)
pry (~> 0.10)
public_suffix (3.0.0)
rabl (0.7.2)
activesupport (>= 2.3.14)
multi_json (~> 1.0)
rack (1.4.7)
rack-cache (1.7.0)
rack (>= 0.4)
rack-livereload (0.3.15)
rack-livereload (0.3.16)
rack
rack-ssl (1.3.4)
rack
@@ -564,9 +574,9 @@ GEM
actionpack (~> 3.0)
activerecord (~> 3.0)
polyamorous (~> 0.5.0)
rb-fsevent (0.9.3)
rb-inotify (0.9.2)
ffi (>= 0.5.0)
rb-fsevent (0.10.2)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
rdoc (3.12.2)
json (~> 1.4)
redcarpet (3.2.3)
@@ -588,24 +598,29 @@ GEM
roo (2.7.1)
nokogiri (~> 1)
rubyzip (~> 1.1, < 2.0.0)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.4)
rspec-expectations (2.14.0)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.14.2)
rspec-rails (2.14.2)
rspec (3.7.0)
rspec-core (~> 3.7.0)
rspec-expectations (~> 3.7.0)
rspec-mocks (~> 3.7.0)
rspec-core (3.7.0)
rspec-support (~> 3.7.0)
rspec-expectations (3.7.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.7.0)
rspec-mocks (3.7.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.7.0)
rspec-rails (3.7.1)
actionpack (>= 3.0)
activemodel (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (~> 3.7.0)
rspec-expectations (~> 3.7.0)
rspec-mocks (~> 3.7.0)
rspec-support (~> 3.7.0)
rspec-retry (0.4.2)
rspec-core
rspec-support (3.7.0)
rubocop (0.49.1)
parallel (~> 1.10)
parser (>= 2.3.3.1, < 3.0)
@@ -623,6 +638,7 @@ GEM
tilt (~> 1.3)
select2-rails (3.5.10)
thor (~> 0.14)
shellany (0.0.1)
shoulda-matchers (1.1.0)
activesupport (>= 3.0.0)
spinjs-rails (1.3)
@@ -639,10 +655,9 @@ GEM
therubyracer (0.12.0)
libv8 (~> 3.16.14.0)
ref
thor (0.19.4)
thor (0.20.0)
tilt (1.4.1)
timecop (0.8.1)
timers (1.1.0)
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
@@ -669,12 +684,12 @@ GEM
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
warden (1.2.6)
warden (1.2.7)
rack (>= 1.0)
webmock (1.8.11)
addressable (>= 2.2.7)
crack (>= 0.1.7)
websocket-driver (0.6.3)
websocket-driver (0.7.0)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
whenever (0.9.2)
@@ -683,7 +698,7 @@ GEM
wicked_pdf (1.1.0)
wkhtmltopdf-binary (0.12.3.1)
xml-simple (1.1.5)
xpath (2.0.0)
xpath (2.1.0)
nokogiri (~> 1.3)
PLATFORMS
@@ -703,7 +718,7 @@ DEPENDENCIES
blockenspiel
bugsnag
byebug (~> 9.0.0)
capybara
capybara (>= 2.15.4)
coffee-rails (~> 3.2.1)
compass-rails
css_splitter
@@ -723,23 +738,24 @@ DEPENDENCIES
foundation-icons-sass-rails
foundation-rails
foundation_rails_helper!
fuubar
fuubar (~> 2.2.0)
geocoder
gmaps4rails
guard
guard-livereload
guard-rails
guard-rspec
guard-rspec (~> 4.7.3)
haml
i18n (~> 0.6.11)
i18n-js (~> 3.0.0)
immigrant
jquery-migrate-rails
jquery-rails
json_spec
json_spec (~> 1.1.4)
jwt (~> 1.5)
knapsack
letter_opener
listen (= 3.0.8)
momentjs-rails
newrelic_rpm
nokogiri (>= 1.6.7.1)
@@ -750,7 +766,7 @@ DEPENDENCIES
paperclip
parallel_tests
pg
poltergeist
poltergeist (>= 1.16.0)
pry-byebug (>= 3.4.3)
rabl
rack-livereload
@@ -761,7 +777,7 @@ DEPENDENCIES
representative_view
roadie-rails (~> 1.0.3)
roo (~> 2.7.0)
rspec-rails
rspec-rails (>= 3.5.2)
rspec-retry
rubocop (>= 0.49.1)
sass (~> 3.3)
@@ -791,4 +807,4 @@ RUBY VERSION
ruby 2.1.5p273
BUNDLED WITH
1.15.4
1.16.0

View File

@@ -45,41 +45,15 @@ You can download the source with the command:
### Get it running
For those new to Rails, the following tutorial will help get you up to speed with configuring a Rails environment: http://guides.rubyonrails.org/getting_started.html .
For those new to Rails, the following tutorial will help get you up to speed with configuring a [Rails environment](http://guides.rubyonrails.org/getting_started.html).
First, check your dependencies: Ensure that you have Ruby 2.1.5 installed:
When ready, run `script/setup`. If the script succeeds you're ready to start developing. If not, take a look at the output as it should be informative enough to help you troubleshoot.
ruby --version
If you run into any other issues getting your local environment up and running please consult [the wiki](https://github.com/openfoodfoundation/openfoodnetwork/wiki).
Install the project's gem dependencies:
If still you get stuck do not hesitate to open an issue reporting the full output of the script.
cd openfoodnetwork
./script/upgrade_bundler.sh
bundle install
Configure the site:
cp config/application.yml.example config/application.yml
edit config/application.yml
Create a PostgreSQL user:
* Login as your system postrgresql priviledged user: `sudo -i -u postgres` (this may vary on your OS). Now your prompt looks like: `[postgres@your_host ~]$`
* Create the `ofn` database superuser and give it the password `f00d`:
```
createuser -s -P ofn
```
Create the development and test databases, using the settings specified in `config/database.yml`, and populate them with a schema and seed data:
```
bundle exec rake db:setup
```
Load some default data for your environment:
```
bundle exec rake openfoodnetwork:dev:load_sample_data
```
At long last, your dreams of spinning up a development server can be realised:
Now, your dreams of spinning up a development server can be realised:
```
bundle exec rails server
```

View File

@@ -49,6 +49,14 @@
//= require textAngular.min.js
//= require i18n/translations
//= require darkswarm/i18n.translate.js
//
//= require moment
//= require moment/en-gb.js
//= require moment/es.js
//= require moment/fr.js
//= require moment/it.js
//= require moment/nb.js
//= require moment/pt-br.js
//= require moment/sv.js
//= require_tree .

View File

@@ -32,7 +32,6 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
$scope.filteredProducts = []
$scope.currentFilters = []
$scope.limit = 15
$scope.productsWithUnsavedVariants = []
$scope.query = ""
$scope.DisplayProperties = DisplayProperties
@@ -114,7 +113,6 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
display_name: null
on_hand: null
price: null
$scope.productsWithUnsavedVariants.push product
DisplayProperties.setShowVariants product.id, true
@@ -196,7 +194,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
filters: $scope.currentFilters
).success((data) ->
DirtyProducts.clear()
BulkProducts.updateVariantLists(data.products, $scope.productsWithUnsavedVariants)
BulkProducts.updateVariantLists(data.products || [])
$timeout -> $scope.displaySuccess()
).error (data, status) ->
if status == 400 && data.errors? && data.errors.length > 0

View File

@@ -1 +1 @@
angular.module("admin.dropdown", ['templates'])
angular.module("admin.dropdown", ['admin.utils'])

View File

@@ -0,0 +1 @@
angular.module("admin.enterpriseRoles", [])

View File

@@ -4,10 +4,8 @@ angular.module("admin.enterprises")
$scope.PaymentMethods = EnterprisePaymentMethods.paymentMethods
$scope.ShippingMethods = EnterpriseShippingMethods.shippingMethods
$scope.navClear = NavigationCheck.clear
$scope.pristineEmail = $scope.Enterprise.email
$scope.menu = SideMenu
$scope.newManager = { id: '', email: (t('add_manager')) }
$scope.StatusMessage = StatusMessage
$scope.$watch 'enterprise_form.$dirty', (newValue) ->
@@ -36,6 +34,8 @@ angular.module("admin.enterprises")
$scope.removeManager = (manager) ->
if manager.id?
if manager.id == $scope.Enterprise.owner.id or manager.id == parseInt($scope.receivesNotifications)
return
for i, user of $scope.Enterprise.users when user.id == manager.id
$scope.Enterprise.users.splice i, 1
if $scope.enterprise_form?
@@ -46,6 +46,7 @@ angular.module("admin.enterprises")
manager =
id: manager.id
email: manager.email
confirmed: manager.confirmed
if (user for user in $scope.Enterprise.users when user.id == manager.id).length == 0
$scope.Enterprise.users.push manager
else

View File

@@ -16,9 +16,9 @@ angular.module("ofn.admin").factory "BulkProducts", (PagedFetcher, dataFetcher,
@unpackProduct newProduct
@insertProductAfter(product, newProduct)
updateVariantLists: (serverProducts, productsWithUnsavedVariants) ->
for product in productsWithUnsavedVariants
server_product = @findProductInList(product.id, serverProducts)
updateVariantLists: (serverProducts) ->
for server_product in serverProducts
product = @findProductInList(server_product.id, @products)
product.variants = server_product.variants
@loadVariantUnitValues product

View File

@@ -23,7 +23,16 @@
#
#= require angular-backstretch.js
#= require angular-flash.min.js
#
#= require moment
#= require moment/en-gb.js
#= require moment/es.js
#= require moment/fr.js
#= require moment/it.js
#= require moment/nb.js
#= require moment/pt-br.js
#= require moment/sv.js
#
#= require modernizr
#
#= require foundation

View File

@@ -10,4 +10,11 @@ Darkswarm.controller "LoginCtrl", ($scope, $http, $window, AuthenticationService
$window.location.href = $window.location.origin + $window.location.pathname # Strips out hash fragments
.error (data) ->
Loading.clear()
$scope.errors = data.message
$scope.errors = data.message || data.error
$scope.user_unconfirmed = (data.error == t('devise.failure.unconfirmed'))
$scope.resend_confirmation = ->
$http.post("/user/spree_user/confirmation", {spree_user: $scope.spree_user}).success (data)->
$scope.messages = t('devise.confirmations.send_instructions')
.error (data) ->
$scope.errors = t('devise.confirmations.failed_to_send')

View File

@@ -9,9 +9,7 @@ Darkswarm.controller "SignupCtrl", ($scope, $http, $window, $location, Redirecti
$scope.submit = ->
$http.post("/user/spree_user", {spree_user: $scope.spree_user}).success (data)->
if Redirections.after_login
$window.location.href = $window.location.origin + Redirections.after_login
else
$window.location.href = $window.location.origin + $window.location.pathname # Strips out hash fragments
$scope.errors = {email: null, password: null}
$scope.messages = t('devise.user_registrations.spree_user.signed_up_but_unconfirmed')
.error (data) ->
$scope.errors = data

View File

@@ -1,6 +1,3 @@
# 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 = {}) ->

View File

@@ -2,7 +2,6 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
new class EnterpriseRegistrationService
enterprise:
user_ids: [CurrentUser.id]
email: CurrentUser.email
email_address: CurrentUser.email
address: {}
country: availableCountries[0]

View File

@@ -2,7 +2,7 @@
%h2 {{ addressType === 'bill_address' ? "#{t('admin.customers.index.edit_bill_address')}" : "#{t('admin.customers.index.edit_ship_address')}" }}
%form{ name: 'edit_address_form', novalidate: true, ng: { submit: 'updateAddress()'}}
.row
= t('admin.customers.index.required_fileds')
{{ 'admin.customers.index.required_fileds' | t }}
(
%span.required *
)
@@ -11,62 +11,62 @@
%table.no-borders
%tr
%td{style: 'width: 30%'}
= t('spree.firstname')
{{ 'spree.firstname' | t }}
%span.required *
%td
%input{ type: 'text', name: 'firstname', required: true, ng: { model: 'address.firstname'} }
%tr
%td
= t('spree.lastname')
{{ 'spree.lastname' | t }}
%span.required *
%td
%input{ type: 'text', name: 'lastname', required: true, ng: { model: 'address.lastname'} }
%tr
%td
= t('spree.street_address')
{{ 'spree.street_address' | t }}
%span.required *
%td
%input{ type: 'text', name: 'address1', required: true, ng: { model: 'address.address1'} }
%tr
%td
= t('spree.street_address_1')
{{ 'spree.street_address_1' | t }}
%td
%input{ type: 'text', name: 'address2', ng: { model: 'address.address2'} }
%tr
%td
= t('spree.city')
{{ 'spree.city' | t }}
%span.required *
%td
%input{ type: 'text', name: 'city', required: true, ng: { model: 'address.city'} }
%tr
%td
= t('spree.zipcode')
{{ 'spree.zipcode' | t }}
%span.required *
%td
%input{ type: 'text', name: 'zipcode', required: true, ng: { model: 'address.zipcode'} }
%tr
%td
= t('spree.country')
{{ 'spree.country' | t }}
%span.required *
%td
%select{ name: 'country', required: true, ng: { model: 'address.country_id' } }
%option{value: ''}
= t('admin.customers.index.select_country')
{{ 'admin.customers.index.select_country' | t }}
%option{ ng: { repeat: 'country in availableCountries' }, value: '{{country.id}}' }
{{country.name}}
%tr
%td
= t('spree.state')
{{ 'spree.state' | t }}
%span.required *
%td
%select{ name: 'state', required: true, ng: { model: 'address.state_id' } }
%option{value: ''}
= t('admin.customers.index.select_state')
{{ 'admin.customers.index.select_state' | t }}
%option{ ng: { repeat: 'state in states' }, value: '{{state.id}}' }
{{state.name}}
%tr
%td
= t('spree.phone')
{{ 'spree.phone' | t }}
%span.required *
%td
%input{ type: 'text', name: 'phone', required: true, ng: { model: 'address.phone'} }

View File

@@ -1,7 +1,7 @@
.ofn-drop-down
%span
%i.icon-check
= t('admin.actions')
{{ 'admin.actions' | t }}
%i{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
%div.menu{ 'ng-show' => "expanded" }
%a.menu_item{ 'ng-repeat' => "link in links", href: '{{link.url}}', target: "{{link.target || '_self'}}", data: { method: "{{ link.method || 'get' }}", confirm: "{{link.confirm}}" } }

View File

@@ -1,19 +1,25 @@
#tag-rule-help
.margin-bottom-30.text-center
.text-big
= t('js.admin.modals.tag_rule_help.title')
{{ 'js.admin.modals.tag_rule_help.title' | t }}
.margin-bottom-30
.text-normal= t('js.admin.modals.tag_rule_help.overview')
%p= t('js.admin.modals.tag_rule_help.overview_text')
.text-normal
{{ 'js.admin.modals.tag_rule_help.overview' | t }}
%p
{{ 'js.admin.modals.tag_rule_help.overview_text' | t }}
.margin-bottom-30
.text-normal= t('js.admin.modals.tag_rule_help.by_default_rules')
%p= t('js.admin.modals.tag_rule_help.by_default_rules_text')
.text-normal
{{ 'js.admin.modals.tag_rule_help.by_default_rules' | t }}
%p
{{ 'js.admin.modals.tag_rule_help.by_default_rules_text' | t }}
.margin-bottom-30
.text-normal= t('js.admin.modals.tag_rule_help.customer_tagged_rules')
%p= t('js.admin.modals.tag_rule_help.customer_tagged_rules_text')
.text-normal
{{ 'js.admin.modals.tag_rule_help.customer_tagged_rules' | t }}
%p
{{ 'js.admin.modals.tag_rule_help.customer_tagged_rules_text' | t }}
.text-center
%input.button.red.icon-plus{ type: 'button', value: t('js.admin.modals.got_it'), ng: { click: 'close()' } }

View File

@@ -1,6 +1,6 @@
#new-customer-dialog
.text-normal.margin-bottom-30.text-center
= t('admin.customers.index.add_a_new_customer_for', shop_name: "{{ CurrentShop.shop.name }}:")
{{ 'admin.customers.index.add_a_new_customer_for' | t:{ shop_name: CurrentShop.shop.name } }}
%form{ name: 'new_customer_form', novalidate: true, ng: { submit: "addCustomer()" }}
@@ -8,7 +8,7 @@
%input.fullwidth{ type: 'email', name: 'email', required: true, placeholder: t('admin.customers.index.customer_placeholder'), ng: { model: "email" } }
%div{ ng: { show: "submitted && new_customer_form.$pristine" } }
.error{ ng: { show: "(new_customer_form.email.$error.email || new_customer_form.email.$error.required)" } }
= t('admin.customers.index.valid_email_error')
{{ 'admin.customers.index.valid_email_error' | t }}
.error{ ng: { repeat: "error in errors", bind: "error" } }
.text-center

View File

@@ -1,6 +1,6 @@
#new-tag-rule-dialog
.text-normal.margin-bottom-30.text-center
= t('js.admin.new_tag_rule_dialog.select_rule_type')
{{ 'js.admin.new_tag_rule_dialog.select_rule_type' | t }}
.text-center.margin-bottom-30
-# %select.fullwidth{ 'select2-min-search' => 5, 'ng-model' => 'newRuleType', 'ng-options' => 'ruleType.id as ruleType.name for ruleType in availableRuleTypes' }

View File

@@ -2,128 +2,162 @@
.alpha.eight.columns
%div{ ng: { if: "!enterprise.is_primary_producer", switch: "enterprise.sells" } }
.info{ ng: { switch: { when: "none" } } }
%h3= t('js.admin.panels.enterprise_package.hub_profile')
%h3
{{ 'js.admin.panels.enterprise_package.hub_profile' | t }}
%p
%strong= t('js.admin.panels.enterprise_package.hub_profile_cost')
%strong
{{ 'js.admin.panels.enterprise_package.hub_profile_cost' | t }}
%p= t('js.admin.panels.enterprise_package.hub_profile_text1')
%p
{{ 'js.admin.panels.enterprise_package.hub_profile_text1' | t }}
%p= t('js.admin.panels.enterprise_package.hub_profile_text2')
%p
{{ 'js.admin.panels.enterprise_package.hub_profile_text2' | t }}
.info{ ng: { switch: { when: "any" } } }
%h3= t('js.admin.panels.enterprise_package.hub_shop')
%h3
{{ 'js.admin.panels.enterprise_package.hub_shop' | t }}
%p
%strong
%monthly-pricing-description{ joiner: "comma" }
%p= t('js.admin.panels.enterprise_package.hub_shop_text1')
%p
{{ 'js.admin.panels.enterprise_package.hub_shop_text1' | t }}
%p= t('js.admin.panels.enterprise_package.hub_shop_text2')
%p
{{ 'js.admin.panels.enterprise_package.hub_shop_text2' | t }}
%p= t('js.admin.panels.enterprise_package.hub_shop_text3')
%p
{{ 'js.admin.panels.enterprise_package.hub_shop_text3' | t }}
.info{ ng: { switch: { default: true } } }
%h3
= t('js.admin.panels.enterprise_package.choose_package')
{{ 'js.admin.panels.enterprise_package.choose_package' | t }}
%i.icon-arrow-right
%p
%strong= t('js.admin.panels.enterprise_package.choose_package_text1')
%strong
{{ 'js.admin.panels.enterprise_package.choose_package_text1' | t }}
%p
= t('js.admin.panels.enterprise_package.choose_package_text2')
{{ 'js.admin.panels.enterprise_package.choose_package_text2' | t }}
%div{ ng: { if: "enterprise.is_primary_producer", switch: "enterprise.sells" } }
.info{ ng: { switch: { when: "none" } } }
%h3= t('js.admin.panels.enterprise_package.profile_only')
%h3
{{ 'js.admin.panels.enterprise_package.profile_only' | t }}
%p
%strong= t('js.admin.panels.enterprise_package.profile_only_cost')
%strong
{{ 'js.admin.panels.enterprise_package.profile_only_cost' | t }}
%p= t('js.admin.panels.enterprise_package.profile_only_text1')
%p
{{ 'js.admin.panels.enterprise_package.profile_only_text1' | t }}
%p= t('js.admin.panels.enterprise_package.profile_only_text2')
%p
{{ 'js.admin.panels.enterprise_package.profile_only_text2' | t }}
%p= t('js.admin.panels.enterprise_package.profile_only_text3')
%p
{{ 'js.admin.panels.enterprise_package.profile_only_text3' | t }}
.info{ ng: { switch: { when: "own" } } }
%h3= t('js.admin.panels.enterprise_package.producer_shop')
%h3
{{ 'js.admin.panels.enterprise_package.producer_shop' | t }}
%p
%strong
%monthly-pricing-description{ joiner: "comma" }
%p= t('js.admin.panels.enterprise_package.producer_shop_text1')
%p
{{ 'js.admin.panels.enterprise_package.producer_shop_text1' | t }}
%p= t('js.admin.panels.enterprise_package.producer_shop_text2')
%p
{{ 'js.admin.panels.enterprise_package.producer_shop_text2' | t }}
.info{ ng: { switch: { when: "any" } } }
%h3= t('js.admin.panels.enterprise_package.producer_hub')
%h3
{{ 'js.admin.panels.enterprise_package.producer_hub' | t }}
%p
%strong
%monthly-pricing-description{ joiner: "comma" }
%p= t('js.admin.panels.enterprise_package.producer_hub_text1')
%p
{{ 'js.admin.panels.enterprise_package.producer_hub_text1' | t }}
%p= t('js.admin.panels.enterprise_package.producer_hub_text2')
%p
{{ 'js.admin.panels.enterprise_package.producer_hub_text2' | t }}
%p= t('js.admin.panels.enterprise_package.producer_hub_text3')
%p
{{ 'js.admin.panels.enterprise_package.producer_hub_text3' | t }}
.info{ ng: { switch: { default: true } } }
%h3
= t('js.admin.panels.enterprise_package.choose_package')
{{ 'js.admin.panels.enterprise_package.choose_package' | t }}
%i.icon-arrow-right
%p
%strong= t('js.admin.panels.enterprise_package.choose_package_text1')
%strong
{{ 'js.admin.panels.enterprise_package.choose_package_text1' | t }}
%p
= t('js.admin.panels.enterprise_package.choose_package_text2')
{{ 'js.admin.panels.enterprise_package.choose_package_text2' | t }}
.omega.eight.columns{ ng: { switch: "enterprise.is_primary_producer" } }
%div{ ng: { switch: { when: "false" } } }
%a.button.selector.hub-profile{ ng: { click: "enterprise.owned && (enterprise.sells='none')", class: "{selected: enterprise.sells=='none', disabled: !enterprise.owned}" } }
.top
%h3= t('js.admin.panels.enterprise_package.profile_only')
%p= t('js.admin.panels.enterprise_package.get_listing')
.bottom= t('js.admin.panels.enterprise_package.always_free')
%h3
{{ 'js.admin.panels.enterprise_package.profile_only' | t }}
%p
{{ 'js.admin.panels.enterprise_package.get_listing' | t }}
.bottom
{{ 'js.admin.panels.enterprise_package.always_free' | t }}
%a.button.selector.hub{ ng: { click: "enterprise.owned && (enterprise.sells='any')", class: "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" } }
.top
%h3= t('js.admin.panels.enterprise_package.hub_shop')
%p= t('js.admin.panels.enterprise_package.sell_produce_others')
%h3
{{ 'js.admin.panels.enterprise_package.hub_shop' | t }}
%p
{{ 'js.admin.panels.enterprise_package.sell_produce_others' | t }}
.bottom
%monthly-pricing-description{ joiner: "newline" }
%div{ ng: { switch: { when: "true" } } }
%a.button.selector.producer-profile{ ng: { click: "enterprise.owned && (enterprise.sells='none')", class: "{selected: enterprise.sells=='none', disabled: !enterprise.owned}" } }
.top
%h3= t('js.admin.panels.enterprise_package.profile_only')
%p= t('js.admin.panels.enterprise_package.get_listing')
.bottom= t('js.admin.panels.enterprise_package.always_free')
%h3
{{ 'js.admin.panels.enterprise_package.profile_only' | t }}
%p
{{ 'js.admin.panels.enterprise_package.get_listing' | t }}
.bottom
{{ 'js.admin.panels.enterprise_package.always_free' | t }}
%a.button.selector.producer-shop{ ng: { click: "enterprise.owned && (enterprise.sells='own')", class: "{selected: enterprise.sells=='own', disabled: !enterprise.owned}" } }
.top
%h3= t('js.admin.panels.enterprise_package.producer_shop')
%p= t('js.admin.panels.enterprise_package.sell_own_produce')
%h3
{{ 'js.admin.panels.enterprise_package.producer_shop' | t }}
%p
{{ 'js.admin.panels.enterprise_package.sell_own_produce' | t }}
.bottom
%monthly-pricing-description{ joiner: "newline" }
%a.button.selector.producer-hub{ ng: { click: "enterprise.owned && (enterprise.sells='any')", class: "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" } }
.top
%h3= t('js.admin.panels.enterprise_package.producer_hub')
%p= t('js.admin.panels.enterprise_package.sell_both')
%h3
{{ 'js.admin.panels.enterprise_package.producer_hub' | t }}
%p
{{ 'js.admin.panels.enterprise_package.sell_both' | t }}
.bottom
%monthly-pricing-description{ joiner: "newline" }
%a.button.update.fullwidth{ ng: { show: "enterprise.owned", class: "{disabled: saved() && !saving, saving: saving}", click: "save()" } }
%span{ ng: {hide: "saved() || saving" } }
= t('js.admin.panels.save')
{{ 'js.admin.panels.save' | t }}
%i.icon-save
%span{ ng: {show: "saved() && !saving" } }
= t('js.admin.panels.saved')
{{ 'js.admin.panels.saved' | t }}
%i.icon-ok-sign
%span{ ng: {show: "saving" } }
= t('js.admin.panels.saving')
{{ 'js.admin.panels.saving' | t }}
%i.icon-refresh

View File

@@ -1,37 +1,47 @@
.row.enterprise_producer_panel{ ng: { controller: 'indexProducerPanelCtrl' } }
.alpha.eight.columns
.info{ ng: { show: "enterprise.is_primary_producer==true" } }
%h3= t('js.admin.panels.enterprise_producer.producer')
%p= t('js.admin.panels.enterprise_producer.producer_text1')
%p= t('js.admin.panels.enterprise_producer.producer_text2')
%h3
{{ 'js.admin.panels.enterprise_producer.producer' | t }}
%p
{{ 'js.admin.panels.enterprise_producer.producer_text1' | t }}
%p
{{ 'js.admin.panels.enterprise_producer.producer_text2' | t }}
.info{ ng: { show: "enterprise.is_primary_producer==false" } }
%h3= t('js.admin.panels.enterprise_producer.non_producer')
%p= t('js.admin.panels.enterprise_producer.non_producer_text1')
%p= t('js.admin.panels.enterprise_producer.non_producer_text2')
%h3
{{ 'js.admin.panels.enterprise_producer.non_producer' | t }}
%p
{{ 'js.admin.panels.enterprise_producer.non_producer_text1' | t }}
%p
{{ 'js.admin.panels.enterprise_producer.non_producer_text2' | t }}
.omega.eight.columns
%a.button.selector.producer{ ng: { click: 'enterprise.owned && changeToProducer()', class: "{selected: enterprise.is_primary_producer==true, disabled: !enterprise.owned}" } }
.top
%h3= t('js.admin.panels.enterprise_producer.producer')
%p= t('js.admin.panels.enterprise_producer.producer_desc')
.bottom= t('js.admin.panels.enterprise_producer.producer_example')
%h3
{{ 'js.admin.panels.enterprise_producer.producer' | t }}
%p
{{ 'js.admin.panels.enterprise_producer.producer_desc' | t }}
.bottom
{{ 'js.admin.panels.enterprise_producer.producer_example' | t }}
%a.button.selector.non-producer{ ng: { click: 'enterprise.owned && changeToNonProducer()', class: "{selected: enterprise.is_primary_producer==false, disabled: !enterprise.owned}" } }
.top
%h3= t('js.admin.panels.enterprise_producer.non_producer')
%p= t('js.admin.panels.enterprise_producer.non_producer_desc')
.bottom= t('js.admin.panels.enterprise_producer.non_producer_example')
%h3
{{ 'js.admin.panels.enterprise_producer.non_producer' | t }}
%p
{{ 'js.admin.panels.enterprise_producer.non_producer_desc' | t }}
.bottom
{{ 'js.admin.panels.enterprise_producer.non_producer_example' | t }}
%a.button.update.fullwidth{ ng: { show: "enterprise.owned", class: "{disabled: saved() && !saving, saving: saving}", click: "save()" } }
%span{ ng: {hide: "saved() || saving" } }
= t('js.admin.panels.save')
{{ 'js.admin.panels.save' | t }}
%i.icon-save
%span{ ng: {show: "saved() && !saving" } }
= t('js.admin.panels.saved')
{{ 'js.admin.panels.saved' | t }}
%i.icon-ok-sign
%span{ ng: {show: "saving" } }
= t('js.admin.panels.saving')
{{ 'js.admin.panels.saving' | t }}
%i.icon-refresh

View File

@@ -2,16 +2,16 @@
.alpha.omega.sixteen.columns
%h4.status-ok.text-center{ ng: { show: "issues.length == 0 && warnings.length == 0" } }
%i.icon-ok-sign
= t('js.admin.panels.enterprise_status.status_title', name: '{{ object.name }}')
{{ 'js.admin.panels.enterprise_status.status_title' | t:{ name: object.name } }}
%table{ ng: { show: "issues.length > 0 || warnings.length > 0" } }
%thead
%th.severity
= t('js.admin.panels.enterprise_status.severity')
{{ 'js.admin.panels.enterprise_status.severity' | t }}
%th.description
= t('js.admin.panels.enterprise_status.description')
{{ 'js.admin.panels.enterprise_status.description' | t }}
%th.resolve
= t('js.admin.panels.enterprise_status.resolve')
{{ 'js.admin.panels.enterprise_status.resolve' | t }}
%tr{ ng: { repeat: "issue in issues"} }
%td.severity
%i.icon-warning-sign.issue

View File

@@ -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' }
= t('admin.select_all')
{{ 'admin.select_all' | t }}
.exchange-products
-# Scope product list based on permissions the current user has to view variants in this exchange

View File

@@ -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' }
= t('admin.select_all')
{{ 'admin.select_all' | t }}
.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' }
= t('admin.obsolete_master')
{{ 'admin.obsolete_master' | t }}
.exchange-product-variant{'ng-repeat' => 'variant in product.variants'}
%label

View File

@@ -1,6 +1,6 @@
.row.exchange-tags
.sixteen.columns.alpha.omega
%span.text-normal
= t('admin.tags')
{{ 'admin.tags' | t }}
%br
%tags-with-translation.fullwidth{ object: 'object' }

View File

@@ -3,9 +3,9 @@
{{$getDisplayText()}}
%span.tag-with-rules{ ng: { if: "data.rules == 1" } }
&mdash;
= t('admin.has_one_rule')
{{ 'admin.has_one_rule' | t }}
%span.tag-with-rules{ ng: { if: "data.rules > 1" } }
&mdash;
= t('admin.has_n_rules', { num: '{{data.rules}}' })
{{ 'admin.has_n_rules' | t:{ num: data.rules } }}
%span{ ng: { if: "!data.rules" } }
{{$getDisplayText()}}

View File

@@ -1,4 +1,5 @@
%tags-input{ template: 'admin/tag.html',
"placeholder" => t('admin.order_cycles.form.add_a_tag'),
ng: { model: 'object[tagsAttr]', class: "{'limit-reached': limitReached}"},
on: { tag: { added: 'tagAdded()', removed:'tagRemoved()' } } }
%auto-complete{ ng: { if: "findTags" }, source: "findTags({query: $query})",

View File

@@ -4,6 +4,10 @@
.large-12.columns
.alert-box.alert{"ng-show" => "errors != null"}
{{ errors }}
%a{ng: {show: 'user_unconfirmed', click: 'resend_confirmation()'}}
= t('devise.confirmations.resend_confirmation_email')
.alert-box.success{ng: {show: 'messages != null'}}
{{ messages }}
.row
.large-12.columns
%label{for: "email"} {{'email' | t}}

View File

@@ -1,13 +1,15 @@
%a.close-reveal-modal{"ng-click" => "$close()"}
%i.ofn-i_009-close
%h3= t('js.out_of_stock.reduced_stock_available')
%h3
{{ 'js.out_of_stock.reduced_stock_available' | t }}
%p= t('js.out_of_stock.out_of_stock_text')
%p
{{ 'js.out_of_stock.out_of_stock_text' | t }}
%p{'ng-repeat' => "v in variants"}
%em {{ v.name_to_display }} - {{ v.unit_to_display }}
%span{'ng-if' => "v.count_on_hand == 0"}
= t('js.out_of_stock.now_out_of_stock')
{{ 'js.out_of_stock.now_out_of_stock' | t }}
%span{'ng-if' => "v.count_on_hand > 0"}
= t('js.out_of_stock.only_n_remainging', num: '{{ v.count_on_hand }}')
{{ 'js.out_of_stock.only_n_remainging' | t:{ num: v.count_on_hand } }}

View File

@@ -17,8 +17,8 @@
%a.cta-hub{"ng-href" => "{{::enterprise.path}}",
"ng-class" => "{primary: enterprise.active, secondary: !enterprise.active}",
"ofn-change-hub" => "enterprise"}
%i.ofn-i_033-open-sign{"ng-if" => "::enterprise.active"}
%i.ofn-i_032-closed-sign{"ng-if" => "::!enterprise.active"}
.hub-name{"ng-bind" => "::enterprise.name"}
%span{"ng-if" => "::enterprise.active"} ({{'maps_open' | t}})
%span{"ng-if" => "::!enterprise.active"} ({{'maps_closed' | t}})
.button-address{"ng-bind" => "::[enterprise.address.city, enterprise.address.state_name] | printArray"}
/ %i.ofn-i_007-caret-right

View File

@@ -14,7 +14,7 @@
%a.cta-hub{"ng-repeat" => "hub in enterprise.hubs | filter:{id: '!'+enterprise.id} | orderBy:'-active'",
"ng-href" => "{{::hub.path}}", "ofn-empties-cart" => "hub",
"ng-class" => "::{primary: hub.active, secondary: !hub.active}"}
%i.ofn-i_033-open-sign{"ng-if" => "::hub.active"}
%i.ofn-i_032-closed-sign{"ng-if" => "::!hub.active"}
.hub-name{"ng-bind" => "::hub.name"}
%span{"ng-if" => "::hub.active"} ({{'maps_open' | t}})
%span{"ng-if" => "::!hub.active"} ({{'maps_closed' | t}})
.button-address{"ng-bind" => "::[hub.address.city, hub.address.state_name] | printArray"}

View File

@@ -1,5 +1,9 @@
%tab#sign-up-content{ heading: "{{'label_signup' | t}}", active: 'tabs.signup.active', select: "select(path)"}
%form{ ng: { controller: "SignupCtrl", submit: "submit()" } }
.row
.large-12.columns
.alert-box.success{ng: {show: 'messages != null'}}
{{ messages }}
.row
.large-12.columns
%label{for: "email"} {{'signup_email' | t}}

View File

@@ -5,7 +5,7 @@
%li.more
%a.dropdown{ data: { dropdown: "{{ 'show-more-' + selectorName }}" }, ng: { class: "{active: selectedOverFlowSelectors().length > 0}" } }
%span
= t('js.more_items', count: "{{ overFlowSelectors().length }}")
{{ 'js.more_items' | t:{ count: overFlowSelectors().length } }}
%i.ofn-i_052-point-down
.f-dropdown.text-right.content{ ng: { attr: { id: "{{ 'show-more-' + selectorName }}" } } }
%ul

View File

@@ -1,3 +1,29 @@
form[name="enterprise_form"] div.row.warning {
color: #DA7F52;
form[name="enterprise_form"] {
div.row.warning {
color: #DA7F52;
}
table.managers {
i.role {
float: right;
margin-left: 0.5em;
font-size: 1.5em;
cursor: pointer;
}
i.confirmation {
margin-left: 0.2em;
font-size: 1.2em;
cursor: pointer;
vertical-align: bottom;
&.confirmed {
color: #1ece1e;
}
&.unconfirmed {
color: #ed9524;
}
}
}
}

View File

@@ -36,6 +36,8 @@
text-align: right
p
max-width: 400px
h4 i
margin-right: 0.3rem
@media all and (max-width: 640px)
float: left
clear: left

View File

@@ -88,6 +88,10 @@ footer {
@include panepadding;
div.row a img {
margin-bottom: 20px;
}
.row {
&, p, h1, h2, h3, h4, h5, h6 {
color: $disabled-med;

View File

@@ -8,6 +8,14 @@
white-space: nowrap;
overflow-x: hidden;
overflow-y: visible;
i {
margin-right: 0.5rem;
}
}
.active_table_row {
line-height: 1rem;
}
//Generic text link style
@@ -30,7 +38,7 @@
//Closed & Open column
.open_closed {
i {
font-size: 2rem;
font-size: 1.75rem;
float: right;
margin-left: 0.5rem;
}

View File

@@ -36,10 +36,15 @@ nav {
.top-bar-section .has-dropdown > a {
padding-right: ($topbar-height / 3) !important;
i.ofn-i_022-cog {
i.ofn-i_022-cog, .ofn-i_071-globe {
font-size: 24px;
line-height: $topbar-height;
}
i.ofn-i_071-globe {
color: #666;
font-size: 27px
}
}
.top-bar-section .has-dropdown > a:after {
@@ -95,6 +100,11 @@ nav {
background-color: white;
}
.off-canvas-list li.language-switcher ul li {
list-style-type: none;
padding-left: 0.5em;
}
.off-canvas-wrap.move-right .tab-bar .menu-icon {
@include box-shadow(inset 0 0 6px 2px rgba(0, 0, 0, 0.5));
}

View File

@@ -160,13 +160,6 @@
color: $clr-brick;
}
i.ofn-i_033-open-sign, i.ofn-i_032-closed-sign {
margin-right: 0.1rem;
font-size: 2rem;
padding: 0.15rem 0.25rem 0.35rem 0.25rem;
float: left;
}
.hub-name {
margin-top: 0.75rem;
margin-bottom: 0.2rem;

View File

@@ -10,4 +10,16 @@
background: #fff;
padding-top: 10px;
}
.alert-box {
a {
color: white;
text-decoration: underline;
&:hover {
color: rgba(255, 255, 255, 0.7);
text-decoration: underline;
}
}
}
}

View File

@@ -233,3 +233,6 @@
.ofn-i_070-shop-map-reversed:before {
content: "\e645";
}
.ofn-i_071-globe:before {
content: "\e646";
}

View File

@@ -39,6 +39,7 @@ module Admin
invoke_callbacks(:update, :before)
tag_rules_attributes = params[object_name].delete :tag_rules_attributes
update_tag_rules(tag_rules_attributes) if tag_rules_attributes.present?
update_enterprise_notifications
if @object.update_attributes(params[object_name])
invoke_callbacks(:update, :after)
flash[:success] = flash_message_for(@object, :successfully_updated)
@@ -198,6 +199,12 @@ module Admin
end
end
def update_enterprise_notifications
if params.key? :receives_notifications
@enterprise.update_contact params[:receives_notifications]
end
end
def create_calculator_for(rule, attrs)
if attrs[:calculator_type].present? && attrs[:calculator_attributes].present?
rule.update_attributes(calculator_type: attrs[:calculator_type])

View File

@@ -135,7 +135,7 @@ module Admin
return
end
available_coordinators = permitted_coordinating_enterprises_for(@order_cycle).select(&:confirmed?)
available_coordinators = permitted_coordinating_enterprises_for(@order_cycle)
case available_coordinators.count
when 0
flash[:error] = I18n.t(:order_cycles_no_permission_to_coordinate_error)

View File

@@ -60,7 +60,12 @@ module Api
def override_sells
has_hub = current_api_user.owned_enterprises.is_hub.any?
new_enterprise_is_producer = !!params[:enterprise][:is_primary_producer]
params[:enterprise][:sells] = (has_hub && !new_enterprise_is_producer) ? 'any' : 'unspecified'
params[:enterprise][:sells] = if has_hub && !new_enterprise_is_producer
'any'
else
'unspecified'
end
end
def override_visible

View File

@@ -45,10 +45,6 @@ class DiscourseSsoController < ApplicationController
end
def require_activation?
!admin_user? && !email_validated?
end
def email_validated?
spree_current_user.enterprises.confirmed.map(&:email).include?(spree_current_user.email)
!admin_user? && !spree_current_user.confirmed?
end
end

View File

@@ -1,55 +0,0 @@
class EnterpriseConfirmationsController < DeviseController
include Spree::Core::ControllerHelpers::Auth # Needed for access to current_ability, so we can authorize! actions
# GET /resource/confirmation/new
def new
build_resource({})
end
# POST /resource/confirmation
def create
self.resource = resource_class.find_by_unconfirmed_email_with_errors(resource_params)
authorize! :resend_confirmation, resource
self.resource = resource_class.send_confirmation_instructions(resource_params)
if successfully_sent?(resource)
set_flash_message(:success, :confirmation_sent) if is_navigational_format?
else
set_flash_message(:error, :confirmation_not_sent) if is_navigational_format?
end
respond_with_navigational(resource){ redirect_to spree.admin_path }
end
# GET /resource/confirmation?confirmation_token=abcdef
def show
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
if resource.errors.empty?
set_flash_message(:success, :confirmed) if is_navigational_format?
else
set_flash_message(:error, :not_confirmed) if is_navigational_format?
end
respond_with_navigational(resource){ redirect_to redirect_path(resource) }
end
private
def new_user_reset_path(resource)
password = Devise.friendly_token.first(8)
user = Spree::User.create(email: resource.email, password: password, password_confirmation: password)
user.send_reset_password_instructions_without_delay
resource.users << user
spree.edit_spree_user_password_path(user, :reset_password_token => user.reset_password_token, return_to: spree.admin_path)
end
def redirect_path(resource)
if resource.persisted? && !Spree::User.exists?(email: resource.email)
new_user_reset_path(resource)
else
spree.admin_path
end
end
end

View File

@@ -7,7 +7,7 @@ class EnterprisesController < BaseController
# These prepended filters are in the reverse order of execution
prepend_before_filter :set_order_cycles, :require_distributor_chosen, :reset_order, only: :shop
before_filter :check_stock_levels, only: :shop
before_filter :check_stock_levels, :set_noindex_meta_tag, only: :shop
before_filter :clean_permalink, only: :check_permalink
before_filter :enable_embedded_shopfront
@@ -85,4 +85,8 @@ class EnterprisesController < BaseController
order_cycle_options = OrderCycle.active.with_distributor(distributor)
order.order_cycle = order_cycle_options.first if order_cycle_options.count == 1
end
def set_noindex_meta_tag
@noindex_meta_tag = true unless current_distributor.visible?
end
end

View File

@@ -3,6 +3,8 @@ require 'spree/core/controller_helpers/respond_with_decorator'
Spree::Admin::BaseController.class_eval do
include I18nHelper
layout 'spree/layouts/admin'
before_filter :set_locale
before_filter :warn_invalid_order_cycles

View File

@@ -4,7 +4,7 @@ Spree::Admin::OrdersController.class_eval do
include OpenFoodNetwork::SpreeApiKeyLoader
helper CheckoutHelper
before_filter :load_spree_api_key, :only => :bulk_management
before_filter :load_order, only: %i[show edit update fire resend invoice print]
before_filter :load_order, only: %i[show edit update fire resend invoice print print_ticket]
before_filter :load_distribution_choices, only: [:new, :edit, :update]

View File

@@ -13,7 +13,7 @@ Spree::Admin::SearchController.class_eval do
}).result.limit(10)
end
render :users
render json: @users, each_serializer: Api::Admin::UserSerializer
end
def customers

View File

@@ -1,12 +1,15 @@
Spree::UsersController.class_eval do
layout 'darkswarm'
include I18nHelper
before_filter :set_locale
before_filter :enable_embedded_shopfront
# Override of spree_auth_devise default
# Ignores invoice orders, only order where state: 'complete'
def show
@orders = @user.orders.where(state: 'complete').order('completed_at desc')
@unconfirmed_email = spree_current_user.unconfirmed_email
return unless Spree::Config.accounts_distributor_id

View File

@@ -0,0 +1,38 @@
class UserConfirmationsController < DeviseController
include Spree::Core::ControllerHelpers::Auth # Needed for access to current_ability, so we can authorize! actions
# GET /resource/confirmation/new
def new
build_resource({})
end
# POST /resource/confirmation
def create
self.resource = resource_class.send_confirmation_instructions(resource_params)
if is_navigational_format?
if successfully_sent?(resource)
set_flash_message(:success, :confirmation_sent)
else
set_flash_message(:error, :confirmation_not_sent)
end
end
respond_with_navigational(resource){ redirect_to login_path }
end
# GET /resource/confirmation?confirmation_token=abcdef
def show
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
if is_navigational_format?
if resource.errors.empty?
set_flash_message(:success, :confirmed)
else
set_flash_message(:error, :not_confirmed)
end
end
respond_with_navigational(resource){ redirect_to login_path }
end
end

View File

@@ -5,14 +5,13 @@ class UserRegistrationsController < Spree::UserRegistrationsController
def create
@user = build_resource(params[:spree_user])
if resource.save
set_flash_message(:success, :signed_up)
sign_in(:spree_user, @user)
session[:spree_user_signup] = true
associate_user
respond_to do |format|
format.html do
sign_in_and_redirect(:spree_user, @user)
set_flash_message(:success, :signed_up_but_unconfirmed)
redirect_to after_sign_in_path_for(@user)
end
format.js do
render json: { email: @user.email }

View File

@@ -87,10 +87,12 @@ module InjectionHelper
def inject_json_ams(name, data, serializer, opts = {})
if data.is_a?(Array)
json = ActiveModel::ArraySerializer.new(data, {each_serializer: serializer}.merge(opts)).to_json
else
json = serializer.new(data, opts).to_json
opts = { each_serializer: serializer }.merge(opts)
serializer = ActiveModel::ArraySerializer
end
serializer_instance = serializer.new(data, opts)
json = serializer_instance.to_json
render partial: "json/injection_ams", locals: {name: name, json: json}
end

View File

@@ -12,7 +12,7 @@ module OrderCyclesHelper
end
def permitted_producer_enterprise_options_for(order_cycle)
validated_enterprise_options permitted_producer_enterprises_for(order_cycle), confirmed: true
validated_enterprise_options permitted_producer_enterprises_for(order_cycle)
end
def permitted_coordinating_enterprises_for(order_cycle)
@@ -20,7 +20,7 @@ module OrderCyclesHelper
end
def permitted_coordinating_enterprise_options_for(order_cycle)
validated_enterprise_options permitted_coordinating_enterprises_for(order_cycle), confirmed: true
validated_enterprise_options permitted_coordinating_enterprises_for(order_cycle)
end
def permitted_hub_enterprises_for(order_cycle)
@@ -28,7 +28,7 @@ module OrderCyclesHelper
end
def permitted_hub_enterprise_options_for(order_cycle)
validated_enterprise_options permitted_hub_enterprises_for(order_cycle), confirmed: true, shipping_and_payment_methods: true
validated_enterprise_options permitted_hub_enterprises_for(order_cycle), shipping_and_payment_methods: true
end
def order_cycle_status_class(order_cycle)
@@ -91,8 +91,6 @@ module OrderCyclesHelper
elsif e.payment_methods.available.empty?
disabled_message = I18n.t(:no_payment)
end
elsif options[:confirmed] && !e.confirmed?
disabled_message = I18n.t(:unconfirmed)
end
if disabled_message

View File

@@ -37,7 +37,7 @@ class UpdateAccountInvoices
if billable_periods.any?
oldest_enterprise = billable_periods.first.enterprise
address = oldest_enterprise.address.dup
first, _space, last = (oldest_enterprise.contact || "").partition(' ')
first, _space, last = (oldest_enterprise.contact_name || "").partition(' ')
address.update_attributes(phone: oldest_enterprise.phone) if oldest_enterprise.phone.present?
address.update_attributes(firstname: first, lastname: last) if first.present? && last.present?
account_invoice.order.update_attributes(bill_address: address, ship_address: address)

View File

@@ -7,21 +7,11 @@ class EnterpriseMailer < Spree::BaseMailer
subject = t('enterprise_mailer.welcome.subject',
enterprise: @enterprise.name,
sitename: Spree::Config[:site_name])
mail(:to => enterprise.email,
mail(:to => enterprise.contact.email,
:from => from_address,
:subject => subject)
end
def confirmation_instructions(record, token)
@token = token
find_enterprise(record)
subject = t('enterprise_mailer.confirmation_instructions.subject',
enterprise: @enterprise.name)
mail(to: (@enterprise.unconfirmed_email || @enterprise.email),
from: from_address,
subject: subject)
end
private
def find_enterprise(enterprise)

View File

@@ -13,11 +13,11 @@ class ProducerMailer < Spree::BaseMailer
subject = "[#{Spree::Config.site_name}] #{I18n.t('producer_mailer.order_cycle.subject', producer: producer.name)}"
if has_orders? order_cycle, producer
mail(to: @producer.email,
mail(to: @producer.contact.email,
from: from_address,
subject: subject,
reply_to: @coordinator.email,
cc: @coordinator.email)
reply_to: @coordinator.contact.email,
cc: @coordinator.contact.email)
end
end

View File

@@ -17,14 +17,14 @@ Spree::OrderMailer.class_eval do
mail(:to => @order.email,
:from => from_address,
:subject => subject,
:reply_to => @order.distributor.email)
:reply_to => @order.distributor.contact.email)
end
def confirm_email_for_shop(order, resend = false)
find_order(order) # Finds an order instance from an id
subject = (resend ? "[#{t(:resend).upcase}] " : '')
subject += "#{Spree::Config[:site_name]} #{t('order_mailer.confirm_email.subject')} ##{@order.number}"
mail(:to => @order.distributor.email,
mail(:to => @order.distributor.contact.email,
:from => from_address,
:subject => subject)
end
@@ -36,7 +36,7 @@ Spree::OrderMailer.class_eval do
mail(:to => @order.email,
:from => from_address,
:subject => subject,
:reply_to => @order.distributor.email)
:reply_to => @order.distributor.contact.email)
end
def find_order(order)

View File

@@ -4,4 +4,13 @@ Spree::UserMailer.class_eval do
mail(:to => user.email, :from => from_address,
:subject => t(:welcome_to) + Spree::Config[:site_name])
end
def confirmation_instructions(user, token)
@user = user
@token = token
subject = t('spree.user_mailer.confirmation_instructions.subject')
mail(to: user.email,
from: from_address,
subject: subject)
end
end

View File

@@ -1,4 +1,5 @@
require_dependency 'spree/calculator'
require 'spree/localized_number'
class Calculator::FlatPercentPerItem < Spree::Calculator
# Spree's FlatPercentItemTotal calculator sums all amounts, and then calculates a percentage
@@ -6,11 +7,14 @@ class Calculator::FlatPercentPerItem < Spree::Calculator
# In the cart, we display line item individual amounts rounded, so to have consistent
# calculations we do the same internally. Here, we round adjustments at the individual
# item level first, then multiply by the item quantity.
extend Spree::LocalizedNumber
preference :flat_percent, :decimal, :default => 0
attr_accessible :preferred_flat_percent
localize_number :preferred_flat_percent
def self.description
I18n.t(:flat_percent_per_item)
end

View File

@@ -10,11 +10,9 @@ class Enterprise < ActiveRecord::Base
# This is hopefully a temporary measure, pending the arrival of multiple named inventories
# for shops. We need this here to allow hubs to restrict visible variants to only those in
# their inventory if they so choose
# TODO: delegate this to a separate model instead of abusing Preferences.
preference :product_selection_from_inventory_only, :boolean, default: false
devise :confirmable, reconfirmable: true, confirmation_keys: [ :id, :email ]
handle_asynchronously :send_confirmation_instructions
handle_asynchronously :send_on_create_confirmation_instructions
has_paper_trail only: [:owner_id, :sells], on: [:update]
self.inheritance_column = nil
@@ -71,34 +69,27 @@ class Enterprise < ActiveRecord::Base
validate :name_is_unique
validates :sells, presence: true, inclusion: {in: SELLS}
validates :address, presence: true, associated: true
validates :email, presence: true
validates_presence_of :owner
validates :permalink, uniqueness: true, presence: true
validate :shopfront_taxons
validate :enforce_ownership_limit, if: lambda { owner_id_changed? && !owner_id.nil? }
validates_length_of :description, :maximum => 255
before_save :confirmation_check, if: lambda { email_changed? }
before_validation :initialize_permalink, if: lambda { permalink.nil? }
before_validation :ensure_owner_is_manager, if: lambda { owner_id_changed? && !owner_id.nil? }
before_validation :ensure_email_set
before_validation :set_unused_address_fields
after_validation :geocode_address
after_touch :touch_distributors
after_create :set_default_contact
after_create :relate_to_owners_enterprises
# TODO: Later versions of devise have a dedicated after_confirmation callback, so use that
after_update :welcome_after_confirm, if: lambda { confirmation_token_changed? && confirmation_token.nil? }
after_create :send_welcome_email, if: lambda { email_is_known? }
after_create :send_welcome_email
after_rollback :restore_permalink
scope :by_name, order('name')
scope :visible, where(visible: true)
scope :confirmed, where('confirmed_at IS NOT NULL')
scope :unconfirmed, where('confirmed_at IS NULL')
scope :activated, where("confirmed_at IS NOT NULL AND sells != 'unspecified'")
scope :activated, where("sells != 'unspecified'")
scope :ready_for_checkout, lambda {
joins(:shipping_methods).
joins(:payment_methods).
@@ -119,16 +110,6 @@ class Enterprise < ActiveRecord::Base
scope :is_distributor, where('sells != ?', 'none')
scope :is_hub, where(sells: 'any')
scope :supplying_variant_in, lambda { |variants| joins(:supplied_products => :variants_including_master).where('spree_variants.id IN (?)', variants).select('DISTINCT enterprises.*') }
scope :with_supplied_active_products_on_hand, lambda {
joins(:supplied_products)
.where('spree_products.deleted_at IS NULL AND spree_products.available_on <= ? AND spree_products.count_on_hand > 0', Time.zone.now)
.uniq
}
scope :with_distributed_active_products_on_hand, lambda {
joins(:distributed_products)
.where('spree_products.deleted_at IS NULL AND spree_products.available_on <= ? AND spree_products.count_on_hand > 0', Time.zone.now)
.uniq
}
scope :with_distributed_products_outer,
joins('LEFT OUTER JOIN product_distributions ON product_distributions.distributor_id = enterprises.id').
@@ -196,8 +177,17 @@ class Enterprise < ActiveRecord::Base
count(distinct: true)
end
def contact
contact = users.where(enterprise_roles: {receives_notifications: true}).first
contact || owner
end
def update_contact(user_id)
enterprise_roles.update_all(["receives_notifications=(user_id=?)", user_id])
end
def activated?
confirmed_at.present? && sells != 'unspecified'
contact.confirmed? && sells != 'unspecified'
end
def set_producer_property(property_name, property_value)
@@ -350,11 +340,6 @@ class Enterprise < ActiveRecord::Base
end
end
# Based on a devise method, but without adding errors
def pending_any_confirmation?
!confirmed? || pending_reconfirmation?
end
def shop_trial_expiry
shop_trial_start_date.andand + Spree::Config[:shop_trial_length_days].days
end
@@ -380,25 +365,6 @@ class Enterprise < ActiveRecord::Base
end
end
def email_is_known?
owner.enterprises.confirmed.map(&:email).include?(email)
end
def confirmation_check
# Skip confirmation/reconfirmation if the new email has already been confirmed
if email_is_known?
new_record? ? skip_confirmation! : skip_reconfirmation!
end
end
def welcome_after_confirm
# Send welcome email if we are confirming a newly created enterprise
# Note: this callback only runs on email confirmation
if confirmed? && unconfirmed_email.nil? && !unconfirmed_email_changed?
send_welcome_email
end
end
def send_welcome_email
Delayed::Job.enqueue WelcomeEnterpriseJob.new(self.id)
end
@@ -419,16 +385,16 @@ class Enterprise < ActiveRecord::Base
users << owner unless users.include?(owner) || owner.admin?
end
def ensure_email_set
self.email = owner.email if email.blank? && owner.present?
end
def enforce_ownership_limit
unless owner.can_own_more_enterprises?
errors.add(:owner, I18n.t(:enterprise_owner_error, email: owner.email, enterprise_limit: owner.enterprise_limit ))
end
end
def set_default_contact
update_contact self.owner_id
end
def relate_to_owners_enterprises
# When a new producer is created, it grants permissions to all pre-existing hubs
# When a new hub is created,

View File

@@ -38,7 +38,8 @@ class OrderCycle < ActiveRecord::Base
joins(:exchanges).
merge(Exchange.outgoing).
merge(Exchange.with_product(product)).
select('DISTINCT order_cycles.*') }
select('DISTINCT order_cycles.*')
}
scope :with_distributor, lambda { |distributor|
joins(:exchanges).merge(Exchange.outgoing).merge(Exchange.to_enterprise(distributor))

View File

@@ -1,5 +1,9 @@
require 'spree/localized_number'
module Spree
Adjustment.class_eval do
extend Spree::LocalizedNumber
# Deletion of metadata is handled in the database.
# So we don't need the option `dependent: :destroy` as long as
# AdjustmentMetadata has no destroy logic itself.
@@ -17,6 +21,8 @@ module Spree
attr_accessible :included_tax
localize_number :amount
def set_included_tax!(rate)
tax = amount - (amount / (1 + rate))
set_absolute_included_tax! tax
@@ -73,6 +79,5 @@ module Spree
result
end
end
end

View File

@@ -42,4 +42,7 @@ Spree::AppConfiguration.class_eval do
# Stripe Connect
preference :stripe_connect_enabled, :boolean, default: false
# Number localization
preference :enable_localized_number?, :boolean, default: false
end

View File

@@ -20,7 +20,8 @@ Spree::Calculator::DefaultTax.class_eval do
per_item_fees_total = order.line_items.sum do |line_item|
calculator.send(:per_item_enterprise_fee_applicators_for, line_item.variant)
.select { |applicator| (!applicator.enterprise_fee.inherits_tax_category && applicator.enterprise_fee.tax_category == rate.tax_category) ||
(applicator.enterprise_fee.inherits_tax_category && line_item.product.tax_category == rate.tax_category) }
(applicator.enterprise_fee.inherits_tax_category && line_item.product.tax_category == rate.tax_category)
}
.sum { |applicator| applicator.enterprise_fee.compute_amount(line_item) }
end

View File

@@ -1,5 +1,11 @@
require 'spree/localized_number'
module Spree
Calculator::FlatPercentItemTotal.class_eval do
extend Spree::LocalizedNumber
localize_number :preferred_flat_percent
def compute(object)
item_total = line_items_for(object).map(&:amount).sum
value = item_total * BigDecimal(self.preferred_flat_percent.to_s) / 100.0

View File

@@ -0,0 +1,9 @@
require 'spree/localized_number'
module Spree
Calculator::FlatRate.class_eval do
extend Spree::LocalizedNumber
localize_number :preferred_amount
end
end

View File

@@ -1,5 +1,12 @@
require 'spree/localized_number'
module Spree
Calculator::FlexiRate.class_eval do
extend Spree::LocalizedNumber
localize_number :preferred_first_item,
:preferred_additional_item
def compute(object)
sum = 0
max = self.preferred_max_items.to_i

View File

@@ -1,5 +1,11 @@
require 'spree/localized_number'
module Spree
Calculator::PerItem.class_eval do
extend Spree::LocalizedNumber
localize_number :preferred_amount
def compute(object=nil)
return 0 if object.nil?
self.preferred_amount * line_items_for(object).reduce(0) do |sum, value|

View File

@@ -0,0 +1,11 @@
require 'spree/localized_number'
module Spree
Calculator::PriceSack.class_eval do
extend Spree::LocalizedNumber
localize_number :preferred_minimal_amount,
:preferred_normal_amount,
:preferred_discount_amount
end
end

View File

@@ -1,11 +1,17 @@
require 'spree/localized_number'
module Spree
Payment.class_eval do
extend Spree::LocalizedNumber
has_one :adjustment, as: :source, dependent: :destroy
after_save :ensure_correct_adjustment, :update_order
attr_accessible :source
localize_number :amount
def ensure_correct_adjustment
revoke_adjustment_eligibility if ['failed', 'invalid'].include?(state)
return if adjustment.try(:finalized?)

View File

@@ -1,8 +1,6 @@
Spree::PaymentMethod.class_eval do
include Spree::Core::CalculatedAdjustments
Spree::PaymentMethod::DISPLAY = [:both, :front_end, :back_end]
acts_as_taggable
has_and_belongs_to_many :distributors, join_table: 'distributors_payment_methods', :class_name => 'Enterprise', association_foreign_key: 'distributor_id'

View File

@@ -16,7 +16,7 @@ module Spree
private
def product_selection_from_inventory_only_changed?
key =~ product_selection_from_inventory_only_regex
!!(key =~ product_selection_from_inventory_only_regex)
end
def enterprise

View File

@@ -97,12 +97,14 @@ Spree::Product.class_eval do
# Find products that are distributed by the given order cycle
scope :in_order_cycle, lambda { |order_cycle| with_order_cycles_inner.
merge(Exchange.outgoing).
where('order_cycles.id = ?', order_cycle) }
where('order_cycles.id = ?', order_cycle)
}
scope :in_an_active_order_cycle, lambda { with_order_cycles_inner.
merge(OrderCycle.active).
merge(Exchange.outgoing).
where('order_cycles.id IS NOT NULL') }
where('order_cycles.id IS NOT NULL')
}
scope :by_producer, joins(:supplier).order('enterprises.name')
scope :by_name, order('name')

View File

@@ -19,10 +19,16 @@ Spree.user_class.class_eval do
accepts_nested_attributes_for :ship_address
attr_accessible :enterprise_ids, :enterprise_roles_attributes, :enterprise_limit, :locale, :bill_address_attributes, :ship_address_attributes
after_create :send_signup_confirmation
validate :limit_owned_enterprises
# We use the same options as Spree and add :confirmable
devise :confirmable, reconfirmable: true
handle_asynchronously :send_confirmation_instructions
handle_asynchronously :send_on_create_confirmation_instructions
# TODO: Later versions of devise have a dedicated after_confirmation callback, so use that
after_update :welcome_after_confirm, if: lambda { confirmation_token_changed? && confirmation_token.nil? }
def known_users
if admin?
Spree::User.scoped
@@ -46,6 +52,14 @@ Spree.user_class.class_eval do
customers.find_by_enterprise_id(enterprise)
end
def welcome_after_confirm
# Send welcome email if we are confirming an user's email
# Note: this callback only runs on email confirmation
if confirmed? && unconfirmed_email.nil? && !unconfirmed_email_changed?
send_signup_confirmation
end
end
def send_signup_confirmation
Delayed::Job.enqueue ConfirmSignupJob.new(id)
end

View File

@@ -3,6 +3,7 @@ require 'open_food_network/variant_and_line_item_naming'
require 'open_food_network/products_cache'
Spree::Variant.class_eval do
extend Spree::LocalizedNumber
# Remove method From Spree, so method from the naming module is used instead
# This file may be double-loaded in delayed job environment, so we check before
# removing the Spree method to prevent error.
@@ -55,6 +56,8 @@ Spree::Variant.class_eval do
.where("o_inventory_items.id IS NULL OR o_inventory_items.visible = (?)", true)
}
localize_number :price, :cost_price, :weight
# Define sope as class method to allow chaining with other scopes filtering id.
# In Rails 3, merging two scopes on the same column will consider only the last scope.
def self.in_distributor(distributor)

View File

@@ -1,4 +1,6 @@
class VariantOverride < ActiveRecord::Base
extend Spree::LocalizedNumber
acts_as_taggable
belongs_to :hub, class_name: 'Enterprise'
@@ -17,6 +19,8 @@ class VariantOverride < ActiveRecord::Base
where(hub_id: hubs)
}
localize_number :price
def self.indexed(hub)
Hash[
for_hubs(hub).preload(:variant).map { |vo| [vo.variant, vo] }

View File

@@ -0,0 +1,7 @@
/ insert_after "fieldset.currency"
%fieldset.number_localization.no-border-bottom
%legend{:align => "center"}= t('admin.number_localization.number_localization_settings')
.field
= preference_field_tag(:enable_localized_number?, Spree::Config[:enable_localized_number?], type: Spree::Config.preference_type(:enable_localized_number?))
= label_tag(:enable_localized_number?, t('admin.number_localization.enable_localized_number')) + tag(:br)

View File

@@ -39,7 +39,7 @@
.alpha.three.columns
-# The 'Category' label here is just a logical descriptor for the data we are trying to collect for 'requires_ship_address'
-# and does not relate to shipping categories in any way.
= f.label :require_ship_address, "Category"
= f.label :require_ship_address, t(:category)
.two.columns
= f.radio_button :require_ship_address, true
&nbsp;

View File

@@ -11,3 +11,8 @@
.field{"data-hook" => "unit_description"}
= f.label :unit_description, t(:spree_admin_unit_description)
= f.text_field :unit_description, class: "fullwidth", placeholder: t('admin.products.unit_name_placeholder')
:javascript
angular.element(document.getElementById("new_variant")).ready(function() {
angular.bootstrap(document.getElementById("new_variant"), ['admin.products']);
});

View File

@@ -0,0 +1,5 @@
/ insert_before "#password-credentials"
- if @unconfirmed_email
%p.alert-box
= t('spree.users.show.unconfirmed_email', unconfirmed_email: @unconfirmed_email)

View File

@@ -1,9 +1,9 @@
class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category, :payment_method_ids, :shipping_method_ids
attributes :producer_profile_only, :email, :long_description, :permalink
attributes :producer_profile_only, :long_description, :permalink
attributes :preferred_shopfront_message, :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order
attributes :preferred_product_selection_from_inventory_only
attributes :owner, :users, :tag_groups, :default_tag_group
attributes :owner, :contact, :users, :tag_groups, :default_tag_group
attributes :require_login, :allow_guest_orders, :allow_order_changes
has_one :owner, serializer: Api::Admin::UserSerializer

View File

@@ -1,7 +1,7 @@
require 'open_food_network/last_used_address'
class Api::Admin::UserSerializer < ActiveModel::Serializer
attributes :id, :email
attributes :id, :email, :confirmed
has_one :ship_address, serializer: Api::AddressSerializer
has_one :bill_address, serializer: Api::AddressSerializer
@@ -15,4 +15,8 @@ class Api::Admin::UserSerializer < ActiveModel::Serializer
object.bill_address ||
OpenFoodNetwork::LastUsedAddress.new(object.email).last_used_bill_address
end
def confirmed
object.confirmed?
end
end

View File

@@ -1,6 +1,7 @@
class Api::VariantSerializer < ActiveModel::Serializer
attributes :id, :is_master, :count_on_hand, :name_to_display, :unit_to_display, :unit_value
attributes :options_text, :on_demand, :price, :fees, :price_with_fees, :product_name
attributes :tag_list
def price
object.price
@@ -22,4 +23,10 @@ class Api::VariantSerializer < ActiveModel::Serializer
def product_name
object.product.name
end
# Used for showing/hiding variants in shopfront based on tag rules
def tag_list
return [] unless object.respond_to?(:tag_list)
object.tag_list
end
end

View File

@@ -46,7 +46,7 @@
.row.margin-bottom-50{ ng: { show: "!RequestMonitor.loading && filteredCustomers.length > 0" } }
%form{ name: "customers_form" }
%save-bar{ dirty: "customers_form.$dirty", persist: "false" }
%input.red{ type: "button", value: "Save Changes", ng: { click: "submitAll(customers_form)", disabled: "!customers_form.$dirty" } }
%input.red{ type: "button", value: "Save Changes", ng: { click: "submitAll(customers_form)" } }
%table.index#customers
%col.email{ width: "20%", 'ng-show' => 'columns.email.visible' }

View File

@@ -46,9 +46,9 @@
.row
.alpha.three.columns
= f.label :contact, t('.contact_name')
= f.label :contact_name, t('.contact_name')
.omega.nine.columns
= f.text_field :contact, { placeholder: t('admin.enterprises.form.contact.name_placeholder')}
= f.text_field :contact_name, { placeholder: t('admin.enterprises.form.contact.name_placeholder')}
.row
.alpha.three.columns
= f.label :email_address, t('admin.enterprises.form.contact.email_address')

View File

@@ -1,11 +1,13 @@
.row
.alpha.three.columns
= f.label :contact, t('.name')
= f.label :contact_name, t('.name')
.omega.eight.columns
= f.text_field :contact, { placeholder: t('.name_placeholder') }
= f.text_field :contact_name, { placeholder: t('.name_placeholder') }
.row
.alpha.three.columns
= f.label :email_address, t('.email_address')
%div{'ofn-with-tip' => t('.email_address_tip')}
%a= t('admin.whats_this')
.omega.eight.columns
= f.text_field :email_address, { placeholder: t('.email_address_placeholder') }
.row

View File

@@ -1,13 +1,6 @@
- owner_email = @enterprise.andand.owner.andand.email || ""
- full_permissions = (spree_current_user.admin? || spree_current_user == @enterprise.andand.owner)
-if @enterprise.pending_any_confirmation?
.alert-box
- email = @enterprise.confirmed? ? @enterprise.unconfirmed_email : @enterprise.email
= t('.email_confirmation_notice_html', {email: "<strong>#{email}</strong>".html_safe})
= link_to(t('.resend'), main_app.enterprise_confirmation_path(enterprise: { id: @enterprise.id, email: email } ), method: :post)
%a.close{ href: "#" } ×
.row
.three.columns.alpha
=f.label :owner_id, t('.owner')
@@ -17,27 +10,24 @@
%a= t('admin.whats_this')
.eight.columns.omega
- if full_permissions
= f.hidden_field :owner_id, class: "select2 fullwidth", 'user-select' => 'Enterprise.owner'
= f.hidden_field :owner_id, class: "select2 fullwidth", 'user-select' => 'Enterprise.owner', 'ng-model' => 'Enterprise.owner'
- else
= owner_email
.row
.three.columns.alpha
= f.label :email, t('.notifications')
=f.label :user_ids, t('.notifications')
- if full_permissions
%span.required *
.with-tip{'data-powertip' => t('.notifications_tip')}
%div{'ofn-with-tip' => t('.contact_tip')}
%a= t('admin.whats_this')
.eight.columns.omega
- if full_permissions
= f.text_field :email, { placeholder: t('.notifications_placeholder'), "ng-model" => "Enterprise.email" }
%select.select2.fullwidth{id: 'receives_notifications_dropdown', name: 'receives_notifications', ng: {model: 'receivesNotifications', init: "receivesNotifications = '#{@enterprise.contact.id}'"}}
%option{ng: {repeat: 'user in Enterprise.users', selected: "user.id == #{@enterprise.contact.id}", hide: '!user.confirmed'}, value: '{{user.id}}'}
{{user.email}}
- else
= @enterprise.email
.row{ ng: { hide: "pristineEmail == null || pristineEmail == Enterprise.email"} }
.alpha.three.columns
&nbsp;
.omega.eight.columns
= t('.notifications_note')
= @enterprise.contact.email
.row
.three.columns.alpha
@@ -48,19 +38,24 @@
%a= t('admin.whats_this')
.eight.columns.omega
- if full_permissions
%table
%table.managers
%tr
%td
- # Ignore this input in the submit
= hidden_field_tag :ignored, :new_manager, class: "select2 fullwidth", 'user-select' => 'newManager', 'ng-model' => 'newManager'
%td.actions
%a{ 'ng-click' => 'addManager(newManager)', :class => "icon-plus no-text" }
%tr.animate-repeat{ ng: { repeat: 'manager in Enterprise.users' }}
%tr.animate-repeat{ id: "manager-{{manager.id}}", ng: { repeat: 'manager in Enterprise.users' }}
%td
= hidden_field_tag "enterprise[user_ids][]", nil, multiple: true, 'ng-value' => 'manager.id'
{{ manager.email }}
%i.confirmation.confirmed.fa.fa-check-circle{ 'ofn-with-tip' => t('.email_confirmed'), ng: {show: 'manager.confirmed'} }
%i.confirmation.unconfirmed.fa.fa-exclamation-triangle{ 'ofn-with-tip' => t('.email_not_confirmed'), ng: {show: '!manager.confirmed'} }
%i.role.contact.fa.fa-envelope-o{ 'ofn-with-tip' => t('.contact'), ng: {show: 'manager.id == receivesNotifications'} }
%i.role.owner.fa.fa-star{ 'ofn-with-tip' => t('.owner'), ng: {show: 'manager.id == Enterprise.owner.id'} }
%td.actions
%a{ 'ng-click' => 'removeManager(manager)', :class => "icon-trash no-text" }
%a{ ng: {click: 'removeManager(manager)', class: "{disabled: manager.id == Enterprise.owner.id || manager.id == receivesNotifications}"}, :class => "icon-trash no-text" }
- else
- @enterprise.users.each do |manager|
= manager.email

View File

@@ -14,7 +14,7 @@
= render 'checkout/accordion_heading'
.small-12.columns.medium-12.columns.large-6.columns
%label{"ng-repeat" => "method in ShippingMethods.shipping_methods"}
%label{"ng-repeat" => "method in ShippingMethods.shipping_methods | orderBy: 'name'"}
%input{type: :radio,
required: true,
name: "order.shipping_method_id",

View File

@@ -1,19 +0,0 @@
%h3
= t :email_confirmation_greeting, contact: @enterprise.contact
%p.lead
= t :email_confirmation_profile_created, name: @enterprise.name
%p &nbsp;
%p.callout
= t :email_confirmation_click_link
%br
%strong
= link_to t(:email_confirmation_link_label), confirmation_url(@enterprise, :confirmation_token => @enterprise.confirmation_token)
%p &nbsp;
%p
= t :email_confirmation_help_html, link: link_to(t(:email_confirmation_userguide), 'http://www.openfoodnetwork.org/platform/user-guide/'), sitename: Spree::Config[:site_name]
= render 'shared/mailers/signoff'
= render 'shared/mailers/social_and_contact'

View File

@@ -1,7 +1,6 @@
%h3
= "#{t(:email_welcome)}, #{@enterprise.contact}!"
= "#{t(:email_welcome)}!"
%p.lead
= t :email_confirmed
%strong
= @enterprise.name
= "#{t(:email_registered)} #{ Spree::Config.site_name }!"
@@ -13,7 +12,7 @@
= t :email_admin_html, link: link_to('Admin Panel', spree.admin_url)
%p
= t :email_community_html, link: link_to(t(:join_the_community), ContentConfig.community_forum_url)
= t :email_community_html, link: link_to(t(:join_community), ContentConfig.community_forum_url)
%p
= t :email_help

View File

@@ -1,4 +1,5 @@
%script
:javascript
I18n.default_locale = "#{I18n.default_locale}";
I18n.locale = "#{I18n.locale}";
I18n.fallbacks = true;
moment.lang([I18n.locale, 'en']);

Some files were not shown because too many files have changed in this diff Show More