Compare commits

...

450 Commits
v1.2 ... v1.3.0

Author SHA1 Message Date
Maikel Linke
61a58bca7d Travis can trigger the Github deploy API
And other build tools like Buildkite can listen to the deploy event.
2015-12-18 10:41:25 +11:00
Rob Harrington
e67e22ee73 Merge remote-tracking branch 'Em-AK/682-xero-report-defaults' into customer-name-security
Conflicts:
	lib/open_food_network/xero_invoices_report.rb
2015-12-17 14:22:16 +11:00
Rob Harrington
7a23f671a2 Restricting access to orders within Sales Tax Report
Managers of suppliers should not be able to generate sales tax reports for orders they only supply products for
2015-12-17 14:21:30 +11:00
Rob Harrington
d115eb816e Restricting access to orders within Xero Invoices Report
Managers of suppliers should not be able to generate xero invoices for orders they supply products for
2015-12-17 14:21:30 +11:00
Rob Harrington
4b5e33d5b0 Implementing new permissions for producers in reports_controller_spec 2015-12-17 14:21:30 +11:00
Rob Harrington
c579d302d5 Fixing customer info security for orders and distributors report 2015-12-17 14:21:30 +11:00
Rob Harrington
2f2ebf419c Fixing customer info security for packing reports 2015-12-17 14:21:30 +11:00
Rob Harrington
2f13ab6adf Fixing customer info security for orders and fulfillments report 2015-12-17 14:21:29 +11:00
Rob Harrington
b121984e76 Fixing customer info security for bulk coop report 2015-12-17 14:21:29 +11:00
Continuous Integration
23b9dd5c71 Auto-merge from CI [skip ci] 2015-12-17 13:02:37 +11:00
Maikel Linke
bc6110c178 Re-defining in_distributor scope as method to allow chaining 2015-12-17 12:42:28 +11:00
Rob Harrington
72f7e545dc Making sure bill > 0 for finalize account invoice spec 2015-12-17 12:04:24 +11:00
Rob Harrington
e0da49e4df Formatting dates for account invoices in rails time zone 2015-12-17 11:34:06 +11:00
Rob Harrington
b004060679 Printing invoices doesn't fail when order has no order cycle 2015-12-17 11:33:18 +11:00
Maikel Linke
ea68619f0b Use bundled rails to prepare imported database 2015-12-17 10:31:31 +11:00
Rob Harrington
555f639026 Fixing unstable update_account_invoice specs
Rounding first then summing != summing first then rounding
2015-12-17 09:16:19 +11:00
Rob Harrington
26a2f1a280 Adjustments on account invoices are created based on presence of a bill
Rather than of turnover
2015-12-16 23:10:47 +11:00
Rob Harrington
83e3fb98f7 Only display billable period adjustments where the amount in > 0
Rather than where the bill (which is calculated according to current settings) is > 0
2015-12-16 19:18:59 +11:00
Rob Harrington
bac4fcbd8f Make sure that adjustments for billable periods have a valid order to attach to when creating/updating 2015-12-16 19:18:59 +11:00
Rob Harrington
ecd11702c3 Fixing up enterprise user account page 2015-12-16 19:18:59 +11:00
Rob Harrington
fe0652e243 When updating a line_item quantity from 0, final_weight_volume is recalculated from the variants unit value 2015-12-16 19:18:59 +11:00
Rob Harrington
f49722ba90 Fixing broken BMC specs 2015-12-16 19:18:58 +11:00
Rob Harrington
0370723edd Attempt to add a sensible name and contact number to Account Invoice addresses 2015-12-16 19:18:58 +11:00
Rob Harrington
d46712de84 Obsolete BillablePeriods only deleted if their associated order is not already complete 2015-12-16 19:18:58 +11:00
Rob Harrington
199a3c38f9 Bill is capped before tax is applied, like we say it is 2015-12-16 19:18:58 +11:00
Rob Harrington
0ed8cf973d Adding an example bill calculator to business model config edit page
To allow super admin to see the effects of any changes they make to BMC settings
2015-12-16 19:18:58 +11:00
Rob Harrington
76d4f74f6b Ammending BillablePeriod spec to be ensure tax is charged correctly 2015-12-16 19:18:58 +11:00
Rob Harrington
ca3c464fda Reorganising busines model config settings, moving account invoice tax rate in busines model config settings 2015-12-16 19:18:57 +11:00
Rob Harrington
85f61364f8 BillablePeriods use global config to calculate bills 2015-12-16 19:18:57 +11:00
Rob Harrington
c1d04af5cc Implementing monthly billing description logic in required pages 2015-12-16 19:18:57 +11:00
Rob Harrington
5b72f53738 Adding helper for describing monthly billing charges 2015-12-16 19:18:57 +11:00
Rob Harrington
da325780b1 Adding BMC link to configurations menu 2015-12-16 19:18:57 +11:00
Rob Harrington
a40a03905f Reorganising BMC edit view 2015-12-16 19:18:57 +11:00
Rob Harrington
044e423543 Adding update logic to business model config controller 2015-12-16 19:18:57 +11:00
Rob Harrington
cb9b61f393 WIP: Adding an edit view for BMC variables 2015-12-16 19:18:56 +11:00
Rob Harrington
58031408f1 Adding basic business model configuration variables to app config 2015-12-16 19:18:56 +11:00
Rob Harrington
e20b06bb97 Adding basic route and controller for business model configuration 2015-12-16 19:18:56 +11:00
Rob Harrington
cc4f9dd09b Making lettuceshare report spec more robust 2015-12-16 18:14:19 +11:00
Rob Harrington
18ea0c1717 Pulling VariantOverride scoping down into products and inventory report base 2015-12-16 14:23:43 +11:00
Rob Harrington
2bb85eb8e0 Revert "Add SKU to LettuceShare report"
This reverts commit 15ea64b409.
2015-12-16 13:42:58 +11:00
Rob Harrington
5d28a7fdf8 Adding SKU to Products and Inventory reports (except lettuceshare) 2015-12-16 13:37:19 +11:00
Rob Harrington
befc558224 Pulling product_and_variant_name down into VariantAndLineItemNaming, renaming to product_and_full_name
Also allowing this method to be used in reports (Xero), to reflect appropriate name for weight/volume adjusted line items
2015-12-16 11:55:24 +11:00
Rob Harrington
c91f1301f0 Adding preferences to enterprises for sorting of order cycles in shopfront list 2015-12-16 11:55:23 +11:00
Rob Harrington
e6a51bb49d Adding actions dropdown to admin order view/pages 2015-12-16 11:55:23 +11:00
Rob Harrington
ae0ad73b4a Printable Invoices Improvements for Food Connect
Adding cusotmer instructions, hiding tax column when not present, order cycle name appears at top of invoice and items are sorted by product name
2015-12-16 11:55:23 +11:00
Continuous Integration
b7edf5e046 Auto-merge from CI [skip ci] 2015-12-16 10:58:03 +11:00
Em-AK
81f244025f Update due_date in feature test
due_date = invoice_date + 1 month
2015-12-13 18:42:27 +01:00
Em-AK
fcc328f00a Display default xero invoice dates
fixes #682

* pre-fill the invoice_date and due_date in the xero report generation form
* increase the default period between invoice_date and due_date to 1 month in
XeroInvoiceReport
2015-12-13 16:42:32 +01:00
Maikel Linke
758b1f8e64 using in_stock? to filter variants in lettuceshare report 2015-12-11 15:12:28 +11:00
Maikel Linke
bb58473b90 Consider variant overrides in LettuceShare report 2015-12-11 15:12:28 +11:00
Maikel Linke
1d46c2febd LettuceShare report: display only if count_on_hand > 0
Use the inventory of a distributor if selected.
2015-12-11 15:12:27 +11:00
Maikel Linke
15ea64b409 Add SKU to LettuceShare report 2015-12-11 15:12:27 +11:00
Maikel Linke
6787709693 LettuceShare report: total in unit value column and total blank 2015-12-11 15:12:27 +11:00
Rohan Mitchell
a3874d42af Spec moved to OpenFoodNetwork::LastUsedAddress 2015-12-11 13:25:40 +11:00
Rohan Mitchell
3f8d470d23 When admin associates user with an order, look up last used address 2015-12-11 13:06:59 +11:00
Rohan Mitchell
ae3061df80 All orders specs use JS 2015-12-11 13:06:59 +11:00
Rohan Mitchell
5579fa5e0b Extract last used address finding into service object 2015-12-11 13:06:59 +11:00
Rohan Mitchell
e33ede0ec2 Include order cycle status in new order form 2015-12-11 13:06:58 +11:00
Rohan Mitchell
76d4fbccf9 Use select2 for order cycle selection 2015-12-11 13:06:58 +11:00
Rohan Mitchell
60e971ad63 Take variant overrides into account for price when admin adds line item to order 2015-12-11 13:06:57 +11:00
Rohan Mitchell
222b390b31 Fix error display 2015-12-11 13:06:57 +11:00
Rohan Mitchell
932ac45ea5 Do not show form until distribution has been chosen 2015-12-11 13:06:57 +11:00
Rohan Mitchell
80ebaece2d Sort distribution choices by name 2015-12-11 13:06:57 +11:00
Rohan Mitchell
3419198635 Disable distributors that do not have an order cycle 2015-12-11 13:06:57 +11:00
Rohan Mitchell
1026b81d0c Do not show order cycle choice until distributor is chosen 2015-12-11 13:06:57 +11:00
Rohan Mitchell
c74463404d Only show order cycle options that include the chosen distributor 2015-12-11 13:06:57 +11:00
Rohan Mitchell
2081744cf6 Fix spec 2015-12-11 13:06:57 +11:00
Rohan Mitchell
cbaf2a0cb3 Angularise edit order form 2015-12-11 13:06:57 +11:00
Rohan Mitchell
6e7b6b5dfc Tidy render partial calls and hash syntax 2015-12-11 13:06:57 +11:00
Rohan Mitchell
815694de31 Move orders/edit template from Spree 2015-12-11 13:06:57 +11:00
Rohan Mitchell
2daceb1111 Angularise new order form 2015-12-11 13:06:57 +11:00
Rohan Mitchell
eb07680f1f Inject shops and order cycles 2015-12-11 13:06:57 +11:00
Rohan Mitchell
47c23c986a Move distribution fields from override to partial 2015-12-11 13:06:56 +11:00
Rohan Mitchell
742e2279ae Tidy render partial calls 2015-12-11 13:06:56 +11:00
Rohan Mitchell
eaae16a486 Copy orders/new template from Spree 2015-12-11 13:06:56 +11:00
Continuous Integration
ae945ace9d Auto-merge from CI [skip ci] 2015-12-11 11:09:54 +11:00
Rohan Mitchell
9d5606a4fd Fix enterprise index page 500 2015-12-11 10:06:07 +11:00
Maikel Linke
cd7721a127 Using date and time of current timezone
Using Time.zone.now and Date.current instead of Time.now and Date.today.
This should make all specs timezone independent.
2015-12-10 11:38:41 +11:00
Rohan Mitchell
ee447c9ce6 Move blankOption service to admin.utils module 2015-12-10 09:35:27 +11:00
Rohan Mitchell
eba2aae353 Copy StatusMessage to admin.utils module, eventually to be moved here 2015-12-10 09:32:04 +11:00
Rohan Mitchell
c1a80b1e8f Require confirmation when saving an order cycle without distributors 2015-12-10 09:17:25 +11:00
Rohan Mitchell
6998df25e0 Fix indentation 2015-12-10 09:17:25 +11:00
Rohan Mitchell
921210012a Swap in StatusMessage service for custom message display in order cycles interface 2015-12-10 09:17:25 +11:00
Rohan Mitchell
8d270e919f Sort exchanges for display when editing an order cycle 2015-12-10 09:17:25 +11:00
Rohan Mitchell
1e397a41ae Refactor to simplify outgoing_exchange_variant_ids 2015-12-10 09:17:25 +11:00
Rohan Mitchell
243ef4ee16 When an outgoing exchange includes a variant that is not in an incoming exchange, remove it from the outgoing exchange 2015-12-10 09:17:25 +11:00
Rohan Mitchell
ea6974d438 Add OrderCycle#supplied_variants 2015-12-10 09:17:25 +11:00
Rohan Mitchell
ccb23cd186 Do not allow re-adding exchange 2015-12-10 09:17:25 +11:00
Rohan Mitchell
d4ee20455e Remove enterprise options from list when added 2015-12-10 09:17:25 +11:00
Rohan Mitchell
ef603a070e Add methods to check for novel suppliers and distributors in an order cycle 2015-12-10 09:17:25 +11:00
Rohan Mitchell
1a4448c6d2 Do not allow adding blank enterprises 2015-12-10 09:17:25 +11:00
Rohan Mitchell
a78d8fa6af Build exchange form on front-end 2015-12-10 09:17:25 +11:00
Rohan Mitchell
8c0a82f26f Provide issues summary for enterprises, pass enterprises through to controller 2015-12-10 09:17:25 +11:00
Rohan Mitchell
93c42d24c7 Extract issue detection into service object 2015-12-10 09:17:25 +11:00
Rohan Mitchell
036ffeb634 Enterprise service splits enterprises into hubs and producers 2015-12-10 09:17:25 +11:00
Rohan Mitchell
3dcbdad088 Show/hide all products 2015-12-10 09:17:25 +11:00
Rohan Mitchell
7820c31976 Show supplier as secondary in information hierarchy 2015-12-10 09:17:25 +11:00
Rohan Mitchell
d314f07887 Use flexbox to more neatly lay out order cycle products 2015-12-10 09:17:25 +11:00
Rohan Mitchell
2efaedc225 Add .exchange-products container div, fill full row with products 2015-12-10 09:17:25 +11:00
Rohan Mitchell
c5e2ed5aa1 Order outgoing products by name 2015-12-10 09:17:24 +11:00
Rohan Mitchell
8f917817b8 Fix broken styles 2015-12-10 09:17:24 +11:00
Rohan Mitchell
a2c0088c91 Do not show flash message if we're performing an async update without reload 2015-12-10 09:17:24 +11:00
Rohan Mitchell
9fef0a9909 When order cycle is updated, display message instead of reloading the page 2015-12-10 09:17:24 +11:00
Rohan Mitchell
29bfac5f54 Order cycle interface may update or update and close 2015-12-10 09:17:24 +11:00
Maikel Linke
efa7c215e2 Removing usage of SimpleCov 2015-12-04 14:51:44 +11:00
Maikel Linke
1589bd9ac3 Use mail() instead of devise_mail
The EnterpriseMailer used `devise_mail` to send confirmation
instructions. That call is more complicated than `mail` and added an
unwanted reply-to header.
2015-12-04 10:37:55 +11:00
Maikel Linke
a810a6e2b7 fix succeed_if_master_merged 2015-12-04 10:37:55 +11:00
Maikel Linke
c4fb4a8510 Removing Suburbs from the code
Suburbs are not used any more. Removing the last code bits should avoid
confusion and save a tiny bit of test time.
2015-12-04 10:37:55 +11:00
Maikel Linke
d67a5aba0e Remove script/delayed_job.sh
This version was dependent on the Australian environment. It is better
to call delayed_job directly from monit. The deployment repository has
been updated.
2015-12-04 10:37:55 +11:00
Maikel Linke
d5c4da3bf0 Not using Paperclip's to avoid HTTP calls to S3 2015-12-04 10:37:55 +11:00
Maikel Linke
261a464b50 Fixing display of shop list in group producer modal 2015-12-04 10:37:55 +11:00
Maikel Linke
0f2ae79e05 Fixing "Shop for" label on groups producer modal 2015-12-04 10:37:55 +11:00
Maikel Linke
caffdee047 Removing depricated sensor parameter for Google Maps 2015-12-04 10:37:55 +11:00
Rohan Mitchell
d320b2e7d4 Merge branch 'fix-delayed-job' into combined/producer-emails-simplify_fix-delayed-job 2015-12-02 15:06:38 +11:00
Rohan Mitchell
e8ccd35363 Simplify producer email to make it more generic 2015-12-02 15:05:49 +11:00
Rohan Mitchell
bd854bf2dd Remove receival_time from exchange, just use receival_instructions 2015-12-02 15:05:49 +11:00
Rohan Mitchell
10edb2b056 Fix delayed job startup - prevent error caused by double load 2015-12-02 10:48:50 +11:00
Rob H
86f1afae92 derp 2015-11-29 18:10:49 +11:00
Rob H
1cffd35968 Fixing up specs pertaining to full_name generation for line_items 2015-11-29 17:52:01 +11:00
Rob H
baeacfb8a9 LineItem inherits display_name from variant
Allows line_items to be named correctly.
2015-11-29 17:25:28 +11:00
Rob Harrington
7ecf5df26a Updating line items through admin controller causes enterprise fees to be recalculated 2015-11-27 15:06:49 +11:00
Rob Harrington
a5a886c51f Only test for coordination when orders actually have order_cycles 2015-11-25 15:27:27 +11:00
Rob Harrington
96aace971f Merge remote-tracking branch 'origin/master' into line_item_naming 2015-11-25 15:13:56 +11:00
Rob Harrington
6c254c534f Upgrade fog to resolve 'Digest::Digest is deprecated; use Digest' warning 2015-11-25 15:13:25 +11:00
Rob Harrington
b341c1ef8a Ensure that dates in BOM AJAX requests have timezones 2015-11-25 15:06:15 +11:00
Rob Harrington
7e6b43266f Making sure that price and final_weight_volume can be updated (by distributor or coordinator) 2015-11-25 14:23:55 +11:00
Maikel
3975eef0c4 Merge pull request #716 from openfoodfoundation/uk/i18n
#715: Add missing strings for en-GB locale.
2015-11-24 18:36:32 +11:00
Paul Mackay
a2a87cc68f #715: Add missing strings for en-GB locale. 2015-11-23 16:44:39 +00:00
Rob Harrington
4bdc1bc418 LineItem final_weight_volume is updated whenever quantity is changed, though can be set directly 2015-11-18 16:22:36 +11:00
Rob Harrington
33454a7090 Adding server validation errors messages to BOM interface 2015-11-18 14:32:29 +11:00
Rob Harrington
6268b7cc7e Printing/sending an invoice uses the same template for generating a pdf 2015-11-18 10:02:51 +11:00
Rob Harrington
75846a4d1f Merge branch 'master' into line_item_naming 2015-11-16 10:38:42 +11:00
Rob Harrington
c199e22190 Make a few BOM specs more robust 2015-11-16 10:31:41 +11:00
Rob Harrington
3b2bdb8397 Change the way changes to underlying model are watched and updated for select2 elements 2015-11-16 10:31:22 +11:00
Rob Harrington
767671c3b4 New pattern: blank Options for index drop down filters are added within service
Rather than in the controller after data is loaded
2015-11-16 10:30:44 +11:00
Rob Harrington
76414dedff Bumping coffee-script version 2015-11-16 10:27:32 +11:00
Rob Harrington
ae7fb91a9a Only reloading line_items and orders on BOM, $timeout for adding blankOption
$timeout required for adding a blank option to lists of suppliers,
distributors and orderCycles to prevent spec failures related to the
use of select2
2015-11-13 15:59:33 +11:00
Maikel Linke
229070a76b Merge branch 'master' of github.com:openfoodfoundation/openfoodnetwork into i18n 2015-11-13 15:20:58 +11:00
Maikel Linke
8bfe459241 i18n fixes of html display 2015-11-13 14:22:17 +11:00
Rohan Mitchell
bb6fb2f5e8 Merge branch 'sell-food-link' into combined/add-to-cart-speed_and_sell-food-link 2015-11-13 14:03:32 +11:00
Rohan Mitchell
6de44877c8 Update link for uber-style sell food dropdown 2015-11-13 14:03:14 +11:00
Rohan Mitchell
b6f3e6eca6 Fix broken spec 2015-11-13 14:03:07 +11:00
Rohan Mitchell
a86cc96452 Use pluck instead of map 2015-11-13 14:03:07 +11:00
Rohan Mitchell
178e5f59e6 Update cart by applying differences rather than clear-and-readd every time 2015-11-13 14:03:07 +11:00
Rohan Mitchell
7fffa03d8d Fix bug: set difference comparison of string with number 2015-11-13 14:03:07 +11:00
Rohan Mitchell
888e4d80ef Add reliable way to check if cart is dirty. Previous way returned true when cart empty. 2015-11-13 14:03:07 +11:00
Rohan Mitchell
d3c7c46800 Add method to remove a variant from an order 2015-11-13 14:03:07 +11:00
Rohan Mitchell
c432ed9e08 Build list of variants removed from the cart when overwriting 2015-11-13 14:03:07 +11:00
Rohan Mitchell
e175149e76 Add method to check whether a passed-in cart value varies from the cart 2015-11-13 14:03:07 +11:00
Rohan Mitchell
1b5901317d Separate concerns: reading products hash and adding items to cart 2015-11-13 14:03:07 +11:00
Rohan Mitchell
2f4b5bad26 Make benchmark more realistic 2015-11-13 14:03:07 +11:00
Rohan Mitchell
64e8927ae9 Add benchmark: add to cart 2015-11-13 14:03:07 +11:00
Rohan Mitchell
c932d20ef5 Extract multi-sample benchmarking into a helper method 2015-11-13 14:03:07 +11:00
Maikel Linke
5d5fda3a25 Merge remote-tracking branch 'origin/master' into i18n
Conflicts:
	config/locales/en.yml
2015-11-13 10:07:29 +11:00
Rob Harrington
a96cdd5ee7 Merge branch 'master' into line_item_naming
Conflicts:
	app/views/admin/order_cycles/edit.html.haml
2015-11-13 09:54:26 +11:00
Rob Harrington
4191e2b6f0 Changing the way select filters are reset on BOM to try and fix specs 2015-11-13 09:44:57 +11:00
Rob Harrington
88fd9f72e6 Retry uncooperative BOM feature spec 2015-11-13 09:14:20 +11:00
Rob Harrington
3d36ebe2e6 Some Ransack trickery to get OrderCycles#index to load only recent OR undated OCs when no orders_close_at predicate is passed in 2015-11-12 18:29:19 +11:00
Rob Harrington
6966fbba7c Present date limits being set in line items controller .js unless orderCycleFilter has actually been set 2015-11-12 17:40:35 +11:00
Rob Harrington
2310bc95bc Committing changes to version used to bundle Gemfile.lock 2015-11-12 17:34:22 +11:00
Rob Harrington
27a5791e26 Fixing Angular Specs for line items controller 2015-11-12 17:33:12 +11:00
Rob Harrington
be8038e9d0 Merge branch 'master' into line_item_naming
Conflicts:
	lib/open_food_network/order_cycle_management_report.rb
	lib/open_food_network/packing_report.rb
2015-11-12 14:40:11 +11:00
Rob Harrington
1556d38b1e Admin Enterprise#update.json renders updated enterprises using index serializer 2015-11-12 14:30:43 +11:00
Rob Harrington
4e4de65cba Fetch undated order cycles by default for index actions 2015-11-12 12:08:39 +11:00
Rob Harrington
6e8d807408 Fixing spec using text-angular broken by upgrade of poltergeist 2015-11-12 11:35:22 +11:00
Rob Harrington
095466cb43 Fixing syntax error for new method for OCs controller 2015-11-12 10:34:09 +11:00
Rob Harrington
2719c699d7 Updating line items index spec 2015-11-12 10:06:41 +11:00
Rob Harrington
34030276d7 Cleaning up line items index (BOM) 2015-11-12 10:06:21 +11:00
Rob Harrington
330977186e Using confirm-change and select2-min-search directive for line items index 2015-11-12 10:05:14 +11:00
Rob Harrington
fc57255b40 Adding save-bar to line items index 2015-11-12 10:04:18 +11:00
Rob Harrington
266820742d Using request monitor on line items index (BOM) 2015-11-12 10:03:28 +11:00
Rob Harrington
722471a111 Allow use of completed_at for orders index ransacking
Needed to override original Spree method to allow intuitive use of
completed_at_gt and completed_at_lt
2015-11-12 10:01:35 +11:00
Rob Harrington
86b5e810e5 Only try to dereference attrs when enough information is present 2015-11-12 09:59:46 +11:00
Rob Harrington
f8a31e8864 Resetting select filters in a way that actually works 2015-11-12 09:58:55 +11:00
Rob Harrington
639472b917 WIP: Adding a request monitoring service to handle loading status 2015-11-12 09:57:02 +11:00
Rob Harrington
193325f81b Improve formatting around saving on line items index (BOM) 2015-11-12 09:52:10 +11:00
Rob Harrington
5a7cac652c Adding confirm-link directive 2015-11-12 09:49:36 +11:00
Rob Harrington
b5aaf36bd2 Create directive for scaling by a factor and then formatting as currency 2015-11-12 09:48:43 +11:00
Rob Harrington
c5a26249ea Removing unneeded directives 2015-11-12 09:47:37 +11:00
Rob Harrington
69ead3c829 Line items serialiser gives a sensible value for max_quantity 2015-11-12 09:47:12 +11:00
Rob Harrington
93caa4a11d Bumping poltergeist version to 1.7.0 2015-11-12 09:45:14 +11:00
Rohan Mitchell
e20d8d3e95 Merge branch 'master' into folklabs-producer-emails 2015-11-11 14:20:25 +11:00
Rohan Mitchell
fb3e292e20 Formatting 2015-11-11 11:53:04 +11:00
Rohan Mitchell
f499dd627a with_tax_included_in_price handles exceptions gracefully 2015-11-11 11:53:04 +11:00
Rohan Mitchell
8e1bade355 Move adjustment specs to their own spec file 2015-11-11 11:53:04 +11:00
Rohan Mitchell
a32321df68 Clarify label 2015-11-11 11:53:04 +11:00
Rohan Mitchell
5a29311137 Choose a more sensible default tax rate: one that calculates to the same amount as the current adjustment tax 2015-11-11 11:53:04 +11:00
Rohan Mitchell
3e7a12cca1 Rename spec support method for faster tab completion on save_and_open_page 2015-11-11 11:53:04 +11:00
Rohan Mitchell
81a6e07d5c Admin can remove tax on an adjustment 2015-11-11 11:53:04 +11:00
Rohan Mitchell
727ecae62b Admin can modify a taxed adjustment on an order 2015-11-11 11:53:04 +11:00
Rohan Mitchell
85e45fa558 Use select2 2015-11-11 11:53:04 +11:00
Rohan Mitchell
83c0093665 Admin can include tax when creating an adjustment 2015-11-11 11:53:04 +11:00
Rohan Mitchell
46a9304ae1 Extract compute_tax from EnterpriseFeeApplicator to Spree::TaxRate model 2015-11-11 11:53:04 +11:00
Rohan Mitchell
d794981ecf Add form field to set tax when creating adjustment on order. Display tax included in adjustments on order interface. 2015-11-11 11:53:04 +11:00
Rohan Mitchell
6476ce6ba9 Make spec more resilient 2015-11-10 15:05:45 +11:00
Maikel Linke
a06b452e7e updated norwegian locale 2015-11-07 16:42:35 +11:00
Maikel Linke
0b6cbb43d6 updated locale nb.yml 2015-11-06 11:56:25 +11:00
Rob Harrington
27903a46e6 Adding new save-bar directive for handling save actions for index pages 2015-11-06 09:53:31 +11:00
Rob Harrington
330882c689 Pulling out styling for red buttons in admin into more generic .red class 2015-11-06 09:52:48 +11:00
Rob Harrington
b1bac703ed WIP: BOM Refactor, delete line_items using ngResource, updating data requests in line_items_controller 2015-11-05 17:50:18 +11:00
Rob Harrington
bf6bd2dc68 Hack down routes available for Admin::LineItemsController 2015-11-05 17:18:32 +11:00
Rob Harrington
eb7b2e7a3b Use ams_prefix not ams_suffix! 2015-11-05 17:17:45 +11:00
Rob Harrington
73c80cb5e5 Ordering index orders within query 2015-11-05 17:11:13 +11:00
Rob Harrington
6769c2c729 Can pass params for order or line items into LineItemsController#index 2015-11-05 17:07:47 +11:00
Rob Harrington
afef9e3211 WIP: BOM Refactor, building order_cycle fetch and update logic with ngResource 2015-11-05 15:13:19 +11:00
Rob Harrington
a9e5f2912f WIP: Fixing Orders service specs 2015-11-05 14:48:26 +11:00
Rob Harrington
66d1e4297e WIP: Renaming admin.order_cycles to admin.orderCycles for consistency 2015-11-05 14:40:42 +11:00
Maikel Linke
5e59048705 i18n typo 2015-11-05 14:39:33 +11:00
Rob Harrington
4d4e2d4abd WIP: Moving order_cycle controller into order_cycles folder 2015-11-05 14:38:01 +11:00
Rob Harrington
db4e8382e4 Oops, updating template to make order filtering work 2015-11-05 14:05:14 +11:00
Rob Harrington
51762753f4 WIP: BOM Refactor, adding json route for OrderCyclesController#index, loading OCs based on show_more or specific order_close_at_gt 2015-11-05 14:04:29 +11:00
Rob Harrington
2483eef4be WIP: BOM Refactor, removing obsolete OrderCycle.recently_closed scope, ordering closed OCs 2015-11-05 14:02:04 +11:00
Maikel Linke
38d2616ea0 No need to empty cache if I18n asset depends on locale 2015-11-05 12:50:11 +11:00
Rohan Mitchell
5db64b6f21 Update travis config and README with new ruby version 2015-11-05 12:48:22 +11:00
Maikel Linke
0505a45de5 Invalidate I18n asset if locale changes 2015-11-05 12:47:15 +11:00
Rob Harrington
e96fa967b8 WIP: BOM refactor, rebuilding bulk orders controller as line items controller using new AJAX routes 2015-11-05 11:54:36 +11:00
Maikel Linke
8b29612614 Merge remote-tracking branch 'origin/master' into i18n 2015-11-05 11:54:06 +11:00
Maikel Linke
90d52151b6 Updated fr.yml 2015-11-05 11:53:38 +11:00
Rohan Mitchell
6666de96b2 Update ruby version used in CI 2015-11-05 11:24:12 +11:00
Rob Harrington
b7d92786d0 Bumping ruby version to 2.1.5 2015-11-05 11:09:22 +11:00
Rob Harrington
d731d4e803 Making sure flash is a hash so that is can be used to initialize OpenStuct 2015-11-05 11:09:21 +11:00
Rob Harrington
2277b9f5a6 Changing ruby version in version manager config 2015-11-05 11:09:21 +11:00
Rob Harrington
aef8b9648e Initial upgrade of Gemfile 2015-11-05 11:09:21 +11:00
Rohan Mitchell
65589d25c6 Display more verbose product and variant name 2015-11-05 09:50:00 +11:00
Rohan Mitchell
5ffad4d343 Fix quantity calculation 2015-11-05 09:43:44 +11:00
Rob Harrington
50a551a87e Coffeescript! 2015-11-04 18:35:14 +11:00
Rob Harrington
1494389d34 WIP: BOM Refactor, organising admin.products files in appropriate folders 2015-11-04 18:28:53 +11:00
Rob Harrington
b43049af47 WIP: BOM Refactor, building line_item fetch and update logic with ngResource 2015-11-04 18:16:17 +11:00
Rob Harrington
f563f04f1c WIP: BOM Refactor, building order fetch and update logic with ngResource, updating rails routes 2015-11-04 16:35:56 +11:00
Rob Harrington
ae7e744644 WIP: BOM Refactor, adding for_line_items action to enterprises controller 2015-11-04 15:02:29 +11:00
Rob Harrington
625e0888ea Adding logic to Admin::BaseController to standardise rendering of data with AMS 2015-11-04 12:10:50 +11:00
Rohan Mitchell
a3d638df67 Merge branch 'master' into folklabs-producer-emails 2015-11-04 11:15:01 +11:00
Rohan Mitchell
9227df54b6 Display detail rows for admin adjustments 2015-11-01 15:19:03 +11:00
Rohan Mitchell
015f3eb9ac Display summary rows for admin adjustments 2015-11-01 13:42:59 +11:00
Maikel Linke
fd747f9012 Updated French locale 2015-10-30 12:20:12 +11:00
Lynne Davis
7350dbb75e Adding tweaks that have been missed from merges 2015-10-30 11:54:06 +11:00
Rohan Mitchell
94e1264aef Add rspec-retry for inconsistently failing spec 2015-10-29 16:01:39 +11:00
Maikel Linke
aec3980a93 Merge remote-tracking branch 'origin/master' into i18n 2015-10-29 14:56:17 +11:00
Maikel Linke
4eed222f18 Fixed several i18n issues reported by Myriam 2015-10-29 14:55:38 +11:00
Rohan Mitchell
f63a80300b Merge branch 'master' into folklabs-producer-emails 2015-10-29 11:49:24 +11:00
Rohan Mitchell
87cf3eda41 Amend 'Detailed orders breakdown' heading with missing content 2015-10-29 11:48:12 +11:00
Rob Harrington
02423d3a41 Using rails time zone account invoice job specs 2015-10-28 16:51:18 +11:00
Rob Harrington
cb1f79f59a Updating front end order details, invoices and pdfs to display names of line_items as opposed to variants 2015-10-28 15:42:14 +11:00
Rob Harrington
18a7317185 Merge branch 'account-invoices' into line_item_naming
Conflicts:
	app/models/spree/line_item_decorator.rb
2015-10-28 13:42:27 +11:00
Rob Harrington
c5810fc003 Improving BOM form validation 2015-10-28 13:08:50 +11:00
Rob Harrington
f60b6994eb Wrapping line_item update with order.update_distribution_charge inside lock 2015-10-28 13:08:50 +11:00
Rob Harrington
50b3635e7e Locking line_items on API update 2015-10-28 13:08:50 +11:00
Rob Harrington
ab7bfd10c5 Revert "Renaming options_text to unit_text so that we can use method from included VariantAndLineItemNaming module"
This reverts commit e86e08b72e939fee61eddd41d56081395666a877.

Conflicts:
	lib/open_food_network/order_and_distributor_report.rb
	spec/features/admin/variants_spec.rb
	spec/lib/open_food_network/order_and_distributor_report_spec.rb
2015-10-28 13:08:50 +11:00
Rob Harrington
cdb0c2db33 Admin Orders show page uses line_item.full_name to describe line_items 2015-10-28 13:07:32 +11:00
Rob Harrington
21e5895a8a Group Buy panel on BOM takes changes to final_weight_volumes into account 2015-10-28 13:07:32 +11:00
Rob Harrington
33e1322a44 Adding form validation to BOM 2015-10-28 13:07:32 +11:00
Rob Harrington
b08556ec7f WIP: Making final_weight_volume adjustment a bit nicer 2015-10-28 13:07:31 +11:00
Rob Harrington
a71999ba84 Weight only returned for products whose variant_unit is 'weight' 2015-10-28 13:07:31 +11:00
Rob Harrington
2d468f5022 Fixing attr_accessible for line_items (broken in previous commit) 2015-10-28 13:07:31 +11:00
Rob Harrington
eba13a0dd7 Line items inherit units from variants upon creation 2015-10-28 13:07:31 +11:00
Rob Harrington
1946bac8e4 Fixing report spec that cares about table title case 2015-10-28 13:07:31 +11:00
Rob Harrington
e52f7165c3 Overriding any last references to options_text in the spree codebase 2015-10-28 13:07:31 +11:00
Rob Harrington
6dfae1b014 Whitespace crusader 2015-10-28 13:07:31 +11:00
Rob Harrington
40972cc6ec Updating reports to use naming information from line_items directly, rather than from the original variant 2015-10-28 13:07:31 +11:00
Rob Harrington
795830d94d Renaming options_text to unit_text so that we can use method from included VariantAndLineItemNaming module 2015-10-28 13:07:31 +11:00
Rob Harrington
039fcb80eb Extracting variant and option_value naming out into a lib class that is now shared between line items and variants, line_items have option_values 2015-10-28 13:06:10 +11:00
Rob Harrington
6a70c162bb Account invoice jobs run according to rails config time zone rather than system time zone 2015-10-23 12:33:05 +11:00
Maikel Linke
0fd29dd32e use expect in bulk_order_management_spec 2015-10-22 13:43:15 +11:00
Maikel Linke
bbeeb8a493 Merge remote-tracking branch 'origin/master' into i18n 2015-10-22 11:03:42 +11:00
Maikel Linke
6c1619ba60 i18n more content 2015-10-22 11:03:35 +11:00
Maikel Linke
df34f6ef8e using default_locale for precompiled assets 2015-10-22 10:50:29 +11:00
Maikel Linke
dc8166ec84 New CI script to check test state via GitHub API 2015-10-21 16:29:41 +11:00
Rob Harrington
ef08977dbe Prevent invoices from being sent unless the distributor of an order has set their ABN 2015-10-21 16:23:48 +11:00
Rob Harrington
9b2653aa2d Updating order invoice template to be more legally compliant 2015-10-21 15:52:14 +11:00
Maikel Linke
adf0a84669 Use ! version of find_by_permalink to recover on missing resource 2015-10-21 15:42:28 +11:00
Maikel Linke
7163664725 updated locales fr and nb 2015-10-21 14:36:02 +11:00
Maikel Linke
2053fbecda Merge branch 'i18n-replace-strings-in-js' into i18n
Conflicts:
	.travis.yml
	app/views/spree/order_mailer/confirm_email_for_customer.html.haml
	config/locales/en.yml
2015-10-21 14:09:43 +11:00
Maikel Linke
6781051fe6 enabling Travis container-based infrastucture 2015-10-21 10:27:16 +11:00
Maikel Linke
2357f46a4e CI scripts use env vars
The CI scripts are configurable through the environment. They had
hardcoded configurations before. The Australian BuildKite setup will
need global environment variables like this:

STAGING_SSH_HOST=ofn-staging2
STAGING_CURRENT_PATH=/home/openfoodweb/apps/openfoodweb/current
STAGING_SERVICE=unicorn_openfoodweb
STAGING_DB_HOST=localhost
STAGING_DB_USER=openfoodweb
STAGING_DB=openfoodweb_production
PRODUCTION_REMOTE=production:/home/openfoodweb/apps/openfoodweb/current
2015-10-21 10:04:29 +11:00
Maikel Linke
8bd78eb139 spec_helper for lib/open_food_network/permissions_spec.rb 2015-10-21 10:04:29 +11:00
Maikel Linke
f152e4054c Remove obsolete deface 2015-10-21 10:04:29 +11:00
Maikel Linke
62d31f79ed Remove obsolete deface 2015-10-21 10:04:28 +11:00
Maikel Linke
2ea1a59666 depricating db2fog.rb initializer due to invalid bucket name
Once everybody changed their server config, we can remove that file.
2015-10-21 10:04:28 +11:00
Maikel Linke
a95727b376 running all specs in Travis 2015-10-21 10:04:28 +11:00
Maikel
b35df3c945 Travis config for parallel execution on five nodes
This Travis configuration runs rspec on five build machines in parallel. Currently, that takes 15 to 20 minutes.
2015-10-21 10:04:28 +11:00
Rohan Mitchell
421774e46c Do not send producer notifications when the producer has no orders for this order cycle 2015-10-17 11:02:47 +11:00
Rob Harrington
5b3e052f78 Using a compiled stylesheet for pdf styling 2015-10-16 21:36:18 +11:00
Rob Harrington
47fb2270bd Making spec do the right thing 2015-10-16 17:25:40 +11:00
Rob Harrington
f12fd7b4a3 Adding button for print action to admin orders show page 2015-10-16 17:25:40 +11:00
Rob Harrington
40d627cb34 Adding new route for printing an order to pdf 2015-10-16 17:25:40 +11:00
Rob Harrington
6e7fc6a0f7 Adding invoice action to orders controller, to allow sending of invoice email 2015-10-16 17:25:40 +11:00
Rob Harrington
104b100fe6 Pulling distributor signoff out into separate partial 2015-10-16 17:25:39 +11:00
Rob Harrington
3a505abfc7 Adding WickedPDF for generation of order invoices 2015-10-16 17:25:39 +11:00
Rohan Mitchell
ecc3bad8c8 Merge branch 'master' into folklabs-producer-emails 2015-10-16 12:38:54 +11:00
Rohan Mitchell
13fc36bad6 Reorder methods 2015-10-15 12:00:40 +11:00
Rohan Mitchell
a766f007fc Display xero report for account invoices 2015-10-15 11:57:51 +11:00
Rohan Mitchell
4fbeb0c3b1 Check if an order is an account invoice 2015-10-15 10:05:27 +11:00
Rohan Mitchell
de80e6d5bf Find adjustments for billable periods 2015-10-15 09:58:22 +11:00
Rohan Mitchell
92f7b72056 Check whether an individual adjustment has tax included 2015-10-15 09:58:06 +11:00
Rob Harrington
b22d591775 BillablePeriods don't get updated when account_invoice has been finalized 2015-10-14 14:36:38 +11:00
Rob Harrington
1ad0f95536 Updating Billable Periods job ignores versions of enterprises created in the future 2015-10-14 14:36:38 +11:00
Rob Harrington
a71410042f Ensuring that account invoice orders have an address 2015-10-14 14:36:37 +11:00
Rob Harrington
815df3d667 Only clean up account invoice orders that aren't already complete, don't attempt to destroy persisted account_invoice orders 2015-10-14 14:36:37 +11:00
Rohan Mitchell
27741863c5 Add simple contribution guide 2015-10-09 15:21:58 +11:00
Maikel Linke
1751a95909 place I18n init at right place in karma task 2015-10-09 11:40:12 +11:00
Maikel Linke
c169e4af92 rename locale nor to nb 2015-10-09 10:43:55 +11:00
Maikel Linke
7d379dbe4b sort travis sets by run time 2015-10-09 10:23:48 +11:00
Maikel Linke
5f80043857 using translate filter instead of root scope function with parameters 2015-10-09 10:21:26 +11:00
Maikel Linke
e9d1cf6eb5 using translate filter instead of root scope function 2015-10-08 18:09:11 +11:00
Maikel Linke
d2470685cd clearing tmp cache with rake 2015-10-08 18:08:21 +11:00
Maikel Linke
a4db4ee782 Merge remote-tracking branch 'off/travis-parallel' into i18n-replace-strings-in-js 2015-10-08 16:07:52 +11:00
Maikel
9115e1175e Travis config for parallel execution on five nodes
This Travis configuration runs rspec on five build machines in parallel. Currently, that takes 15 to 20 minutes.
2015-10-08 15:24:48 +11:00
Maikel Linke
56fd91f82b CI server has to empty the cache if language files changed 2015-10-07 19:10:44 +11:00
Maikel Linke
d62775a785 update specs and fix labels yes and no 2015-10-07 18:05:59 +11:00
Maikel Linke
8b40d094ee new translate filter and updated specs for js translations 2015-10-07 15:47:51 +11:00
Maikel Linke
91fae79be4 Update tests for new label "Login" 2015-10-07 14:06:34 +11:00
Maikel Linke
5aa3ebde9c Set the locale to "en" in test environment. 2015-10-07 14:05:50 +11:00
Maikel Linke
bd737ef727 I18n object file for karma 2015-10-01 16:38:47 +10:00
Maikel Linke
31e7ca9fa2 locale data as js asset 2015-10-01 15:54:46 +10:00
Maikel Linke
0eed8b4578 better testing of existence of I18n 2015-10-01 14:16:59 +10:00
Maikel Linke
6b1e66ed26 Renamed no.yml to nor.yml due to error caused by using "no" 2015-10-01 13:53:10 +10:00
Maikel Linke
da42032d92 Merge remote-tracking branch 'origin/master' into i18n-replace-strings-in-js 2015-10-01 11:15:22 +10:00
Maikel Linke
143c005f0a Merge remote-tracking branch 'origin/i18n-replace-strings-in-views' into i18n-replace-strings-in-js 2015-10-01 11:15:01 +10:00
Maikel Linke
ae96541112 Internationalisation of Javascript views 2015-10-01 11:13:45 +10:00
Maikel Linke
f8725a0174 Removing unused JS partial 2015-10-01 11:12:31 +10:00
Rohan Mitchell
9c6264c4a0 On detailed xero report, do not show product totals (xero treats them as additional line items) 2015-09-25 13:52:51 +10:00
Rohan Mitchell
10bc3919ca Add SKU to detailed xero report 2015-09-22 09:28:50 +10:00
Rohan Mitchell
b5bc4701fa Detailed xero report 2015-09-22 09:15:55 +10:00
Rohan Mitchell
7552776349 Add product_and_variant_name display for Variant 2015-09-21 16:49:31 +10:00
Rohan Mitchell
8f40702369 Line items report whether they have tax included 2015-09-21 15:57:04 +10:00
Rob Harrington
9dc0598870 Adding fix to prevent account_invoice orders from being sucked into the frontend as normal orders 2015-09-18 17:25:34 +10:00
Maikel
4f05b9c28d Changing en: to fr: in French locale file 2015-09-18 09:38:21 +10:00
Maikel
aa4f1f1dec Fixing syntax typo in Norwegian language file 2015-09-18 09:37:35 +10:00
Rob Harrington
14fbeda29e Adding bugsnag notification for case where account_invoice order has errors 2015-09-17 22:38:29 +10:00
Rob Harrington
1c6f3f4877 Translating words on admin accounts page 2015-09-17 22:38:29 +10:00
Rob Harrington
2dcbe2b4f2 Updating the admin account view to show use the new account_invoice model to display data 2015-09-17 22:38:29 +10:00
Rob Harrington
27384439f8 Fixing edge case in update_billable_periods job 2015-09-17 22:38:29 +10:00
Rob Harrington
13adb61b3a Refactoring invoice update process to use new AccountInvoice model 2015-09-17 22:38:29 +10:00
Rob Harrington
77c10dafd6 Linking billable_periods to the relevant account_invoice upon creation 2015-09-17 22:38:29 +10:00
Rob Harrington
4a8f9d1e36 Adding reference to account_invoice for each billable_period 2015-09-17 22:38:29 +10:00
Rob Harrington
0debdcdd9c Renaming files from user_invoice to account_invoice 2015-09-17 22:38:28 +10:00
Rob Harrington
ae30007fed Redesignating all references to user_invoices as account_invoices 2015-09-17 22:38:28 +10:00
Rob Harrington
aa183dc9e0 Account Invoice jobs run by specifying a year and month rather than a specific start and end times 2015-09-17 22:38:28 +10:00
Rob Harrington
b1285cd07f WIP: Adding AccountInvoice model to more robustly record information about enterprise user invoices 2015-09-17 22:38:28 +10:00
Rob Harrington
79497d28d2 Associating billable periods with the relevant adjustment, and moving labelling logic to model 2015-09-17 22:38:13 +10:00
Rob Harrington
5eb20fd8cd Adding tax settings for billing enterprise users 2015-09-17 22:38:13 +10:00
Rob Harrington
01c9560a19 Account page reads from created at date of invoice 2015-09-17 22:38:13 +10:00
Rob Harrington
6cc403cd92 Preventing double creation of invoices by recognising completed invoices within the specifed period 2015-09-17 22:38:13 +10:00
Rob Harrington
11c3cf5f71 Pushing setting validation for accounts jobs into separate methods capable of logging errors to bugsnag 2015-09-17 22:38:12 +10:00
Rob Harrington
448bd12e9f Adding billing tasks to whenever schedule 2015-09-17 22:38:12 +10:00
Rob Harrington
204a3275ac Sorting billable_periods before adding adjustments to user invoices, partly for sanity, partly so that specs works in a logical way 2015-09-17 22:38:12 +10:00
Rob Harrington
6665f9b4a0 Adding global settings for controlling automatic scheduling of accounts tasks 2015-09-17 22:38:12 +10:00
Rob Harrington
ddb0aa4e74 Billable periods from the future are not obsolete 2015-09-17 22:38:12 +10:00
Rob Harrington
aa8e486a45 Look for job names without 'Struct', now that we aren't using structs 2015-09-17 22:38:12 +10:00
Rob Harrington
619c4959ff Removing button for updating billable periods from accounts and billing settings page 2015-09-17 22:38:12 +10:00
Rob Harrington
1b2a06572b Converting accounts jobs to classes, which allows initialization with start and end dates 2015-09-17 22:38:12 +10:00
Rob Harrington
cc26321ab2 Billable Period Updater does not run when end_date is in the future 2015-09-17 22:38:11 +10:00
Rob Harrington
fb01f6d32a User Invoice Finalizer does not run when end_date is in the future 2015-09-17 22:38:11 +10:00
Rob Harrington
0fbd26a3c5 User Invoice Updater does not run when end_date is in the future 2015-09-17 22:38:11 +10:00
Rob Harrington
6f3fad5864 Adding comments 2015-09-17 22:38:11 +10:00
Rob Harrington
5f61952785 UpdateUserInvoices can be run for a specific month 2015-09-17 22:38:11 +10:00
Rob Harrington
128b6853f4 Styling tweaks to the admin account page 2015-09-17 22:38:11 +10:00
Rob Harrington
bed3815df5 User invoice updater formats date strings in localtime 2015-09-17 22:38:11 +10:00
Rob Harrington
7c5816af82 Switching accounts interface over to showing invoices 2015-09-17 22:38:10 +10:00
Rob Harrington
15df1f7f26 Tightening up user selection in UpdateUserInvoices job 2015-09-17 22:38:10 +10:00
Rob Harrington
065bc087d5 Invoice updater cleans up obsolete billable adjustments, ignore billable adjustments without bills and destroys empty invoices 2015-09-17 22:38:10 +10:00
Rob Harrington
c53b5f3edb Adding finalize step to accounts and billing settigns page + controller 2015-09-17 22:38:10 +10:00
Rob Harrington
60cd5ce879 Splitting out invoice finalization as a separate step 2015-09-17 22:38:10 +10:00
Rob Harrington
8bbda5715d Adding basic template for account page 2015-09-17 22:38:10 +10:00
Rob Harrington
92eb5ed367 Adding routes for a new admin account page for users to manage their billing preferences and access invoices 2015-09-17 22:38:10 +10:00
Rob Harrington
70de4fd1fd Touching unchanged billable_periods to prevent them from being marked for deletion 2015-09-17 22:38:10 +10:00
Rob Harrington
c2c0c3684d Refactoring accounts and billing settings controller, adding start_job action 2015-09-17 22:38:09 +10:00
Rob Harrington
38e3690f56 Adding route for start_job action on accounts and billing settings controller 2015-09-17 22:38:09 +10:00
Rob Harrington
2048800c43 Billable periods updater does not auto-run user invoices updater 2015-09-17 22:38:09 +10:00
Rob Harrington
cc0f1ccfa7 Update Billable Periods automatically runs Update User Invoices immediately afterwards 2015-09-17 22:38:09 +10:00
Rob Harrington
d3e8966e65 Update User Invoices job does not run unless necessary global settings have been configured 2015-09-17 22:38:09 +10:00
Rob Harrington
e6f6a3ad81 Commenting out global configs for nightly job switches, use a button to manually run jobs instead (for now) 2015-09-17 22:38:09 +10:00
Rob Harrington
160c0d75fe Confirmation emails do not get send for orders distributed by accounts_distributor 2015-09-17 22:38:09 +10:00
Rob Harrington
f2389ee672 User Invoice Updater finalizes user invoices using global preferences for payment method and shipping method 2015-09-17 22:38:08 +10:00
Rob Harrington
0812643136 Adding views and feature spec for updating default payment and shipping method 2015-09-17 22:38:08 +10:00
Rob Harrington
3e9a61a693 Adding js infrastructure to dynamically fetch available payment and shipping methods for accounts distributor 2015-09-17 22:38:08 +10:00
Rob Harrington
e3e59d76a9 Adding global config for setting default payment and shipping methods for accounts distributor 2015-09-17 22:38:08 +10:00
Rob Harrington
65c26296bd Billable period updater cleans up untouched billable periods for the current billing period 2015-09-17 22:38:08 +10:00
Rob Harrington
9c4ed5f092 Enterprises have billable_periods 2015-09-17 22:38:08 +10:00
Rob Harrington
f0fa696d2f Default scope for BPs ignores deleted records 2015-09-17 22:38:08 +10:00
Rob Harrington
4d58faefd8 Adding timestamps to billable periods 2015-09-17 22:38:08 +10:00
Rob Harrington
311ffc3dc9 wip: user invoice updater finalizes orders on the first of the month 2015-09-17 22:37:56 +10:00
Rob Harrington
d51c69d353 WIP: User invoice updater adds adjustments to current_invoice for each relevant billable_period 2015-09-17 22:37:56 +10:00
Rob Harrington
ee8a86d495 User model can generate a current invoice for enterprise users 2015-09-17 22:37:56 +10:00
Rob Harrington
fa8c3d65dc Adding settings for global accounts and billing setup 2015-09-17 22:37:56 +10:00
Rob Harrington
b4e58a1a79 WIP: Basic structure for daily job to update user invoices 2015-09-17 22:37:55 +10:00
Rob Harrington
550434dfe8 Renaming bill_items to billable_periods 2015-09-17 22:37:55 +10:00
Rob Harrington
fc44e57171 Finishing refactor of bill item updater spec 2015-09-17 22:37:45 +10:00
Rob Harrington
77f735c722 WIP: Refactoring bill item updater specs 2015-09-17 22:37:45 +10:00
Rob Harrington
b736e209ca Bill Item Update handles enterprises created part-way through the month 2015-09-17 22:37:45 +10:00
Rob Harrington
af2bc99c71 Clean up update_bill_items spec after refactor 2015-09-17 22:37:44 +10:00
Rob Harrington
924b3b4cc3 Refactoring update_bill_items job 2015-09-17 22:37:44 +10:00
Rob Harrington
b724745acc WIP: First take at a nightly job for calculating turnover for enterprises 2015-09-17 22:37:44 +10:00
Rob Harrington
bbe25da117 Adding paper_trail verisoning RSpec helpers 2015-09-17 22:37:44 +10:00
Rob Harrington
77e361dd52 Adding shop_trial_expiry method to enterpise model 2015-09-17 22:37:44 +10:00
Rob Harrington
083d7327bc Adding BillItem to database 2015-09-17 22:37:44 +10:00
Rob Harrington
2fa217df56 Adding paper_trail to enterprise model, to track changes to owner_id and sells 2015-09-17 22:37:33 +10:00
Rob Harrington
6489848eff Adding paper_trail gem 2015-09-17 22:37:33 +10:00
sigmundpetersen
b8e40d799b Added translations 2015-09-17 14:18:09 +02:00
Continuous Integration
205a7f1673 Auto-merge from CI [skip ci] 2015-09-17 09:16:20 +10:00
Maikel Linke
2e591b98e1 remove unused javascript 2015-09-16 16:52:26 +10:00
Maikel Linke
0b4a43d77a Merge remote-tracking branch 'origin/master' into i18n-replace-strings-in-views
Conflicts:
	app/views/shared/menu/_cart.html.haml
	app/views/spree/order_mailer/confirm_email_for_shop.html.haml
2015-09-16 16:32:16 +10:00
Maikel Linke
ce87ea54cd Merge branch 'i18n-replace-strings-in-views' of github.com:openfoodfoundation/openfoodnetwork into i18n-replace-strings-in-views 2015-09-16 16:24:38 +10:00
Maikel Linke
637e5c4fee PermalinkGenerator for products 2015-09-16 15:45:10 +10:00
Maikel Linke
ecca23488d Merge branch 'ci-handling-git-tags' into combined/deadlock-js-spec_ci-git-tags_product-permalinks 2015-09-16 15:43:13 +10:00
Maikel Linke
2488411b94 JS feature specs completing before cleaning db
Some specs ran into a deadlock when the Database::Cleaner tried to do
its job while AJAX requests were still triggering other actions.
2015-09-16 15:38:09 +10:00
Maikel Linke
3f822ed0e3 trying to get rid of intermittent failures 2015-09-16 13:06:32 +10:00
Maikel Linke
33af6cbfb1 Specs pending for lagging JS spec test 2015-09-16 11:24:44 +10:00
Maikel Linke
326c972f63 Handling nil in final_weight_volume calculation 2015-09-16 10:12:59 +10:00
Myriam
11892ffe21 creation of the french translation file 2015-09-14 14:42:37 +02:00
Maikel Linke
10cd654ff5 CI Handling git tags
Buildkite is running tags like branches. This caused `git branch`
commands to fail. The function got extended to handle tags as well.
Ideally, Buildkite will offer an option not to rebuild tags.
2015-09-11 15:41:44 +10:00
Myriam
3e53decd85 Delete fr.yml 2015-09-04 15:25:53 +02:00
Myriam
4f0e75893e Create fr.yml 2015-09-04 15:22:19 +02:00
sigmundpetersen
e61abb92d2 Create no.yml 2015-09-03 12:16:58 +02:00
Maikel Linke
832f47d6b0 fix i18n typo 2015-09-02 16:58:04 +10:00
Maikel Linke
415dac3ae3 Updating spec for new Login label 2015-08-28 21:12:56 +10:00
Maikel Linke
8b6f5b4a99 Updating spec for new Login label 2015-08-28 18:37:24 +10:00
Continuous Integration
06010bd8ad Auto-merge from CI [skip ci] 2015-08-28 17:04:53 +10:00
Maikel Linke
85c99102dd i18n: Replacing all language strings in app/view/
Languages strings were moved to config/locale/en.yml. All views contain
according calls to t() now.
2015-08-28 16:59:23 +10:00
Rohan Mitchell
d908701b59 Merge branch 'master' into folklabs-producer-emails
Conflicts:
	Gemfile
2015-06-11 17:02:34 +10:00
Rohan Mitchell
e3085d9224 Merge branch 'producer-emails' of https://github.com/folklabs/openfoodnetwork into folklabs-producer-emails 2015-05-29 17:36:56 +10:00
Rohan Mitchell
3dbc2e0382 Merge branch 'master' into folklabs-producer-emails 2015-05-29 17:36:11 +10:00
Paul Mackay
baaa192967 #275: Code cleanup. 2015-05-24 10:44:39 +01:00
Paul Mackay
2f05fc3824 #275: Insert receival time and instructions into email. 2015-05-24 10:38:49 +01:00
Paul Mackay
955f41633a Merge remote-tracking branch 'refs/remotes/origin/master' into producer-emails 2015-05-11 08:36:09 +01:00
Paul Mackay
fd37324359 #536: Add permissions checking for Notify producers action. 2015-05-09 11:02:25 +01:00
Rohan Mitchell
63ec0d7dcf Merge branch 'master' into folklabs-producer-emails 2015-05-05 11:48:31 +10:00
Rohan Mitchell
91ca5f0213 Fix specs for receival_time / instructions 2015-05-01 10:08:24 +10:00
Rohan Mitchell
f5b45fa0ba Merge branch 'master' into folklabs-producer-emails 2015-05-01 09:51:01 +10:00
Rohan Mitchell
73376b30e2 Convention 2015-04-29 15:56:27 +10:00
Rohan Mitchell
3565548e91 Extract data preparation into private methods 2015-04-29 15:50:42 +10:00
Rohan Mitchell
6999bcfd4e Only include complete orders in producer mailer report 2015-04-29 15:43:50 +10:00
Rohan Mitchell
2fe5d7c73f Remove commented code, use neater syntax for accessing Spree config var 2015-04-29 15:33:39 +10:00
Rohan Mitchell
3a3bf19cf8 Clean up duplication 2015-04-29 15:31:42 +10:00
Rohan Mitchell
30e04b509d Clean up routes 2015-04-29 15:31:13 +10:00
Rohan Mitchell
4279742de5 Avoid serialising entire order cycle when enqueuing OrderCycleNotificationJob 2015-04-29 15:21:05 +10:00
Rohan Mitchell
713c93a570 Fix OrderCycleFormApplicator specs 2015-04-29 15:00:22 +10:00
Rohan Mitchell
36584f0177 Remove puts from specs, fix failing controller spec 2015-04-29 14:46:20 +10:00
Rohan Mitchell
6b1c125b03 Merge branch 'producer-emails' of https://github.com/folklabs/openfoodnetwork into folklabs-producer-emails
Conflicts:
	Gemfile.lock
	app/controllers/admin/order_cycles_controller.rb
	app/views/admin/order_cycles/edit.html.haml
	app/views/admin/order_cycles/show.rep
	db/schema.rb
	spec/controllers/admin/order_cycles_controller_spec.rb
2015-04-29 14:42:17 +10:00
Paul Mackay
0f1ec17698 #275: Use better path variable in test. 2015-04-28 16:08:26 +01:00
Paul Mackay
9103e83ce2 #275: spec test for controller method. Other small fixes. 2015-04-11 18:28:31 +01:00
Paul Mackay
99709b53ed Change controller action to 'notify_producers'.
Add flash message on completion.
Simplify job variables.
Improve mailer query.
Spec for job.
2015-04-11 13:19:48 +01:00
Paul Mackay
717b3b6494 #275: Fixes for testing aggregated orders. 2015-03-10 19:19:57 +00:00
Paul Mackay
ca665dc6bc Merge master into producer-emails. 2015-03-04 19:09:43 +00:00
Paul Mackay
67b17de695 #275: Add receival time and instructions to order cycle for incoming exchanges. Fix issues from feedback. 2014-12-30 11:33:13 +00:00
Paul Mackay
8d5a0aea9f Setup daemon and delayed job table. 2014-11-24 21:25:58 +00:00
Paul Mackay
803d790b7a Remove nokigiri warning.
Tweak email subject.
2014-11-24 21:00:36 +00:00
Paul Mackay
375bdc0586 #275: Change report format. Improved mailer. 2014-11-16 07:14:29 +00:00
Paul Mackay
9b7fd1c16b #275: small tweaks. 2014-11-09 11:19:26 +00:00
Paul Mackay
05437e2a56 #275: start on producer email. 2014-11-09 11:17:46 +00:00
490 changed files with 13585 additions and 19474 deletions

1
.gitignore vendored
View File

@@ -34,6 +34,7 @@ config/abr.yml
config/heroku_env.rb
config/newrelic.yml
config/initializers/feature_toggle.rb
config/initializers/db2fog.rb
NERD_tree*
coverage
libpeerconnection.log

View File

@@ -1 +1 @@
1.9.3-p392
2.1.5

View File

@@ -1,15 +1,56 @@
language: ruby
sudo: false
cache: bundler
bundler_args: --without development
rvm:
- "1.9.3"
services: postgresql
before_install:
- "2.1.5"
# Set the timezone for phantomjs with TZ
# Set the timezone for karma with TIMEZONE
#
# The test cases are roughly split according to their test times.
# It would be better to use https://github.com/ArturT/knapsack.
env:
global:
- TZ="Australia/Melbourne"
- TIMEZONE="Australia/Melbourne"
matrix:
- TEST_CASES="./spec/features/admin" GITHUB_DEPLOY="true"
- TEST_CASES="./spec/features/consumer ./spec/serializers ./spec/performance"
- TEST_CASES="./spec/models"
- TEST_CASES="./spec/controllers ./spec/views ./spec/jobs"
- TEST_CASES="./spec/requests ./spec/helpers ./spec/mailers ./spec/lib" KARMA="true"
before_script:
- cp config/database.travis.yml config/database.yml
- psql -c 'create database open_food_network_test;' -U postgres
- cp config/application.yml.example config/application.yml
- RAILS_ENV=test bundle exec rake db:create db:schema:load
- >
if [ "$KARMA" = "true" ]; then
npm install karma@0.12.31
npm install karma-jasmine@0.1.5
npm install karma-phantomjs-launcher@0.1.4
npm install karma-coffee-preprocessor@0.2.1
npm install -g karma-cli@0.0.4
fi
script:
- RAILS_ENV=test bundle exec rake db:migrate --trace
- bundle exec rake spec
- '[ "$KARMA" = "true" ] && bundle exec rake karma:run || echo "Skipping karma run"'
- "bundle exec rspec $TEST_CASES"
after_success:
- >
if [ "$GITHUB_DEPLOY" = "true" -a "$TRAVIS_PULL_REQUEST" = "false" -a -n "$TRAVIS_BRANCH" -a -n "$GITHUB_API_SECRET" ]; then
description="`git show "$TRAVIS_BRANCH" -s --oneline --no-color`"
data="{
\"ref\":\"$TRAVIS_BRANCH\",
\"description\":\"$description\",
\"environment\":\"staging\",
\"required_contexts\":[]}"
curl -u "$GITHUB_API_SECRET" -d "$data" "https://api.github.com/repos/$TRAVIS_REPO_SLUG/deployments"
else
echo "Not deploying on this build."
fi
notifications:
email: false

33
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,33 @@
# Contributing
We love pull requests from everyone. Here are some instructions for
contributing code to Open Food Network.
Fork, then clone the repo:
git clone git@github.com:your-username/openfoodnetwork.git
Follow the instructions in README.markdown to set up your machine.
Make sure the tests pass:
rspec spec
Make your change. Add tests for your change. Make the tests pass:
rspec spec
Push to your fork and [submit a pull request][pr].
[pr]: https://github.com/openfoodfoundation/openfoodnetwork/compare/
At this point you're waiting on us. We may suggest some changes or
improvements or alternatives.
To increase the chance that your pull request is swiftly accepted:
* Write tests
* Use a style consistent with the rest of the codebase
* Before submitting, [rebase your work][rebase] on the current master branch
[rebase]: https://www.atlassian.com/git/tutorials/merging-vs-rebasing/workflow-walkthrough

12
Gemfile
View File

@@ -1,10 +1,12 @@
source 'https://rubygems.org'
ruby "1.9.3"
ruby "2.1.5"
gem 'rails', '3.2.21'
gem 'rails-i18n', '~> 3.0.0'
gem 'i18n', '~> 0.6.11'
gem 'nokogiri'
gem 'pg'
gem 'spree', :github => 'openfoodfoundation/spree', :branch => '1-3-stable'
gem 'spree_i18n', :github => 'spree/spree_i18n', :branch => '1-3-stable'
@@ -52,6 +54,10 @@ gem 'roadie-rails', '~> 1.0.3'
gem 'figaro'
gem 'blockenspiel'
gem 'acts-as-taggable-on', '~> 3.4'
gem 'paper_trail', '~> 3.0.8'
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
gem 'foreigner'
gem 'immigrant'
@@ -91,7 +97,6 @@ group :test, :development do
gem 'factory_girl_rails', :require => false
gem 'capybara'
gem 'database_cleaner', '0.7.1', :require => false
gem 'simplecov', :require => false
gem 'awesome_print'
gem 'letter_opener'
gem 'timecop'
@@ -99,6 +104,7 @@ group :test, :development do
gem 'rspec-retry'
gem 'json_spec'
gem 'unicorn-rails'
gem 'atomic'
end
group :test do
@@ -109,7 +115,7 @@ group :test do
end
group :development do
gem 'pry-debugger'
gem 'pry-byebug'
gem 'debugger-linecache'
gem 'guard'
gem 'guard-livereload'

View File

@@ -107,6 +107,7 @@ GIT
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (2.3.2)
actionmailer (3.2.21)
actionpack (= 3.2.21)
mail (~> 2.5.4)
@@ -155,6 +156,7 @@ GEM
angularjs-rails (1.2.13)
ansi (1.4.2)
arel (3.0.3)
atomic (1.1.99)
awesome_nested_set (2.1.5)
activerecord (>= 3.0.0)
awesome_print (1.0.2)
@@ -170,8 +172,11 @@ GEM
httparty (>= 0.6, < 1.0)
multi_json (~> 1.0)
builder (3.0.4)
byebug (2.7.0)
columnize (~> 0.3)
debugger-linecache (~> 1.2)
cancan (1.6.8)
capybara (2.2.1)
capybara (2.5.0)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
@@ -190,12 +195,12 @@ GEM
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
railties (~> 3.2.0)
coffee-script (2.2.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.3.3)
coffee-script-source (1.10.0)
colorize (0.7.7)
columnize (0.3.6)
columnize (0.9.0)
comfortable_mexican_sofa (1.6.24)
active_link_to (~> 1.0.0)
paperclip (>= 2.3.0)
@@ -229,12 +234,7 @@ GEM
activerecord (~> 3.0)
fog (~> 1.0)
rails (~> 3.0)
debugger (1.6.1)
columnize (>= 0.3.1)
debugger-linecache (~> 1.2.0)
debugger-ruby_core_source (~> 1.2.3)
debugger-linecache (1.2.0)
debugger-ruby_core_source (1.2.3)
delayed_job (4.0.4)
activesupport (>= 3.0, < 4.2)
delayed_job_active_record (4.0.2)
@@ -252,9 +252,9 @@ GEM
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.5.3)
erubis (2.7.0)
eventmachine (1.0.3)
excon (0.25.3)
execjs (2.5.2)
eventmachine (1.0.8)
excon (0.45.4)
execjs (2.6.0)
factory_girl (3.3.0)
activesupport (>= 3.0.0)
factory_girl_rails (3.3.0)
@@ -265,19 +265,117 @@ GEM
figaro (0.7.0)
bundler (~> 1.0)
rails (>= 3, < 5)
fog (1.14.0)
fission (0.5.0)
CFPropertyList (~> 2.2)
fog (1.36.0)
fog-aliyun (>= 0.1.0)
fog-atmos
fog-aws (>= 0.6.0)
fog-brightbox (~> 0.4)
fog-core (~> 1.32)
fog-dynect (~> 0.0.2)
fog-ecloud (~> 0.1)
fog-google (<= 0.1.0)
fog-json
fog-local
fog-powerdns (>= 0.1.1)
fog-profitbricks
fog-radosgw (>= 0.0.2)
fog-riakcs
fog-sakuracloud (>= 0.0.4)
fog-serverlove
fog-softlayer
fog-storm_on_demand
fog-terremark
fog-vmfusion
fog-voxel
fog-xenserver
fog-xml (~> 0.1.1)
ipaddress (~> 0.5)
nokogiri (~> 1.5, >= 1.5.11)
fog-aliyun (0.1.0)
fog-core (~> 1.27)
fog-json (~> 1.0)
ipaddress (~> 0.8)
xml-simple (~> 1.1)
fog-atmos (0.1.0)
fog-core
fog-xml
fog-aws (0.7.6)
fog-core (~> 1.27)
fog-json (~> 1.0)
fog-xml (~> 0.1)
ipaddress (~> 0.8)
fog-brightbox (0.9.0)
fog-core (~> 1.22)
fog-json
inflecto (~> 0.0.2)
fog-core (1.35.0)
builder
excon (~> 0.25.0)
formatador (~> 0.2.0)
mime-types
multi_json (~> 1.0)
net-scp (~> 1.1)
net-ssh (>= 2.1.3)
nokogiri (~> 1.5)
ruby-hmac
excon (~> 0.45)
formatador (~> 0.2)
fog-dynect (0.0.2)
fog-core
fog-json
fog-xml
fog-ecloud (0.3.0)
fog-core
fog-xml
fog-google (0.1.0)
fog-core
fog-json
fog-xml
fog-json (1.0.2)
fog-core (~> 1.0)
multi_json (~> 1.10)
fog-local (0.2.1)
fog-core (~> 1.27)
fog-powerdns (0.1.1)
fog-core (~> 1.27)
fog-json (~> 1.0)
fog-xml (~> 0.1)
fog-profitbricks (0.0.5)
fog-core
fog-xml
nokogiri
fog-radosgw (0.0.4)
fog-core (>= 1.21.0)
fog-json
fog-xml (>= 0.0.1)
fog-riakcs (0.1.0)
fog-core
fog-json
fog-xml
fog-sakuracloud (1.4.0)
fog-core
fog-json
fog-serverlove (0.1.2)
fog-core
fog-json
fog-softlayer (1.0.2)
fog-core
fog-json
fog-storm_on_demand (0.1.1)
fog-core
fog-json
fog-terremark (0.1.0)
fog-core
fog-xml
fog-vmfusion (0.1.0)
fission
fog-core
fog-voxel (0.1.0)
fog-core
fog-xml
fog-xenserver (0.2.2)
fog-core
fog-xml
fog-xml (0.1.2)
fog-core
nokogiri (~> 1.5, >= 1.5.11)
foreigner (1.6.1)
activerecord (>= 3.0.0)
formatador (0.2.4)
formatador (0.2.5)
foundation-icons-sass-rails (3.0.0)
railties (>= 3.1.1)
sass-rails (>= 3.1.1)
@@ -319,6 +417,8 @@ GEM
immigrant (0.1.6)
activerecord (>= 3.0)
foreigner (>= 1.2.1)
inflecto (0.0.2)
ipaddress (0.8.0)
journey (1.0.4)
jquery-rails (2.2.2)
railties (>= 3.0, < 5.0)
@@ -335,7 +435,7 @@ GEM
addressable (~> 2.3)
letter_opener (1.0.0)
launchy (>= 2.0.4)
libv8 (3.16.14.3)
libv8 (3.16.14.11)
listen (2.2.0)
celluloid (>= 0.15.2)
rb-fsevent (>= 0.9.3)
@@ -351,16 +451,16 @@ GEM
railties (>= 3.1)
money (5.1.1)
i18n (~> 0.6.0)
multi_json (1.11.0)
multi_json (1.11.2)
multi_xml (0.5.5)
net-scp (1.1.2)
net-ssh (>= 2.6.5)
net-ssh (2.6.8)
newrelic_rpm (3.12.0.288)
nokogiri (1.6.6.2)
nokogiri (1.6.6.4)
mini_portile (~> 0.6.0)
oj (2.1.2)
orm_adapter (0.5.0)
paper_trail (3.0.8)
activerecord (>= 3.0, < 5.0)
activesupport (>= 3.0, < 5.0)
paperclip (3.5.4)
activemodel (>= 3.0.0)
activesupport (>= 3.0.0)
@@ -375,7 +475,7 @@ GEM
paypal-sdk-merchant (1.106.1)
paypal-sdk-core (~> 0.2.3)
pg (0.13.2)
poltergeist (1.5.0)
poltergeist (1.7.0)
capybara (~> 2.1)
cliver (~> 0.3.1)
multi_json (~> 1.0)
@@ -387,13 +487,13 @@ GEM
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
pry-debugger (0.2.2)
debugger (~> 1.3)
pry (~> 0.9.10)
pry-byebug (1.3.2)
byebug (~> 2.7)
pry (~> 0.9.12)
rabl (0.7.2)
activesupport (>= 2.3.14)
multi_json (~> 1.0)
rack (1.4.5)
rack (1.4.7)
rack-cache (1.2)
rack (>= 0.4)
rack-livereload (0.3.15)
@@ -464,7 +564,6 @@ GEM
rspec-mocks (~> 2.14.0)
rspec-retry (0.4.2)
rspec-core
ruby-hmac (0.4.0)
ruby-progressbar (1.7.1)
safe_yaml (0.9.5)
sass (3.3.14)
@@ -476,10 +575,6 @@ GEM
thor (~> 0.14)
shoulda-matchers (1.1.0)
activesupport (>= 3.0.0)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
simplecov-html (0.7.1)
slop (3.4.5)
spinjs-rails (1.3)
rails (>= 3.1)
@@ -527,10 +622,15 @@ GEM
webmock (1.13.0)
addressable (>= 2.2.7)
crack (>= 0.3.2)
websocket-driver (0.3.2)
websocket-driver (0.6.2)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
whenever (0.9.2)
activesupport (>= 2.3.4)
chronic (>= 0.6.3)
wicked_pdf (0.11.0)
rails
wkhtmltopdf-binary (0.9.9.3)
xml-simple (1.1.4)
xpath (2.0.0)
nokogiri (~> 1.3)
@@ -547,6 +647,7 @@ DEPENDENCIES
angular-rails-templates (~> 0.2.0)
angularjs-file-upload-rails (~> 1.1.0)
angularjs-rails (= 1.2.13)
atomic
awesome_print
aws-sdk
blockenspiel
@@ -586,12 +687,14 @@ DEPENDENCIES
letter_opener
momentjs-rails
newrelic_rpm
nokogiri
oj
paper_trail (~> 3.0.8)
paperclip
parallel_tests
pg
poltergeist
pry-debugger
pry-byebug
rabl
rack-livereload
rack-ssl
@@ -606,7 +709,6 @@ DEPENDENCIES
sass-rails (~> 3.2.3)
shoulda-matchers
simple_form!
simplecov
spinjs-rails
spree!
spree_auth_devise!
@@ -622,3 +724,5 @@ DEPENDENCIES
unicorn-rails
webmock
whenever
wicked_pdf
wkhtmltopdf-binary

View File

@@ -20,7 +20,7 @@ Below are instructions for setting up a development environment for Open Food Ne
## Dependencies
* Rails 3.2.x
* Ruby 1.9.3
* Ruby 2.1.5
* PostgreSQL database
* PhantomJS (for testing)
* See Gemfile for a list of gems required
@@ -44,7 +44,7 @@ You can download the source with the command:
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 >= 1.9.3 installed:
First, check your dependencies: Ensure that you have Ruby 2.1.5 installed:
ruby --version

View File

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

View File

@@ -0,0 +1,14 @@
angular.module("admin.accounts_and_billing_settings").directive "methodSettingsFor", ->
template: "<div ng-include='include_html'></div>"
restrict: 'A'
scope: {
enterprise_id: '=methodSettingsFor'
}
link: (scope, element, attrs) ->
scope.include_html = ""
scope.$watch "enterprise_id", (newVal, oldVal)->
if !newVal? || newVal == ""
scope.include_html = ""
else
scope.include_html = "/admin/accounts_and_billing_settings/show_methods?enterprise_id=#{newVal};"

View File

@@ -1,3 +1,3 @@
angular.module("ofn.admin", ["ngResource", "ngAnimate", "admin.indexUtils", "admin.dropdown", "admin.products", "admin.taxons", "infinite-scroll"]).config ($httpProvider) ->
angular.module("ofn.admin", ["ngResource", "ngAnimate", "admin.utils", "admin.indexUtils", "admin.dropdown", "admin.products", "admin.taxons", "infinite-scroll"]).config ($httpProvider) ->
$httpProvider.defaults.headers.common["X-CSRF-Token"] = $("meta[name=csrf-token]").attr("content")
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*"

View File

@@ -22,11 +22,16 @@
//= require angular-rails-templates
//= require_tree ../templates/admin
//= require ./admin
//= require ./accounts_and_billing_settings/accounts_and_billing_settings
//= require ./business_model_configuration/business_model_configuration
//= require ./customers/customers
//= require ./dropdown/dropdown
//= require ./enterprises/enterprises
//= require ./enterprise_groups/enterprise_groups
//= require ./index_utils/index_utils
//= require ./line_items/line_items
//= require ./orders/orders
//= require ./order_cycles/order_cycles
//= require ./payment_methods/payment_methods
//= require ./products/products
//= require ./shipping_methods/shipping_methods

View File

@@ -11,7 +11,6 @@ angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [
$scope.confirmDelete = true
$scope.startDate = formatDate start
$scope.endDate = formatDate end
$scope.pendingChanges = pendingChanges
$scope.quickSearch = ""
$scope.bulkActions = [ { name: "Delete Selected", callback: $scope.deleteLineItems } ]
$scope.selectedBulkAction = $scope.bulkActions[0]
@@ -77,6 +76,10 @@ angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [
line_item.checked = false
line_item.supplier = $scope.matchObject $scope.suppliers, line_item.supplier, null
line_item.order = orderWithoutLineItems
line_item.original_final_weight_volume = line_item.final_weight_volume
line_item.original_quantity = line_item.quantity
line_item.original_price = line_item.price
lineItems.concat order.line_items
, []
@@ -107,6 +110,12 @@ angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [
$scope.deleteLineItem lineItem for lineItem in lineItems when lineItem.checked
$scope.confirmDelete = existingState
$scope.submit = ->
if $scope.bulk_order_form.$valid
pendingChanges.submitAll()
else
alert "Some errors must be resolved be before you can update orders.\nAny fields with red borders contain errors."
$scope.allBoxesChecked = ->
checkedCount = $scope.filteredLineItems.reduce (count,lineItem) ->
count + (if lineItem.checked then 1 else 0 )
@@ -123,17 +132,17 @@ angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [
$scope.sumUnitValues = ->
sum = $scope.filteredLineItems.reduce (sum,lineItem) ->
sum = sum + lineItem.quantity * lineItem.units_variant.unit_value
sum = sum + lineItem.final_weight_volume
, 0
$scope.sumMaxUnitValues = ->
sum = $scope.filteredLineItems.reduce (sum,lineItem) ->
sum = sum + Math.max(lineItem.max_quantity,lineItem.quantity) * lineItem.units_variant.unit_value
sum = sum + Math.max(lineItem.max_quantity,lineItem.original_quantity) * lineItem.units_variant.unit_value
, 0
$scope.allUnitValuesPresent = ->
$scope.allFinalWeightVolumesPresent = ->
for i,lineItem of $scope.filteredLineItems
return false if !lineItem.units_variant.hasOwnProperty('unit_value') || !(lineItem.units_variant.unit_value > 0)
return false if !lineItem.hasOwnProperty('final_weight_volume') || !(lineItem.final_weight_volume > 0)
true
# How is this different to OptionValueNamer#name?
@@ -164,13 +173,11 @@ angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [
$scope.orderCycleFilter = $scope.orderCycles[0].id
$scope.quickSearch = ""
$scope.weightAdjustedPrice = (lineItem, oldValue) ->
if oldValue <= 0
oldValue = lineItem.units_variant.unit_value * line_item.quantity
if lineItem.final_weight_volume <= 0
lineItem.final_weight_volume = lineItem.units_variant.unit_value * lineItem.quantity
lineItem.price = lineItem.price * lineItem.final_weight_volume / oldValue
#$scope.bulk_order_form.line_item.price.$setViewValue($scope.bulk_order_form.line_item.price.$viewValue)
$scope.weightAdjustedPrice = (lineItem) ->
if lineItem.final_weight_volume > 0
unit_value = lineItem.final_weight_volume / lineItem.quantity
original_unit_value = lineItem.original_final_weight_volume / lineItem.original_quantity
lineItem.price = lineItem.original_price * (unit_value / original_unit_value)
$scope.unitValueLessThanZero = (lineItem) ->
if lineItem.units_variant.unit_value <= 0
@@ -178,12 +185,10 @@ angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [
else
false
$scope.updateOnQuantity = (lineItem, oldQuantity) ->
if lineItem.quantity <= 0
lineItem.quantity = 1
# reset price to original unit value
lineItem.price = lineItem.price * (oldQuantity * lineItem.units_variant.unit_value) / lineItem.final_weight_volume
lineItem.final_weight_volume = lineItem.units_variant.unit_value * lineItem.quantity
$scope.updateOnQuantity = (lineItem) ->
if lineItem.quantity > 0
lineItem.final_weight_volume = lineItem.original_final_weight_volume * lineItem.quantity / lineItem.original_quantity
$scope.weightAdjustedPrice(lineItem)
$scope.$watch "orderCycleFilter", (newVal, oldVal) ->
unless $scope.orderCycleFilter == "0" || angular.equals(newVal, oldVal)

View File

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

View File

@@ -0,0 +1,21 @@
angular.module("admin.businessModelConfiguration").controller "BusinessModelConfigCtrl", ($scope, $filter) ->
$scope.turnover = 1000
$scope.bill = ->
return $filter('currency')(0) unless $scope.fixed || $scope.rate
Number($scope.fixed) + Number($scope.turnover) * Number($scope.rate)
$scope.cappedBill = ->
return $scope.bill() if !$scope.cap? || Number($scope.cap) == 0
Math.min($scope.bill(), Number($scope.cap))
$scope.capReached = ->
return "No" if !$scope.cap? || Number($scope.cap) == 0
if $scope.bill() >= Number($scope.cap) then "Yes" else "No"
$scope.includedTax = ->
return 0 if !$scope.taxRate? || Number($scope.taxRate) == 0
($scope.cappedBill() * Number($scope.taxRate))
$scope.total = ->
$scope.cappedBill() + $scope.includedTax()

View File

@@ -1,7 +0,0 @@
angular.module("ofn.admin").directive "ofnConfirmLinkPath", (ofnConfirmHandler) ->
restrict: "A"
scope:
path: "@ofnConfirmLinkPath"
link: (scope, element, attrs) ->
element.click ofnConfirmHandler scope, ->
window.location = scope.path

View File

@@ -1,6 +0,0 @@
angular.module("ofn.admin").directive "ofnConfirmModelChange", (ofnConfirmHandler,$timeout) ->
restrict: "A"
link: (scope, element, attrs) ->
handler = ofnConfirmHandler scope, -> scope.fetchOrders()
scope.$watch attrs.ngModel, (oldValue,newValue) ->
handler() unless oldValue == undefined || newValue == oldValue

View File

@@ -0,0 +1,5 @@
angular.module("admin.dropdown").directive "linksDropdown", ($window)->
restrict: "C"
scope:
links: "="
templateUrl: "admin/links_dropdown.html"

View File

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

View File

@@ -1,9 +1,9 @@
angular.module("admin.enterprises").controller 'enterprisesCtrl', ($scope, Enterprises, Columns) ->
Enterprises.loaded = false
$scope.allEnterprises = Enterprises.index()
angular.module("admin.enterprises").controller 'enterprisesCtrl', ($scope, $q, Enterprises, Columns) ->
requests = []
requests.push ($scope.allEnterprises = Enterprises.index(ams_prefix: "index")).$promise
$scope.loaded = ->
Enterprises.loaded
$q.all(requests).then ->
$scope.loaded = true
$scope.columns = Columns.setColumns
name: { name: "Name", visible: true }

View File

@@ -0,0 +1,8 @@
angular.module("admin.enterprises").directive "monthlyPricingDescription", (monthlyBillDescription) ->
restrict: 'E'
scope:
joiner: "@"
template: "<span ng-bind-html='billDescription'></span>"
link: (scope, element, attrs) ->
joiners = { comma: ", ", newline: "<br>" }
scope.billDescription = monthlyBillDescription.replace("{joiner}", joiners[scope.joiner])

View File

@@ -1,5 +1,5 @@
angular.module("admin.enterprises").factory 'EnterpriseResource', ($resource) ->
$resource('/admin/enterprises/:id.json', {}, {
$resource('/admin/enterprises/:id/:action.json', {}, {
'index':
method: 'GET'
isArray: true

View File

@@ -1,26 +1,27 @@
angular.module("admin.enterprises").factory 'Enterprises', ($q, EnterpriseResource) ->
angular.module("admin.enterprises").factory 'Enterprises', ($q, EnterpriseResource, blankOption) ->
new class Enterprises
enterprises: []
enterprises_by_id: {}
pristine_by_id: {}
loaded: false
enterprisesByID: {}
pristineByID: {}
index: (params={}, callback=null) ->
EnterpriseResource.index params, (data) =>
includeBlank = !!params['includeBlank']
delete params['includeBlank']
EnterpriseResource.index(params, (data) =>
for enterprise in data
@enterprises.push enterprise
@pristine_by_id[enterprise.id] = angular.copy(enterprise)
@enterprisesByID[enterprise.id] = enterprise
@pristineByID[enterprise.id] = angular.copy(enterprise)
@loaded = true
(callback || angular.noop)(@enterprises)
(callback || angular.noop)(data)
@enterprises
data.unshift(blankOption()) if includeBlank
data
)
save: (enterprise) ->
deferred = $q.defer()
enterprise.$update({id: enterprise.permalink})
.then( (data) =>
@pristine_by_id[enterprise.id] = angular.copy(enterprise)
@pristineByID[enterprise.id] = angular.copy(enterprise)
deferred.resolve(data)
).catch (response) ->
deferred.reject(response)
@@ -31,9 +32,9 @@ angular.module("admin.enterprises").factory 'Enterprises', ($q, EnterpriseResour
diff: (enterprise) ->
changed = []
for attr, value of enterprise when not angular.equals(value, @pristine_by_id[enterprise.id][attr])
for attr, value of enterprise when not angular.equals(value, @pristineByID[enterprise.id][attr])
changed.push attr unless attr is "$$hashKey"
changed
resetAttribute: (enterprise, attribute) ->
enterprise[attribute] = @pristine_by_id[enterprise.id][attribute]
enterprise[attribute] = @pristineByID[enterprise.id][attribute]

View File

@@ -1,7 +0,0 @@
angular.module("ofn.admin").filter "selectFilter", (blankOption) ->
return (lineItems,selectedSupplier,selectedDistributor,selectedOrderCycle) ->
filtered = []
filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,"0") || lineItem.supplier.id == selectedSupplier) &&
(angular.equals(selectedDistributor,"0") || lineItem.order.distributor.id == selectedDistributor) &&
(angular.equals(selectedOrderCycle,"0") || lineItem.order.order_cycle.id == selectedOrderCycle)
filtered

View File

@@ -0,0 +1,9 @@
angular.module("admin.indexUtils").directive "datepicker", ->
require: "ngModel"
link: (scope, element, attrs, ngModel) ->
element.datepicker
dateFormat: "yy-mm-dd"
onSelect: (dateText, inst) ->
scope.$apply (scope) ->
# Fires ngModel.$parsers
ngModel.$setViewValue dateText

View File

@@ -0,0 +1,6 @@
angular.module("admin.indexUtils").directive "ignoreDirty", ->
restrict: 'A'
require: 'ngModel'
link: (scope, element, attrs, ngModel) ->
#TODO: This is broken, requires AngularJS > 1.3
ngModel.$setDirty = angular.noop

View File

@@ -0,0 +1,7 @@
angular.module("admin.indexUtils").directive "saveBar", ->
restrict: "E"
scope:
save: "&"
saving: "&"
dirty: "&"
templateUrl: "admin/save_bar.html"

View File

@@ -0,0 +1,9 @@
angular.module("admin.indexUtils").directive "select2MinSearch", ($timeout) ->
require: 'ngModel'
link: (scope, element, attrs, ngModel) ->
element.select2
minimumResultsForSearch: attrs.select2MinSearch
ngModel.$formatters.push (value) ->
element.select2('val', value)
value

View File

@@ -0,0 +1,11 @@
angular.module("admin.indexUtils").factory 'Dereferencer', ->
new class Dereferencer
dereference: (array, data)->
if array
for object, i in array
array[i] = data[object.id]
dereferenceAttr: (array, attr, data)->
if array
for object in array
object[attr] = data[object[attr].id] unless object[attr] == null

View File

@@ -0,0 +1,11 @@
angular.module("admin.indexUtils").factory 'RequestMonitor', ($q) ->
new class RequestMonitor
loadQueue: $q.when([])
loadId: 0
loading: false
load: (promise) ->
loadId = (@loadId += 1)
@loading = true
@loadQueue = $q.all([@loadQueue, promise]).then =>
@loading = false if @loadId == loadId

View File

@@ -0,0 +1,181 @@
angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, Columns, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, blankOption, VariantUnitManager, RequestMonitor) ->
$scope.initialized = false
$scope.RequestMonitor = RequestMonitor
$scope.saving = false
$scope.filteredLineItems = []
$scope.confirmDelete = true
$scope.startDate = formatDate daysFromToday -7
$scope.endDate = formatDate daysFromToday 1
$scope.bulkActions = [ { name: "Delete Selected", callback: 'deleteLineItems' } ]
$scope.selectedUnitsProduct = {};
$scope.selectedUnitsVariant = {};
$scope.sharedResource = false
$scope.columns = Columns.setColumns
order_no: { name: "Order No.", visible: false }
full_name: { name: "Name", visible: true }
email: { name: "Email", visible: false }
phone: { name: "Phone", visible: false }
order_date: { name: "Order Date", visible: true }
producer: { name: "Producer", visible: true }
order_cycle: { name: "Order Cycle", visible: false }
hub: { name: "Hub", visible: false }
variant: { name: "Variant", visible: true }
quantity: { name: "Quantity", visible: true }
max: { name: "Max", visible: true }
final_weight_volume: { name: "Weight/Volume", visible: false }
price: { name: "Price", visible: false }
$scope.confirmRefresh = ->
LineItems.allSaved() || confirm("Unsaved changes exist and will be lost if you continue.")
$scope.resetSelectFilters = ->
$scope.distributorFilter = blankOption().id
$scope.supplierFilter = blankOption().id
$scope.orderCycleFilter = blankOption().id
$scope.quickSearch = ""
$scope.refreshData = ->
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == "0"
$scope.startDate = OrderCycles.orderCyclesByID[$scope.orderCycleFilter].first_order
$scope.endDate = OrderCycles.orderCyclesByID[$scope.orderCycleFilter].last_order
RequestMonitor.load $scope.orders = Orders.index("q[state_not_eq]": "canceled", "q[completed_at_not_null]": "true", "q[completed_at_gt]": "#{parseDate($scope.startDate)}", "q[completed_at_lt]": "#{parseDate($scope.endDate)}")
RequestMonitor.load $scope.lineItems = LineItems.index("q[order][state_not_eq]": "canceled", "q[order][completed_at_not_null]": "true", "q[order][completed_at_gt]": "#{parseDate($scope.startDate)}", "q[order][completed_at_lt]": "#{parseDate($scope.endDate)}")
unless $scope.initialized
RequestMonitor.load $scope.distributors = Enterprises.index(includeBlank: true, action: "for_line_items", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
RequestMonitor.load $scope.orderCycles = OrderCycles.index(includeBlank: true, ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{daysFromToday(-90)}")
RequestMonitor.load $scope.suppliers = Enterprises.index(includeBlank: true, action: "for_line_items", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.distributors.$promise, $scope.orderCycles.$promise]).then ->
Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.enterprisesByID
Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.orderCyclesByID
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.suppliers.$promise, $scope.lineItems.$promise]).then ->
Dereferencer.dereferenceAttr $scope.lineItems, "supplier", Enterprises.enterprisesByID
Dereferencer.dereferenceAttr $scope.lineItems, "order", Orders.ordersByID
$scope.bulk_order_form.$setPristine()
unless $scope.initialized
$scope.initialized = true
$timeout ->
$scope.resetSelectFilters()
$scope.refreshData()
$scope.submit = =>
if $scope.bulk_order_form.$valid
$scope.saving = true
$q.all(LineItems.saveAll()).then(->
$scope.bulk_order_form.$setPristine()
$scope.saving = false
).catch ->
alert "Some errors must be resolved be before you can update orders.\nAny fields with red borders contain errors."
else
alert "Some errors must be resolved be before you can update orders.\nAny fields with red borders contain errors."
$scope.deleteLineItem = (lineItem) ->
if ($scope.confirmDelete && confirm("Are you sure?")) || !$scope.confirmDelete
LineItems.delete lineItem, =>
$scope.lineItems.splice $scope.lineItems.indexOf(lineItem), 1
$scope.deleteLineItems = (lineItems) ->
existingState = $scope.confirmDelete
$scope.confirmDelete = false
$scope.deleteLineItem lineItem for lineItem in lineItems when lineItem.checked
$scope.confirmDelete = existingState
$scope.allBoxesChecked = ->
checkedCount = $scope.filteredLineItems.reduce (count,lineItem) ->
count + (if lineItem.checked then 1 else 0 )
, 0
checkedCount == $scope.filteredLineItems.length
$scope.toggleAllCheckboxes = ->
changeTo = !$scope.allBoxesChecked()
lineItem.checked = changeTo for lineItem in $scope.filteredLineItems
$scope.setSelectedUnitsVariant = (unitsProduct,unitsVariant) ->
$scope.selectedUnitsProduct = unitsProduct
$scope.selectedUnitsVariant = unitsVariant
$scope.sumUnitValues = ->
sum = $scope.filteredLineItems.reduce (sum,lineItem) ->
sum + lineItem.final_weight_volume
, 0
$scope.sumMaxUnitValues = ->
sum = $scope.filteredLineItems.reduce (sum,lineItem) ->
sum + lineItem.max_quantity * lineItem.units_variant.unit_value
, 0
$scope.allFinalWeightVolumesPresent = ->
for i,lineItem of $scope.filteredLineItems
return false if !lineItem.hasOwnProperty('final_weight_volume') || !(lineItem.final_weight_volume > 0)
true
# How is this different to OptionValueNamer#name?
# Should it be extracted to that class or VariantUnitManager?
$scope.formattedValueWithUnitName = (value, unitsProduct, unitsVariant) ->
# A Units Variant is an API object which holds unit properies of a variant
if unitsProduct.hasOwnProperty("variant_unit") && (unitsProduct.variant_unit == "weight" || unitsProduct.variant_unit == "volume") && value > 0
scale = VariantUnitManager.getScale(value, unitsProduct.variant_unit)
Math.round(value/scale * 1000)/1000 + " " + VariantUnitManager.getUnitName(scale, unitsProduct.variant_unit)
else
''
$scope.fulfilled = (sumOfUnitValues) ->
# A Units Variant is an API object which holds unit properies of a variant
if $scope.selectedUnitsProduct.hasOwnProperty("group_buy_unit_size") && $scope.selectedUnitsProduct.group_buy_unit_size > 0 &&
$scope.selectedUnitsProduct.hasOwnProperty("variant_unit") &&
( $scope.selectedUnitsProduct.variant_unit == "weight" || $scope.selectedUnitsProduct.variant_unit == "volume" )
Math.round( sumOfUnitValues / $scope.selectedUnitsProduct.group_buy_unit_size * 1000)/1000
else
''
$scope.unitsVariantSelected = ->
!angular.equals($scope.selectedUnitsVariant,{})
$scope.weightAdjustedPrice = (lineItem) ->
if lineItem.final_weight_volume > 0
unit_value = lineItem.final_weight_volume / lineItem.quantity
pristine_unit_value = LineItems.pristineByID[lineItem.id].final_weight_volume / LineItems.pristineByID[lineItem.id].quantity
lineItem.price = LineItems.pristineByID[lineItem.id].price * (unit_value / pristine_unit_value)
$scope.unitValueLessThanZero = (lineItem) ->
if lineItem.units_variant.unit_value <= 0
true
else
false
$scope.updateOnQuantity = (lineItem) ->
if lineItem.quantity > 0
lineItem.final_weight_volume = LineItems.pristineByID[lineItem.id].final_weight_volume * lineItem.quantity / LineItems.pristineByID[lineItem.id].quantity
$scope.weightAdjustedPrice(lineItem)
daysFromToday = (days) ->
now = new Date
now.setHours(0)
now.setMinutes(0)
now.setSeconds(0)
now.setDate( now.getDate() + days )
now
formatDate = (date) ->
year = date.getFullYear()
month = twoDigitNumber date.getMonth() + 1
day = twoDigitNumber date.getDate()
return year + "-" + month + "-" + day
formatTime = (date) ->
hours = twoDigitNumber date.getHours()
mins = twoDigitNumber date.getMinutes()
secs = twoDigitNumber date.getSeconds()
return hours + ":" + mins + ":" + secs
parseDate = (dateString) ->
new Date(Date.parse(dateString))
twoDigitNumber = (number) ->
twoDigits = "" + number
twoDigits = ("0" + number) if number < 10
twoDigits

View File

@@ -0,0 +1,19 @@
# Used with the ngChange directive to prevent updates to the relevant model unless a callback returns true
angular.module("admin.lineItems").directive "confirmChange", ->
restrict: "A"
require: 'ngModel'
scope:
confirmChange: "&"
link: (scope, element, attrs, ngModel) ->
valid = null
ngModel.$parsers.push (val) =>
return val if val == valid
if scope.confirmChange()
# ngModel is changed, triggers ngChange callback
return valid = val
else
valid = ngModel.$modelValue
ngModel.$setViewValue(valid)
ngModel.$render()
return valid

View File

@@ -0,0 +1,9 @@
# Used on a link to prevent link clicks unless a callback returns true (probably asking for user confirmation)
angular.module("admin.lineItems").directive "confirmLinkClick", ->
restrict: "A"
scope:
confirmLinkClick: "&"
link: (scope, element, attrs) ->
element.bind "click", (event) ->
unless scope.confirmLinkClick()
event.preventDefault()

View File

@@ -0,0 +1,8 @@
angular.module("admin.lineItems").filter "selectFilter", (blankOption, RequestMonitor) ->
return (lineItems,selectedSupplier,selectedDistributor,selectedOrderCycle) ->
filtered = []
unless RequestMonitor.loading
filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,"0") || lineItem.supplier.id == selectedSupplier) &&
(angular.equals(selectedDistributor,"0") || lineItem.order.distributor.id == selectedDistributor) &&
(angular.equals(selectedOrderCycle,"0") || lineItem.order.order_cycle.id == selectedOrderCycle)
filtered

View File

@@ -1,6 +1,6 @@
angular.module("ofn.admin").filter "variantFilter", ->
angular.module("admin.lineItems").filter "variantFilter", ->
return (lineItems,selectedUnitsProduct,selectedUnitsVariant,sharedResource) ->
filtered = []
filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedUnitsProduct,{}) ||
(lineItem.units_product.id == selectedUnitsProduct.id && (sharedResource || lineItem.units_variant.id == selectedUnitsVariant.id ) ) )
filtered
filtered

View File

@@ -0,0 +1 @@
angular.module("admin.lineItems", ["admin.indexUtils", "admin.products", "admin.orders", "admin.enterprises", "admin.orderCycles"])

View File

@@ -0,0 +1,12 @@
angular.module("admin.lineItems").factory 'LineItemResource', ($resource) ->
$resource('/admin/:orders/:order_number/line_items/:id.json', {}, {
'index':
method: 'GET'
isArray: true
'update':
method: 'PUT'
transformRequest: (data, headersGetter) =>
line_item = {}
line_item[attr] = data[attr] for attr in ["price", "quantity", "final_weight_volume"]
angular.toJson(line_item: line_item)
})

View File

@@ -0,0 +1,63 @@
angular.module("admin.lineItems").factory 'LineItems', ($q, LineItemResource) ->
new class LineItems
lineItemsByID: {}
pristineByID: {}
index: (params={}, callback=null) ->
LineItemResource.index params, (data) =>
@resetData()
for lineItem in data
@lineItemsByID[lineItem.id] = lineItem
@pristineByID[lineItem.id] = angular.copy(lineItem)
(callback || angular.noop)(data)
resetData: ->
@lineItemsByID = {}
@pristineByID = {}
saveAll: ->
for id, lineItem of @lineItemsByID
lineItem.errors = {} # removes errors when line_item has been returned to original state
@save(lineItem) if !@isSaved(lineItem)
save: (lineItem) ->
deferred = $q.defer()
lineItem.errors = {}
lineItem.$update({id: lineItem.id, orders: "orders", order_number: lineItem.order.number})
.then( (data) =>
@pristineByID[lineItem.id] = angular.copy(lineItem)
deferred.resolve(data)
).catch (response) ->
lineItem.errors = response.data.errors if response.data.errors?
deferred.reject(response)
deferred.promise
allSaved: ->
for id, lineItem of @lineItemsByID
return false unless @isSaved(lineItem)
true
isSaved: (lineItem) ->
@diff(lineItem).length == 0
diff: (lineItem) ->
changed = []
for attr, value of lineItem when not angular.equals(value, @pristineByID[lineItem.id][attr])
changed.push attr if attr in ["price", "quantity", "final_weight_volume"]
changed
resetAttribute: (lineItem, attribute) ->
lineItem[attribute] = @pristineByID[lineItem.id][attribute]
delete: (lineItem, callback=null) ->
deferred = $q.defer()
lineItem.$delete({id: lineItem.id, orders: "orders", order_number: lineItem.order.number})
.then( (data) =>
delete @lineItemsByID[lineItem.id]
delete @pristineByID[lineItem.id]
(callback || angular.noop)(data)
deferred.resolve(data)
).catch (response) ->
deferred.reject(response)
deferred.promise

View File

@@ -1,11 +1,16 @@
angular.module('admin.order_cycles', ['ngResource'])
.controller('AdminCreateOrderCycleCtrl', ['$scope', '$filter', 'OrderCycle', 'Enterprise', 'EnterpriseFee', 'ocInstance', ($scope, $filter, OrderCycle, Enterprise, EnterpriseFee, ocInstance) ->
angular.module('admin.orderCycles', ['ngResource', 'admin.utils'])
.controller('AdminCreateOrderCycleCtrl', ['$scope', '$filter', 'OrderCycle', 'Enterprise', 'EnterpriseFee', 'ocInstance', 'StatusMessage', ($scope, $filter, OrderCycle, Enterprise, EnterpriseFee, ocInstance, StatusMessage) ->
$scope.enterprises = Enterprise.index(coordinator_id: ocInstance.coordinator_id)
$scope.supplier_enterprises = Enterprise.producer_enterprises
$scope.distributor_enterprises = Enterprise.hub_enterprises
$scope.supplied_products = Enterprise.supplied_products
$scope.enterprise_fees = EnterpriseFee.index(coordinator_id: ocInstance.coordinator_id)
$scope.OrderCycle = OrderCycle
$scope.order_cycle = OrderCycle.new({ coordinator_id: ocInstance.coordinator_id})
$scope.StatusMessage = StatusMessage
$scope.loaded = ->
Enterprise.loaded && EnterpriseFee.loaded
@@ -74,19 +79,23 @@ angular.module('admin.order_cycles', ['ngResource'])
$scope.removeDistributionOfVariant = (variant_id) ->
OrderCycle.removeDistributionOfVariant(variant_id)
$scope.submit = (event) ->
event.preventDefault()
OrderCycle.create()
$scope.submit = (destination) ->
OrderCycle.create(destination)
])
.controller('AdminEditOrderCycleCtrl', ['$scope', '$filter', '$location', 'OrderCycle', 'Enterprise', 'EnterpriseFee', ($scope, $filter, $location, OrderCycle, Enterprise, EnterpriseFee) ->
.controller('AdminEditOrderCycleCtrl', ['$scope', '$filter', '$location', 'OrderCycle', 'Enterprise', 'EnterpriseFee', 'StatusMessage', ($scope, $filter, $location, OrderCycle, Enterprise, EnterpriseFee, StatusMessage) ->
order_cycle_id = $location.absUrl().match(/\/admin\/order_cycles\/(\d+)/)[1]
$scope.enterprises = Enterprise.index(order_cycle_id: order_cycle_id)
$scope.supplier_enterprises = Enterprise.producer_enterprises
$scope.distributor_enterprises = Enterprise.hub_enterprises
$scope.supplied_products = Enterprise.supplied_products
$scope.enterprise_fees = EnterpriseFee.index(order_cycle_id: order_cycle_id)
$scope.OrderCycle = OrderCycle
$scope.order_cycle = OrderCycle.load(order_cycle_id)
$scope.StatusMessage = StatusMessage
$scope.loaded = ->
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
@@ -155,9 +164,8 @@ angular.module('admin.order_cycles', ['ngResource'])
$scope.removeDistributionOfVariant = (variant_id) ->
OrderCycle.removeDistributionOfVariant(variant_id)
$scope.submit = (event) ->
event.preventDefault()
OrderCycle.update()
$scope.submit = (destination) ->
OrderCycle.update(destination)
])
.config(['$httpProvider', ($httpProvider) ->

View File

@@ -1,4 +1,6 @@
angular.module('admin.order_cycles').controller "AdminSimpleCreateOrderCycleCtrl", ($scope, OrderCycle, Enterprise, EnterpriseFee, ocInstance) ->
angular.module('admin.orderCycles').controller "AdminSimpleCreateOrderCycleCtrl", ($scope, OrderCycle, Enterprise, EnterpriseFee, StatusMessage, ocInstance) ->
$scope.StatusMessage = StatusMessage
$scope.OrderCycle = OrderCycle
$scope.order_cycle = OrderCycle.new {coordinator_id: ocInstance.coordinator_id}, =>
# TODO: make this a get method, which only fetches one enterprise
$scope.enterprises = Enterprise.index {coordinator_id: ocInstance.coordinator_id}, (enterprises) =>
@@ -39,7 +41,6 @@ angular.module('admin.order_cycles').controller "AdminSimpleCreateOrderCycleCtrl
$scope.enterpriseFeesForEnterprise = (enterprise_id) ->
EnterpriseFee.forEnterprise(parseInt(enterprise_id))
$scope.submit = (event) ->
event.preventDefault()
$scope.submit = (destination) ->
OrderCycle.mirrorIncomingToOutgoingProducts()
OrderCycle.create()
OrderCycle.create(destination)

View File

@@ -1,9 +1,11 @@
angular.module('admin.order_cycles').controller "AdminSimpleEditOrderCycleCtrl", ($scope, $location, OrderCycle, Enterprise, EnterpriseFee) ->
angular.module('admin.orderCycles').controller "AdminSimpleEditOrderCycleCtrl", ($scope, $location, OrderCycle, Enterprise, EnterpriseFee, StatusMessage) ->
$scope.orderCycleId = ->
$location.absUrl().match(/\/admin\/order_cycles\/(\d+)/)[1]
$scope.StatusMessage = StatusMessage
$scope.enterprises = Enterprise.index(order_cycle_id: $scope.orderCycleId())
$scope.enterprise_fees = EnterpriseFee.index(order_cycle_id: $scope.orderCycleId())
$scope.OrderCycle = OrderCycle
$scope.order_cycle = OrderCycle.load $scope.orderCycleId(), (order_cycle) =>
$scope.init()
@@ -32,7 +34,6 @@ angular.module('admin.order_cycles').controller "AdminSimpleEditOrderCycleCtrl",
$event.preventDefault()
OrderCycle.removeCoordinatorFee(index)
$scope.submit = (event) ->
event.preventDefault()
$scope.submit = (destination) ->
OrderCycle.mirrorIncomingToOutgoingProducts()
OrderCycle.update()
OrderCycle.update(destination)

View File

@@ -1,4 +1,4 @@
angular.module("admin.order_cycles").filter "filterExchangeVariants", ->
angular.module("admin.orderCycles").filter "filterExchangeVariants", ->
return (variants, rules) ->
if variants? && rules?
return (variant for variant in variants when variant in rules)

View File

@@ -1,4 +1,4 @@
angular.module("admin.order_cycles").filter "visibleProductVariants", ->
angular.module("admin.orderCycles").filter "visibleProductVariants", ->
return (product, exchange, rules) ->
variants = product.variants.concat( [{ "id": product.master_id}] )
return (variant for variant in variants when variant.id in rules[exchange.enterprise_id])

View File

@@ -1,3 +1,3 @@
angular.module("admin.order_cycles").filter "visibleProducts", ($filter) ->
angular.module("admin.orderCycles").filter "visibleProducts", ($filter) ->
return (products, exchange, rules) ->
return (product for product in products when $filter('visibleProductVariants')(product, exchange, rules).length > 0)

View File

@@ -0,0 +1 @@
angular.module('admin.orderCycles', ['ngResource', 'admin.indexUtils'])

View File

@@ -1,4 +1,4 @@
angular.module('admin.order_cycles').factory('Enterprise', ($resource) ->
angular.module('admin.orderCycles').factory('Enterprise', ($resource) ->
Enterprise = $resource('/admin/enterprises/for_order_cycle/:enterprise_id.json', {}, {
'index':
method: 'GET'
@@ -10,6 +10,8 @@ angular.module('admin.order_cycles').factory('Enterprise', ($resource) ->
{
Enterprise: Enterprise
enterprises: {}
producer_enterprises: []
hub_enterprises: []
supplied_products: []
loaded: false
@@ -17,6 +19,8 @@ angular.module('admin.order_cycles').factory('Enterprise', ($resource) ->
Enterprise.index params, (data) =>
for enterprise in data
@enterprises[enterprise.id] = enterprise
@producer_enterprises.push(enterprise) if enterprise.is_primary_producer
@hub_enterprises.push(enterprise) if enterprise.sells == 'any'
for product in enterprise.supplied_products
@supplied_products.push(product)

View File

@@ -1,4 +1,4 @@
angular.module('admin.order_cycles').factory('EnterpriseFee', ($resource) ->
angular.module('admin.orderCycles').factory('EnterpriseFee', ($resource) ->
EnterpriseFee = $resource('/admin/enterprise_fees/for_order_cycle/:enterprise_fee_id.json', {}, {
'index':
method: 'GET'

View File

@@ -1,15 +1,27 @@
angular.module('admin.order_cycles').factory('OrderCycle', ($resource, $window) ->
OrderCycle = $resource '/admin/order_cycles/:action_name/:order_cycle_id.json', {}, {
angular.module('admin.orderCycles').factory 'OrderCycle', ($resource, $window, StatusMessage) ->
OrderCycleResource = $resource '/admin/order_cycles/:action_name/:order_cycle_id.json', {}, {
'index': { method: 'GET', isArray: true}
'new' : { method: 'GET', params: { action_name: "new" } }
'create': { method: 'POST'}
'update': { method: 'PUT'}}
{
order_cycle: {}
new class OrderCycle
order_cycle: {incoming_exchanges: [], outgoing_exchanges: []}
showProducts: {incoming: false, outgoing: false}
loaded: false
exchangeIds: (direction) ->
parseInt(exchange.enterprise_id) for exchange in @exchangesByDirection(direction)
novelSupplier: (enterprise) =>
id = enterprise?.id || parseInt(enterprise)
@exchangeIds('incoming').indexOf(id) == -1
novelDistributor: (enterprise) =>
id = enterprise?.id || parseInt(enterprise)
@exchangeIds('outgoing').indexOf(id) == -1
exchangeSelectedVariants: (exchange) ->
numActiveVariants = 0
numActiveVariants++ for id, active of exchange.variants when active
@@ -21,6 +33,10 @@ angular.module('admin.order_cycles').factory('OrderCycle', ($resource, $window)
toggleProducts: (exchange) ->
exchange.showProducts = !exchange.showProducts
toggleAllProducts: (direction) ->
this.showProducts[direction] = !this.showProducts[direction]
exchange.showProducts = this.showProducts[direction] for exchange in this.exchangesByDirection(direction)
setExchangeVariants: (exchange, variants, selected) ->
direction = if exchange.incoming then "incoming" else "outgoing"
editable = @order_cycle["editable_variants_for_#{direction}_exchanges"][exchange.enterprise_id] || []
@@ -80,12 +96,18 @@ angular.module('admin.order_cycles').factory('OrderCycle', ($resource, $window)
distributors = (exchange.enterprise_id for exchange in this.order_cycle.outgoing_exchanges)
jQuery.unique(suppliers.concat(distributors)).sort()
exchangesByDirection: (direction) ->
if direction == 'incoming'
this.order_cycle.incoming_exchanges
else
this.order_cycle.outgoing_exchanges
removeDistributionOfVariant: (variant_id) ->
for exchange in this.order_cycle.outgoing_exchanges
exchange.variants[variant_id] = false
new: (params, callback=null) ->
OrderCycle.new params, (oc) =>
OrderCycleResource.new params, (oc) =>
delete oc.$promise
delete oc.$resolved
angular.extend(@order_cycle, oc)
@@ -100,7 +122,7 @@ angular.module('admin.order_cycles').factory('OrderCycle', ($resource, $window)
load: (order_cycle_id, callback=null) ->
service = this
OrderCycle.get {order_cycle_id: order_cycle_id}, (oc) ->
OrderCycleResource.get {order_cycle_id: order_cycle_id}, (oc) ->
delete oc.$promise
delete oc.$resolved
angular.extend(service.order_cycle, oc)
@@ -123,22 +145,33 @@ angular.module('admin.order_cycles').factory('OrderCycle', ($resource, $window)
this.order_cycle
create: ->
oc = new OrderCycle({order_cycle: this.dataForSubmit()})
oc.$create (data) ->
if data['success']
$window.location = '/admin/order_cycles'
else
create: (destination) ->
return unless @confirmNoDistributors()
oc = new OrderCycleResource({order_cycle: this.dataForSubmit()})
oc.$create (data) ->
if data['success']
$window.location = destination
else
console.log('Failed to create order cycle')
update: ->
oc = new OrderCycle({order_cycle: this.dataForSubmit()})
oc.$update {order_cycle_id: this.order_cycle.id}, (data) ->
if data['success']
$window.location = '/admin/order_cycles'
else
update: (destination) ->
return unless @confirmNoDistributors()
oc = new OrderCycleResource({order_cycle: this.dataForSubmit()})
oc.$update {order_cycle_id: this.order_cycle.id, reloading: (if destination? then 1 else 0)}, (data) =>
if data['success']
if destination?
$window.location = destination
else
StatusMessage.display 'success', 'Your order cycle has been updated.'
else
console.log('Failed to update order cycle')
confirmNoDistributors: ->
if @order_cycle.outgoing_exchanges.length == 0
confirm 'There are no distributors in this order cycle. This order cycle will not be visible to customers until you add one. Would you like to continue saving this order cycle?'
else
true
dataForSubmit: ->
data = this.deepCopy()
data = this.stripNonSubmittableAttributes(data)
@@ -200,4 +233,3 @@ angular.module('admin.order_cycles').factory('OrderCycle', ($resource, $window)
for id, active of incoming.variants
outgoing.variants[id] = active
})

View File

@@ -0,0 +1,8 @@
angular.module("admin.orderCycles").factory 'OrderCycleResource', ($resource) ->
$resource('/admin/order_cycles/:id/:action.json', {}, {
'index':
method: 'GET'
isArray: true
'update':
method: 'PUT'
})

View File

@@ -0,0 +1,40 @@
angular.module("admin.orderCycles").factory 'OrderCycles', ($q, OrderCycleResource, blankOption) ->
new class OrderCycles
orderCyclesByID: {}
pristineByID: {}
index: (params={}, callback=null) ->
includeBlank = !!params['includeBlank']
delete params['includeBlank']
OrderCycleResource.index(params, (data) =>
for orderCycle in data
@orderCyclesByID[orderCycle.id] = orderCycle
@pristineByID[orderCycle.id] = angular.copy(orderCycle)
(callback || angular.noop)(data)
data.unshift(blankOption()) if includeBlank
data
)
save: (order_cycle) ->
deferred = $q.defer()
order_cycle.$update({id: order_cycle.id})
.then( (data) =>
@pristineByID[order_cycle.id] = angular.copy(order_cycle)
deferred.resolve(data)
).catch (response) ->
deferred.reject(response)
deferred.promise
saved: (order_cycle) ->
@diff(order_cycle).length == 0
diff: (order_cycle) ->
changed = []
for attr, value of order_cycle when not angular.equals(value, @pristineByID[order_cycle.id][attr])
changed.push attr unless attr is "$$hashKey"
changed
resetAttribute: (order_cycle, attribute) ->
order_cycle[attribute] = @pristineByID[order_cycle.id][attribute]

View File

@@ -0,0 +1,22 @@
angular.module("admin.orders").controller "ordersCtrl", ($scope, $compile, $attrs, shops, orderCycles) ->
$scope.$compile = $compile
$scope.shops = shops
$scope.orderCycles = orderCycles
for oc in $scope.orderCycles
oc.name_and_status = "#{oc.name} (#{oc.status})"
$scope.distributor_id = $attrs.ofnDistributorId
$scope.order_cycle_id = $attrs.ofnOrderCycleId
$scope.validOrderCycle = (oc, index, array) ->
$scope.orderCycleHasDistributor oc, parseInt($scope.distributor_id)
$scope.distributorHasOrderCycles = (distributor) ->
(oc for oc in orderCycles when @orderCycleHasDistributor(oc, distributor.id)).length > 0
$scope.orderCycleHasDistributor = (oc, distributor_id) ->
distributor_ids = (d.id for d in oc.distributors)
distributor_ids.indexOf(distributor_id) != -1
$scope.distributionChosen = ->
$scope.distributor_id && $scope.order_cycle_id

View File

@@ -0,0 +1 @@
angular.module("admin.orders", ['ngResource'])

View File

@@ -0,0 +1,8 @@
angular.module("admin.orders").factory 'OrderResource', ($resource) ->
$resource('/admin/orders/:id/:action.json', {}, {
'index':
method: 'GET'
isArray: true
'update':
method: 'PUT'
})

View File

@@ -0,0 +1,34 @@
angular.module("admin.orders").factory 'Orders', ($q, OrderResource) ->
new class Orders
ordersByID: {}
pristineByID: {}
index: (params={}, callback=null) ->
OrderResource.index params, (data) =>
for order in data
@ordersByID[order.id] = order
@pristineByID[order.id] = angular.copy(order)
(callback || angular.noop)(data)
save: (order) ->
deferred = $q.defer()
order.$update({id: order.number})
.then( (data) =>
@pristineByID[order.id] = angular.copy(order)
deferred.resolve(data)
).catch (response) ->
deferred.reject(response)
deferred.promise
saved: (order) ->
@diff(order).length == 0
diff: (order) ->
changed = []
for attr, value of order when not angular.equals(value, @pristineByID[order.id][attr])
changed.push attr unless attr is "$$hashKey"
changed
resetAttribute: (order, attribute) ->
order[attribute] = @pristineByID[order.id][attribute]

View File

@@ -1,2 +0,0 @@
angular.module("ofn.admin").value "blankOption", ->
{ id: "0", name: "All" }

View File

@@ -0,0 +1,11 @@
angular.module("admin.utils").directive "watchValueAs", ->
restrict: 'A'
scope: {
value: "=watchValueAs"
}
link: (scope, element, attrs) ->
scope.value = element.val()
element.on "change blur load", ->
scope.$apply ->
scope.value = element.val()

View File

@@ -0,0 +1,2 @@
angular.module("admin.utils").value "blankOption", ->
{ id: "0", name: "All" }

View File

@@ -0,0 +1,26 @@
angular.module("admin.utils").factory "StatusMessage", ($timeout) ->
new class StatusMessage
types:
progress: {timeout: false, style: {color: '#ff9906'}}
alert: {timeout: 5000, style: {color: 'grey'}}
notice: {timeout: false, style: {color: 'grey'}}
success: {timeout: 5000, style: {color: '#9fc820'}}
failure: {timeout: false, style: {color: '#da5354'}}
statusMessage:
text: ""
style: {}
display: (type, text) ->
@statusMessage.text = text
@statusMessage.style = @types[type].style
$timeout.cancel @statusMessage.timeout if @statusMessage.timeout
timeout = @types[type].timeout
if timeout
@statusMessage.timeout = $timeout =>
@clear()
, timeout, true
clear: ->
@statusMessage.text = ''
@statusMessage.style = {}

View File

@@ -15,5 +15,5 @@ $(document).ready ->
$('td.cart-adjustments a').click ->
$('.cart_adjustment').toggle()
$(this).html('Item Handling Fees (included in item totals)')
$(this).html(t('item_handling_fees'))
false

View File

@@ -7,6 +7,6 @@ Darkswarm.controller "ForgotCtrl", ($scope, $http, $location, AuthenticationServ
$http.post("/user/spree_user/password", {spree_user: $scope.spree_user}).success (data)->
$scope.sent = true
.error (data) ->
$scope.errors = "Email address not found"
$scope.errors = t 'email_not_found'
else
$scope.errors = "You must provide an email address"
$scope.errors = t 'email_required'

View File

@@ -2,7 +2,7 @@ Darkswarm.controller "LoginCtrl", ($scope, $http, $window, AuthenticationService
$scope.path = "/login"
$scope.submit = ->
Loading.message = "Hold on a moment, we're logging you in"
Loading.message = t 'logging_in'
$http.post("/user/spree_user/sign_in", {spree_user: $scope.spree_user}).success (data)->
if Redirections.after_login
$window.location.href = $window.location.origin + Redirections.after_login

View File

@@ -3,18 +3,18 @@ Darkswarm.controller "PaymentCtrl", ($scope, $timeout) ->
$scope.name = "payment"
$scope.months = [
{key: "January", value: "1"},
{key: "February", value: "2"},
{key: "March", value: "3"},
{key: "April", value: "4"},
{key: "May", value: "5"},
{key: "June", value: "6"},
{key: "July", value: "7"},
{key: "August", value: "8"},
{key: "September", value: "9"},
{key: "October", value: "10"},
{key: "November", value: "11"},
{key: "December", value: "12"},
{key: t("january"), value: "1"},
{key: t("february"), value: "2"},
{key: t("march"), value: "3"},
{key: t("april"), value: "4"},
{key: t("may"), value: "5"},
{key: t("june"), value: "6"},
{key: t("july"), value: "7"},
{key: t("august"), value: "8"},
{key: t("september"), value: "9"},
{key: t("october"), value: "10"},
{key: t("november"), value: "11"},
{key: t("december"), value: "12"},
]
$scope.years = [moment().year()..(moment().year()+15)]

View File

@@ -1,14 +1,20 @@
Darkswarm.controller "GroupPageCtrl", ($scope, group_enterprises, Enterprises, MapConfiguration, OfnMap) ->
Darkswarm.controller "GroupPageCtrl", ($scope, group_enterprises, Enterprises, MapConfiguration, OfnMap, visibleFilter) ->
$scope.Enterprises = Enterprises
group_enterprises_ids = group_enterprises.map (enterprise) =>
enterprise.id
is_in_group = (enterprise) ->
group_enterprises_ids.indexOf(enterprise.id) != -1
all_enterprises_by_id = Enterprises.enterprises_by_id
$scope.group_producers = Enterprises.producers.filter is_in_group
$scope.group_hubs = Enterprises.hubs.filter is_in_group
dereferenced_enterprises = group_enterprises.map (enterprise) =>
all_enterprises_by_id[enterprise.id]
visible_enterprises = visibleFilter dereferenced_enterprises
# TODO: this is duplicate code with app/assets/javascripts/darkswarm/services/enterprises.js.coffee
# It would be better to load only the needed enterprises (group + related shops).
$scope.group_producers = visible_enterprises.filter (enterprise) ->
enterprise.category in ["producer_hub", "producer_shop", "producer"]
$scope.group_hubs = visible_enterprises.filter (enterprise) ->
enterprise.category in ["hub", "hub_profile", "producer_hub", "producer_shop"]
$scope.map = angular.copy MapConfiguration.options
$scope.mapMarkers = OfnMap.enterprise_markers group_enterprises
$scope.mapMarkers = OfnMap.enterprise_markers visible_enterprises

View File

@@ -10,7 +10,7 @@ Darkswarm.directive "ofnChangeHub", (CurrentHub, Cart) ->
if cart_will_need_emptying()
elm.bind 'click', (ev)->
if confirm "Are you sure? This will change your selected hub and remove any items in your shopping cart."
if confirm t('confirm_hub_change')
Cart.clear()
else
ev.preventDefault()

View File

@@ -12,7 +12,7 @@ Darkswarm.directive "ofnChangeOrderCycle", (OrderCycle, Cart, storage) ->
elm.bind 'change', (ev)->
if cart_needs_emptying()
if confirm "Are you sure? This will change your selected order cycle and remove any items in your shopping cart."
if confirm t('confirm_oc_change')
Cart.clear()
scope.changeOrderCycle()
else

View File

@@ -3,7 +3,7 @@ Darkswarm.directive 'mapSearch', ($timeout)->
restrict: 'E'
require: '^googleMap'
replace: true
template: '<input id="pac-input" placeholder="Type in a location..."></input>'
template: '<input id="pac-input" placeholder="' + t('location_placeholder') + '"></input>'
link: (scope, elem, attrs, ctrl)->
$timeout =>
map = ctrl.getMap()

View File

@@ -9,5 +9,5 @@ Darkswarm.directive "ofnRegistrationLimitModal", (Navigation, $modal, Loading) -
scope.modalInstance.result.then scope.close, scope.close
scope.close = ->
Loading.message = "Taking you back to the home page"
Loading.message = t 'going_back_to_home_page'
Navigation.go "/"

View File

@@ -5,6 +5,6 @@ Darkswarm.filter "date_in_words", ->
Darkswarm.filter "sensible_timeframe", (date_in_wordsFilter)->
(date) ->
if moment().add('days', 2) < moment(date)
"Orders open"
t 'orders_open'
else
"Closing #{date_in_wordsFilter(date)}"
t('closing') + date_in_wordsFilter(date)

View File

@@ -0,0 +1,7 @@
Darkswarm.filter "translate", ->
(key, options) ->
t(key, options)
Darkswarm.filter "t", ->
(key, options) ->
t(key, options)

View File

@@ -0,0 +1,9 @@
<%# Defines a global I18n object containing the language of the current locale %>
<%
# Invalidate this asset if locale changes.
Dir[Rails.root.join('config', 'locales', "#{I18n.default_locale}.yml").to_s].each do |f|
depend_on(f)
end
%>
<%- I18n.backend.send(:init_translations) unless I18n.backend.initialized? %>
window.I18n = <%= I18n.backend.send(:translations)[I18n.default_locale].with_indifferent_access.to_json.html_safe %>

View File

@@ -0,0 +1,12 @@
# Declares the translation function t.
# You can use translate('login') or t('login') in Javascript.
window.translate = (key, options = {}) ->
unless 'I18n' of window
console.log 'The I18n object is undefined. Cannot translate text.'
return key
return key unless key of I18n
text = I18n[key]
for name, value of options
text = text.split("%{#{name}}").join(value)
text
window.t = window.translate

View File

@@ -32,10 +32,10 @@ window.FieldsetMixin = ($scope)->
errors = for error, invalid of $scope.error(path)
if invalid
switch error
when "required" then "can't be blank"
when "number" then "must be number"
when "email" then "must be email address"
when "required" then t('error_required')
when "number" then t('error_number')
when "email" then t('error_email')
#server_errors = $scope.Order.errors[path.replace('order.', '')]
#errors.push server_errors if server_errors?
(errors.filter (error) -> error?).join ", "
(errors.filter (error) -> error?).join ", "

View File

@@ -28,6 +28,6 @@ Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redir
if location.pathname in ["/", "/checkout"]
Navigation.navigate "/"
else
Loading.message = "Taking you back to the home page"
Loading.message = t 'going_back_to_home_page'
location.hash = ""
location.pathname = "/"

View File

@@ -44,7 +44,7 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, storage)->
unsaved: =>
@dirty = true
$(window).bind "beforeunload", ->
"Your order hasn't been saved yet. Give us a few seconds to finish!"
t 'order_not_saved_yet'
line_items_present: =>
@line_items.filter (li)->

View File

@@ -6,7 +6,7 @@ Darkswarm.factory 'Checkout', (CurrentOrder, ShippingMethods, PaymentMethods, $h
ship_address_same_as_billing: true
submit: ->
Loading.message = "Submitting your order: please wait"
Loading.message = t 'submitting_order'
$http.put('/checkout', {order: @preprocess()}).success (data, status)=>
Navigation.go data.path
.error (response, status)=>

View File

@@ -11,7 +11,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
@enterprise[key] = value
create: =>
Loading.message = "Creating " + @enterprise.name
Loading.message = t('creating') + " " + @enterprise.name
$http(
method: "POST"
url: "/api/enterprises"
@@ -28,14 +28,13 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
Loading.clear()
if data?.errors?
errors = ("#{k.capitalize()} #{v[0]}" for k, v of data.errors when v.length > 0)
alert "Failed to create your enterprise.\n" + errors.join('\n')
alert t('failed_to_create_enterprise') + "\n" + errors.join('\n')
else
alert('Failed to create your enterprise.\nPlease ensure all fields are completely filled out.')
alert(t('failed_to_create_enterprise_unknown'))
)
# RegistrationService.select('about')
update: (step) =>
Loading.message = "Updating " + @enterprise.name
Loading.message = t('updating') + " " + @enterprise.name
$http(
method: "PUT"
url: "/api/enterprises/#{@enterprise.id}"
@@ -48,9 +47,8 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
RegistrationService.select(step)
).error((data) ->
Loading.clear()
alert('Failed to update your enterprise.\nPlease ensure all fields are completely filled out.')
alert(t('failed_to_update_enterprise_unknown'))
)
# RegistrationService.select(step)
prepare: =>
enterprise = {}

View File

@@ -16,11 +16,11 @@ Darkswarm.factory "FilterSelectorsService", ->
filterText: (active)=>
total = @totalActive()
if total == 0
if active then "Hide filters" else "Filter by"
if active then t('hide_filters') else t('filter_by')
else if total == 1
"1 filter applied"
t 'one_filter_applied'
else
"#{@totalActive()} filters applied"
@totalActive() + t('x_filters_applied')
clearAll: =>
for selector in @selectors

View File

@@ -19,5 +19,5 @@ angular.module('Darkswarm').factory "RegistrationService", (Navigation, $modal,
@current_step
close: ->
Loading.message = "Taking you back to the home page"
Loading.message = t 'going_back_to_home_page'
Navigation.go "/"

View File

@@ -1,3 +0,0 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -0,0 +1,10 @@
.ofn_drop_down{ "ofn-drop-down" => true }
%span
%i.icon-check
Actions
%i{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
%div.menu{ 'ng-show' => "expanded", style: 'width: 200px' }
%a.menu_item{ 'ng-repeat' => "link in links", href: '{{link.url}}', target: "{{link.target || '_self'}}", data: { method: "{{ link.method || 'get' }}", confirm: "{{link.confirm}}" }, style: 'display: inline-block; width: 100%' }
%span{ :style => 'text-align: center; display: inline-block; width: 20%'}
%i{ ng: { class: "link.icon" } }
%span{ style: "display: inline-block; width: auto"} {{ link.name }}

View File

@@ -15,7 +15,8 @@
%h3 Hub Shop
%p
%strong COST: 2% OF SALES, CAPPED AT $50 PER MONTH
%strong
%monthly-pricing-description{ joiner: "comma" }
%p Your enterprise is the backbone of your local food system. You aggregate produce from other enterprises and can sell it through your shop on the Open Food Network.
@@ -53,7 +54,8 @@
%h3 Producer Shop
%p
%strong COST: 2% OF SALES, CAPPED AT $50 PER MONTH
%strong
%monthly-pricing-description{ joiner: "comma" }
%p Sell your products directly to customers through your very own Open Food Network shopfront.
@@ -63,7 +65,8 @@
%h3 Producer Hub
%p
%strong COST: 2% OF SALES, CAPPED AT $50 PER MONTH
%strong
%monthly-pricing-description{ joiner: "comma" }
%p Your enterprise is the backbone of your local food system. You can sell your own produce as well as produce aggregated from other enterprises through your shopfront on the Open Food Network.
@@ -94,9 +97,7 @@
%h3 Hub Shop
%p Sell produce from others
.bottom
\2% OF SALES
%br
CAPPED AT $50 PER MONTH
%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}" } }
@@ -109,17 +110,14 @@
%h3 Producer Shop
%p Sell your own produce
.bottom
\2% OF SALES
%br
CAPPED AT $50 PER MONTH
%monthly-pricing-description{ joiner: "newline" }
%a.button.selector.producer-hub{ ng: { click: "enterprise.owned && (enterprise.sells='any')", class: "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" } }
.top
%h3 Producer Hub
%p Sell produce from self and others
.bottom
\2% OF SALES
%br
CAPPED AT $50 PER MONTH
%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" } }

View File

@@ -0,0 +1,10 @@
#save-bar.animate-show{ ng: { show: 'dirty()' } }
.twelve.columns.alpha
%h5{ ng: { show: "dirty() && !saving()" } }
You have unsaved changes
%h5{ ng: { hide: "dirty() || saving()" } }
All changes saved
%h5{ ng: { show: "saving()" } }
Saving...
.four.columns.omega.text-right
%input.red{type: "button", value: "Save Changes", ng: { click: "save()" } }

View File

@@ -1,5 +1,5 @@
%tab#forgot{"ng-controller" => "ForgotCtrl",
heading: "Forgot Password?",
heading: "{{'forgot_password' | t}}",
active: "active(path)",
select: "select(path)"}
@@ -8,7 +8,7 @@
.row
.large-12.columns
.alert-box.success.radius{"ng-show" => "sent"}
An email with instructions on resetting your password has been sent!
{{'password_reset_sent' | t}}
%div{"ng-show" => "!sent"}
.alert-box.alert{"ng-show" => "errors != null"}
@@ -16,7 +16,7 @@
.row
.large-12.columns
%label{for: "email"} Your email
%label{for: "email"} {{'signup_email' | t}}
%input.title.input-text{name: "email",
type: "email",
id: "email",
@@ -27,4 +27,4 @@
%input.button.primary{name: "commit",
tabindex: "3",
type: "submit",
value: "Reset password"}
value: "{{'reset_password' | t}}"}

View File

@@ -1,5 +1,5 @@
%tab#login-content{"ng-controller" => "LoginCtrl",
heading: "Log in",
heading: "{{'label_login' | t}}",
active: "active(path)",
select: "select(path)"}
%form{"ng-submit" => "submit()"}
@@ -9,7 +9,7 @@
{{ errors }}
.row
.large-12.columns
%label{for: "email"} Email
%label{for: "email"} {{'email' | t}}
%input.title.input-text{name: "email",
type: "email",
id: "email",
@@ -17,7 +17,7 @@
"ng-model" => "spree_user.email"}
.row
.large-12.columns
%label{for: "password"} Password
%label{for: "password"} {{'password' | t}}
%input.title.input-text{name: "password",
type: "password",
id: "password",
@@ -31,10 +31,10 @@
id: "remember_me",
value: "1",
"ng-model" => "spree_user.remember_me"}
%label{for: "remember_me"} Remember Me
%label{for: "remember_me"} {{'remember_me' | t}}
.row
.large-12.columns
%input.button.primary{name: "commit",
tabindex: "3",
type: "submit",
value: "Log in"}
value: "{{'label_login' | t}}"}

View File

@@ -1,6 +1,6 @@
%div.contact-container{bindonce: true}
%div.modal-centered{"bo-if" => "enterprise.email || enterprise.website || enterprise.phone"}
%p.modal-header Contact
%p.modal-header {{'contact' | t}}
%p{"bo-if" => "enterprise.phone", "bo-text" => "enterprise.phone"}
%p.word-wrap{"ng-if" => "enterprise.email"}

View File

@@ -3,7 +3,7 @@
/ TODO: Rob add logic for taxons and properties too:
/ %div{"ng-if" => "enterprise.long_description.length > 0 || enterprise.logo"}
%div
%p.modal-header About
%p.modal-header {{'label_about' | t}}
/ TODO: Rob - add in taxons and properties and property pop-overs
-# TODO: Add producer taxons and properties here

View File

@@ -1,5 +1,5 @@
%div.modal-centered{bindonce: true, "bo-if" => "enterprise.twitter || enterprise.facebook || enterprise.linkedin || enterprise.instagram"}
%p.modal-header Follow
%p.modal-header {{'follow' | t}}
.follow-icons
%span{"bo-if" => "enterprise.twitter"}
%a{"bo-href-i" => "http://twitter.com/{{enterprise.twitter}}", target: "_blank"}

View File

@@ -1,15 +0,0 @@
.row.pad-top{bindonce: true, "ng-if" => "enterprise.hubs.length > 0 && enterprise.is_distributor"}
.cta-container.small-12.columns
%label
Shop for
%strong{"bo-text" => "enterprise.name"}
products at:
%a.cta-hub{"ng-repeat" => "hub in enterprise.hubs",
"bo-href" => "hub.path",
"bo-class" => "{primary: hub.active, secondary: !hub.active}",
"ofn-change-hub" => "hub"}
%i.ofn-i_033-open-sign{"bo-if" => "hub.active"}
%i.ofn-i_032-closed-sign{"bo-if" => "!hub.active"}
.hub-name{"bo-text" => "hub.name"}
.button-address{"bo-bind" => "[hub.address.city, hub.address.state_name] | printArray"}
/ %i.ofn-i_007-caret-right

View File

@@ -2,16 +2,16 @@
.cta-container.small-12.columns
.row
.small-4.columns
%label{"active-table-hub-link" => "enterprise", change: "Change shop to:", shop: "Shop now at:"}
%label{"active-table-hub-link" => "enterprise", change: "{{'change_shop' | t}}", shop: "{{'shop_at' | t}}"}
.small-8.columns.right
%label.right{"bo-if" => "enterprise.pickup || enterprise.delivery"}
Delivery options:
{{'hubs_delivery_options' | t}}:
%span{"bo-if" => "enterprise.pickup"}
%i.ofn-i_038-takeaway
Pickup
{{'hubs_pickup' | t}}
%span{"bo-if" => "enterprise.delivery"}
%i.ofn-i_039-delivery
Delivery
{{'hubs_delivery' | t}}
.row
.columns.small-12
%a.cta-hub{"bo-href" => "enterprise.path",

View File

@@ -6,10 +6,7 @@
.row
.columns.small-12.fat
%div{"bo-if" => "enterprise.name"}
%label
Shop for
%span.turquoise{"bo-text" => "enterprise.name"}
products at:
%label{"bo-html" => "'shop_for_products_html' | t:{enterprise: enterprise.name}"}
%div.show-for-medium-up{"bo-if" => "!enterprise.name"}
&nbsp;
.row.cta-container

View File

@@ -4,35 +4,35 @@
.collapsed{"ng-show" => "!expanded"}
%price-percentage{percentage: 'variant.basePricePercentage'}
%a{"ng-click" => "expanded = !expanded"}
Full price breakdown
%span{"bo-text" => "'price_breakdown' | t"}
%i.ofn-i_005-caret-down
.expanded{"ng-show" => "expanded"}
%ul
%li.cost
.right {{ variant.price | localizeCurrency }}
Item cost
%span{"bo-text" => "'item_cost' | t"}
%li.admin-fee{"bo-if" => "variant.fees.admin"}
.right {{ variant.fees.admin | localizeCurrency }}
Admin fee
%span{"bo-text" => "'admin_fee' | t"}
%li.sales-fee{"bo-if" => "variant.fees.sales"}
.right {{ variant.fees.sales | localizeCurrency }}
Sales fee
%span{"bo-text" => "'sales_fee' | t"}
%li.packing-fee{"bo-if" => "variant.fees.packing"}
.right {{ variant.fees.packing | localizeCurrency }}
Packing fee
%span{"bo-text" => "'packing_fee' | t"}
%li.transport-fee{"bo-if" => "variant.fees.transport"}
.right {{ variant.fees.transport | localizeCurrency }}
Transport fee
%span{"bo-text" => "'transport_fee' | t"}
%li.fundraising-fee{"bo-if" => "variant.fees.fundraising"}
.right {{ variant.fees.fundraising | localizeCurrency }}
Fundraising fee
%span{"bo-text" => "'fundraising_fee' | t"}
%li.total
%strong
.right = {{ variant.price_with_fees | localizeCurrency }}
&nbsp;
%a{"ng-click" => "expanded = !expanded"}
Price graph
%span{"bo-text" => "'price_graph' | t"}
%i.ofn-i_006-caret-up

View File

@@ -1,5 +1,5 @@
.progress
.right Fees
.right {{'fees' | t}}
.meter
Item cost
{{'item_cost' | t}}

View File

@@ -3,7 +3,7 @@
.columns.small-12.large-6.product-header
%h3{"bo-text" => "product.name"}
%span
%em from
%em {{'products_from' | t}}
%span{"bo-text" => "enterprise.name"}
%br

View File

@@ -3,9 +3,9 @@
.row
.small-12.columns
%header
%h2 Nice one!
%h2 {{'enterprise_about_headline' | t}}
%h5
Now let's flesh out the details about
{{'enterprise_about_message' | t}}
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
{{ enterprise.name }}
@@ -13,45 +13,45 @@
.row
.small-12.columns
.alert-box.info{ "ofn-inline-alert" => true, ng: { show: "visible" } }
%h6 Success! {{ enterprise.name }} added to the Open Food Network
%span If you exit this wizard at any stage, you need to click the confirmation link in the email you have received. This will take you to your admin interface where you can continue setting up your profile.
%h6{ "ng-bind" => "'enterprise_success' | t:{enterprise: enterprise.name}" }
%span {{'enterprise_registration_exit_message' | t}}
%a.close{ ng: { click: "close()" } } &times;
.small-12.large-8.columns
.row
.small-12.columns
.field
%label{ for: 'enterprise_description' } Short Description:
%input.chunky{ id: 'enterprise_description', placeholder: "A short sentence describing your enterprise", ng: { model: 'enterprise.description' } }
%label{ for: 'enterprise_description' } {{'enterprise_description' | t}}:
%input.chunky{ id: 'enterprise_description', placeholder: "{{'enterprise_description_placeholder' | t}}", ng: { model: 'enterprise.description' } }
.row
.small-12.columns
.field
%label{ for: 'enterprise_long_desc' } Long Description:
%textarea.chunky{ id: 'enterprise_long_desc', rows: 6, placeholder: "This is your opportunity to tell the story of your enterprise - what makes you different and wonderful? We'd suggest keeping your description to under 600 characters or 150 words.", ng: { model: 'enterprise.long_description' } }
%small {{ enterprise.long_description.length }} characters / up to 600 recommended
%label{ for: 'enterprise_long_desc' } {{'enterprise_long_desc' | t}}:
%textarea.chunky{ id: 'enterprise_long_desc', rows: 6, placeholder: "{{'enterprise_long_desc_placeholder' | t}}", ng: { model: 'enterprise.long_description' } }
%small{ "ng-bind" => "'enterprise_long_desc_length' | t:{num: enterprise.long_description.length}" }
.small-12.large-4.columns
.row
.small-12.columns
.field
%label{ for: 'enterprise_abn' } ABN:
%input.chunky{ id: 'enterprise_abn', placeholder: "eg. 99 123 456 789", ng: { model: 'enterprise.abn' } }
%label{ for: 'enterprise_abn' } {{'enterprise_abn' | t}}:
%input.chunky{ id: 'enterprise_abn', placeholder: "{{'enterprise_abn_placeholder' | t}}", ng: { model: 'enterprise.abn' } }
.row
.small-12.columns
.field
%label{ for: 'enterprise_acn' } ACN:
%input.chunky{ id: 'enterprise_acn', placeholder: "eg. 123 456 789", ng: { model: 'enterprise.acn' } }
%label{ for: 'enterprise_acn' } {{'enterprise_acn' | t}}:
%input.chunky{ id: 'enterprise_acn', placeholder: "{{'enterprise_acn_placeholder' | t}}", ng: { model: 'enterprise.acn' } }
.row
.small-12.columns
.field
%label{ for: 'enterprise_charges_sales_tax' }= t(:charges_sales_tax)
%input{ id: 'enterprise_charges_sales_tax_true', type: 'radio', name: 'charges_sales_tax', value: 'true', required: true, ng: { model: 'enterprise.charges_sales_tax' } }
%label{ for: 'enterprise_charges_sales_tax_true' } Yes
%label{ for: 'enterprise_charges_sales_tax_true' } {{'say_yes' | t}}
%input{ id: 'enterprise_charges_sales_tax_false', type: 'radio', name: 'charges_sales_tax', value: 'false', required: true, ng: { model: 'enterprise.charges_sales_tax' } }
%label{ for: 'enterprise_charges_sales_tax_false' } No
%label{ for: 'enterprise_charges_sales_tax_false' } {{'say_no' | t}}
%span.error.small-12.columns{ ng: { show: "about.charges_sales_tax.$error.required && submitted" } }
You need to make a selection.
{{'enterprise_tax_required' | t}}
.row.buttons.pad-top
.small-12.columns
%input.button.primary.right{ type: "submit", value: "Continue" }
%input.button.primary.right{ type: "submit", value: "{{'continue' | t}}" }

View File

@@ -3,28 +3,27 @@
.row
.small-12.columns
%header
%h2 Greetings!
%h5
Who is responsible for managing {{ enterprise.name }}?
%h2 {{'registration_greeting' | t}}
%h5{ "ng-bind" => "'who_is_managing_enterprise' | t:{enterprise: enterprise.name}" }
%form{ name: 'contact', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('type',contact)" } }
.row.content
.small-12.medium-12.large-7.columns
.row
.small-12.columns.field
%label{ for: 'enterprise_contact' } Primary Contact:
%label{ for: 'enterprise_contact' } {{'enterprise_contact' | t}}:
%input.chunky.small-12.columns{ id: 'enterprise_contact', name: 'contact', required: true, placeholder: "Contact Name", ng: { model: 'enterprise.contact' } }
%span.error.small-12.columns{ ng: { show: "contact.contact.$error.required && submitted" } }
You need to enter a primary contact.
{{'enterprise_contact_required' | t}}
.row
.small-12.columns.field
%label{ for: 'enterprise_email' } Email address:
%label{ for: 'enterprise_email' } {{'enterprise_email' | t}}:
%input.chunky.small-12.columns{ id: 'enterprise_email', name: 'email', type: 'email', required: true, placeholder: "eg. charlie@thefarm.com", ng: { model: 'enterprise.email' } }
%span.error.small-12.columns{ ng: { show: "(contact.email.$error.email || contact.email.$error.required) && submitted" } }
You need to enter valid email address.
{{'enterprise_email_required' | t}}
.row
.small-12.columns.field
%label{ for: 'enterprise_phone' } Phone number:
%label{ for: 'enterprise_phone' } {{'enterprise_phone' | t}}:
%input.chunky.small-12.columns{ id: 'enterprise_phone', name: 'phone', placeholder: "eg. (03) 1234 5678", ng: { model: 'enterprise.phone' } }
.small-12.medium-12.large-5.hide-for-small-only
/ %h6
@@ -43,5 +42,5 @@
.row.buttons
.small-12.columns
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('details')" } }
%input.button.primary.right{ type: "submit", value: "Continue" }
%input.button.secondary{ type: "button", value: "{{'back' | t}}", ng: { click: "select('details')" } }
%input.button.primary.right{ type: "submit", value: "{{'continue' | t}}" }

View File

@@ -3,75 +3,62 @@
.row
.small-12.columns
%header
%h2 Let's Get Started
%h5{ bo: { if: "enterprise.type != 'own'" } } Woot! First we need to know a little bit about your enterprise:
%h5{ bo: { if: "enterprise.type == 'own'" } } Woot! First we need to know a little bit about your farm:
%h2 {{'registration_detail_headline' | t}}
%h5{ bo: { if: "enterprise.type != 'own'" } } {{'registration_detail_enterprise' | t}}
%h5{ bo: { if: "enterprise.type == 'own'" } } {{'registration_detail_producer' | t}}
%form{ name: 'details', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('contact',details)" } }
.row
.small-12.medium-9.large-12.columns.end
.field
%label{ for: 'enterprise_name', bo: { if: "enterprise.type != 'own'" } } Enterprise Name:
%label{ for: 'enterprise_name', bo: { if: "enterprise.type == 'own'" } } Farm Name:
%input.chunky{ id: 'enterprise_name', name: 'name', placeholder: "e.g. Charlie's Awesome Farm", required: true, ng: { model: 'enterprise.name' } }
%label{ for: 'enterprise_name', bo: { if: "enterprise.type != 'own'" } } {{'registration_detail_name_enterprise' | t}}
%label{ for: 'enterprise_name', bo: { if: "enterprise.type == 'own'" } } {{'registration_detail_name_producer' | t}}
%input.chunky{ id: 'enterprise_name', name: 'name', placeholder: "{{'registration_detail_name_placeholder' | t}}", required: true, ng: { model: 'enterprise.name' } }
%span.error{ ng: { show: "details.name.$error.required && submitted" } }
Please choose a unique name for your enterprise
{{'registration_detail_name_error' | t}}
.row
.small-12.medium-9.large-6.columns
.field
%label{ for: 'enterprise_address' } Address line 1:
%input.chunky{ id: 'enterprise_address', name: 'address1', required: true, placeholder: "e.g. 123 Cranberry Drive", required: true, ng: { model: 'enterprise.address.address1' } }
%label{ for: 'enterprise_address' } {{'registration_detail_address1' | t}}
%input.chunky{ id: 'enterprise_address', name: 'address1', required: true, placeholder: "{{'registration_detail_address1_placeholder' | t}}", required: true, ng: { model: 'enterprise.address.address1' } }
%span.error{ ng: { show: "details.address1.$error.required && submitted" } }
Please enter an address
{{'registration_detail_address1_error' | t}}
.field
%label{ for: 'enterprise_address2' } Address line 2:
%label{ for: 'enterprise_address2' } {{'registration_detail_address2' | t}}
%input.chunky{ id: 'enterprise_address2', name: 'address2', required: false, placeholder: "", required: false, ng: { model: 'enterprise.address.address2' } }
.small-12.medium-9.large-6.columns.end
.row
.small-12.medium-8.large-8.columns
.field
%label{ for: 'enterprise_city' } Suburb:
%input.chunky{ id: 'enterprise_city', name: 'city', required: true, placeholder: "e.g. Northcote", ng: { model: 'enterprise.address.city' } }
%label{ for: 'enterprise_city' } {{'registration_detail_suburb' | t}}
%input.chunky{ id: 'enterprise_city', name: 'city', required: true, placeholder: "{{'registration_detail_suburb_placeholder' | t}}", ng: { model: 'enterprise.address.city' } }
%span.error{ ng: { show: "details.city.$error.required && submitted" } }
Please enter a suburb
{{'registration_detail_suburb_error' | t}}
.small-12.medium-4.large-4.columns
.field
%label{ for: 'enterprise_zipcode' } Postcode:
%input.chunky{ id: 'enterprise_zipcode', name: 'zipcode', required: true, placeholder: "e.g. 3070", ng: { model: 'enterprise.address.zipcode' } }
%label{ for: 'enterprise_zipcode' } {{'registration_detail_postcode' | t}}
%input.chunky{ id: 'enterprise_zipcode', name: 'zipcode', required: true, placeholder: "{{'registration_detail_postcode_placeholder' | t}}", ng: { model: 'enterprise.address.zipcode' } }
%span.error{ ng: { show: "details.zipcode.$error.required && submitted" } }
Postcode required
{{'registration_detail_postcode_error' | t}}
.row
.small-12.medium-4.large-4.columns
.field
%label{ for: 'enterprise_state' } State:
%label{ for: 'enterprise_state' } {{'registration_detail_state' | t}}
%select.chunky{ id: 'enterprise_state', name: 'state', ng: { model: 'enterprise.address.state_id', options: 's.id as s.abbr for s in enterprise.country.states', show: 'countryHasStates()', required: 'countryHasStates()' } }
%span.error{ ng: { show: "details.state.$error.required && submitted" } }
State required
{{'registration_detail_state_error' | t}}
.small-12.medium-8.large-8.columns
.field
%label{ for: 'enterprise_country' } Country:
%label{ for: 'enterprise_country' } {{'registration_detail_country' | t}}
%select.chunky{ id: 'enterprise_country', name: 'country', required: true, ng: { model: 'enterprise.country', options: 'c as c.name for c in countries' } }
%span.error{ ng: { show: "details.country.$error.required && submitted" } }
Please select a country
/ .small-12.medium-12.large-5.hide-for-small-only
/ %h6
/ Location display
/ %i.ofn-i_013-help.has-tip{ 'data-tooltip' => true, title: "Choose how you want to display your enterprise's address on the Open Food Network. By default, full location is shown everywhere including street name and number."}
/ .row
/ .small-12.columns
/ %label.indent-checkbox
/ %input{ type: 'checkbox', id: 'enterpise_suburb_only', ng: { model: 'enterprise.suburb_only' } }
/ Hide my street name and street number from the public (ie. only show the suburb)
/ .small-12.columns
/ %label.indent-checkbox
/ %input{ type: 'checkbox', id: 'enterprise_on_map', ng: { model: 'enterprise.on_map' } }
/ Blur my location on the map (show an approximate, not exact pin)
{{'registration_detail_country_error' | t}}
.row.buttons
.small-12.columns
%hr
%input.button.primary.right{ type: "submit", value: "Continue" }
%input.button.primary.right{ type: "submit", value: "{{'continue' | t}}" }

View File

@@ -2,23 +2,14 @@
.row
.small-12.columns.pad-top
%header
%h2 Finished!
%h2 {{'registration_finished_headline' | t}}
.panel.callout
%p
Thanks for filling out the details for
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
{{ enterprise.name }}
%p You can change or update your enterprise at any stage by logging into Open Food Network and going to Admin.
%p{ "ng-bind" => "'registration_finished_thanks' | t:{enterprise: enterprise.name}" }
%p {{'registration_finished_login' | t}}
.row
.small-12.columns.text-center
%h4
Activate
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
{{ enterprise.name }}
%h4{ "ng-bind" => "'registration_finished_activate' | t:{enterprise: enterprise.name}" }
%p
We've sent a confirmation email to
%strong {{ enterprise.email }} if it hasn't been activated before.
%br Please follow the instructions there to make your enterprise visible on the Open Food Network.
%p{ "ng-bind-html" => "t('registration_finished_activate_instruction_html', {email: enterprise.email})"}
%a.button.primary{ type: "button", href: "/" } Open Food Network home &gt;
%a.button.primary{ type: "button", href: "/" } {{'registration_finished_action' | t}} &gt;

View File

@@ -3,8 +3,8 @@
.row
.small-12.columns
%header
%h2 Thanks!
%h5 Let's upload some pretty pictures so your profile looks great! :)
%h2 {{'registration_images_headline' | t}}
%h5 {{'registration_images_description' | t}}
%form{ name: 'images', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "select('social')" } }
.row{ ng: { repeat: 'image_step in imageSteps', show: "imageStep == image_step" } }
@@ -18,5 +18,5 @@
.row.buttons.pad-top{ ng: { if: "imageStep == 'promo'" } }
.small-12.columns
%input.button.secondary{ type: "button", value: "Back", ng: { click: "imageSelect('logo')" } }
%input.button.primary.right{ type: "submit", value: "Continue" }
%input.button.secondary{ type: "button", value: "{{'back' | t}}", ng: { click: "imageSelect('logo')" } }
%input.button.primary.right{ type: "submit", value: "{{'continue' | t}}" }

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