kete_gets_trollied 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +63 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/app/views/user_notifier/cancelled.html.erb +7 -0
- data/app/views/user_notifier/in_process.html.erb +7 -0
- data/app/views/user_notifier/new_note.html.erb +7 -0
- data/app/views/user_notifier/ready.html.erb +7 -0
- data/app/views/user_notifier/reviewing_of.html.erb +14 -0
- data/app/views/user_notifier/user_review.html.erb +7 -0
- data/config/locales/en.yml +75 -0
- data/config/routes.rb +26 -0
- data/lib/kete_gets_trollied.rb +4 -0
- data/lib/kete_gets_trollied/extensions/controllers/application_controller.rb +24 -0
- data/lib/kete_gets_trollied/extensions/controllers/line_items_controller.rb +3 -0
- data/lib/kete_gets_trollied/extensions/controllers/notes_controller.rb +3 -0
- data/lib/kete_gets_trollied/extensions/controllers/orders_controller.rb +36 -0
- data/lib/kete_gets_trollied/extensions/controllers/trolleys_controller.rb +3 -0
- data/lib/kete_gets_trollied/extensions/helpers/application_helper.rb +30 -0
- data/lib/kete_gets_trollied/extensions/models/basket.rb +4 -0
- data/lib/kete_gets_trollied/extensions/models/line_item.rb +4 -0
- data/lib/kete_gets_trollied/extensions/models/order.rb +81 -0
- data/lib/kete_gets_trollied/extensions/models/topic.rb +7 -0
- data/lib/kete_gets_trollied/extensions/models/trolley.rb +10 -0
- data/lib/kete_gets_trollied/extensions/models/user.rb +3 -0
- data/lib/kete_gets_trollied/extensions/models/user_notifier.rb +3 -0
- data/lib/kete_gets_trollied/has_trolley_controller_helpers_overrides.rb +51 -0
- data/lib/kete_gets_trollied/line_items_helper_overrides.rb +10 -0
- data/lib/kete_gets_trollied/orders_helper_overrides.rb +141 -0
- data/lib/kete_gets_trollied/user_order_notifications.rb +43 -0
- data/rails/init.rb +28 -0
- data/test/helper.rb +10 -0
- data/test/test_kete_gets_trollied.rb +7 -0
- metadata +132 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Horowhenua Library Trust
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
= kete_gets_trollied
|
2
|
+
|
3
|
+
A Kete add-on that uses the Trollied gem to deliver ordering of items from Kete.
|
4
|
+
|
5
|
+
== Usage
|
6
|
+
|
7
|
+
Currently only tested against Rails 2.3.5. When Kete moves to Rails 3, this gem will be updated to.
|
8
|
+
|
9
|
+
Install the Trollied gem and this gem:
|
10
|
+
|
11
|
+
gem install trollied kete_gets_trollied
|
12
|
+
|
13
|
+
After installing the gem do the following to add kete_gets_trollied to your app:
|
14
|
+
|
15
|
+
In the Rails::Initializer.run config block config/environment.rb:
|
16
|
+
|
17
|
+
config.gem "trollied"
|
18
|
+
config.gem "kete_gets_trollied"
|
19
|
+
|
20
|
+
You also need to add config/initializers/kete_gets_trollied.rb with the following:
|
21
|
+
|
22
|
+
ActionController::Base.send(:include, HasTrolleyControllerHelpersOverrides)
|
23
|
+
ActionController::Base.send(:helper, OrdersHelperOverrides)
|
24
|
+
ActionController::Base.send(:helper, LineItemsHelperOverrides)
|
25
|
+
|
26
|
+
This makes kete_gets_trollied's overrides take precedence over the straight trollied gem's stuff.
|
27
|
+
|
28
|
+
Now you need to run the migration generator to add the tables and columns that kete_gets_trollied needs to work. Do this in your Kete application's root directory.
|
29
|
+
|
30
|
+
$ script/generate trollied_migrations
|
31
|
+
|
32
|
+
Alter this:
|
33
|
+
|
34
|
+
t.integer :purchasable_item_id, :null => false
|
35
|
+
|
36
|
+
to
|
37
|
+
|
38
|
+
t.integer :purchasable_item_id, :null => false, :references => nil
|
39
|
+
|
40
|
+
Then run the migration command:
|
41
|
+
|
42
|
+
$ rake db:migrate # add environment if necessary, i.e. rake db:migrate RAILS_ENV=production
|
43
|
+
|
44
|
+
Lastly you will want restart your Kete server and backgroundrb:
|
45
|
+
|
46
|
+
$ touch tmp/restart.txt
|
47
|
+
$ script/backgroundrb stop
|
48
|
+
...
|
49
|
+
$ script/backgroundrb start
|
50
|
+
|
51
|
+
== Note on Patches/Pull Requests
|
52
|
+
|
53
|
+
* Fork the project.
|
54
|
+
* Make your feature addition or bug fix in a corresponding branch (even better, make an ticket first and name the branch with the ticket number in it)
|
55
|
+
* Add tests for it. This is important so I don't break it in a
|
56
|
+
future version unintentionally.
|
57
|
+
* Commit, do not mess with rakefile, version, or history.
|
58
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
59
|
+
* Send me a pull request.
|
60
|
+
|
61
|
+
== Copyright
|
62
|
+
|
63
|
+
Copyright (c) 2011 Horowhenua Library Trust. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "kete_gets_trollied"
|
8
|
+
gem.summary = %Q{Uses the trollied gem for adding item ordering to Kete.}
|
9
|
+
gem.description = %Q{Uses the trollied gem for adding item ordering to Kete.}
|
10
|
+
gem.email = "walter@katipo.co.nz"
|
11
|
+
gem.homepage = "http://github.com/kete/kete_gets_trollied"
|
12
|
+
gem.authors = ["Walter McGinnis"]
|
13
|
+
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
14
|
+
gem.add_dependency "trollied", ">= 0.1.4"
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
Rake::TestTask.new(:test) do |test|
|
24
|
+
# in the future may include own tests under dummy app or generators for kete app specific tests.
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
require 'rcov/rcovtask'
|
29
|
+
Rcov::RcovTask.new do |test|
|
30
|
+
test.libs << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
rescue LoadError
|
35
|
+
task :rcov do
|
36
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
task :test => :check_dependencies
|
41
|
+
|
42
|
+
task :default => :test
|
43
|
+
|
44
|
+
require 'rake/rdoctask'
|
45
|
+
Rake::RDocTask.new do |rdoc|
|
46
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
47
|
+
|
48
|
+
rdoc.rdoc_dir = 'rdoc'
|
49
|
+
rdoc.title = "kete_gets_trollied #{version}"
|
50
|
+
rdoc.rdoc_files.include('README*')
|
51
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
52
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%= @user.user_name %>,
|
2
|
+
|
3
|
+
<%=t 'user_notifier.reviewing_of.description',
|
4
|
+
:revision => @revision,
|
5
|
+
:flag => Kete.reviewed_flag %>
|
6
|
+
|
7
|
+
<%= @url %>
|
8
|
+
|
9
|
+
<% if !@message.blank? -%>
|
10
|
+
<%=t 'user_notifier.reviewing_of.reason' %>
|
11
|
+
<%= @message %>
|
12
|
+
<% end -%>
|
13
|
+
|
14
|
+
<%= render 'email_footer' %>
|
@@ -0,0 +1,75 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
line_items:
|
4
|
+
new:
|
5
|
+
confirm_order: "Confirm Enquiry"
|
6
|
+
controllers:
|
7
|
+
created: "Added to enquiry"
|
8
|
+
updated: "Updated in enquiry"
|
9
|
+
deleted: "Deleted from enquiry"
|
10
|
+
orders:
|
11
|
+
checkout_form:
|
12
|
+
confirm_order: "Confirm enquiry details"
|
13
|
+
additional_info_for_order: "What is the subject or nature of your enquiry?"
|
14
|
+
helpers:
|
15
|
+
cancelled_orders: "Cancelled Enquiries"
|
16
|
+
completed_orders: "Completed Enquiries"
|
17
|
+
current_orders: "Current Enquiries"
|
18
|
+
in_process_orders: "Enquiries Under Action"
|
19
|
+
order_number: "Enquiry:"
|
20
|
+
ready_orders: "Ready Enquiries"
|
21
|
+
user_review_orders: "Enquiries needing user attention"
|
22
|
+
contact_name: "Contact Name"
|
23
|
+
contact_name_example: "Fill out the name of the person to speak to about the enquiry if it is different from this account's username."
|
24
|
+
contact_phone: "Contact Phone"
|
25
|
+
contact_phone_example: "A staff member may be in contact to discuss your enquiry."
|
26
|
+
required_by: "Date enquiry is required by"
|
27
|
+
index:
|
28
|
+
in_process: "under action"
|
29
|
+
new: "New Enquiry"
|
30
|
+
no_orders: "No enquiries match your criteria."
|
31
|
+
title: "Enquiries"
|
32
|
+
user_review: "needing user attention"
|
33
|
+
order:
|
34
|
+
order_controls_preface: "Enquiry actions:"
|
35
|
+
order_notes: "Notes for this enquiry:"
|
36
|
+
show:
|
37
|
+
your_order: "Your Enquiry"
|
38
|
+
for_user_title: "Enquiry for {{name}}"
|
39
|
+
controllers:
|
40
|
+
change_to_cancel: "Enquiry Cancelled"
|
41
|
+
change_to_checkout: "Enquiry Checked Out"
|
42
|
+
change_to_finish: "Enquiry Completed"
|
43
|
+
change_to_fulfilled_without_acceptance: "Enquiry Ready"
|
44
|
+
change_to_alteration_approve: "You approved the changes to the enquiry. It is now back in process."
|
45
|
+
created: "Created enquiry"
|
46
|
+
updated: "Updated enquiry"
|
47
|
+
deleted: "Deleted enquiry"
|
48
|
+
checkout: "Your enquiry has been made."
|
49
|
+
trolleys:
|
50
|
+
orders:
|
51
|
+
cancelled: "Cancelled Enquiries"
|
52
|
+
completed: "Completed Enquiries"
|
53
|
+
current: "Current Enquiries"
|
54
|
+
in_process: "Under Action"
|
55
|
+
none_pending: "No enquiries pending."
|
56
|
+
ready: "Ready Enquiries"
|
57
|
+
user_review: "Enquiries needing your attention"
|
58
|
+
user_notifier:
|
59
|
+
cancelled:
|
60
|
+
user_has_cancelled: "{{cancelling_user}} has cancelled the following order:"
|
61
|
+
in_process:
|
62
|
+
user_has_checked_out: "{{order_user}} has checked out the following order:"
|
63
|
+
new_note:
|
64
|
+
user_has_created_note: "{{note_user}} has created a new note on the following order:"
|
65
|
+
ready:
|
66
|
+
your_order_is_ready: "Your order is ready:"
|
67
|
+
user_review:
|
68
|
+
please_review_order: "Your enquiry has been altered, please review:"
|
69
|
+
user_notifier_model:
|
70
|
+
subject_cancelled: "An order has been cancelled."
|
71
|
+
subject_in_process: "An order has been checked out."
|
72
|
+
subject_new_note: "A new note to an order has been added."
|
73
|
+
subject_ready: "Your order is now available."
|
74
|
+
subject_user_review: "An order needs your review."
|
75
|
+
|
data/config/routes.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'kete_gets_trollied'
|
2
|
+
|
3
|
+
# extend routes for translations of kete content
|
4
|
+
ActionController::Routing::Routes.draw do |map|
|
5
|
+
# Walter McGinnis, 2011-05-12
|
6
|
+
# adding shopping chart functionality
|
7
|
+
# WARNING user just for show at the moment
|
8
|
+
map.resources :user, :path_prefix => ':urlified_name' do |user|
|
9
|
+
user.resource :trolley, :only => :show do |trolley|
|
10
|
+
trolley.resources :orders, :shallow => true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
map.resources :topics, :path_prefix => ':urlified_name', :only => [:index], :has_many => :line_items
|
15
|
+
|
16
|
+
if Object.const_defined?(:Order)
|
17
|
+
members = Order.workflow_event_names.inject(Hash.new) do |hash, event_name|
|
18
|
+
hash[event_name.to_sym] = :post
|
19
|
+
hash
|
20
|
+
end
|
21
|
+
|
22
|
+
members[:checkout_form] = :get
|
23
|
+
|
24
|
+
map.resources :orders, :path_prefix => ':urlified_name', :member => members, :except => [:new, :create], :has_many => :line_items
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
ApplicationController.class_eval do
|
2
|
+
def user_is_trolley_owner_or_appropriate_admin?
|
3
|
+
return false unless logged_in?
|
4
|
+
|
5
|
+
if %w(trolleys line_items orders notes).include?(params[:controller])
|
6
|
+
if params[:controller] == 'orders' && params[:action] == 'index'
|
7
|
+
return at_least_a_moderator?
|
8
|
+
else
|
9
|
+
owned_by = @trolley || @order || @line_item || @note
|
10
|
+
unless owned_by.blank? && params[:controller] == 'line_items' && %w(new index create).include?(params[:action])
|
11
|
+
return (at_least_a_moderator? || current_user == owned_by.user)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
def authorize_trollied_action
|
20
|
+
return true if user_is_trolley_owner_or_appropriate_admin?
|
21
|
+
# otherwise they shouldn't be here
|
22
|
+
redirect_to DEFAULT_REDIRECTION_HASH
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
OrdersController.class_eval do
|
2
|
+
before_filter :authorize_trollied_action
|
3
|
+
|
4
|
+
alias_method :original_default_conditions_hash, :default_conditions_hash
|
5
|
+
def default_conditions_hash
|
6
|
+
hash = original_default_conditions_hash
|
7
|
+
if @current_basket != @site_basket
|
8
|
+
hash[:basket_id] = @current_basket.id
|
9
|
+
end
|
10
|
+
hash
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_defaults_for_order_checkout
|
14
|
+
return if @order.contact_name.present? && @order.contact_phone.present?
|
15
|
+
|
16
|
+
trolley = @trolley || current_user.trolley
|
17
|
+
# opted for two queries rather than one combined query
|
18
|
+
# and pulling apart latest values from multiple results
|
19
|
+
# WARNING: mysql specific select distinct syntax
|
20
|
+
previous_contact_name_order = trolley.orders.find(:first,
|
21
|
+
:select => "distinct(contact_name)",
|
22
|
+
:order => 'updated_at DESC')
|
23
|
+
|
24
|
+
@order.contact_name ||= previous_contact_name_order.contact_name if previous_contact_name_order.present? && previous_contact_name_order.contact_name.present?
|
25
|
+
|
26
|
+
previous_contact_phone_order = trolley.orders.find(:first,
|
27
|
+
:select => "distinct(contact_phone)",
|
28
|
+
:order => 'updated_at DESC')
|
29
|
+
|
30
|
+
@order.contact_phone ||= previous_contact_phone_order.contact_phone if previous_contact_phone_order.present? && previous_contact_phone_order.contact_phone.present?
|
31
|
+
end
|
32
|
+
|
33
|
+
def number_per_page
|
34
|
+
50
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
ApplicationHelper.module_eval do
|
2
|
+
# in application layout
|
3
|
+
# override in your add-on to add to it
|
4
|
+
def add_ons_logged_in_user_list
|
5
|
+
link_html = link_to_unless_current("Cart",
|
6
|
+
url_for_trolley(:user => current_user),
|
7
|
+
{ :tabindex => '2', :class => "trolley-button" })
|
8
|
+
|
9
|
+
content_tag('li', link_html)
|
10
|
+
end
|
11
|
+
|
12
|
+
# in application layout
|
13
|
+
# override in your add-on to add to it
|
14
|
+
def add_ons_basket_admin_list
|
15
|
+
"| " + link_to_unless_current('orders',
|
16
|
+
{ :controller => :orders,
|
17
|
+
:action => :index,
|
18
|
+
:urlified_name => @current_basket.urlified_name},
|
19
|
+
:tabindex => '2')
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_ons_site_admin_list
|
23
|
+
"| " + link_to_unless_current('all orders for site',
|
24
|
+
{ :controller => :orders,
|
25
|
+
:action => :index,
|
26
|
+
:urlified_name => @site_basket.urlified_name},
|
27
|
+
:tabindex => '2')
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# kete specific tie-in to trollied order model
|
2
|
+
Order.class_eval do
|
3
|
+
belongs_to :basket
|
4
|
+
before_save :set_basket_from_line_item
|
5
|
+
|
6
|
+
# this gives us a settings hash per order
|
7
|
+
# that we can use for preferences
|
8
|
+
acts_as_configurable
|
9
|
+
|
10
|
+
### implementing state methods, so far just for notifications
|
11
|
+
# corresponding methods for actual delivery are in lib/user_order_notifications.rb
|
12
|
+
# these methods are responsible for triggering the deliver and to whom
|
13
|
+
|
14
|
+
# notify the basket moderators that a new order is in_process
|
15
|
+
def checkout
|
16
|
+
# assumes that an in_process must have at least one line_item
|
17
|
+
# and therefore a basket
|
18
|
+
raise "An in_process order should have a basket." unless basket
|
19
|
+
|
20
|
+
basket.moderators_or_next_in_line.each do |user|
|
21
|
+
UserNotifier.deliver_in_process(self, user)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
# notify the ordering user that their order is ready
|
27
|
+
def fulfilled_without_acceptance
|
28
|
+
UserNotifier.deliver_ready(self, user)
|
29
|
+
end
|
30
|
+
|
31
|
+
# notify the ordering user that their order has been cancelled
|
32
|
+
# notify basket moderators that the order has been cancelled
|
33
|
+
def cancel(cancelling_user)
|
34
|
+
UserNotifier.deliver_cancelled(self, user, cancelling_user) unless user == cancelling_user
|
35
|
+
|
36
|
+
basket.moderators_or_next_in_line.each do |user_in_line|
|
37
|
+
UserNotifier.deliver_cancelled(self, user_in_line, cancelling_user) unless user_in_line == cancelling_user
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# notify the ordering user that their order requires user review
|
42
|
+
def alter
|
43
|
+
UserNotifier.deliver_user_review(self, user)
|
44
|
+
end
|
45
|
+
|
46
|
+
# notify staff that user has approved changes and the order is now in process
|
47
|
+
def alteration_approve
|
48
|
+
UserNotifier.deliver_in_process(self, user)
|
49
|
+
end
|
50
|
+
|
51
|
+
alias_method :original_new_note, :new_note
|
52
|
+
|
53
|
+
def new_note(note)
|
54
|
+
original_new_note(note)
|
55
|
+
|
56
|
+
if user == note.user
|
57
|
+
basket.moderators_or_next_in_line.each do |user_in_line|
|
58
|
+
UserNotifier.deliver_new_note(self, note, user_in_line)
|
59
|
+
end
|
60
|
+
else
|
61
|
+
UserNotifier.deliver_new_note(self, note, user)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def set_basket_from_line_item
|
66
|
+
basket ||= line_items.size > 0 ? line_items.first.basket : nil
|
67
|
+
end
|
68
|
+
|
69
|
+
# notes, except in the context of checkout_form, are not allowed
|
70
|
+
def may_note?
|
71
|
+
false
|
72
|
+
end
|
73
|
+
|
74
|
+
# TODO: this is archivescentral specific at this point, move to something that can be configured or something
|
75
|
+
def validate
|
76
|
+
if !new_record? && current?
|
77
|
+
errors.add('contact_name', 'Please provide a contact name for your enquiry') unless contact_name.present?
|
78
|
+
errors.add('contact_phone', 'Please provide a phone number where we may contact you at about your enquiry') unless contact_phone.present?
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Trolley.class_eval do
|
2
|
+
alias_method :original_correct_order, :correct_order
|
3
|
+
|
4
|
+
def correct_order(purchasable_item)
|
5
|
+
correct_orders = orders.with_state_current.select { |o| o.basket == purchasable_item.basket }
|
6
|
+
order = correct_orders.last
|
7
|
+
order = orders.create!(:basket => purchasable_item.basket) unless order.present?
|
8
|
+
order
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'kete_url_for'
|
2
|
+
module HasTrolleyControllerHelpersOverrides
|
3
|
+
def self.included(klass)
|
4
|
+
klass.send :include, UrlFor
|
5
|
+
klass.send :include, KeteUrlFor
|
6
|
+
end
|
7
|
+
|
8
|
+
module UrlFor
|
9
|
+
# expects user in options or @user or trolley being set
|
10
|
+
# unless @purchasable_item is present
|
11
|
+
# WARNING: in the case of @purchasable_item
|
12
|
+
# this method name breaks the principle of least surprise
|
13
|
+
# maybe alter trollied gem in future to come right
|
14
|
+
def url_for_trolley(options = { })
|
15
|
+
return url_for_dc_identifier(@purchasable_item) if @purchasable_item && params[:action] == 'create'
|
16
|
+
|
17
|
+
user = options.delete(:user)
|
18
|
+
trolley = options[:trolley] || @trolley || user.trolley
|
19
|
+
|
20
|
+
if trolley.blank?
|
21
|
+
user = @user
|
22
|
+
else
|
23
|
+
user = trolley.user
|
24
|
+
end
|
25
|
+
|
26
|
+
options[:user_id] = user.id
|
27
|
+
options[:controller] = 'trolleys'
|
28
|
+
options[:action] = 'show'
|
29
|
+
options[:urlified_name] = Basket.site_basket.urlified_name
|
30
|
+
|
31
|
+
url = url_for(options) # .split(".%23%")[0]
|
32
|
+
end
|
33
|
+
|
34
|
+
# expects order
|
35
|
+
# either as instance variables or in options
|
36
|
+
def url_for_order(options = { })
|
37
|
+
trolley = options.delete(:trolley) || @trolley
|
38
|
+
trolley = @order.trolley if @order
|
39
|
+
|
40
|
+
order = options.delete(:order) || @order || trolley.selected_order
|
41
|
+
|
42
|
+
options[:id] = order
|
43
|
+
options[:controller] = 'orders'
|
44
|
+
options[:action] = 'show'
|
45
|
+
options[:urlified_name] = Basket.site_basket.urlified_name
|
46
|
+
|
47
|
+
url_for options
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module LineItemsHelperOverrides
|
2
|
+
unless included_modules.include? LineItemsHelperOverrides
|
3
|
+
def link_to_purchasable_in(line_item)
|
4
|
+
item = line_item.purchasable_item
|
5
|
+
link_to item.description_for_purchasing, :controller => zoom_class_controller(item.class.name),
|
6
|
+
:urlified_name => item.basket.urlified_name,
|
7
|
+
:action => :show, :id => item
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module OrdersHelperOverrides
|
2
|
+
unless included_modules.include? OrdersHelperOverrides
|
3
|
+
def can_trigger_fulfilled_without_acceptance?
|
4
|
+
params[:controller] == 'orders' && at_least_a_moderator?
|
5
|
+
end
|
6
|
+
|
7
|
+
def can_trigger_finish?
|
8
|
+
params[:controller] == 'orders' && at_least_a_moderator?
|
9
|
+
end
|
10
|
+
|
11
|
+
def link_to_orders_for(user)
|
12
|
+
options = set_options_from_vars.merge({:user => user})
|
13
|
+
link_to(user.trolley_user_display_name, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def link_to_state_unless_current(state, count)
|
17
|
+
options = set_options_from_vars.merge({:state => state})
|
18
|
+
link_to_unless_current(t("orders.index.#{state}") + show_count_for(count), options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def orders_state_headline
|
22
|
+
html = super
|
23
|
+
if @current_basket != @site_basket
|
24
|
+
html += ' ' + t('base.inside') + ' ' + @current_basket.name
|
25
|
+
end
|
26
|
+
html
|
27
|
+
end
|
28
|
+
|
29
|
+
# override ### TODO: this isn't overriding the default method
|
30
|
+
def add_ons_logged_in_user_list
|
31
|
+
link_html = super
|
32
|
+
|
33
|
+
link_html += link_to_unless_current(t('base.your_cart'),
|
34
|
+
{ :user_id => current_user.id, :controller => :trolleys, :action => :show },
|
35
|
+
{ :tabindex => '2', :class => "trolley-button" })
|
36
|
+
|
37
|
+
content_tag('li', link_html)
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_options_from_vars
|
41
|
+
options = url_for_options_for_orders_index
|
42
|
+
options[:state] = @state if @state
|
43
|
+
options[:from] = @from if @from
|
44
|
+
options[:until] = @until if @until
|
45
|
+
options[:user] = @user if @user
|
46
|
+
options
|
47
|
+
end
|
48
|
+
|
49
|
+
def url_for_options_for_orders_index
|
50
|
+
{ :urlified_name => @current_basket.urlified_name,
|
51
|
+
:controller => 'orders',
|
52
|
+
:action => 'index' }
|
53
|
+
end
|
54
|
+
|
55
|
+
def meta_data_for(order)
|
56
|
+
html = '<div id="order-meta-data">'
|
57
|
+
html += '<h3 id="order-id">' + t('orders.helpers.order_number') + " #{order.id}"
|
58
|
+
# TODO: move "order in" to I18n
|
59
|
+
html += " ("
|
60
|
+
if current_user == order.user && params[:controller] == 'trolleys'
|
61
|
+
html += council_full_name_from(order.basket.name)
|
62
|
+
else
|
63
|
+
html += link_basket_orders(order.basket)
|
64
|
+
end
|
65
|
+
html += ')</h3>'
|
66
|
+
if !order.current? && !(order.contact_name.blank? && order.contact_phone.blank?)
|
67
|
+
html += '<h4 id="order-info">'
|
68
|
+
html += order.contact_name + ' - ' if order.contact_name
|
69
|
+
html += order.contact_phone if order.contact_phone
|
70
|
+
html += '</h4>'
|
71
|
+
end
|
72
|
+
html += '</div>'
|
73
|
+
end
|
74
|
+
|
75
|
+
def link_basket_orders(basket)
|
76
|
+
options = set_options_from_vars.merge({:urlified_name => basket.urlified_name})
|
77
|
+
link_to(council_full_name_from(basket.name), options)
|
78
|
+
end
|
79
|
+
|
80
|
+
def clear_extra_params
|
81
|
+
if @user || @from || @until
|
82
|
+
options = set_options_from_vars
|
83
|
+
|
84
|
+
to_be_cleared = [:user, :trolley, :from, :until]
|
85
|
+
|
86
|
+
to_be_cleared.each { |key_sym| options.delete(key_sym) }
|
87
|
+
|
88
|
+
clear_link = link_to(t("orders.helpers.clear_params"), options)
|
89
|
+
|
90
|
+
clear_link = ' [ ' + clear_link + ' ]'
|
91
|
+
content_tag('span', clear_link, :class => 'clear-params')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def button_to_checkout(order)
|
96
|
+
order_button_for('checkout', order,
|
97
|
+
{ :method => 'get',
|
98
|
+
:target_action => 'checkout_form',
|
99
|
+
:url_for_options => { :urlified_name => @site_basket.urlified_name } })
|
100
|
+
end
|
101
|
+
|
102
|
+
def order_checkout_fields(form)
|
103
|
+
html = '<div class="form-element">'
|
104
|
+
html += "<label for=\"order_contact_name\">#{t('orders.helpers.contact_name')}</label>"
|
105
|
+
html += form.text_field(:contact_name, { :tabindex => '1', :label => t('orders.helpers.contact_name')})
|
106
|
+
# html += "<div class=\"form-example\">#{t('orders.helpers.contact_name_example')}</div>"
|
107
|
+
html += '</div>'
|
108
|
+
html += '<div class="form-element">'
|
109
|
+
html += "<label for=\"order_contact_phone\">#{t('orders.helpers.contact_phone')}</label>"
|
110
|
+
html += form.text_field(:contact_phone, { :tabindex => '1' })
|
111
|
+
html += "<div class=\"form-example\">#{t('orders.helpers.contact_phone_example')}</div>"
|
112
|
+
html += '</div>'
|
113
|
+
html += '<div class="form-element">'
|
114
|
+
html += '</div>'
|
115
|
+
html
|
116
|
+
end
|
117
|
+
|
118
|
+
# order number
|
119
|
+
# order user
|
120
|
+
# council
|
121
|
+
# number of line_items
|
122
|
+
# date required by
|
123
|
+
def link_to_as_summary_of(order, user = nil)
|
124
|
+
link_text = t('orders.helpers.order_number') + " #{order.id}"
|
125
|
+
link_text += " - #{user.trolley_user_display_name}" if user.present? && params[:controller] == 'orders'
|
126
|
+
link_text += " - #{council_full_name_from(order.basket.name)}"
|
127
|
+
link_text += " - (#{order.line_items.size} #{t 'orders.helpers.items'})" if order.line_items.size > 0
|
128
|
+
link_text += " - #{order.updated_at.to_s(:db).split(' ')[0]}"
|
129
|
+
|
130
|
+
link_to(link_text, url_for_order(:order => order))
|
131
|
+
end
|
132
|
+
|
133
|
+
def sorted_state_names
|
134
|
+
[:in_process, :ready, :completed, :cancelled]
|
135
|
+
end
|
136
|
+
|
137
|
+
def checkout_form_target_action_url_hash
|
138
|
+
{:action => 'checkout', :id => @order, :urlified_name => @site_basket.urlified_name}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# each notification expects an order object
|
2
|
+
module UserOrderNotifications
|
3
|
+
unless included_modules.include? UserOrderNotifications
|
4
|
+
def self.included(klass)
|
5
|
+
klass.send :include, HasTrolleyControllerHelpersOverrides
|
6
|
+
end
|
7
|
+
|
8
|
+
def cancelled(order, user, cancelling_user)
|
9
|
+
setup_email(user)
|
10
|
+
@subject += I18n.t("user_notifier_model.subject_cancelled")
|
11
|
+
@body[:order] = order
|
12
|
+
@body[:cancelling_user] = cancelling_user
|
13
|
+
set_body_url_for(order, user)
|
14
|
+
end
|
15
|
+
|
16
|
+
%w(in_process ready user_review).each do |state_name|
|
17
|
+
code = lambda { |order, user|
|
18
|
+
setup_email(user)
|
19
|
+
@subject += I18n.t("user_notifier_model.subject_#{state_name}")
|
20
|
+
@body[:order] = order
|
21
|
+
set_body_url_for(order, user)
|
22
|
+
}
|
23
|
+
|
24
|
+
define_method(state_name, &code)
|
25
|
+
end
|
26
|
+
|
27
|
+
def new_note(order, note, user)
|
28
|
+
setup_email(user)
|
29
|
+
@subject += I18n.t("user_notifier_model.subject_new_note")
|
30
|
+
@body[:order] = order
|
31
|
+
@body[:note] = note
|
32
|
+
set_body_url_for(order, user)
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_body_url_for(order, user)
|
36
|
+
@body[:url] = url_for(:controller => :orders,
|
37
|
+
:action => :show,
|
38
|
+
:id => order,
|
39
|
+
:urlified_name => order.basket.urlified_name,
|
40
|
+
:host => Kete.site_name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'trollied'
|
2
|
+
require 'kete_gets_trollied'
|
3
|
+
|
4
|
+
config.to_prepare do
|
5
|
+
# In development/production, we want to only setup stuff if IS_CONFIGURED is true
|
6
|
+
# In test mode however, we always want to have it, since IS_CONFIGURED won't be true
|
7
|
+
# at this stage, but it will be changed to true after Rails initializes.
|
8
|
+
if (IS_CONFIGURED || Rails.env.test?)
|
9
|
+
# no duplicate view files at this time, so no need for engine's views to take precedence
|
10
|
+
# if that changes in the future, see kete_translatable_content/rails/init.rb for how it is done
|
11
|
+
|
12
|
+
# load our locales
|
13
|
+
I18n.load_path += Dir[ File.join(File.dirname(__FILE__), '../config/locales/*.{rb,yml}') ]
|
14
|
+
|
15
|
+
# override some controllers and helpers to be kete gets trollied aware
|
16
|
+
exts = File.join(File.dirname(__FILE__), '../lib/kete_gets_trollied/extensions/{controllers,helpers}/*')
|
17
|
+
# use Kernel.load here so that changes to the extensions are reloaded on each request in development
|
18
|
+
Dir[exts].each { |ext_path| Kernel.load(ext_path) }
|
19
|
+
|
20
|
+
# models we extend
|
21
|
+
Kete.extensions[:blocks] ||= Hash.new
|
22
|
+
Dir[ File.join(File.dirname(__FILE__), '../lib/kete_gets_trollied/extensions/models/*') ].each do |ext_path|
|
23
|
+
key = File.basename(ext_path, '.rb').to_sym
|
24
|
+
Kete.extensions[:blocks][key] ||= Array.new
|
25
|
+
Kete.extensions[:blocks][key] << Proc.new { Kernel.load(ext_path) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/test/helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kete_gets_trollied
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Walter McGinnis
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-10-13 00:00:00 +13:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: thoughtbot-shoulda
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: trollied
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 19
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 1
|
47
|
+
- 4
|
48
|
+
version: 0.1.4
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
description: Uses the trollied gem for adding item ordering to Kete.
|
52
|
+
email: walter@katipo.co.nz
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files:
|
58
|
+
- LICENSE
|
59
|
+
- README.rdoc
|
60
|
+
files:
|
61
|
+
- .document
|
62
|
+
- .gitignore
|
63
|
+
- LICENSE
|
64
|
+
- README.rdoc
|
65
|
+
- Rakefile
|
66
|
+
- VERSION
|
67
|
+
- app/views/user_notifier/cancelled.html.erb
|
68
|
+
- app/views/user_notifier/in_process.html.erb
|
69
|
+
- app/views/user_notifier/new_note.html.erb
|
70
|
+
- app/views/user_notifier/ready.html.erb
|
71
|
+
- app/views/user_notifier/reviewing_of.html.erb
|
72
|
+
- app/views/user_notifier/user_review.html.erb
|
73
|
+
- config/locales/en.yml
|
74
|
+
- config/routes.rb
|
75
|
+
- lib/kete_gets_trollied.rb
|
76
|
+
- lib/kete_gets_trollied/extensions/controllers/application_controller.rb
|
77
|
+
- lib/kete_gets_trollied/extensions/controllers/line_items_controller.rb
|
78
|
+
- lib/kete_gets_trollied/extensions/controllers/notes_controller.rb
|
79
|
+
- lib/kete_gets_trollied/extensions/controllers/orders_controller.rb
|
80
|
+
- lib/kete_gets_trollied/extensions/controllers/trolleys_controller.rb
|
81
|
+
- lib/kete_gets_trollied/extensions/helpers/application_helper.rb
|
82
|
+
- lib/kete_gets_trollied/extensions/models/basket.rb
|
83
|
+
- lib/kete_gets_trollied/extensions/models/line_item.rb
|
84
|
+
- lib/kete_gets_trollied/extensions/models/order.rb
|
85
|
+
- lib/kete_gets_trollied/extensions/models/topic.rb
|
86
|
+
- lib/kete_gets_trollied/extensions/models/trolley.rb
|
87
|
+
- lib/kete_gets_trollied/extensions/models/user.rb
|
88
|
+
- lib/kete_gets_trollied/extensions/models/user_notifier.rb
|
89
|
+
- lib/kete_gets_trollied/has_trolley_controller_helpers_overrides.rb
|
90
|
+
- lib/kete_gets_trollied/line_items_helper_overrides.rb
|
91
|
+
- lib/kete_gets_trollied/orders_helper_overrides.rb
|
92
|
+
- lib/kete_gets_trollied/user_order_notifications.rb
|
93
|
+
- rails/init.rb
|
94
|
+
- test/helper.rb
|
95
|
+
- test/test_kete_gets_trollied.rb
|
96
|
+
has_rdoc: true
|
97
|
+
homepage: http://github.com/kete/kete_gets_trollied
|
98
|
+
licenses: []
|
99
|
+
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options:
|
102
|
+
- --charset=UTF-8
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 3
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
version: "0"
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
hash: 3
|
120
|
+
segments:
|
121
|
+
- 0
|
122
|
+
version: "0"
|
123
|
+
requirements: []
|
124
|
+
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 1.3.7
|
127
|
+
signing_key:
|
128
|
+
specification_version: 3
|
129
|
+
summary: Uses the trollied gem for adding item ordering to Kete.
|
130
|
+
test_files:
|
131
|
+
- test/helper.rb
|
132
|
+
- test/test_kete_gets_trollied.rb
|