Compare commits

...

194 Commits

Author SHA1 Message Date
Rohan Mitchell
f03d9b66f0 Update spree_paypal_express to fail gracefully when setting address 2012-10-31 15:17:05 +11:00
Rohan Mitchell
5dcba7403b Avoid contaminating test data 2012-10-31 13:54:14 +11:00
Rohan Mitchell
926440a978 Fix namespacing of Distributor in reports controller 2012-10-31 11:13:55 +11:00
Rohan Mitchell
9b32579bd6 Group buy report handles nil variant weight gracefully 2012-10-31 10:37:40 +11:00
Rohan Mitchell
5ac904005b Merge branch 'order-cycle-reports'
Conflicts:
	app/controllers/spree/admin/reports_controller_decorator.rb
	config/routes.rb
2012-10-31 10:18:11 +11:00
Rohan Mitchell
03610c93de Upgrade capybara and selenium-webdriver for compatibility with Firefox 16 2012-10-28 12:28:55 +11:00
Rohan Mitchell
c5941d6cb5 Update distributor details when distributor is changed 2012-10-27 18:50:09 +11:00
Rohan Mitchell
773adca838 Display distributor details on product page when distributor is selected 2012-10-27 12:49:57 +11:00
Rohan Mitchell
13317347bb Display an explanation message on product page when no distributor is selected 2012-10-27 12:19:44 +11:00
Rob H
f960cc44ba Fixed calculations when variant weight is nil 2012-10-26 17:27:08 +11:00
Rob H
a9293709d8 Merge branch 'master', remote-tracking branch 'origin' 2012-10-26 17:24:17 +11:00
Rohan Mitchell
a3042118c7 Merge branch 'group-reports'
Conflicts:
	app/controllers/spree/admin/reports_controller_decorator.rb
	config/routes.rb
2012-10-26 17:14:49 +11:00
Rob H
ede4649fbf Merge branch 'master', remote-tracking branch 'origin' 2012-10-26 16:12:11 +11:00
Rob H
4dd5e12968 Fix reports controller, previous changes to fix change generate_report were incomplete 2012-10-26 13:49:39 +11:00
Rob H
d74591afe6 Fixes to reports controller and addition of order cycles reports 2012-10-26 13:44:13 +11:00
Rohan Mitchell
09b60908b8 Fix links to admin distributor edit and delete 2012-10-25 12:20:20 +11:00
Rohan Mitchell
d1b9ce92f6 Move distributors helper out of spree namespace 2012-10-25 10:45:39 +11:00
Rohan Mitchell
784969097d Move admin non-Spree controllers out of Spree namespace 2012-10-25 10:45:39 +11:00
Rohan Mitchell
15e91f7743 WIP Move non-admin non-Spree controllers out of Spree namespace 2012-10-25 10:45:39 +11:00
Rohan Mitchell
c46019d68c WIP: Move Supplier, Distributor, DistributorSet and ProductDistribution models out of Spree namespace 2012-10-25 10:45:39 +11:00
Rohan Mitchell
aa336d9b9f Merge branch 'feedback' 2012-10-25 10:34:27 +11:00
Rob H
ff029b8903 Add feedback bar to all pages on the front end 2012-10-24 18:26:21 +11:00
Rob H
a362dd5161 Change reports controller: generate_report to render_report 2012-10-24 17:01:50 +11:00
Rohan Mitchell
51850be83e Update spree_paypal_express to handle blank states from paypal 2012-10-24 16:19:53 +11:00
Rob H
41d547ac2d Minor formatting changes to Order Group Spec 2012-10-24 16:13:23 +11:00
Rob H
81b33772fe Fixes to syntax and formatting for group-reports 2012-10-24 15:21:16 +11:00
Rohan Mitchell
32db258db0 Use spree_heroku with support for staging env 2012-10-24 13:11:40 +11:00
Rob H
3b855a866a Merge branch 'grouper-reports' into group-reports 2012-10-22 11:35:56 +11:00
Rob H
eb7d69fe6b commit routes.rb file to prevent overwriting 2012-10-22 11:35:48 +11:00
Rob H
4c0109bccc Merge branch 'master', remote-tracking branch 'origin' 2012-10-22 11:15:23 +11:00
Rob H
f83a5b0ba8 Merge branch 'master', remote-tracking branch 'origin' 2012-10-22 10:45:35 +11:00
Rob H
ddb01e4ccb WIP: Create report grouper, write reports for bulk co-ops and payments 2012-10-21 13:12:48 +11:00
Rohan Mitchell
87a89324d9 Update repo in readme, add Rob to creds 2012-10-19 17:02:09 +11:00
Rohan Mitchell
4fc7295b97 Use S3 configuration from environment vars instead of s3.yml 2012-10-19 16:40:18 +11:00
Rohan Mitchell
5b025a6cba Make group_buy_unit_size accessible 2012-10-18 15:15:54 +11:00
Rohan Mitchell
9166829930 Add group buy unit size field 2012-10-18 11:56:21 +11:00
Rohan Mitchell
8c7a02ec10 Fix image uploads with CMS 2012-10-18 11:13:40 +11:00
Rohan Mitchell
f4f250675c Use eaterprises spree_paypal_express with Bugsnag notification of paypal gateway errors 2012-10-18 10:30:35 +11:00
Rohan Mitchell
394a269df2 Update Spree, fixes paypal password blanking bug. Update spree_paypal_express, fixes nil state error on checkout. 2012-10-18 10:17:52 +11:00
Rohan Mitchell
41dcc85ad1 Update version of spree_paypal_express for debugging 2012-10-17 15:26:06 +11:00
Rohan Mitchell
9be9d75cb5 Update version of spree_paypal_express for debugging 2012-10-17 15:10:04 +11:00
Rohan Mitchell
11483a77e8 Update bugsnag and spree_paypal_express for paypal error debugging 2012-10-17 08:42:33 +11:00
Rohan Mitchell
ba895ed486 Display CMS content for suppliers page 2012-10-17 07:54:12 +11:00
Rohan Mitchell
36d342f216 Add view all suppliers page 2012-10-17 07:50:58 +11:00
Rohan Mitchell
d09123eb22 Do not show suppliers with no products in stock 2012-10-17 07:36:18 +11:00
Rohan Mitchell
642f58551c Use spree_paypal_express from RohanM with debugging for nil state from paypal address error 2012-10-16 10:34:11 +11:00
Rohan Mitchell
9fbcd8c01b Display CMS pages with Spree's layout 2012-10-12 10:21:21 +11:00
Rohan Mitchell
927970d1a9 Viewing another products listing page does not display home page content 2012-10-12 09:39:49 +11:00
Rohan Mitchell
3dd3d8030f Display CMS pages in menu 2012-10-11 17:00:34 +11:00
Rohan Mitchell
cab61ddb7c CMS content on home page 2012-10-11 16:21:33 +11:00
Rohan Mitchell
015b7f88b0 Add tests for CMS admin security 2012-10-11 13:17:05 +11:00
Rohan Mitchell
28fc16ac66 Create links between Spree and CMS admin sections 2012-10-11 12:50:59 +11:00
Rohan Mitchell
e1d4ee318c Fix issues with elRTE - sprites and functionality now work for link and image functions 2012-10-11 12:00:30 +11:00
Rohan Mitchell
48497266da Precompile CMS assets 2012-10-11 11:06:52 +11:00
Rohan Mitchell
fe5fd76415 Further syntax fixes for GroupBuyReport 2012-10-11 10:53:33 +11:00
Rohan Mitchell
c05911fa10 Fix spree_creditcards table renamed in Spree 1.2 upgrade, remove old pending test 2012-10-11 10:50:37 +11:00
Rohan Mitchell
a686a820d9 Add distributor show page, redirect here after selecting distributor 2012-10-11 10:50:36 +11:00
Rohan Mitchell
3889545f2b Convert suppliers page to HAML 2012-10-11 10:50:36 +11:00
Rohan Mitchell
7432cb416e Andand all the html_safes 2012-10-11 10:50:36 +11:00
Rohan Mitchell
0b830a7845 Suppliers and distributors long description editable with WYSIWYG editor from CMS and displayed as HTML 2012-10-11 10:50:36 +11:00
Rohan Mitchell
58e5724f81 Display supplier details on supplier page 2012-10-11 10:50:36 +11:00
Rohan Mitchell
c07a33d88c Edit long description field in admin for suppliers and distributors 2012-10-11 10:50:36 +11:00
Rohan Mitchell
d080aa49d5 Add long description field to distributors and suppliers 2012-10-11 10:50:36 +11:00
Rohan Mitchell
a31c5bbe46 Authorise CMS via Spree login 2012-10-11 10:50:36 +11:00
Rohan Mitchell
b35fb618f3 Add base install of Comfortable Mexican Sofa 2012-10-11 10:50:36 +11:00
Rob H
8c7ed6f4ef Merge branch 'group-buy-report' 2012-10-10 15:47:02 +11:00
Rob H
1709083d8f Merge branch 'master' of github.com:andrewspinks/openfoodweb 2012-10-10 15:45:42 +11:00
Rob H
5803da9c55 Syntax fixes for group buy report classes and tests 2012-10-10 15:13:15 +11:00
Rohan Mitchell
0ad6045363 Fix struct superclass mismatch error 2012-10-10 14:02:44 +11:00
Rob H
9737f21bb8 WIP: Write body of group buy report 2012-10-10 13:46:51 +11:00
Rohan Mitchell
2535e3965b When merging orders, set distributor when target order distributor is nil 2012-10-09 08:42:29 +11:00
Rohan Mitchell
568d948cbe Destroy incomplete orders if they can't be merged, prevents that order unexpectedly appearing in cart after checkout. Also ensure all orders have a shipping method. 2012-10-05 12:09:53 +10:00
Rob H
d7a5a87aef create group buy report, display header 2012-10-03 11:49:21 +10:00
Rob H
3b8c41840f Merge branch 'master' of github.com:andrewspinks/openfoodweb
Conflicts:
	app/models/spree/line_item_decorator.rb
	db/migrate/20120919013335_add_shipping_method_to_line_items.rb
2012-10-03 10:27:19 +10:00
Rohan Mitchell
6d9257d941 Do not delete shipping method referenced by a line item 2012-10-02 12:15:09 +10:00
Rohan Mitchell
7430fc9bdd Do not delete shipping method referenced by a product distribution 2012-10-02 11:58:18 +10:00
Rohan Mitchell
473b4e9adc Add positive case test 2012-10-02 11:54:18 +10:00
Rohan Mitchell
2aa450b072 Do not delete shipping method referenced by an order 2012-10-02 11:51:13 +10:00
Rohan Mitchell
3886ec39f7 Add web helper method to visit paths with delete method 2012-10-02 11:47:55 +10:00
Rohan Mitchell
afb8faa96f Update zeus config 2012-10-02 11:44:50 +10:00
Rohan Mitchell
27b7d59f46 BaseController does not attempt to merge incomplete and current orders when they have differing distributors 2012-10-02 09:44:51 +10:00
Rohan Mitchell
bc408d8b6e Add jquery and jquery_ujs includes to admin/all.js, as these have been removed from spree/admin/spree_core.js 2012-09-22 09:20:27 +10:00
Rohan Mitchell
a8758f1271 Fix OrdersHelper for upgraded spree 2012-09-21 16:36:50 +10:00
Rohan Mitchell
2bce9df25a Track 1-1-stable on spree git, fixes order quantity change bug 2012-09-21 15:55:51 +10:00
Rohan Mitchell
479c49752c Update spree_paypal_express, hopefully fixing 'Validation failed: State can't be blank' error 2012-09-21 15:32:19 +10:00
Rohan Mitchell
62d6067c1a Do not truncate cents for product price update on add to cart JS 2012-09-21 12:44:38 +10:00
Rohan Mitchell
a1b5102476 Fix checkout totals, also amend factories for valid test shipping method data 2012-09-21 12:35:01 +10:00
Rohan Mitchell
593f3887c8 Switch pry for pry-debugger 2012-09-21 12:29:06 +10:00
Rohan Mitchell
757456dd57 Set line item shipping method in callback so that Order#update shipping calcs run correctly 2012-09-20 10:45:50 +10:00
Rohan Mitchell
3894ce946d Fix error on supplier page, add test to cover 2012-09-19 15:46:56 +10:00
Rohan Mitchell
f1f9b5b2e8 Make order and distributor report resilient to orders without distributors 2012-09-19 15:19:30 +10:00
Rohan Mitchell
5402590d5f Add debug output on line item migration for lost data 2012-09-19 15:08:05 +10:00
Rohan Mitchell
eaca160367 Set line item shipping method when added to cart, update specs for changes to line item shipping method 2012-09-19 15:01:50 +10:00
Rohan Mitchell
85f18cfb12 Rob: Replace LineItem shipping_method method with relation 2012-09-19 14:27:28 +10:00
Rob H
fe3743af16 Replace shipping method lookup with relation 2012-09-19 12:06:43 +10:00
Rohan Mitchell
7492522066 Improve clarity of various totals (items, shipping, grand total) on checkout page 2012-09-14 15:35:22 +10:00
Rohan Mitchell
334f84637d Fix empty cart button alignment at checkout 2012-09-14 13:32:49 +10:00
Rohan Mitchell
3f15fc0b52 Set default admin orders view to sort with most recent orders first 2012-09-14 13:27:33 +10:00
Rohan Mitchell
a013854d2d Change logo to Eaterprises, update link colour to match 2012-09-14 11:25:36 +10:00
Rohan Mitchell
c883ab87b6 Add db backups and uploaded images to gitignore 2012-09-14 10:32:10 +10:00
Rohan Mitchell
0e313e5826 Add Zeus config 2012-09-14 10:23:22 +10:00
Rohan Mitchell
3794c00856 Upgrade Rails to 3.2.8 and Spree to 1.1.3 2012-09-14 10:20:52 +10:00
Rohan Mitchell
b87c59c051 Default to blank distributor on add to cart to require user to select one 2012-09-13 15:29:04 +10:00
Rohan Mitchell
356ae40c7b Display product descriptions as HTML in checkout 2012-09-13 13:05:12 +10:00
Rohan Mitchell
8394c47064 Add admin js includes 2012-09-13 12:27:20 +10:00
Rohan Mitchell
a84f6f08eb Compile all admin javascripts, fixes admin/images/new.js not found error 2012-09-13 12:20:35 +10:00
Rohan Mitchell
3a391d1e76 Give undefined payment method tolerance to orders and distributors report 2012-08-08 15:30:25 +10:00
Rohan Mitchell
9dd94eaf57 Weight shipping calculator treats variants without weight defined as zero weight 2012-08-08 15:29:47 +10:00
Rohan Mitchell
9f013f0e37 When loading distributors for sidebar, only show those that have active products on hand 2012-08-04 17:51:08 +10:00
Rohan Mitchell
f0ec3080e4 Remove instrumentation 2012-08-04 17:50:30 +10:00
Rohan Mitchell
245de4fe1a Add instrumentation to debug products not appearing on distributor view 2012-08-04 16:52:18 +10:00
Rohan Mitchell
9d33ef460c Max quantity field doesn't affect JS price calcs on products without variants 2012-08-04 16:51:43 +10:00
Rohan Mitchell
e0b8b8b4d4 Force precompile admin css and js 2012-08-04 10:27:15 +10:00
Rohan Mitchell
529de72f75 Force precompilation of store/all.css and store/all.js 2012-08-04 10:23:00 +10:00
Rohan Mitchell
b4f867924b Do not connect to db during asset precompile, fix heroku deploy to cedar 2012-08-04 10:12:06 +10:00
Rohan Mitchell
9d3afe80c6 split_products_by_distributor was not written with pre-pagination by searcher in mind, resulting in silently dropped products. Disable pagination at searcher. 2012-08-03 18:47:33 +10:00
Rohan Mitchell
28e75d6467 Fix add to cart JS for compatibility with group buy 2012-08-03 18:32:19 +10:00
Rohan Mitchell
b0fa05df0c Remove assets from git 2012-08-03 18:31:28 +10:00
Rohan Mitchell
f3ffba378a Add a product with variants to the cart with max quantity for a group buy 2012-08-03 18:05:45 +10:00
Rohan Mitchell
2d89640271 Instrument orders controller to debug populate_variant_attributes 2012-08-03 14:11:59 +10:00
Rohan Mitchell
e6ee6b5164 Itemwise shipping calculator returns 0 instead of nil when there are no items 2012-08-03 08:44:53 +10:00
Rohan Mitchell
768a170bb8 Fix with_products_on_hand query for server db compatibility 2012-08-03 08:21:45 +10:00
Rohan Mitchell
8834268970 Fix error on no shipping method defined 2012-08-02 17:45:22 +10:00
Rohan Mitchell
fe61b4aab1 Display shipping fee at all steps of the checkout process, not just after delivery method is chosen 2012-08-02 16:24:08 +10:00
Rohan Mitchell
a6c2490597 Enable auto-capture for spree_paypal_express 2012-08-02 15:45:31 +10:00
Rohan Mitchell
9110dc6414 Fix form local var naming for admin shared address form 2012-08-02 15:33:39 +10:00
Rohan Mitchell
77be0dd6eb Adding a product with a max quantity less than quantity results in max_quantity==quantity 2012-08-02 15:26:13 +10:00
Rohan Mitchell
40544eb27b Adding a product to cart that is not a group buy does not show max quantity field 2012-08-02 15:16:44 +10:00
Rohan Mitchell
306cb5b089 Add max quantity to order and distributor report 2012-08-02 15:07:34 +10:00
Rohan Mitchell
c46613877c Add max quantity field to add to cart form, add end-to-end test for max_quantity 2012-08-02 14:45:55 +10:00
Rohan Mitchell
2db2fbcade Change set_variant_attribute to set_variant_attributes, implement it on Order 2012-08-02 14:45:27 +10:00
Rohan Mitchell
ea05f05576 When adding a group buy product to the cart, set the max quantity on the order 2012-08-02 14:29:05 +10:00
Rohan Mitchell
361a87f580 Add group buy option to new/edit product in admin 2012-08-02 13:42:47 +10:00
Rohan Mitchell
330c62716c Add fields for group buy feature 2012-08-02 13:15:17 +10:00
Rohan Mitchell
63bf25293d Only show distributors in sidebar that have products in stock 2012-08-02 11:49:10 +10:00
Rohan Mitchell
93867682bb Only show distributors in sidebar that have products 2012-08-02 11:33:36 +10:00
Rohan Mitchell
7d5c158021 Install Bugsnag 2012-08-02 10:32:33 +10:00
Rohan Mitchell
06c6422591 Fix by-weight calculator to take line item quantity into account 2012-07-23 18:49:03 +10:00
Rohan Mitchell
5e04032797 Explicitly specify Spree 1.1.1, fix test regression in OrdersController 2012-07-23 18:48:30 +10:00
Andrew Spinks
f716176361 specify ruby version in Gemfile as per heroku requirement: https://devcenter.heroku.com/articles/ruby-versions 2012-07-20 20:40:55 +10:00
Andrew Spinks
2826f62497 Add extra details to the order report. 2012-07-20 20:25:53 +10:00
Andrew Spinks
7172fe0c87 added extra fields to order report. 2012-07-20 00:07:41 +10:00
Andrew Spinks
7e9a84087e cleaning up order report 2012-07-19 22:48:42 +10:00
Andrew Spinks
58e9cd3eeb fix distributor name in report 2012-07-15 21:00:10 +10:00
Andrew Spinks
54559c4a5f first cut at orders report. 2012-07-15 20:48:10 +10:00
Andrew Spinks
8f5b5e7ae4 allow shipping instructions to be provided. 2012-07-11 23:33:03 +10:00
Andrew Spinks
759ceae23f add distributor name to confirmation email 2012-07-11 23:20:59 +10:00
Andrew Spinks
32b37a1390 add padding to the second address line. 2012-07-11 22:45:57 +10:00
Andrew Spinks
0e43fcfaa1 adjust address formatting in confirmation email. 2012-07-11 22:25:42 +10:00
Andrew Spinks
6a27f8da32 update formatting of confirmation email. 2012-07-11 22:15:46 +10:00
Andrew Spinks
c24543c237 Add delivery details to confirmation email. 2012-07-11 22:07:18 +10:00
Andrew Spinks
44314ccb99 copied original spree confirmation mail 2012-07-11 21:35:07 +10:00
Andrew Spinks
9ad42a3966 adding precompiled assets 2012-07-11 20:46:20 +10:00
Andrew Spinks
d34e6570fc trying to get asset precompilation to work on deploy 2012-07-11 20:39:49 +10:00
Andrew Spinks
b5b35491cc allow asset precompile to work on new heroku instance 2012-07-07 10:17:33 +10:00
Rohan Mitchell
1e471e5e22 Name all form-containing partials with _form, tweak admin new product form 2012-07-02 16:28:31 +10:00
Rohan Mitchell
aa027f6e29 Display subtotal for delivery fees 2012-07-02 16:13:55 +10:00
Rohan Mitchell
6f581fce43 Admin can edit next collection date/time when editing an individual distributor 2012-07-02 14:36:45 +10:00
Rohan Mitchell
8156da509e Display distributor next collection time in checkout process 2012-07-02 14:32:53 +10:00
Rohan Mitchell
718e54f933 Add distributor next_collection_at field, bulk edit in admin backend 2012-07-02 14:24:52 +10:00
Rohan Mitchell
cb56e9f658 Display delivery fee breakdown along with cart 2012-07-01 19:09:34 +10:00
Rohan Mitchell
9afa566be5 Add spree_last_address extension, which retrieves a customer's address when they order a second time so they don't need to retype it 2012-07-01 11:44:18 +10:00
Rohan Mitchell
86847d99da Make Leave Distributor link more intuitive 2012-07-01 11:33:40 +10:00
Rohan Mitchell
258559f9d0 Update the price on the product details page in real time when the variant or the quantity are changed 2012-07-01 10:07:08 +10:00
Rohan Mitchell
af05448dd8 For check payment method, display description after purchase for use with EFT 2012-06-29 15:27:30 +10:00
Rohan Mitchell
e74f9054ae Fix seeds: shipping and payment info created for successful checkout out of the box 2012-06-29 15:03:32 +10:00
Rohan Mitchell
82dd485e01 Install spree_paypal_express gem 2012-06-29 14:40:20 +10:00
Rohan Mitchell
1d5e4d22e7 Add pending spree migrations 2012-06-29 14:34:19 +10:00
Rohan Mitchell
28d2292de0 Add by-weight shipping calculator 2012-06-29 12:46:33 +10:00
Rohan Mitchell
73e601315b Add acceptance spec for itemwise shipping fees 2012-06-29 11:50:43 +10:00
Rohan Mitchell
a0c1d1d255 Look up a product's shipping method though a particular distributor 2012-06-29 11:02:34 +10:00
Rohan Mitchell
411ba107ce Perform shipping calculation in line item model 2012-06-29 10:47:11 +10:00
Rohan Mitchell
4f1e4fc223 Compute itemwise shipping cost for a line item 2012-06-29 08:46:31 +10:00
Rohan Mitchell
eae05ea59c Add itemwise shipping cost calculator 2012-06-29 07:52:29 +10:00
Rohan Mitchell
c09d4c98c8 Product distributions now editable 2012-06-28 15:38:26 +10:00
Rohan Mitchell
474c049f0d Set up basic form for admin editing product distributions (not yet functional) 2012-06-28 15:13:26 +10:00
Rohan Mitchell
1d3b7de5c6 Require ProductDistribution to be unique on [product, distributor] 2012-06-28 15:12:15 +10:00
Rohan Mitchell
3f08c2a9b0 Convert distributors_products join table into ProductDistribution explicit join model 2012-06-27 11:55:10 +10:00
Rohan Mitchell
5930363fa2 Validate presence of address on supplier and distributor 2012-06-27 09:25:14 +10:00
Rohan Mitchell
5f9b823b9c Add basic payment information to db:seed - more work needed to make valid for checkout 2012-06-27 09:21:01 +10:00
Rohan Mitchell
d859999bdc Checkout spec passes 2012-06-27 09:11:40 +10:00
Rohan Mitchell
c5270d6fa1 Set shipping address from distributor, fix zone init in checkout spec 2012-06-27 09:06:18 +10:00
Rohan Mitchell
340259eb2a Fix database cleaner strategy: http://blog.55minutes.com/2012/05/faster-capybara-specs/ 2012-06-26 16:19:54 +10:00
Rohan Mitchell
09f5bb8eed Switch database cleaner strategy back to transaction after js test has run 2012-06-26 16:05:21 +10:00
Rohan Mitchell
e0e566e625 Display distributor information on checkout address page 2012-06-26 16:04:59 +10:00
Rohan Mitchell
4b9c0f01e2 Update admin backend for supplier/distributor address extraction 2012-06-26 14:54:35 +10:00
Rohan Mitchell
ba3c02346d Extract distributor and supplier address to spree address model 2012-06-26 14:52:55 +10:00
Rohan Mitchell
f75b9bb176 Swap order of continue shopping and empty cart buttons 2012-06-26 10:58:09 +10:00
Rohan Mitchell
cb6ac2064d Rearrange buttons on cart checkout form 2012-06-26 10:50:50 +10:00
Rohan Mitchell
3ad575cb5f Display variant price differences as absolute, not relative values 2012-06-26 09:54:00 +10:00
Rohan Mitchell
34b694666c Grey out inactive distributors 2012-06-26 08:24:32 +10:00
Rohan Mitchell
0662e8f676 Show links to distributor home page, particularly when viewing product not available at current distributor 2012-06-26 08:12:35 +10:00
Rohan Mitchell
f3d52825ae Remove redirect_back_or_default, which was causing unexpected behaviour 2012-06-26 07:54:55 +10:00
Rohan Mitchell
9258d47e55 When adding subsequent products, add valid products to cart 2012-06-26 07:52:45 +10:00
190 changed files with 4525 additions and 984 deletions

32
.gitignore vendored
View File

@@ -10,48 +10,22 @@ log/*.log.lck
log/*.log.*
tmp/
.idea/*
solr/data/
solr/pids/
\#*
.#*
*~
*.~lock.*
.emacs.desktop
.DS_Store
.emacs.desktop.lock*
coverage
merged_coverage
upstream_coverage
true/
reports
*.tmproj
*tags
dump.rdb
bin/
spec/javascripts/generated/*
db/development_structure.sql
db/test_structure.sql
db/staging_structure.sql
db/production_structure.sql
db/bootstrap/*.sql
db/bootstrap/*.dump
db/bootstrap/*.bak
db/bootstrap/*.pgz
db/bootstrap/image_fixtures/*
db/bootstrap/image_fixtures/properties/*
db/backup
public/system
public/stylesheets
public/images
vendor/bundle
config/database.Tom-Meiers-MacBook-Pro.local.yml
public/spree
config/abr.yml
vendor/ruby
ey-cloud-recipes/db/bootstrap/*.dump
ey-cloud-recipes/db/bootstrap/*.pgz
ey-cloud-recipes/db/bootstrap/image_fixtures/*
ey-cloud-recipes/.idea/*
chromedriver.log
financial_reports/*.csv
config/heroku_env.rb
NERD_tree*
spec/reference_images/*
public/search

30
Gemfile
View File

@@ -1,23 +1,27 @@
source 'http://rubygems.org'
ruby "1.9.3"
gem 'rails', '3.2.3'
gem 'rails', '3.2.8'
gem 'pg'
gem 'spree'
gem 'spree', :git => 'git://github.com/spree/spree.git', :branch => '1-1-stable'
gem 'spree_i18n', :git => 'git://github.com/spree/spree_i18n.git'
gem 'spree_paypal_express', :git => 'git://github.com/eaterprises/spree_paypal_express.git', :branch => '1-1-stable'
gem 'spree_last_address', :git => 'git://github.com/dancinglightning/spree-last-address.git'
gem 'spree_usa_epay'
gem 'spree_skrill'
gem 'comfortable_mexican_sofa'
# Fix bug in simple_form preventing collection_check_boxes usage within form_for block
# When merged, revert to upstream gem
gem 'simple_form', :git => 'git://github.com/RohanM/simple_form.git'
gem 'unicorn'
gem 'spree_heroku', :git => 'git://github.com/joneslee85/spree-heroku.git'
gem 'bugsnag'
gem 'spree_heroku', :git => 'git://github.com/eaterprises/spree-heroku.git'
gem 'haml'
gem 'aws-s3'
gem 'aws-sdk'
gem 'andand'
gem 'truncate_html'
# Gems used only for assets and not required
# in production environments by default.
@@ -33,17 +37,6 @@ end
gem 'jquery-rails'
# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'
# Use unicorn as the web server
# gem 'unicorn'
# Deploy with Capistrano
# gem 'capistrano'
# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'
group :test, :development do
# Pretty printed test output
@@ -55,6 +48,7 @@ group :test, :development do
gem 'capybara'
gem 'database_cleaner', '0.7.1', :require => false
gem 'spork', '~> 1.0rc'
gem 'pry'
gem 'pry-debugger'
gem 'awesome_print'
end

View File

@@ -7,13 +7,77 @@ GIT
activemodel (~> 3.0)
GIT
remote: git://github.com/joneslee85/spree-heroku.git
revision: 63f0cfa47089cae50365e226ec7dd1eccde0ac05
remote: git://github.com/dancinglightning/spree-last-address.git
revision: f5ed71a5482fbc16da559737903bb46fe032c150
specs:
spree_last_address (1.1.0)
spree_core (>= 1.1)
GIT
remote: git://github.com/eaterprises/spree-heroku.git
revision: a1e07bf7a22fc0c07a1be9148f477d20b557dbf6
specs:
spree_heroku (1.0)
aws-sdk (~> 1.3.4)
spree_core (>= 0.70.0)
GIT
remote: git://github.com/eaterprises/spree_paypal_express.git
revision: 7dd46e6e549d82c4d603f685a7cb7fbb4af0d973
branch: 1-1-stable
specs:
spree_paypal_express (1.1.0)
spree_auth (>= 1.0.0)
spree_core (>= 1.0.0)
GIT
remote: git://github.com/spree/spree.git
revision: 46691e075129fd3d7b59e296d73149a9066c1b9d
branch: 1-1-stable
specs:
spree (1.1.3)
spree_api (= 1.1.3)
spree_auth (= 1.1.3)
spree_cmd (= 1.1.3)
spree_core (= 1.1.3)
spree_dash (= 1.1.3)
spree_promo (= 1.1.3)
spree_sample (= 1.1.3)
spree_api (1.1.3)
rabl (= 0.6.5)
spree_auth (= 1.1.3)
spree_core (= 1.1.3)
spree_auth (1.1.3)
cancan (= 1.6.7)
devise (~> 2.0.0)
spree_core (= 1.1.3)
spree_cmd (1.1.3)
thor (>= 0.14.6)
spree_core (1.1.3)
activemerchant (= 1.28.0)
acts_as_list (= 0.1.4)
aws-sdk (~> 1.3.4)
deface (>= 0.9.0)
ffaker (~> 1.12.0)
highline (= 1.6.11)
jquery-rails (~> 2.0)
kaminari (= 0.13.0)
nested_set (= 1.7.0)
paperclip (~> 2.8)
rails (~> 3.2.8)
ransack (~> 0.6.0)
state_machine (= 1.1.2)
stringex (~> 1.3.2)
spree_dash (1.1.3)
httparty (~> 0.8.1)
spree_auth (= 1.1.3)
spree_core (= 1.1.3)
spree_promo (1.1.3)
spree_auth (= 1.1.3)
spree_core (= 1.1.3)
spree_sample (1.1.3)
spree_core (= 1.1.3)
GIT
remote: git://github.com/spree/spree_i18n.git
revision: a96bee02340e008e60549295a4f09e047fd2e628
@@ -25,65 +89,61 @@ GIT
GEM
remote: http://rubygems.org/
specs:
actionmailer (3.2.3)
actionpack (= 3.2.3)
actionmailer (3.2.8)
actionpack (= 3.2.8)
mail (~> 2.4.4)
actionpack (3.2.3)
activemodel (= 3.2.3)
activesupport (= 3.2.3)
actionpack (3.2.8)
activemodel (= 3.2.8)
activesupport (= 3.2.8)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.1)
journey (~> 1.0.4)
rack (~> 1.4.0)
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.1.2)
active_utils (1.0.3)
sprockets (~> 2.1.3)
active_link_to (1.0.0)
active_utils (1.0.5)
activesupport (>= 2.3.11)
i18n
activemerchant (1.20.4)
activemerchant (1.28.0)
active_utils (>= 1.0.2)
activesupport (>= 2.3.11)
braintree (>= 2.0.0)
builder (>= 2.0.0)
i18n
json (>= 1.5.1)
money (<= 3.7.1)
activemodel (3.2.3)
activesupport (= 3.2.3)
money
nokogiri
activemodel (3.2.8)
activesupport (= 3.2.8)
builder (~> 3.0.0)
activerecord (3.2.3)
activemodel (= 3.2.3)
activesupport (= 3.2.3)
activerecord (3.2.8)
activemodel (= 3.2.8)
activesupport (= 3.2.8)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.3)
activemodel (= 3.2.3)
activesupport (= 3.2.3)
activesupport (3.2.3)
activeresource (3.2.8)
activemodel (= 3.2.8)
activesupport (= 3.2.8)
activesupport (3.2.8)
i18n (~> 0.6)
multi_json (~> 1.0)
acts_as_list (0.1.4)
addressable (2.2.8)
akami (1.1.0)
gyoku (>= 0.4.0)
nokogiri (>= 1.5.2)
addressable (2.3.2)
andand (1.3.3)
ansi (1.4.2)
arel (3.0.2)
aws-s3 (0.6.3)
builder
mime-types
xml-simple
awesome_print (1.0.2)
aws-sdk (1.3.9)
httparty (~> 0.7)
json (~> 1.4)
nokogiri (>= 1.4.4)
uuidtools (~> 2.1)
bcrypt-ruby (3.0.1)
braintree (2.16.0)
builder (>= 2.0.0)
builder (3.0.0)
bugsnag (1.2.4)
httparty (>= 0.5, < 1.0)
multi_json (~> 1.0)
builder (3.0.4)
cancan (1.6.7)
capybara (1.1.2)
mime-types (>= 1.16)
@@ -92,10 +152,10 @@ GEM
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 0.1.4)
childprocess (0.3.2)
ffi (~> 1.0.6)
cocaine (0.2.1)
coderay (1.0.6)
childprocess (0.3.6)
ffi (~> 1.0, >= 1.0.6)
cocaine (0.4.2)
coderay (1.0.7)
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
railties (~> 3.2.0)
@@ -103,7 +163,19 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.3.3)
columnize (0.3.6)
comfortable_mexican_sofa (1.6.24)
active_link_to (~> 1.0.0)
paperclip (>= 2.3.0)
rails (>= 3.0.0)
database_cleaner (0.7.1)
debugger (1.1.4)
columnize (>= 0.3.1)
debugger-linecache (~> 1.1.1)
debugger-ruby_core_source (~> 1.1.3)
debugger-linecache (1.1.2)
debugger-ruby_core_source (>= 1.1.1)
debugger-ruby_core_source (1.1.3)
deface (0.9.1)
nokogiri (~> 1.5.0)
rails (~> 3.1)
@@ -124,48 +196,44 @@ GEM
faker (1.0.1)
i18n (~> 0.4)
ffaker (1.12.1)
ffi (1.0.11)
gyoku (0.4.5)
builder (>= 2.1.2)
ffi (1.1.5)
haml (3.1.6)
highline (1.6.11)
hike (1.2.1)
httparty (0.8.3)
multi_json (~> 1.0)
multi_xml
httpi (1.0.0)
rack
i18n (0.6.0)
i18n (0.6.1)
journey (1.0.4)
jquery-rails (2.0.2)
railties (>= 3.2.0, < 5.0)
jquery-rails (2.1.3)
railties (>= 3.1.0, < 5.0)
thor (~> 0.14)
json (1.7.3)
json (1.7.5)
kaminari (0.13.0)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
railties (>= 3.0.0)
kgio (2.7.4)
libv8 (3.3.10.4)
libwebsocket (0.1.3)
libwebsocket (0.1.5)
addressable
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
method_source (0.7.1)
mime-types (1.18)
money (3.7.1)
method_source (0.8)
mime-types (1.19)
money (5.0.0)
i18n (~> 0.4)
json
multi_json (1.3.6)
multi_xml (0.5.1)
nested_set (1.7.0)
activerecord (>= 3.0.0)
railties (>= 3.0.0)
nokogiri (1.5.3)
nori (1.1.0)
nokogiri (1.5.5)
orm_adapter (0.0.7)
paperclip (2.7.0)
paperclip (2.8.0)
activerecord (>= 2.3.0)
activesupport (>= 2.3.2)
cocaine (>= 0.0.2)
@@ -174,10 +242,13 @@ GEM
polyamorous (0.5.0)
activerecord (~> 3.0)
polyglot (0.3.3)
pry (0.9.9.6)
pry (0.9.10)
coderay (~> 1.0.5)
method_source (~> 0.7.1)
slop (>= 2.4.4, < 3)
method_source (~> 0.8)
slop (~> 3.3.1)
pry-debugger (0.2.0)
debugger (~> 1.1.3)
pry (~> 0.9.9)
rabl (0.6.5)
activesupport (>= 2.3.14)
multi_json (~> 1.0)
@@ -186,23 +257,23 @@ GEM
rack (>= 0.4)
rack-ssl (1.3.2)
rack
rack-test (0.6.1)
rack-test (0.6.2)
rack (>= 1.0)
rails (3.2.3)
actionmailer (= 3.2.3)
actionpack (= 3.2.3)
activerecord (= 3.2.3)
activeresource (= 3.2.3)
activesupport (= 3.2.3)
rails (3.2.8)
actionmailer (= 3.2.8)
actionpack (= 3.2.8)
activerecord (= 3.2.8)
activeresource (= 3.2.8)
activesupport (= 3.2.8)
bundler (~> 1.0)
railties (= 3.2.3)
railties (3.2.3)
actionpack (= 3.2.3)
activesupport (= 3.2.3)
railties (= 3.2.8)
railties (3.2.8)
actionpack (= 3.2.8)
activesupport (= 3.2.8)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.6)
thor (>= 0.14.6, < 2.0)
raindrops (0.9.0)
rake (0.9.2.2)
ransack (0.6.0)
@@ -224,76 +295,21 @@ GEM
activesupport (>= 3.0)
railties (>= 3.0)
rspec (~> 2.10.0)
rubyzip (0.9.8)
rubyzip (0.9.9)
sass (3.1.19)
sass-rails (3.2.5)
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
savon (0.9.14)
akami (~> 1.1)
builder (>= 2.1.2)
gyoku (>= 0.4.0)
httpi (~> 1.0)
nokogiri (>= 1.4.0)
nori (~> 1.1)
wasabi (~> 2.2)
selenium-webdriver (2.22.2)
selenium-webdriver (2.25.0)
childprocess (>= 0.2.5)
ffi (~> 1.0)
libwebsocket (~> 0.1.3)
multi_json (~> 1.0)
rubyzip
shoulda-matchers (1.1.0)
activesupport (>= 3.0.0)
slop (2.4.4)
slop (3.3.3)
spork (1.0.0rc3)
spree (1.1.1)
spree_api (= 1.1.1)
spree_auth (= 1.1.1)
spree_cmd (= 1.1.1)
spree_core (= 1.1.1)
spree_dash (= 1.1.1)
spree_promo (= 1.1.1)
spree_sample (= 1.1.1)
spree_api (1.1.1)
rabl (= 0.6.5)
spree_auth (= 1.1.1)
spree_core (= 1.1.1)
spree_auth (1.1.1)
cancan (= 1.6.7)
devise (~> 2.0.0)
spree_core (= 1.1.1)
spree_cmd (1.1.1)
spree_core (1.1.1)
activemerchant (= 1.20.4)
acts_as_list (= 0.1.4)
aws-sdk (~> 1.3.4)
deface (>= 0.8.0)
ffaker (~> 1.12.0)
highline (= 1.6.11)
jquery-rails (~> 2.0.0)
kaminari (>= 0.13.0)
nested_set (= 1.7.0)
paperclip (~> 2.7)
rails (>= 3.2.2, <= 3.2.3)
ransack (~> 0.6.0)
state_machine (= 1.1.2)
stringex (~> 1.3.2)
spree_dash (1.1.1)
httparty (~> 0.8.1)
spree_auth (= 1.1.1)
spree_core (= 1.1.1)
spree_promo (1.1.1)
spree_auth (= 1.1.1)
spree_core (= 1.1.1)
spree_sample (1.1.1)
spree_core (= 1.1.1)
spree_skrill (1.0.2)
spree_core (>= 1.0.0)
spree_usa_epay (1.0.2)
savon
spree_core (>= 1.0.0)
sprockets (2.1.3)
hike (~> 1.2)
rack (~> 1.0)
@@ -302,14 +318,15 @@ GEM
stringex (1.3.3)
therubyracer (0.10.1)
libv8 (~> 3.3.10)
thor (0.14.6)
thor (0.16.0)
tilt (1.3.3)
treetop (1.4.10)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
truncate_html (0.5.5)
turn (0.8.3)
ansi
tzinfo (0.3.33)
tzinfo (0.3.34)
uglifier (1.2.4)
execjs (>= 0.3.0)
multi_json (>= 1.0.2)
@@ -317,13 +334,9 @@ GEM
kgio (~> 2.6)
rack
raindrops (~> 0.7)
uuidtools (2.1.2)
uuidtools (2.1.3)
warden (1.1.1)
rack (>= 1.0)
wasabi (2.4.0)
httpi (~> 1.0)
nokogiri (>= 1.4.0)
xml-simple (1.1.1)
xpath (0.1.4)
nokogiri (~> 1.3)
@@ -332,28 +345,32 @@ PLATFORMS
DEPENDENCIES
andand
aws-s3
awesome_print
aws-sdk
bugsnag
capybara
coffee-rails (~> 3.2.1)
comfortable_mexican_sofa
database_cleaner (= 0.7.1)
factory_girl_rails
faker
haml
jquery-rails
pg
pry
rails (= 3.2.3)
pry-debugger
rails (= 3.2.8)
rspec-rails
sass-rails (~> 3.2.3)
shoulda-matchers
simple_form!
spork (~> 1.0rc)
spree
spree!
spree_heroku!
spree_i18n!
spree_skrill
spree_usa_epay
spree_last_address!
spree_paypal_express!
therubyracer
truncate_html
turn (~> 0.8.3)
uglifier (>= 1.0.3)
unicorn

View File

@@ -20,11 +20,11 @@ hosted at GitHub.
You can view the code at:
https://github.com/andrewspinks/openfoodweb
https://github.com/eaterprises/openfoodweb
You can download the source with the command:
git clone git@github.com:andrewspinks/openfoodweb
git clone git@github.com:eaterprises/openfoodweb
## Get it running
@@ -80,6 +80,7 @@ speak to Andrew Spinks.
* Andrew Spinks (http://github.com/andrewspinks)
* Rohan Mitchell (http://github.com/rohanm)
* Rob Harrington (http://github.com/oeoeaio)
## Licence

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
app/assets/images/logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

BIN
app/assets/images/store/cart.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

View File

@@ -5,6 +5,8 @@
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require admin/spree_core
//= require admin/spree_auth
//= require admin/spree_promo

View File

@@ -0,0 +1,47 @@
/**
* Update the price on the product details page in real time when the variant or the quantity are changed.
**/
$(document).ready(function() {
// Product page with variant choice
$("#product-variants input[type='radio']").change(products_update_price_with_variant);
$("#quantity").change(products_update_price_with_variant);
$("#quantity").change();
// Product page with master price only
$(".add-to-cart input.title:not(#quantity):not(.max_quantity)").change(products_update_price_without_variant).change();
// Product page other
$("#distributor_id").change(function() {
var distributor_html = distributors[$(this).val()];
if(!distributor_html) {
distributor_html = 'When you select a distributor for your order, their address and pickup times will be displayed here.';
}
$("#product-distributor-details .distributor-details").html(distributor_html);
});
});
function products_update_price_with_variant() {
var variant_price = $("#product-variants input[type='radio']:checked").parent().find("span.price").html();
variant_price = variant_price.substr(2, variant_price.length-3);
var quantity = $("#quantity").val();
$("#product-price span.price").html("$"+(parseFloat(variant_price) * parseInt(quantity)).toFixed(2));
}
function products_update_price_without_variant() {
var master_price = $("#product-price span.price").data('master-price');
if(master_price == null) {
// Store off the master price
master_price = $("#product-price span.price").html();
master_price = master_price.substring(1);
$("#product-price span.price").data('master-price', master_price);
}
var quantity = $(this).val();
$("#product-price span.price").html("$"+(parseFloat(master_price)*parseInt(quantity)).toFixed(2));
}

View File

@@ -0,0 +1,14 @@
#header #logo {
top: 10px;
}
#header h1 {
left: 275px;
}
/* Fix conflict between Spree and elRTE's styles */
.el-rte .toolbar {
float: none;
margin-bottom: 0;
}

View File

@@ -1,11 +1,34 @@
@import "screen";
a:hover {
color: lighten($link_text_color, 20) !important;
}
table {
tbody, tfoot {
tr {
&.alt, &.odd {
background-color: lighten($link_text_color, 75) !important;
}
}
}
}
#header #logo {
padding-top: 10px;
}
/* Style current distributor in main nav bar */
nav #main-nav-bar {
li {
&#current-distributor {
float: right;
margin-right: 24px;
a {
font-size: 12px;
padding: 0;
}
}
}
}
@@ -28,8 +51,13 @@ nav#filters {
margin-bottom: 20px;
list-style: disc outside;
li a {
font-size: $main_navigation_font_size;
li {
a {
font-size: $main_navigation_font_size;
}
span.inactive {
color: #999;
}
}
}
}
@@ -100,6 +128,13 @@ ul.product-listing {
}
/* Supplier and distributor description */
.supplier-description, .distributor-description {
margin-bottom: 2em;
}
/* Highlight local products in distributor-split product listings */
#products-local ul {
margin-bottom: 1em;
@@ -109,14 +144,84 @@ ul.product-listing {
}
/* Distributor details on product details page */
fieldset#product-distributor-details {
float: right;
margin-top: 0;
width: 250px;
@extend #shipping;
}
#product-variants {
float: none;
}
/* Add to cart form on product details page */
#cart-form {
.error-distributor {
font-size: 120%;
font-weight: bold;
color: #f00;
a {
color: #f00;
text-decoration: underline;
}
}
.distributor-fixed {
}
}
/* View cart form */
#subtotal {
width: 100%;
}
.links {
float: right;
text-align: right;
}
#empty-cart {
float: left;
margin-top: 15px !important;
p {
padding: 0;
}
}
/* Delivery fees table on checkout page */
#delivery-fees {
clear: both;
padding-top: 6em;
table#delivery {
width: 100%;
tbody {
tr {
td.item-shipping-cost, td.item-shipping-method {
text-align: center;
}
td.item-shipping-cost {
@extend span.price;
@extend span.price.selling;
}
}
}
}
.subtotal {
width: 100%;
text-align: right;
text-transform: uppercase;
margin-top: 15px;
span.order-total {
@extend span.price;
}
}
}

View File

@@ -0,0 +1,58 @@
/*--------------------------------------*/
/* Colors
/*--------------------------------------*/
$c_green: #8dba53; /* Spree green */
$c_red: #e45353; /* Error red */
$layout_background_color: #FFFFFF;
$title_text_color: #404042;
$body_text_color: #404042;
$link_text_color: #006066;
$product_background_color: #FFFFFF;
$product_title_text_color: #404042;
$product_body_text_color: #404042;
$product_link_text_color: #BBBBBB;
/*--------------------------------------*/
/* Fonts import from remote
/*--------------------------------------*/
@import url(//fonts.googleapis.com/css?family=Ubuntu:400,700,400italic,700italic|&subset=latin,cyrillic,greek,greek-ext,latin-ext,cyrillic-ext);
/*--------------------------------------*/
/* Font families
/*--------------------------------------*/
$ff_base: 'Ubuntu', sans-serif;
/*--------------------------------------
| Font sizes
|--------------------------------------
|- Navigation
| */
$header_navigation_font_size: 14px;
$horizontal_navigation_font_size: 16px;
$main_navigation_header_font_size: 14px;
$main_navigation_font_size: 12px;
/*|------------------------------------
|- Product Listing
| */
$product_list_name_font_size: 12px;
$product_list_price_font_size: 16px;
$product_list_header_font_size: 20px;
$product_list_search_font_size: 14px;
/*|------------------------------------
|- Product Details
| */
$product_detail_name_font_size: 24px;
$product_detail_description_font_size: 12px;
$product_detail_price_font_size: 20px;
$product_detail_title_font_size: 14px;
/*|------------------------------------
|- Basic
| */
$heading_font_size: 24px;
$sub_heading_font_size: 14px;
$button_font_size: 12px;
$input_box_font_size: 13px;
$base_font_size: 12px;
$button_border_color: rgba(0, 138, 189, .75);

View File

@@ -0,0 +1,28 @@
module Admin
class DistributorsController < ResourceController
before_filter :load_distributor_set, :only => :index
before_filter :load_countries, :except => :index
def bulk_update
@distributor_set = DistributorSet.new(params[:distributor_set])
if @distributor_set.save
redirect_to main_app.admin_distributors_path, :notice => 'Distributor collection times updated.'
else
render :index
end
end
private
def load_distributor_set
@distributor_set = DistributorSet.new :distributors => collection
end
def load_countries
@countries = Spree::Country.order(:name)
end
def collection
super.order(:name)
end
end
end

View File

@@ -0,0 +1,42 @@
module Admin
class ResourceController < Spree::Admin::ResourceController
def model_class
"#{controller_name.classify}".constantize
end
# URL helpers
def new_object_url(options = {})
if parent_data.present?
main_app.new_polymorphic_url([:admin, parent, model_class], options)
else
main_app.new_polymorphic_url([:admin, model_class], options)
end
end
def edit_object_url(object, options = {})
if parent_data.present?
main_app.send "edit_admin_#{model_name}_#{object_name}_url", parent, object, options
else
main_app.send "edit_admin_#{object_name}_url", object, options
end
end
def object_url(object = nil, options = {})
target = object ? object : @object
if parent_data.present?
main_app.send "admin_#{model_name}_#{object_name}_url", parent, target, options
else
main_app.send "admin_#{object_name}_url", target, options
end
end
def collection_url(options = {})
if parent_data.present?
main_app.polymorphic_url([:admin, parent, model_class], options)
else
main_app.polymorphic_url([:admin, model_class], options)
end
end
end
end

View File

@@ -0,0 +1,16 @@
module Admin
class SuppliersController < ResourceController
before_filter :load_data, :except => [:index]
helper 'spree/products'
private
def load_data
@countries = Spree::Country.order(:name)
end
def collection
super.order(:name)
end
end
end

View File

@@ -1,12 +1,18 @@
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :load_data_for_menu
before_filter :load_data_for_sidebar
private
def load_data_for_menu
@cms_site = Cms::Site.where(:identifier => 'open-food-web').first
end
def load_data_for_sidebar
@suppliers = Spree::Supplier.all
@distributors = Spree::Distributor.all
@suppliers = Supplier.all
@distributors = Distributor.with_active_products_on_hand.by_name
end
end

View File

@@ -0,0 +1,10 @@
class BaseController < ApplicationController
include Spree::Core::ControllerHelpers
include Spree::Core::RespondWith
helper 'spree/base'
# Spree::Core::ControllerHelpers declares helper_method get_taxonomies, so we need to
# include Spree::ProductsHelper so that method is available on the controller
include Spree::ProductsHelper
end

View File

@@ -0,0 +1,45 @@
class DistributorsController < BaseController
def index
@distributors = Distributor.all
respond_to do |format|
format.js do
@distributor_details = Hash[@distributors.map { |d| [d.id, render_to_string(:partial => 'distributors/details', :locals => {:distributor => d})] }]
end
end
end
def show
options = {:distributor_id => params[:id]}
options.merge(params.reject { |k,v| k == :id })
@distributor = Distributor.find params[:id]
@searcher = Spree::Config.searcher_class.new(options)
@products = @searcher.retrieve_products
end
def select
distributor = Distributor.find params[:id]
order = current_order(true)
if order.can_change_distributor?
order.distributor = distributor
order.save!
end
redirect_to distributor
end
def deselect
order = current_order(true)
if order.can_change_distributor?
order.distributor = nil
order.save!
end
redirect_to root_path
end
end

View File

@@ -1,16 +0,0 @@
module Spree
module Admin
class DistributorsController < ResourceController
before_filter :load_data, :except => [:index]
private
def load_data
@countries = Country.order(:name)
end
def collection
super.order(:name)
end
end
end
end

View File

@@ -0,0 +1,494 @@
require 'csv'
require 'open_food_web/order_and_distributor_report'
require 'open_food_web/group_buy_report'
require 'open_food_web/order_grouper'
Spree::Admin::ReportsController.class_eval do
Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:orders_and_distributors => {:name => "Orders And Distributors", :description => "Orders with distributor details"}})
Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:group_buys => {:name => "Group Buys", :description => "Orders by supplier and variant"}})
Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:bulk_coop => {:name => "Bulk Co-Op", :description => "Reports for Bulk Co-Op orders"}})
Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:payments => {:name => "Payment Reports", :description => "Reports for Payments"}})
Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:order_cycles => {:name => "Order Cycle Reports", :description => "Reports for Order Cycles"}})
def orders_and_distributors
params[:q] = {} unless params[:q]
if params[:q][:created_at_gt].blank?
params[:q][:created_at_gt] = Time.zone.now.beginning_of_month
else
params[:q][:created_at_gt] = Time.zone.parse(params[:q][:created_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
end
if params[:q] && !params[:q][:created_at_lt].blank?
params[:q][:created_at_lt] = Time.zone.parse(params[:q][:created_at_lt]).end_of_day rescue ""
end
params[:q][:meta_sort] ||= "created_at.desc"
@search = Spree::Order.complete.search(params[:q])
orders = @search.result
@report = OpenFoodWeb::OrderAndDistributorReport.new orders
unless params[:csv]
render :html => @report
else
csv_string = CSV.generate do |csv|
csv << @report.header
@report.table.each { |row| csv << row }
end
send_data csv_string, :filename => "orders_and_distributors.csv"
end
end
def group_buys
params[:q] = {} unless params[:q]
if params[:q][:created_at_gt].blank?
params[:q][:created_at_gt] = Time.zone.now.beginning_of_month
else
params[:q][:created_at_gt] = Time.zone.parse(params[:q][:created_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
end
if params[:q] && !params[:q][:created_at_lt].blank?
params[:q][:created_at_lt] = Time.zone.parse(params[:q][:created_at_lt]).end_of_day rescue ""
end
params[:q][:meta_sort] ||= "created_at.desc"
@search = Spree::Order.complete.search(params[:q])
orders = @search.result
@distributors = Distributor.all
@report = OpenFoodWeb::GroupBuyReport.new orders
unless params[:csv]
render :html => @report
else
csv_string = CSV.generate do |csv|
csv << @report.header
@report.table.each { |row| csv << row }
end
send_data csv_string, :filename => "group_buy.csv"
end
end
def bulk_coop
params[:q] = {} unless params[:q]
if params[:q][:created_at_gt].blank?
params[:q][:created_at_gt] = Time.zone.now.beginning_of_month
else
params[:q][:created_at_gt] = Time.zone.parse(params[:q][:created_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
end
if params[:q] && !params[:q][:created_at_lt].blank?
params[:q][:created_at_lt] = Time.zone.parse(params[:q][:created_at_lt]).end_of_day rescue ""
end
params[:q][:meta_sort] ||= "created_at.desc"
@search = Spree::Order.complete.search(params[:q])
orders = @search.result
line_items = orders.map { |o| o.line_items }.flatten
@distributors = Distributor.all
@report_type = params[:report_type]
case params[:report_type]
when "bulk_coop_supplier_report"
header = ["Supplier", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total"]
columns = [ proc { |lis| lis.first.variant.product.supplier.name },
proc { |lis| lis.first.variant.product.name },
proc { |lis| "UNIT SIZE" },
proc { |lis| lis.first.variant.options_text },
proc { |lis| lis.first.variant.weight || 0 },
proc { |lis| lis.sum { |li| li.quantity } },
proc { |lis| lis.sum { |li| li.max_quantity || 0 } } ]
rules = [ { group_by: proc { |li| li.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |li| li.variant.product },
sort_by: proc { |product| product.name },
summary_columns: [ proc { |lis| lis.first.variant.product.supplier.name },
proc { |lis| lis.first.variant.product.name },
proc { |lis| "UNIT SIZE" },
proc { |lis| "" },
proc { |lis| "" },
proc { |lis| lis.sum { |li| li.quantity * li.variant.weight || 0 } },
proc { |lis| lis.sum { |li| (li.max_quantity || 0) * li.variant.weight || 0 } } ] },
{ group_by: proc { |li| li.variant },
sort_by: proc { |variant| variant.options_text } } ]
when "bulk_coop_allocation"
header = ["Customer", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total"]
columns = [ proc { |lis| lis.first.order.bill_address.firstname + " " + lis.first.order.bill_address.lastname },
proc { |lis| lis.first.variant.product.name },
proc { |lis| "UNIT SIZE" },
proc { |lis| lis.first.variant.options_text },
proc { |lis| lis.first.variant.weight || 0 },
proc { |lis| lis.sum { |li| li.quantity } },
proc { |lis| lis.sum { |li| li.max_quantity || 0 } } ]
rules = [ { group_by: proc { |li| li.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |li| li.variant },
sort_by: proc { |variant| variant.options_text } },
{ group_by: proc { |li| li.order.user },
sort_by: proc { |user| user.to_s } } ]
when "bulk_coop_packing_sheets"
header = ["Customer", "Product", "Variant", "Sum Total"]
columns = [ proc { |lis| lis.first.order.bill_address.firstname + " " + lis.first.order.bill_address.lastname },
proc { |lis| lis.first.variant.product.name },
proc { |lis| lis.first.variant.options_text },
proc { |lis| lis.sum { |li| li.quantity } } ]
rules = [ { group_by: proc { |li| li.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |li| li.variant },
sort_by: proc { |variant| variant.options_text } },
{ group_by: proc { |li| li.order.user },
sort_by: proc { |user| user.to_s } } ]
when "bulk_coop_customer_payments"
header = ["Customer", "Date of Order", "Total Cost", "Amount Owing", "Amount Paid"]
columns = [ proc { |lis| lis.first.order.bill_address.firstname + " " + lis.first.order.bill_address.lastname },
proc { |lis| lis.first.order.created_at.to_s },
proc { |lis| lis.map { |li| li.order }.uniq.sum { |o| o.total } },
proc { |lis| lis.map { |li| li.order }.uniq.sum { |o| o.outstanding_balance } },
proc { |lis| lis.map { |li| li.order }.uniq.sum { |o| o.payment_total } } ]
rules = [ { group_by: proc { |li| li.order.user },
sort_by: proc { |user| user.to_s } },
{ group_by: proc { |li| li.order },
sort_by: proc { |order| order.created_at } } ]
else # List all line items
header = ["Supplier", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total"]
columns = [ proc { |lis| lis.first.variant.product.supplier.name },
proc { |lis| lis.first.variant.product.name },
proc { |lis| "UNIT SIZE" },
proc { |lis| lis.first.variant.options_text },
proc { |lis| lis.first.variant.weight || 0 },
proc { |lis| lis.sum { |li| li.quantity } },
proc { |lis| lis.sum { |li| li.max_quantity || 0 } } ]
rules = [ { group_by: proc { |li| li.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |li| li.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |li| li.variant },
sort_by: proc { |variant| variant.options_text } } ]
end
order_grouper = OpenFoodWeb::OrderGrouper.new rules, columns
@header = header
@table = order_grouper.table(line_items)
csv_file_name = "bulk_coop.csv"
render_report(@header, @table, params[:csv], csv_file_name)
end
def payments
params[:q] = {} unless params[:q]
if params[:q][:created_at_gt].blank?
params[:q][:created_at_gt] = Time.zone.now.beginning_of_month
else
params[:q][:created_at_gt] = Time.zone.parse(params[:q][:created_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
end
if params[:q] && !params[:q][:created_at_lt].blank?
params[:q][:created_at_lt] = Time.zone.parse(params[:q][:created_at_lt]).end_of_day rescue ""
end
params[:q][:meta_sort] ||= "created_at.desc"
@search = Spree::Order.complete.search(params[:q])
orders = @search.result
payments = orders.map { |o| o.payments.select { |payment| payment.completed? } }.flatten # Only select completed payments
@distributors = Distributor.all
@report_type = params[:report_type]
case params[:report_type]
when "payments_by_payment_type"
table_items = payments
header = ["Payment State", "Distributor", "Payment Type", "Total ($)"]
columns = [ proc { |payments| payments.first.order.payment_state },
proc { |payments| payments.first.order.distributor.name },
proc { |payments| payments.first.payment_method.name },
proc { |payments| payments.sum { |payment| payment.amount } } ]
rules = [ { group_by: proc { |payment| payment.order.payment_state },
sort_by: proc { |payment_state| payment_state } },
{ group_by: proc { |payment| payment.order.distributor },
sort_by: proc { |distributor| distributor.name } },
{ group_by: proc { |payment| payment.payment_method },
sort_by: proc { |method| method.name } } ]
when "itemised_payment_totals"
table_items = orders
header = ["Payment State", "Distributor", "Product Total ($)", "Shipping Total ($)", "Outstanding Balance ($)", "Total ($)"]
columns = [ proc { |orders| orders.first.payment_state },
proc { |orders| orders.first.distributor.name },
proc { |orders| orders.sum { |o| o.item_total } },
proc { |orders| orders.sum { |o| o.ship_total } },
proc { |orders| orders.sum { |o| o.outstanding_balance } },
proc { |orders| orders.sum { |o| o.total } } ]
rules = [ { group_by: proc { |order| order.payment_state },
sort_by: proc { |payment_state| payment_state } },
{ group_by: proc { |order| order.distributor },
sort_by: proc { |distributor| distributor.name } } ]
when "payment_totals"
table_items = orders
header = ["Payment State", "Distributor", "Product Total ($)", "Shipping Total ($)", "Total ($)", "EFT ($)", "PayPal ($)", "Outstanding Balance ($)"]
columns = [ proc { |orders| orders.first.payment_state },
proc { |orders| orders.first.distributor.name },
proc { |orders| orders.sum { |o| o.item_total } },
proc { |orders| orders.sum { |o| o.ship_total } },
proc { |orders| orders.sum { |o| o.total } },
proc { |orders| orders.sum { |o| o.payments.select { |payment| payment.completed? && (payment.payment_method.name.to_s.include? "EFT") }.sum { |payment| payment.amount } } },
proc { |orders| orders.sum { |o| o.payments.select { |payment| payment.completed? && (payment.payment_method.name.to_s.include? "PayPal") }.sum{ |payment| payment.amount } } },
proc { |orders| orders.sum { |o| o.outstanding_balance } } ]
rules = [ { group_by: proc { |order| order.payment_state },
sort_by: proc { |payment_state| payment_state } },
{ group_by: proc { |order| order.distributor },
sort_by: proc { |distributor| distributor.name } } ]
else
table_items = payments
header = ["Payment State", "Distributor", "Payment Type", "Total ($)"]
columns = [ proc { |payments| payments.first.order.payment_state },
proc { |payments| payments.first.order.distributor.name },
proc { |payments| payments.first.payment_method.name },
proc { |payments| payments.sum { |payment| payment.amount } } ]
rules = [ { group_by: proc { |payment| payment.order.payment_state },
sort_by: proc { |payment_state| payment_state } },
{ group_by: proc { |payment| payment.order.distributor },
sort_by: proc { |distributor| distributor.name } },
{ group_by: proc { |payment| payment.payment_method },
sort_by: proc { |method| method.name } } ]
end
order_grouper = OpenFoodWeb::OrderGrouper.new rules, columns
@header = header
@table = order_grouper.table(table_items)
csv_file_name = "payments.csv"
render_report(@header, @table, params[:csv], csv_file_name)
end
def order_cycles
params[:q] = {} unless params[:q]
if params[:q][:created_at_gt].blank?
params[:q][:created_at_gt] = Time.zone.now.beginning_of_month
else
params[:q][:created_at_gt] = Time.zone.parse(params[:q][:created_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
end
if params[:q] && !params[:q][:created_at_lt].blank?
params[:q][:created_at_lt] = Time.zone.parse(params[:q][:created_at_lt]).end_of_day rescue ""
end
params[:q][:meta_sort] ||= "created_at.desc"
@search = Spree::Order.complete.search(params[:q])
orders = @search.result
line_items = orders.map { |o| o.line_items }.flatten
#payments = orders.map { |o| o.payments.select { |payment| payment.completed? } }.flatten # Only select completed payments
@distributors = Distributor.all
@report_type = params[:report_type]
case params[:report_type]
when "order_cycle_supplier_totals"
table_items = line_items
@include_blank = 'All'
header = ["Supplier", "Product", "Variant", "Amount", "Cost per Unit", "Total Cost", "Status", "Incoming Transport"]
columns = [ proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "status" },
proc { |line_items| "incoming transport" } ]
rules = [ { group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.options_text } } ]
when "order_cycle_supplier_totals_by_distributor"
table_items = line_items
@include_blank = 'All'
header = ["Supplier", "Product", "Variant", "To Distributor", "Amount", "Cost per Unit", "Total Cost", "Shipping Method"]
columns = [ proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| line_items.first.order.distributor.name },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "shipping method" } ]
rules = [ { group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.options_text },
summary_columns: [ proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| "TOTAL" },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "" } ] },
{ group_by: proc { |line_item| line_item.order.distributor },
sort_by: proc { |distributor| distributor.name } } ]
when "order_cycle_distributor_totals_by_supplier"
table_items = line_items
@include_blank = 'All'
header = ["Distributor", "Supplier", "Product", "Variant", "Amount", "Cost per Unit", "Total Cost", "Total Shipping Cost", "Shipping Method"]
columns = [ proc { |line_items| line_items.first.order.distributor.name },
proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "" },
proc { |line_items| "shipping method" } ]
rules = [ { group_by: proc { |line_item| line_item.order.distributor },
sort_by: proc { |distributor| distributor.name },
summary_columns: [ proc { |line_items| line_items.first.order.distributor.name },
proc { |line_items| "TOTAL" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "total shipping cost" },
proc { |line_items| "" } ] },
{ group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.options_text } } ]
when "order_cycle_customer_totals"
table_items = line_items
@include_blank = false
header = ["Customer", "Email", "Phone", "Product", "Variant", "Amount", "Total Cost", "Paid?", "Packed?", "Shipped?"]
columns = [ proc { |line_items| line_items.first.order.bill_address.firstname + " " + line_items.first.order.bill_address.lastname },
proc { |line_items| line_items.first.order.email },
proc { |line_items| line_items.first.order.bill_address.phone },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| "" } ]
rules = [ { group_by: proc { |line_item| line_item.order.user },
sort_by: proc { |user| user.to_s },
summary_columns: [ proc { |line_items| line_items.first.order.bill_address.firstname + " " + line_items.first.order.bill_address.lastname },
proc { |line_items| line_items.first.order.email },
proc { |line_items| line_items.first.order.bill_address.phone },
proc { |line_items| "TOTAL" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "work out whether paid or not" },
proc { |line_items| "" },
proc { |line_items| "" } ] },
{ group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.options_text } } ]
else
table_items = line_items
header = ["Supplier", "Product", "Variant", "Amount", "Cost per Unit", "Total Cost", "Status", "Incoming Transport"]
columns = [ proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "status" },
proc { |line_items| "incoming transport" } ]
rules = [ { group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.options_text } } ]
end
order_grouper = OpenFoodWeb::OrderGrouper.new rules, columns
@header = header
@table = order_grouper.table(table_items)
csv_file_name = "order_cycles.csv"
render_report(@header, @table, params[:csv], csv_file_name)
end
def render_report (header, table, create_csv, csv_file_name)
unless create_csv
render :html => table
else
csv_string = CSV.generate do |csv|
csv << header
table.each { |row| csv << row }
end
send_data csv_string, :filename => csv_file_name
end
end
end

View File

@@ -0,0 +1,28 @@
module Spree
module Admin
ShippingMethodsController.class_eval do
before_filter :do_not_destroy_referenced_shipping_methods, :only => :destroy
def do_not_destroy_referenced_shipping_methods
order = Order.where(:shipping_method_id => @object).first
if order
flash[:error] = "That shipping method cannot be deleted as it is referenced by an order: #{order.number}."
redirect_to collection_url and return
end
product_distribution = ProductDistribution.where(:shipping_method_id => @object).first
if product_distribution
p = product_distribution.product
flash[:error] = "That shipping method cannot be deleted as it is referenced by a product distribution: #{p.id} - #{p.name}."
redirect_to collection_url and return
end
line_item = LineItem.where(:shipping_method_id => @object).first
if line_item
flash[:error] = "That shipping method cannot be deleted as it is referenced by a line item in order: #{line_item.order.number}."
redirect_to collection_url and return
end
end
end
end
end

View File

@@ -1,16 +0,0 @@
module Spree
module Admin
class SuppliersController < ResourceController
before_filter :load_data, :except => [:index]
private
def load_data
@countries = Country.order(:name)
end
def collection
super.order(:name)
end
end
end
end

View File

@@ -0,0 +1,25 @@
module Spree
BaseController.class_eval do
# Override definition in spree/auth/app/controllers/spree/base_controller_decorator.rb
# Do not attempt to merge incomplete and current orders when they have differing distributors
# Instead, destroy the incomplete orders, otherwise they are restored after checkout, causing much confusion
def set_current_order
if current_user
if current_user.respond_to?(:last_incomplete_order)
last_incomplete_order = current_user.last_incomplete_order
if session[:order_id].nil? && last_incomplete_order
session[:order_id] = last_incomplete_order.id
elsif current_order && last_incomplete_order && current_order != last_incomplete_order
if current_order.distributor.nil? || current_order.distributor == last_incomplete_order.distributor
current_order.set_distributor! last_incomplete_order.distributor if current_order.distributor.nil?
current_order.merge!(last_incomplete_order)
else
last_incomplete_order.destroy
end
end
end
end
end
end
end

View File

@@ -1,36 +0,0 @@
module Spree
class DistributorsController < BaseController
def show
options = {:distributor_id => params[:id]}
options.merge(params.reject { |k,v| k == :id })
@searcher = Config.searcher_class.new(options)
@products = @searcher.retrieve_products
render :template => 'spree/products/index'
end
def select
distributor = Distributor.find params[:id]
order = current_order(true)
if order.can_change_distributor?
order.distributor = distributor
order.save!
end
redirect_back_or_default(root_path)
end
def deselect
order = current_order(true)
if order.can_change_distributor?
order.distributor = nil
order.save!
end
redirect_back_or_default(root_path)
end
end
end

View File

@@ -1,7 +1,7 @@
require 'open_food_web/split_products_by_distributor'
Spree::HomeController.class_eval do
include Spree::DistributorsHelper
include DistributorsHelper
include OpenFoodWeb::SplitProductsByDistributor
respond_override :index => { :html => { :success => lambda {

View File

@@ -1,20 +1,38 @@
Spree::OrdersController.class_eval do
before_filter :populate_order_distributor, :only => :populate
before_filter :populate_order_distributor, :only => :populate
after_filter :populate_variant_attributes, :only => :populate
def populate_order_distributor
@distributor = params.key?(:distributor_id) ? Spree::Distributor.find(params[:distributor_id]) : nil
@distributor = params[:distributor_id].present? ? Distributor.find(params[:distributor_id]) : nil
if populate_valid? @distributor
order = current_order(true)
order.distributor = @distributor
order.save!
order.set_distributor! @distributor
else
redirect_to cart_path
flash[:error] = "Please choose a distributor for this order." if @distributor.nil?
redirect_populate_to_first_product
end
end
def populate_variant_attributes
if params.key? :variant_attributes
params[:variant_attributes].each do |variant_id, attributes|
@order.set_variant_attributes(Spree::Variant.find(variant_id), attributes)
end
end
if params.key? :quantity
params[:products].each do |product_id, variant_id|
max_quantity = params[:max_quantity].to_i
@order.set_variant_attributes(Spree::Variant.find(variant_id), {:max_quantity => max_quantity})
end
end
end
private
def populate_valid? distributor
# -- Distributor must be specified
return false if distributor.nil?
@@ -38,4 +56,14 @@ Spree::OrdersController.class_eval do
true
end
def redirect_populate_to_first_product
product = if params[:products].present?
Spree::Product.find(params[:products].keys.first)
else
Spree::Variant.find(params[:variants].keys.first).product
end
redirect_to product
end
end

View File

@@ -1,7 +1,7 @@
require 'open_food_web/split_products_by_distributor'
Spree::ProductsController.class_eval do
include Spree::DistributorsHelper
include DistributorsHelper
include OpenFoodWeb::SplitProductsByDistributor
respond_override :index => { :html => { :success => lambda {

View File

@@ -1,12 +0,0 @@
module Spree
class SuppliersController < BaseController
def show
options = {:supplier_id => params[:id]}
options.merge(params.reject { |k,v| k == :id })
@searcher = Config.searcher_class.new(options)
@products = @searcher.retrieve_products
render :template => 'spree/products/index'
end
end
end

View File

@@ -1,7 +1,7 @@
require 'open_food_web/split_products_by_distributor'
Spree::TaxonsController.class_eval do
include Spree::DistributorsHelper
include DistributorsHelper
include OpenFoodWeb::SplitProductsByDistributor
respond_override :show => { :html => { :success => lambda {

View File

@@ -0,0 +1,15 @@
class SuppliersController < BaseController
def index
@suppliers = Supplier.all
end
def show
options = {:supplier_id => params[:id]}
options.merge(params.reject { |k,v| k == :id })
@supplier = Supplier.find params[:id]
@searcher = Spree::Config.searcher_class.new(options)
@products = @searcher.retrieve_products
end
end

View File

@@ -1,2 +1,18 @@
module ApplicationHelper
def home_page_cms_content
if controller.controller_name == 'home' && controller.action_name == 'index'
cms_page_content(:content, Cms::Page.find_by_full_path('/'))
end
end
# Pass URL helper calls on to spree where applicable so that we don't need to use
# spree.foo_path in any view rendered from non-spree-namespaced controllers.
def method_missing(method, *args, &block)
if (method.to_s.end_with?('_path') || method.to_s.end_with?('_url')) && spree.respond_to?(method)
spree.send(method, *args)
else
super
end
end
end

View File

@@ -0,0 +1,5 @@
module DistributorsHelper
def current_distributor
@current_distributor ||= current_order(false).andand.distributor
end
end

View File

@@ -1,7 +0,0 @@
module Spree
module DistributorsHelper
def current_distributor
@current_distributor ||= current_order(false).andand.distributor
end
end
end

View File

@@ -0,0 +1,9 @@
module Spree
module OrdersHelper
def order_delivery_fee_subtotal(order, options={})
options.reverse_merge! :format_as_currency => true
amount = order.line_items.map { |li| li.itemwise_shipping_cost }.sum
options.delete(:format_as_currency) ? number_to_currency(amount) : amount
end
end
end

View File

@@ -0,0 +1,8 @@
module Spree
ProductsHelper.class_eval do
# Return the price of the variant
def variant_price_diff(variant)
"(#{number_to_currency variant.price})"
end
end
end

31
app/models/distributor.rb Normal file
View File

@@ -0,0 +1,31 @@
class Distributor < ActiveRecord::Base
belongs_to :pickup_address, :foreign_key => 'pickup_address_id', :class_name => 'Spree::Address'
has_many :orders, :class_name => 'Spree::Order'
has_many :product_distributions, :dependent => :destroy
has_many :products, :through => :product_distributions
accepts_nested_attributes_for :pickup_address
validates_presence_of :name, :pickup_address
validates_associated :pickup_address
scope :by_name, order('name')
scope :with_active_products_on_hand, lambda { joins(:products).where('spree_products.deleted_at IS NULL AND spree_products.available_on <= ? AND spree_products.count_on_hand > 0', Time.now).select('distinct(distributors.*)') }
after_initialize :initialize_country
before_validation :set_unused_address_fields
def initialize_country
self.pickup_address ||= Spree::Address.new
self.pickup_address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id]) if self.pickup_address.new_record?
end
def set_unused_address_fields
pickup_address.firstname = pickup_address.lastname = pickup_address.phone = 'unused' if pickup_address.present?
end
def to_param
"#{id}-#{name.parameterize}"
end
end

View File

@@ -0,0 +1,34 @@
# Tableless model to handle updating multiple distributors at once from a
# single form. Used to update next_collection_at field for all distributors in
# admin backend.
class DistributorSet
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :distributors
def initialize(attributes={})
@distributors = Distributor.all
attributes.each do |name, value|
send("#{name}=", value)
end
end
def distributors_attributes=(attributes)
attributes.each do |k, attributes|
# attributes == {:id => 123, :next_collection_at => '...'}
d = @distributors.detect { |d| d.id.to_s == attributes[:id].to_s }
d.assign_attributes(attributes.except(:id))
end
end
def save
distributors.all?(&:save)
end
def persisted?
false
end
end

View File

@@ -0,0 +1,13 @@
module OpenFoodWeb
class Calculator::Itemwise < Spree::Calculator
def self.description
"Itemwise Shipping"
end
def compute(object)
# Given an order, sum the shipping on each individual item
object.line_items.map { |li| li.itemwise_shipping_cost }.inject(:+) || 0
end
end
end

View File

@@ -0,0 +1,15 @@
module OpenFoodWeb
class Calculator::Weight < Spree::Calculator
preference :per_kg, :decimal, :default => 0.0
attr_accessible :preferred_per_kg
def self.description
"Weight (per kg)"
end
def compute(object)
total_weight = object.line_items.inject(0) { |sum, li| sum + ((li.variant.andand.weight || 0) * li.quantity) }
total_weight * self.preferred_per_kg
end
end
end

View File

@@ -0,0 +1,9 @@
class ProductDistribution < ActiveRecord::Base
belongs_to :product, :class_name => 'Spree::Product'
belongs_to :distributor
belongs_to :shipping_method, :class_name => 'Spree::ShippingMethod'
validates_presence_of :product_id, :on => :update
validates_presence_of :distributor_id, :shipping_method_id
validates_uniqueness_of :product_id, :scope => :distributor_id
end

View File

@@ -1,23 +0,0 @@
module Spree
class Distributor < ActiveRecord::Base
self.table_name = 'distributors'
belongs_to :country
belongs_to :state
has_and_belongs_to_many :products
has_many :orders
validates :name, :pickup_address, :country_id, :state_id, :city, :post_code, :presence => true
scope :by_name, order('name')
after_initialize :initialize_country
def initialize_country
self.country = Spree::Country.find_by_id(Spree::Config[:default_country_id])
end
def to_param
"#{id}-#{name.parameterize}"
end
end
end

View File

@@ -0,0 +1,19 @@
Spree::LineItem.class_eval do
belongs_to :shipping_method
attr_accessible :max_quantity
before_create :set_itemwise_shipping_method
def itemwise_shipping_cost
order = OpenStruct.new :line_items => [self]
shipping_method.compute_amount(order)
end
private
def set_itemwise_shipping_method
self.shipping_method = self.product.shipping_method_for_distributor(self.order.distributor)
end
end

View File

@@ -1,36 +1,69 @@
Spree::Order.class_eval do
belongs_to :distributor
before_validation :shipping_address_from_distributor
after_create :set_default_shipping_method
def can_change_distributor?
# Distributor may not be changed once an item has been added to the cart/order
line_items.empty?
end
def distributor=(distributor)
raise "You cannot change the distributor of an order with products" unless can_change_distributor?
raise "You cannot change the distributor of an order with products" unless distributor == self.distributor || can_change_distributor?
super(distributor)
end
def set_distributor!(distributor)
self.distributor = distributor
save!
end
def can_add_product_to_cart?(product)
can_change_distributor? || product.distributors.include?(distributor)
end
def set_variant_attributes(variant, attributes)
line_item = contains?(variant)
if attributes.key?(:max_quantity) && attributes[:max_quantity].to_i < line_item.quantity
attributes[:max_quantity] = line_item.quantity
end
line_item.assign_attributes(attributes)
line_item.save!
end
# before_validation :shipping_address_from_distributor
private
# def shipping_address_from_distributor
# if distributor
# ship_address.firstname = bill_address.firstname
# ship_address.lastname = bill_address.lastname
# ship_address.phone = bill_address.phone
# ship_address.address1 = distributor.pickup_address
# ship_address.city = distributor.city
# ship_address.zipcode = distributor.post_code
# ship_address.state = distributor.state
# ship_address.country_id = distributor.country_id
# end
# end
# On creation of the order (when the first item is added to the user's cart), set the
# shipping method to the first one available and create a shipment.
# order.create_shipment! creates an adjustment for the shipping cost on the order,
# which means that the customer can see their shipping cost at every step of the
# checkout process, not just after the delivery step.
# This is based on the assumption that there's only one shipping method visible to the user,
# which is a method using the itemwise shipping calculator.
def set_default_shipping_method
self.shipping_method = Spree::ShippingMethod.where("display_on != 'back_end'").first
if self.shipping_method
self.save!
self.create_shipment!
else
raise 'No default shipping method found'
end
end
def shipping_address_from_distributor
if distributor
self.ship_address = distributor.pickup_address.clone
if bill_address
self.ship_address.firstname = bill_address.firstname
self.ship_address.lastname = bill_address.lastname
self.ship_address.phone = bill_address.phone
end
end
end
end

View File

@@ -1,11 +1,32 @@
Spree::Product.class_eval do
belongs_to :supplier
has_and_belongs_to_many :distributors
attr_accessible :supplier_id, :distributor_ids
has_many :product_distributions, :dependent => :destroy
has_many :distributors, :through => :product_distributions
validates_presence_of :supplier, :distributors
accepts_nested_attributes_for :product_distributions, :allow_destroy => true
attr_accessible :supplier_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size
validates_presence_of :supplier
scope :in_supplier, lambda { |supplier| where(:supplier_id => supplier) }
scope :in_distributor, lambda { |distributor| joins(:distributors).where('distributors.id = ?', (distributor.respond_to?(:id) ? distributor.id : distributor.to_i)) }
scope :in_distributor, lambda { |distributor| joins(:product_distributions).where('product_distributions.distributor_id = ?', (distributor.respond_to?(:id) ? distributor.id : distributor.to_i)) }
def shipping_method_for_distributor(distributor)
distribution = self.product_distributions.find_by_distributor_id(distributor)
raise ArgumentError, "This product is not available through that distributor" unless distribution
distribution.shipping_method
end
# Build a product distribution for each distributor
def build_product_distributions
Distributor.all.each do |distributor|
unless self.product_distributions.find_by_distributor_id distributor.id
self.product_distributions.build(:distributor => distributor)
end
end
end
end

View File

@@ -1,20 +0,0 @@
module Spree
class Supplier < ActiveRecord::Base
self.table_name = 'suppliers'
has_many :products
belongs_to :country
belongs_to :state
validates :name, :address, :country_id, :state_id, :city, :postcode, :presence => true
after_initialize :initialize_country
def initialize_country
self.country = Spree::Country.find_by_id(Spree::Config[:default_country_id])
end
def to_param
"#{id}-#{name.parameterize}"
end
end
end

33
app/models/supplier.rb Normal file
View File

@@ -0,0 +1,33 @@
class Supplier < ActiveRecord::Base
has_many :products, :class_name => 'Spree::Product'
belongs_to :address, :class_name => 'Spree::Address'
accepts_nested_attributes_for :address
validates_presence_of :name, :address
validates_associated :address
after_initialize :initialize_country
before_validation :set_unused_address_fields
def has_products_on_hand?
self.products.where('count_on_hand > 0').present?
end
def to_param
"#{id}-#{name.parameterize}"
end
private
def initialize_country
self.address ||= Spree::Address.new
self.address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id]) if self.address.new_record?
end
def set_unused_address_fields
address.firstname = address.lastname = address.phone = 'unused' if address.present?
end
end

View File

@@ -0,0 +1,4 @@
Deface::Override.new(:virtual_path => "spree/layouts/admin",
:name => "cms_admin_tab",
:insert_bottom => "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
:text => "<li><%= link_to('CMS Admin', main_app.cms_admin_path) %></li>")

View File

@@ -0,0 +1,9 @@
Deface::Override.new(:virtual_path => "spree/products/show",
:insert_before => "[data-hook='cart_form']",
:partial => "spree/products/distributor_details",
:name => "product_distributor_details")
Deface::Override.new(:virtual_path => "spree/products/show",
:insert_after => "[data-hook='product_show']",
:text => "<%= javascript_include_tag main_app.distributors_path(:format => :js) %>",
:name => "product_distributor_details_js")

View File

@@ -0,0 +1,4 @@
Deface::Override.new(:virtual_path => "spree/orders/edit",
:insert_after => "#empty-cart",
:partial => "spree/orders/distributor_fees",
:name => "cart_distributor_fees")

View File

@@ -1,9 +1,9 @@
Deface::Override.new(:virtual_path => "spree/admin/products/_form",
:insert_top => "[data-hook='admin_product_form_right']",
:partial => "spree/admin/products/distributors",
:name => "distributors")
:insert_bottom => "[data-hook='admin_product_form_additional_fields']",
:partial => "spree/admin/products/distributors_form",
:name => "distributors")
Deface::Override.new(:virtual_path => "spree/admin/products/new",
:insert_bottom => ".left",
:partial => "spree/admin/products/distributors",
:name => "distributors")
:insert_after => "[data-hook='new_product_attrs']",
:partial => "spree/admin/products/distributors_form",
:name => "distributors")

View File

@@ -0,0 +1,4 @@
Deface::Override.new(:virtual_path => "spree/layouts/spree_application",
:insert_bottom => "[data-hook='inside_head']",
:partial => "layouts/feedback_script",
:name => "feedback_script")

View File

@@ -0,0 +1,9 @@
Deface::Override.new(:virtual_path => "spree/admin/products/_form",
:insert_top => "[data-hook='admin_product_form_right']",
:partial => "spree/admin/products/group_buy_form",
:name => "group buy")
Deface::Override.new(:virtual_path => "spree/admin/products/new",
:insert_bottom => ".right",
:partial => "spree/admin/products/group_buy_form",
:name => "group buy")

View File

@@ -1,9 +1,9 @@
Deface::Override.new(:virtual_path => "spree/admin/products/_form",
:insert_top => "[data-hook='admin_product_form_right']",
:partial => "spree/admin/products/supplier",
:name => "supplier")
Deface::Override.new(:virtual_path => "spree/admin/products/_form",
:insert_top => "[data-hook='admin_product_form_right']",
:partial => "spree/admin/products/supplier_form",
:name => "supplier")
Deface::Override.new(:virtual_path => "spree/admin/products/new",
:insert_bottom => ".left",
:partial => "spree/admin/products/supplier",
:name => "supplier")
:insert_bottom => ".right",
:partial => "spree/admin/products/supplier_form",
:name => "supplier")

View File

@@ -0,0 +1,4 @@
Deface::Override.new(:virtual_path => "spree/orders/_line_item",
:replace => "[data-hook='cart_item_description']",
:partial => "spree/orders/cart_item_description",
:name => "cart_item_description")

View File

@@ -0,0 +1,4 @@
Deface::Override.new(:virtual_path => "spree/shared/_order_details",
:replace => "div.payment-info",
:partial => "spree/shared/order_details_payment_info",
:name => "order_details_payment_info")

View File

@@ -1,11 +1,11 @@
Deface::Override.new(:virtual_path => "spree/layouts/admin",
:name => "distributors_admin_tabs",
:insert_bottom => "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
:text => "<%= tab(:distributors, :url => spree.admin_distributors_path) %>",
:text => "<%= tab(:distributors, :url => main_app.admin_distributors_path) %>",
:disabled => false)
Deface::Override.new(:virtual_path => "spree/layouts/admin",
:name => "suppliers_admin_tabs",
:insert_bottom => "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
:text => "<%= tab(:suppliers, :url => spree.admin_suppliers_path) %>",
:disabled => false)
:text => "<%= tab(:suppliers, :url => main_app.admin_suppliers_path) %>",
:disabled => false)

View File

@@ -0,0 +1,10 @@
# Remove column layout from cart form items so we can style it with CSS
Deface::Override.new(:virtual_path => "spree/orders/edit",
:replace => "[data-hook='inside_cart_form']",
:partial => "spree/orders/inside_cart_form",
:name => "inside_cart_form")
Deface::Override.new(:virtual_path => "spree/orders/edit",
:replace => "#empty-cart[data-hook]",
:partial => "spree/orders/empty_cart_form",
:name => "empty_cart_form")

View File

@@ -1,5 +1,4 @@
Deface::Override.new(:virtual_path => "spree/checkout/_address",
:replace => "[data-hook='shipping_fieldset_wrapper']",
:partial => "spree/checkout/distributor",
:name => "drop_off_point")
:name => "delivery_address")

View File

@@ -0,0 +1,42 @@
- content_for :head do
= render 'shared/cms_elrte_head'
%table{"data-hook" => "distributors"}
%tr{"data-hook" => "name"}
%td Name:
%td= f.text_field :name
%tr{"data-hook" => "description"}
%td Description:
%td= f.text_field :description
%tr{'data-hook' => "long_description"}
%td Extended Description:
%td= f.text_area :long_description, :class => 'rich_text'
%tr{"data-hook" => "contact"}
%td Contact:
%td= f.text_field :contact
%tr{"data-hook" => "phone"}
%td Phone:
%td= f.text_field :phone
%tr{"data-hook" => "email"}
%td Email:
%td= f.text_field :email
%tr{"data-hook" => "url"}
%td URL:
%td= f.text_field :url
%tr{"data-hook" => "abn"}
%td ABN:
%td= f.text_field :abn
%tr{"data-hook" => "acn"}
%td ACN:
%td= f.text_field :acn
%fieldset
%legend Pickup details
%table{"data-hook" => "distributors_pickup_details"}
%tr{"data-hook" => "next_collection_at"}
%td Next collection date/time:
%td= f.text_field :next_collection_at
%tr{"data-hook" => "pickup_times"}
%td Regular pickup times:
%td= f.text_field :pickup_times
= f.fields_for :pickup_address do |pickup_address_form|
= render 'spree/admin/shared/address_form', :f => pickup_address_form

View File

@@ -0,0 +1,40 @@
<div class="toolbar" data-hook="toolbar">
<ul class="actions">
<li>
<%= button_link_to "New Distributor", main_app.new_admin_distributor_path, :icon => 'add', :id => 'admin_new_distributor_link' %>
</li>
</ul>
<br class="clear" />
</div>
<%= form_for @distributor_set, :url => main_app.bulk_update_admin_distributors_path do |f| %>
<table class="index" id="listing_distributors">
<thead>
<tr data-hook="distributors_header">
<th>Name</th>
<th>Next Collection Date/Time</th>
<th>Description</th>
<th></th>
</tr>
</thead>
<tbody>
<%= f.fields_for :distributors do |distributor_form| %>
<% distributor = distributor_form.object %>
<tr>
<td><%= link_to distributor.name, main_app.admin_distributor_path(distributor) %></td>
<td><%= distributor_form.text_field :next_collection_at %></td>
<td><%= distributor.description %></td>
<td data-hook="admin_users_index_row_actions">
<%= link_to_edit distributor, :class => 'edit' %> &nbsp;
<%= link_to_delete distributor %>
</td>
</tr>
<% end %>
<% if @distributors.empty? %>
<tr><td colspan="4"><%= t(:none) %></td></tr>
<% end %>
</tbody>
</table>
<%= f.submit 'Update' %>
<% end %>

View File

@@ -1,7 +1,7 @@
<%= render :partial => 'spree/shared/error_messages', :locals => { :target => @distributor } %>
<%= form_for [:admin, @distributor] do |f| %>
<%= form_for [main_app, :admin, @distributor] do |f| %>
<%= render :partial => 'form', :locals => { :f => f } %>
<%= render :partial => 'spree/admin/shared/new_resource_links' %>
<% end %>

View File

@@ -0,0 +1,42 @@
%h1 Distributor
%table
%tr
%th Name:
%td= @distributor.name
%tr
%th Description:
%td= @distributor.description
%tr
%th Extended Description:
%td= @distributor.long_description.andand.html_safe
%tr
%th Contact person:
%td= @distributor.contact
%tr
%th Phone number:
%td= @distributor.phone
%tr
%th Email:
%td= @distributor.email
%tr
%th Pickup address:
%td= render 'spree/shared/address', :address => @distributor.pickup_address
%tr
%th Next collection date/time:
%td= @distributor.next_collection_at
%tr
%th Regular pickup times:
%td= @distributor.pickup_times
%tr
%th ABN:
%td= @distributor.abn
%tr
%th ACN:
%td= @distributor.acn
%tr
%th URL:
%td= @distributor.url
%p
= link_to :Edit, main_app.edit_admin_distributor_path(@distributor), :class => 'edit_distributor'
= t(:or)
= link_to t(:back), main_app.admin_distributors_path

View File

@@ -0,0 +1,24 @@
- content_for :head do
= render 'shared/cms_elrte_head'
%table{'data-hook' => "suppliers"}
%tr{'data-hook' => "name"}
%td Name:
%td= f.text_field :name
%tr{'data-hook' => "description"}
%td Description:
%td= f.text_field :description
%tr{'data-hook' => "long_description"}
%td Extended Description:
%td= f.text_area :long_description, :class => 'rich_text'
= f.fields_for :address do |address_form|
= render 'spree/admin/shared/address_form', :f => address_form
%tr{'data-hook' => "email"}
%td Email:
%td= f.text_field :email
%tr{'data-hook' => "website"}
%td Website:
%td= f.text_field :website
%tr{'data-hook' => "twitter"}
%td Twitter:
%td= f.text_field :twitter

View File

@@ -1,6 +1,6 @@
.toolbar{'data-hook' => "suppliers"}
%ul.actions
%li= button_link_to "New Supplier", spree.new_admin_supplier_path, :icon => 'add', :id => 'admin_new_supplier_link'
%li= button_link_to "New Supplier", main_app.new_admin_supplier_path, :icon => 'add', :id => 'admin_new_supplier_link'
%br.clear
%table#listing_suppliers.index
%thead
@@ -11,7 +11,7 @@
%tbody
- @suppliers.each do |supplier|
%tr
%td= link_to supplier.name, spree.admin_supplier_path(supplier)
%td= link_to supplier.name, main_app.admin_supplier_path(supplier)
%td= supplier.description
%td{'data-hook' => "admin_supplier_index_row_actions"}
= link_to_edit supplier, :class => 'edit'

View File

@@ -1,6 +1,5 @@
= render :partial => 'spree/shared/error_messages', :locals => { :target => @supplier }
= form_for [:admin, @supplier] do |f|
= form_for [main_app, :admin, @supplier] do |f|
= render :partial => 'form', :locals => { :f => f }
= render :partial => 'spree/admin/shared/new_resource_links'

View File

@@ -0,0 +1,27 @@
%h1 Supplier
%table
%tr
%th Name:
%td= @supplier.name
%tr
%th Description:
%td= @supplier.description
%tr
%th Extended Description:
%td= @supplier.long_description.andand.html_safe
%tr
%th Address:
%td= render 'spree/shared/address', :address => @supplier.address
%tr
%th Email:
%td= @supplier.email
%tr
%th Website:
%td= @supplier.website
%tr
%th Twitter:
%td= @supplier.twitter
%p
= link_to :Edit, main_app.edit_admin_supplier_path(@supplier), :class => 'edit_supplier'
= t(:or)
= link_to t(:back), main_app.admin_suppliers_path

View File

@@ -0,0 +1,23 @@
%h2= distributor.name
%p
%strong Address:
%br/
= render 'spree/shared/address', :address => distributor.pickup_address
%p
%strong Next collection time:
%br/
= distributor.next_collection_at
%p
%strong Regular collection times:
%br/
= distributor.pickup_times
%p
%strong Contact:
%br/
= distributor.contact
%br/
= "Phone: #{distributor.phone}"
%br/
= "Email: #{distributor.email}"
%p= distributor.description
%p= link_to distributor.url, distributor.url if distributor.url

View File

@@ -0,0 +1 @@
distributors = <%= @distributor_details.to_json.html_safe %>;

View File

@@ -0,0 +1,7 @@
%h2= @distributor.name
.distributor-description= @distributor.long_description.andand.html_safe
%h3 Available Now
= render :template => 'spree/products/index'

View File

@@ -0,0 +1 @@
%li= link_to 'Spree Admin', spree.admin_path

View File

@@ -0,0 +1,8 @@
<script type="text/javascript">
var uvOptions = {};
(function() {
var uv = document.createElement('script'); uv.type = 'text/javascript'; uv.async = true;
uv.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'widget.uservoice.com/mCbT1cbjQZkPELXOix9Ag.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(uv, s);
})();
</script>

View File

@@ -1,14 +1 @@
<!DOCTYPE html>
<html>
<head>
<title>Openfoodweb</title>
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
<%= render :file => 'spree/layouts/spree_application' %>

View File

@@ -0,0 +1,17 @@
-# Include all stylesheets except reset (which overrides Spree styles)
-# See cms/app/views/layouts/cms_admin/_head.html.erb
= stylesheet_link_tag 'comfortable_mexican_sofa/structure',
'comfortable_mexican_sofa/typography',
'comfortable_mexican_sofa/form',
'comfortable_mexican_sofa/content',
'comfortable_mexican_sofa/files',
'comfortable_mexican_sofa/elrte',
'comfortable_mexican_sofa/codemirror',
'comfortable_mexican_sofa/jquery_ui',
'comfortable_mexican_sofa/dialogs',
'comfortable_mexican_sofa/widgets'
= javascript_include_tag('comfortable_mexican_sofa/application')
%meta{:name => "cms-admin-path", :content => ComfortableMexicanSofa.config.admin_route_prefix}
%meta{:name => "cms-locale", :content => I18n.locale}

View File

@@ -1,67 +0,0 @@
<table data-hook="distributors">
<tr data-hook="name">
<td>Name:</td>
<td><%= f.text_field :name %></td>
</tr>
<tr data-hook="description">
<td>Description:</td>
<td><%= f.text_field :description %></td>
</tr>
<tr data-hook="contact">
<td>Contact:</td>
<td><%= f.text_field :contact %></td>
</tr>
<tr data-hook="phone">
<td>Phone:</td>
<td><%= f.text_field :phone %></td>
</tr>
<tr data-hook="email">
<td>Email:</td>
<td><%= f.text_field :email %></td>
</tr>
<tr data-hook="pickup_address">
<td>Address: </td>
<td><%= f.text_field :pickup_address %></td>
</tr>
<tr data-hook="pickup_city">
<td>City:</td>
<td><%= f.text_field :city %></td>
</tr>
<tr data-hook="pickup_post_code">
<td>Post code:</td>
<td><%= f.text_field :post_code %></td>
</tr>
<tr data-hook="pickup_country">
<td>Country: </td>
<td><%= f.collection_select(:country_id, @countries, :id, :name, :include_blank => true) %></td>
</tr>
<tr data-hook="pickup_state">
<td>State: </td>
<td><%= f.collection_select(:state_id, @distributor.country.states, :id, :name, :include_blank => true) %></td>
</tr>
<tr data-hook="pickup_times">
<td>Pickup times:</td>
<td><%= f.text_field :pickup_times %></td>
</tr>
<tr data-hook="url">
<td>URL:</td>
<td><%= f.text_field :url %></td>
</tr>
<tr data-hook="abn">
<td>ABN:</td>
<td><%= f.text_field :abn %></td>
</tr>
<tr data-hook="acn">
<td>ACN:</td>
<td><%= f.text_field :acn %></td>
</tr>
</table>

View File

@@ -1,37 +0,0 @@
<div class="toolbar" data-hook="toolbar">
<ul class="actions">
<li>
<%= button_link_to "New Distributor", spree.new_admin_distributor_path, :icon => 'add', :id => 'admin_new_distributor_link' %>
</li>
</ul>
<br class="clear" />
</div>
<table class="index" id='listing_distributors'>
<thead>
<tr data-hook="distributors_header">
<th>Name</th>
<th>
Description
</th>
<th>
</th>
</tr>
</thead>
<tbody>
<% @distributors.each do |distributor| %>
<tr >
<td><%= link_to distributor.name, spree.admin_distributor_path(distributor) %></td>
<td><%=distributor.description %></td>
<td data-hook="admin_users_index_row_actions">
<%= link_to_edit distributor, :class => 'edit' %> &nbsp;
<%= link_to_delete distributor %>
</td>
</tr>
<% end %>
<% if @distributors.empty? %>
<tr><td colspan="2"><%= t(:none) %></td></tr>
<% end %>
</tbody>
</table>

View File

@@ -1,92 +0,0 @@
<h1>Distributor</h1>
<table>
<tr>
<th>Name</th>
<td>
<%= @distributor.name %>
</td>
</tr>
<tr>
<th>Description</th>
<td>
<%= @distributor.description %>
</td>
</tr>
<tr>
<th>Contact person</th>
<td>
<%= @distributor.contact %>
</td>
</tr>
<tr>
<th>Phone number</th>
<td>
<%= @distributor.phone %>
</td>
</tr>
<tr>
<th>Email</th>
<td>
<%= @distributor.email %>
</td>
</tr>
<th>Pickup address</th>
<td>
<%= @distributor.pickup_address %>
</td>
</tr>
<th>Pickup city</th>
<td>
<%= @distributor.city %>
</td>
</tr>
<th>Pickup post code</th>
<td>
<%= @distributor.post_code %>
</td>
</tr>
<th>Pickup country</th>
<td>
<%= @distributor.country.name if @distributor.country %>
</td>
</tr>
<th>Pickup state</th>
<td>
<%= @distributor.state.name if @distributor.state %>
</td>
</tr>
<th>Pickup times</th>
<td>
<%= @distributor.pickup_times %>
</td>
</tr>
<th>ABN</th>
<td>
<%= @distributor.abn %>
</td>
</tr>
<th>ACN</th>
<td>
<%= @distributor.acn %>
</td>
</tr>
<th>URL</th>
<td>
<%= @distributor.url %>
</td>
</tr>
</table>
<p>
<%= link_to :Edit, spree.edit_admin_distributor_path(@distributor), :class => 'edit_distributor' %> <%= t(:or) %>
<%= link_to t(:back), spree.admin_distributors_path %>
</p>

View File

@@ -1,5 +0,0 @@
= f.field_container :distributors do
= f.label :distributors
%br
= f.collection_check_boxes(:distributor_ids, Spree::Distributor.all, :id, :name)
= f.error_message_on :distributors

View File

@@ -0,0 +1,14 @@
%h2 Distributors
= f.field_container :product_distributions do
- f.object.build_product_distributions
%table
= f.fields_for :product_distributions do |pd_form|
%tr
%td
= hidden_field_tag "#{pd_form.object_name}[_destroy]", 1, :id => nil
= check_box_tag "#{pd_form.object_name}[_destroy]", 0, !pd_form.object.new_record?
%td
= label_tag "#{pd_form.object_name}[_destroy]", pd_form.object.distributor.name
= pd_form.hidden_field :distributor_id
%td
= pd_form.collection_select :shipping_method_id, Spree::ShippingMethod.all, :id, :name

View File

@@ -0,0 +1,12 @@
= f.field_container :group_buy do
= f.label :group_buy, 'Group buy?'
%br
= f.radio_button :group_buy, '1', :checked => f.object.group_buy
= f.label :group_buy_1, 'Yes'
= f.radio_button :group_buy, '0', :checked => !f.object.group_buy
= f.label :group_buy_0, 'No'
= f.field_container :group_buy_unit_size do
= f.label :group_buy_unit_size
%br
= f.text_field :group_buy_unit_size

View File

@@ -1,5 +0,0 @@
= f.field_container :supplier do
= f.label :supplier
%br
= f.collection_select(:supplier_id, Spree::Supplier.all, :id, :name, :include_blank => true)
= f.error_message_on :supplier

View File

@@ -0,0 +1,5 @@
= f.field_container :supplier do
= f.label :supplier
%br
= f.collection_select(:supplier_id, Supplier.all, :id, :name, :include_blank => true)
= f.error_message_on :supplier

View File

@@ -0,0 +1,39 @@
= form_for @search, :url => spree.bulk_coop_admin_reports_path do |f|
= label_tag nil, t(:date_range)
%br
.date-range-filter
%div{"class" => "left sub-field"}
= f.text_field :created_at_gt, :class => 'datepicker'
%br
= label_tag nil, t(:start), :class => 'sub'
%div{"class" => "right sub-field"}
= f.text_field :created_at_lt, :class => 'datepicker'
%br
= label_tag nil, t(:stop)
%br
= label_tag nil, "Distributor: "
= f.collection_select(:distributor_id_eq, @distributors, :id, :name, :include_blank => 'All')
%br
= label_tag nil, "Report Type: "
= select_tag(:report_type, options_for_select([['Bulk Co-op - Totals by Supplier',:bulk_coop_supplier_report],['Bulk Co-op - Allocation',:bulk_coop_allocation],['Bulk Co-op - Packing Sheets',:bulk_coop_packing_sheets],['Bulk Co-op - Customer Payments',:bulk_coop_customer_payments]], @report_type))
%br
%br
= check_box_tag :csv
= label_tag :csv, "Download as csv"
%br
= button t(:search)
%br
%br
%table#listing_orders.index
%thead
%tr{'data-hook' => "orders_header"}
- @header.each do |heading|
%th=heading
%tbody
- @table.each do |row|
%tr
- row.each do |column|
%td= column
- if @table.empty?
%tr
%td{:colspan => "2"}= t(:none)

View File

@@ -0,0 +1,37 @@
= form_for @search, :url => spree.group_buys_admin_reports_path do |f|
= label_tag nil, t(:date_range)
%br
.date-range-filter
%div{"class" => "left sub-field"}
= f.text_field :created_at_gt, :class => 'datepicker'
%br
= label_tag nil, t(:start), :class => 'sub'
%div{"class" => "right sub-field"}
= f.text_field :created_at_lt, :class => 'datepicker'
%br
= label_tag nil, t(:stop)
%br
= label_tag nil, "Distributor: "
= f.collection_select(:distributor_id_eq, @distributors, :id, :name)
%br
%br
= check_box_tag :csv
= label_tag :csv, "Download as csv"
%br
= button t(:search)
%br
%br
%table#listing_orders.index
%thead
%tr{'data-hook' => "orders_header"}
- @report.header.each do |heading|
%th=heading
%tbody
- @report.table.each do |row|
%tr
- row.each do |column|
%td= column
- if @report.table.empty?
%tr
%td{:colspan => "2"}= t(:none)

View File

@@ -0,0 +1,39 @@
= form_for @search, :url => spree.order_cycles_admin_reports_path do |f|
= label_tag nil, t(:date_range)
%br
.date-range-filter
%div{"class" => "left sub-field"}
= f.text_field :created_at_gt, :class => 'datepicker'
%br
= label_tag nil, t(:start), :class => 'sub'
%div{"class" => "right sub-field"}
= f.text_field :created_at_lt, :class => 'datepicker'
%br
= label_tag nil, t(:stop)
%br
= label_tag nil, "Distributor: "
= f.collection_select(:distributor_id_eq, @distributors, :id, :name, :include_blank => @include_blank)
%br
= label_tag nil, "Report Type: "
= select_tag(:report_type, options_for_select([['Order Cycle Supplier Totals',:order_cycle_supplier_totals], ['Order Cycle Supplier Totals by Distributor',:order_cycle_supplier_totals_by_distributor], ['Order Cycle Distributor Totals by Supplier',:order_cycle_distributor_totals_by_supplier], ['Order Cycle Customer Totals',:order_cycle_customer_totals]], @report_type))
%br
%br
= check_box_tag :csv
= label_tag :csv, "Download as csv"
%br
= button t(:search)
%br
%br
%table#listing_orders.index
%thead
%tr{'data-hook' => "orders_header"}
- @header.each do |heading|
%th=heading
%tbody
- @table.each do |row|
%tr
- row.each do |column|
%td= column
- if @table.empty?
%tr
%td{:colspan => "2"}= t(:none)

View File

@@ -0,0 +1,32 @@
= form_for @search, :url => spree.orders_and_distributors_admin_reports_path do |s|
= label_tag nil, t(:date_range)
%br
.date-range-filter
%div{"class" => "left sub-field"}
= s.text_field :created_at_gt, :class => 'datepicker'
%br
= label_tag nil, t(:start), :class => 'sub'
%div{"class" => "right sub-field"}
= s.text_field :created_at_lt, :class => 'datepicker'
%br
= label_tag nil, t(:stop)
= check_box_tag :csv
= label_tag :csv, "Download as csv"
%br
= button t(:search)
%br
%br
%table#listing_orders.index
%thead
%tr{'data-hook' => "orders_header"}
- @report.header.each do |heading|
%th=heading
%tbody
- @report.table.each do |row|
%tr
- row.each do |column|
%td= column
- if @report.table.empty?
%tr
%td{:colspan => "2"}= t(:none)

View File

@@ -0,0 +1,39 @@
= form_for @search, :url => spree.payments_admin_reports_path do |f|
= label_tag nil, t(:date_range)
%br
.date-range-filter
%div{"class" => "left sub-field"}
= f.text_field :created_at_gt, :class => 'datepicker'
%br
= label_tag nil, t(:start), :class => 'sub'
%div{"class" => "right sub-field"}
= f.text_field :created_at_lt, :class => 'datepicker'
%br
= label_tag nil, t(:stop)
%br
= label_tag nil, "Distributor: "
= f.collection_select(:distributor_id_eq, @distributors, :id, :name, :include_blank => 'All')
%br
= label_tag nil, "Report Type: "
= select_tag(:report_type, options_for_select([['Payments By Type',:payments_by_payment_type],['Itemised Payment Totals',:itemised_payment_totals],['Payment Totals',:payment_totals]], @report_type))
%br
%br
= check_box_tag :csv
= label_tag :csv, "Download as csv"
%br
= button t(:search)
%br
%br
%table#listing_orders.index
%thead
%tr{'data-hook' => "orders_header"}
- @header.each do |heading|
%th=heading
%tbody
- @table.each do |row|
%tr
- row.each do |column|
%td= column
- if @table.empty?
%tr
%td{:colspan => "2"}= t(:none)

View File

@@ -0,0 +1,18 @@
%tr{"data-hook" => "address1"}
%td Address:
%td= f.text_field :address1
%tr{"data-hook" => "address2"}
%td Address (cont.):
%td= f.text_field :address2
%tr{"data-hook" => "city"}
%td City:
%td= f.text_field :city
%tr{"data-hook" => "zipcode"}
%td Postcode:
%td= f.text_field :zipcode
%tr{"data-hook" => "country"}
%td Country:
%td= f.collection_select(:country_id, available_countries, :id, :name)
%tr{"data-hook" => "state"}
%td State:
%td= f.collection_select(:state_id, f.object.country.states, :id, :name)

View File

@@ -0,0 +1,6 @@
<%= tab :overview, :route => :admin %>
<%= tab :orders, :payments, :creditcard_payments, :shipments, :creditcards, :return_authorizations, {:url => admin_orders_path('q[s]' => 'completed_at desc')} %>
<%= tab :products , :option_types, :properties, :prototypes, :variants, :product_properties, :taxons %>
<%= tab :reports %>
<%= tab :configurations, :general_settings, :mail_methods, :tax_categories, :zones, :states, :payment_methods, :inventory_settings, :taxonomies, :shipping_methods, :trackers, :label => 'configuration' %>
<%= tab :users %>

View File

@@ -1,31 +0,0 @@
%table{'data-hook' => "suppliers"}
%tr{'data-hook' => "name"}
%td Name:
%td= f.text_field :name
%tr{'data-hook' => "description"}
%td Description:
%td= f.text_field :description
%tr{'data-hook' => "address"}
%td Address:
%td= f.text_field :address
%tr{'data-hook' => "city"}
%td City:
%td= f.text_field :city
%tr{'data-hook' => "post_code"}
%td Post Code:
%td= f.text_field :postcode
%tr{'data-hook' => "country"}
%td Country:
%td= f.collection_select(:country_id, @countries, :id, :name, :include_blank => true)
%tr{'data-hook' => "state"}
%td State:
%td= f.collection_select(:state_id, @supplier.country.states, :id, :name, :include_blank => true)
%tr{'data-hook' => "email"}
%td Email:
%td= f.text_field :email
%tr{'data-hook' => "website"}
%td Website:
%td= f.text_field :website
%tr{'data-hook' => "twitter"}
%td Twitter:
%td= f.text_field :twitter

View File

@@ -1,36 +0,0 @@
%h1 Supplier
%table
%tr
%th Name
%td= @supplier.name
%tr
%th Description
%td= @supplier.description
%tr
%th Address
%td= @supplier.address
%tr
%th City:
%td= @supplier.city
%tr
%th Post Code:
%td= @supplier.postcode
%tr
%th Country:
%td= @supplier.country.name if @supplier.country
%tr
%th State:
%td= @supplier.state.name if @supplier.state
%tr
%th Email
%td= @supplier.email
%tr
%th Website
%td= @supplier.website
%tr
%th Twitter
%td= @supplier.twitter
%p
= link_to :Edit, spree.edit_admin_supplier_path(@supplier), :class => 'edit_supplier'
= t(:or)
= link_to t(:back), spree.admin_suppliers_path

View File

@@ -1,5 +1,4 @@
.columns.omega.six
%fieldset{:id => 'shipping'}
%legend Collection Point
=form.collection_select("distributor_id", Spree::Distributor.all, :id, :name, {}, {:class => 'required'})
%fieldset#shipping
%legend Distributor
= render 'distributors/details', :distributor => @order.distributor

View File

@@ -0,0 +1,33 @@
Dear Customer,
Please review and retain the following order information for your records.
============================================================
Order Summary
============================================================
<% @order.line_items.each do |item| %>
<%= item.variant.sku %> <%= raw(item.variant.product.name) %> <%= raw(item.variant.options_text) -%> (<%=item.quantity%>) @ <%= number_to_currency item.price %> = <%= number_to_currency(item.price * item.quantity) %>
<% end %>
============================================================
Subtotal: <%= number_to_currency @order.item_total %>
<% @order.adjustments.each do |adjustment| %>
<%= raw(adjustment.label) %> <%= number_to_currency(adjustment.amount) %>
<% end %>
Order Total: <%= number_to_currency(@order.total) %>
============================================================
Delivery Details
============================================================
Address:
<%= @order.distributor.name %>
<% address = @order.distributor.pickup_address %>
<%= address.address1 %> <%= ",\n #{address.address2}" unless address.address2.blank? %>
<%= [address.city, address.state_text, address.zipcode, address.country.name].compact.join ', ' %>
Colection time:
<%= @order.distributor.next_collection_at %>
Contact:
<%= @order.distributor.contact %>
<%= "Phone: #{@order.distributor.phone}" %>
<%= "Email: #{@order.distributor.email}" %>
Thank you for your business.

View File

@@ -0,0 +1,8 @@
%td{'data-hook' => "cart_item_description"}
%h4= link_to variant.product.name, product_path(variant.product)
= variant.options_text
- if @order.insufficient_stock_lines.include? line_item
%span.out-of-stock
= variant.in_stock? ? t(:insufficient_stock, :on_hand => variant.on_hand) : t(:out_of_stock)
%br/
= truncate_html(variant.product.description, :length => 100, :omission => "...")

View File

@@ -0,0 +1,23 @@
#delivery-fees
%h2 Delivery Fees
%table#delivery
%thead
%tr
%th Item
%th Shipping Method
%th Delivery Fee
%tbody
- @order.line_items.each do |line_item|
- tr_class = cycle('', 'alt')
%tr{:class => tr_class}
%td
%h4= link_to line_item.product.name, product_path(line_item.product)
%td.item-shipping-method= line_item.shipping_method.name
%td.item-shipping-cost= number_to_currency line_item.itemwise_shipping_cost
.subtotal{'data-hook' => 'delivery_fees_subtotal'}
%h5
Shipping total
\:
%span.order-total= order_delivery_fee_subtotal(@order)

View File

@@ -0,0 +1,6 @@
#empty-cart{'data-hook' => ""}
= form_tag empty_cart_path, :method => :put do
%p#clear_cart_link{'data-hook' => ""}
= link_to t(:continue_shopping), products_path, :class => 'continue button'
= t(:or)
= submit_tag t(:empty_cart), :class => 'button'

View File

@@ -0,0 +1,22 @@
%div{'data-hook' => "inside_cart_form"}
%div{'data-hook' => "cart_items"}
= render :partial => 'form', :locals => { :order_form => order_form }
#subtotal{'data-hook' => ""}
%h5
Item total
\:
%span.order-total.item-total= number_to_currency @order.item_total
%h5
Shipping total
\:
%span.order-total.shipping-total= order_delivery_fee_subtotal(@order)
%h4
Total
\:
%span.order-total.grand-total= order_subtotal(@order)
.links{'data-hook' => "cart_buttons"}
= button_tag :class => 'primary', :id => 'update-button' do
= t(:update)
= link_to t(:checkout), checkout_path, :class => 'button checkout primary', :id => 'checkout-link'

View File

@@ -3,16 +3,23 @@
= content_tag('strong', t(:out_of_stock))
- elsif current_order(false) && !current_order(false).can_add_product_to_cart?(@product)
.error-distributor= "Please complete your order at #{current_distributor.name} before shopping with another distributor."
.error-distributor
Please complete your order at
= link_to current_distributor.name, root_path
before shopping with another distributor.
- else
%p Quantity
= number_field_tag (@product.has_variants? ? :quantity : "variants[#{@product.master.id}]"), 1, :class => 'title', :in => 1..@product.on_hand
- if @product.group_buy
%p Max quantity
= number_field_tag (@product.has_variants? ? :max_quantity : "variant_attributes[#{@product.master.id}][max_quantity]"), 1, :class => 'title max_quantity', :in => 1..@product.on_hand
- order = current_order(false)
- if order.nil? || order.can_change_distributor?
%p Distributor
= select_tag "distributor_id", options_from_collection_for_select(@product.distributors, "id", "name", current_distributor.andand.id)
= select_tag "distributor_id", options_from_collection_for_select([Distributor.new]+@product.distributors, "id", "name", current_distributor.andand.id)
- else
= hidden_field_tag "distributor_id", order.distributor.id
.distributor-fixed= "Your distributor for this order is #{order.distributor.name}"
%br/
= button_tag :class => 'large primary', :id => 'add-to-cart-button', :type => :submit do

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