kete_gets_trollied 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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