kete_gets_trollied 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +63 -0
  5. data/Rakefile +52 -0
  6. data/VERSION +1 -0
  7. data/app/views/user_notifier/cancelled.html.erb +7 -0
  8. data/app/views/user_notifier/in_process.html.erb +7 -0
  9. data/app/views/user_notifier/new_note.html.erb +7 -0
  10. data/app/views/user_notifier/ready.html.erb +7 -0
  11. data/app/views/user_notifier/reviewing_of.html.erb +14 -0
  12. data/app/views/user_notifier/user_review.html.erb +7 -0
  13. data/config/locales/en.yml +75 -0
  14. data/config/routes.rb +26 -0
  15. data/lib/kete_gets_trollied.rb +4 -0
  16. data/lib/kete_gets_trollied/extensions/controllers/application_controller.rb +24 -0
  17. data/lib/kete_gets_trollied/extensions/controllers/line_items_controller.rb +3 -0
  18. data/lib/kete_gets_trollied/extensions/controllers/notes_controller.rb +3 -0
  19. data/lib/kete_gets_trollied/extensions/controllers/orders_controller.rb +36 -0
  20. data/lib/kete_gets_trollied/extensions/controllers/trolleys_controller.rb +3 -0
  21. data/lib/kete_gets_trollied/extensions/helpers/application_helper.rb +30 -0
  22. data/lib/kete_gets_trollied/extensions/models/basket.rb +4 -0
  23. data/lib/kete_gets_trollied/extensions/models/line_item.rb +4 -0
  24. data/lib/kete_gets_trollied/extensions/models/order.rb +81 -0
  25. data/lib/kete_gets_trollied/extensions/models/topic.rb +7 -0
  26. data/lib/kete_gets_trollied/extensions/models/trolley.rb +10 -0
  27. data/lib/kete_gets_trollied/extensions/models/user.rb +3 -0
  28. data/lib/kete_gets_trollied/extensions/models/user_notifier.rb +3 -0
  29. data/lib/kete_gets_trollied/has_trolley_controller_helpers_overrides.rb +51 -0
  30. data/lib/kete_gets_trollied/line_items_helper_overrides.rb +10 -0
  31. data/lib/kete_gets_trollied/orders_helper_overrides.rb +141 -0
  32. data/lib/kete_gets_trollied/user_order_notifications.rb +43 -0
  33. data/rails/init.rb +28 -0
  34. data/test/helper.rb +10 -0
  35. data/test/test_kete_gets_trollied.rb +7 -0
  36. metadata +132 -0
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
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.
@@ -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.
@@ -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,7 @@
1
+ <%= @user.user_name %>,
2
+
3
+ <%= t '.user_has_cancelled', :cancelling_user => @cancelling_user.resolved_name -%>
4
+
5
+ <%= @url %>
6
+
7
+ <%= render 'email_footer' %>
@@ -0,0 +1,7 @@
1
+ <%= @user.user_name %>,
2
+
3
+ <%= t '.user_has_checked_out', :order_user => @order.user.resolved_name -%>
4
+
5
+ <%= @url %>
6
+
7
+ <%= render 'email_footer' %>
@@ -0,0 +1,7 @@
1
+ <%= @user.user_name %>,
2
+
3
+ <%= t '.user_has_created_note', :note_user => @note.user.resolved_name -%>
4
+
5
+ <%= @url %>
6
+
7
+ <%= render 'email_footer' %>
@@ -0,0 +1,7 @@
1
+ <%= @user.user_name %>,
2
+
3
+ <%= t '.your_order_is_ready' -%>
4
+
5
+ <%= @url %>
6
+
7
+ <%= render 'email_footer' %>
@@ -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,7 @@
1
+ <%= @user.user_name %>,
2
+
3
+ <%= t '.please_review_order' -%>
4
+
5
+ <%= @url %>
6
+
7
+ <%= 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
+
@@ -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,4 @@
1
+ require 'kete_gets_trollied/has_trolley_controller_helpers_overrides'
2
+ require 'kete_gets_trollied/orders_helper_overrides'
3
+ require 'kete_gets_trollied/line_items_helper_overrides'
4
+ require 'kete_gets_trollied/user_order_notifications'
@@ -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,3 @@
1
+ LineItemsController.class_eval do
2
+ before_filter :authorize_trollied_action
3
+ end
@@ -0,0 +1,3 @@
1
+ NotesController.class_eval do
2
+ before_filter :authorize_trollied_action
3
+ 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,3 @@
1
+ TrolleysController.class_eval do
2
+ before_filter :authorize_trollied_action
3
+ 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,4 @@
1
+ # extensions to the kete basket model
2
+ Basket.class_eval do
3
+ has_many :orders
4
+ end
@@ -0,0 +1,4 @@
1
+ # kete specific tie-in to trollied line item model
2
+ LineItem.class_eval do
3
+ delegate :basket, :to => :purchasable_item
4
+ 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,7 @@
1
+ # extensions to the kete topic model
2
+ Topic.class_eval do
3
+ # Walter McGinnis, 2011-05-12
4
+ # adding shopping cart functionality
5
+ include GetsTrollied
6
+ set_up_to_get_trollied :described_as => :reference_title_date_range
7
+ 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,3 @@
1
+ User.class_eval do
2
+ include HasTrolley
3
+ end
@@ -0,0 +1,3 @@
1
+ UserNotifier.class_eval do
2
+ include UserOrderNotifications
3
+ 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
@@ -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
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'kete_gets_trollied'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestKeteGetsTrollied < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
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