kete_trackable_items 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/.specification +146 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +27 -0
- data/LICENSE +20 -0
- data/README.rdoc +24 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/app/controllers/repositories_controller.rb +70 -0
- data/app/controllers/shelf_locations_controller.rb +98 -0
- data/app/controllers/trackable_item_shelf_locations_controller.rb +64 -0
- data/app/controllers/tracked_items_controller.rb +44 -0
- data/app/controllers/tracking_lists_controller.rb +88 -0
- data/app/helpers/trackable_item_shelf_locations_helper.rb +17 -0
- data/app/helpers/trackable_items_helper.rb +52 -0
- data/app/models/on_loan_organization.rb +8 -0
- data/app/models/repository.rb +11 -0
- data/app/models/shelf_location.rb +69 -0
- data/app/models/trackable_item_shelf_location.rb +58 -0
- data/app/models/tracked_item.rb +18 -0
- data/app/models/tracking_list.rb +50 -0
- data/app/views/repositories/_form.html.erb +14 -0
- data/app/views/repositories/edit.html.erb +9 -0
- data/app/views/repositories/index.html.erb +22 -0
- data/app/views/repositories/new.html.erb +9 -0
- data/app/views/repositories/show.html.erb +30 -0
- data/app/views/shelf_locations/_event_button.html.erb +1 -0
- data/app/views/shelf_locations/_form.html.erb +34 -0
- data/app/views/shelf_locations/_shelf_location.html.erb +17 -0
- data/app/views/shelf_locations/_shelf_locations.html.erb +14 -0
- data/app/views/shelf_locations/_trackable_item.html.erb +12 -0
- data/app/views/shelf_locations/edit.html.erb +9 -0
- data/app/views/shelf_locations/index.html.erb +7 -0
- data/app/views/shelf_locations/new.html.erb +9 -0
- data/app/views/shelf_locations/show.html.erb +48 -0
- data/app/views/trackable_item_shelf_locations/new.html.erb +70 -0
- data/app/views/tracked_items/_tracked_item.html.erb +18 -0
- data/app/views/tracking_lists/_event_button.html.erb +1 -0
- data/app/views/tracking_lists/_form.html.erb +27 -0
- data/app/views/tracking_lists/_trackable_item_search_form.html.erb +28 -0
- data/app/views/tracking_lists/_tracking_list.html.erb +11 -0
- data/app/views/tracking_lists/_tracking_lists.html.erb +14 -0
- data/app/views/tracking_lists/edit.html.erb +9 -0
- data/app/views/tracking_lists/index.html.erb +11 -0
- data/app/views/tracking_lists/show.html.erb +45 -0
- data/app/views/tracking_lists/show.xls.builder +48 -0
- data/config/locales/en.yml +151 -0
- data/config/routes.rb +6 -0
- data/generators/kete_trackable_items_migrations/USAGE +2 -0
- data/generators/kete_trackable_items_migrations/kete_trackable_items_migrations_generator.rb +19 -0
- data/generators/kete_trackable_items_migrations/templates/add_trackable_item_columns_to_topics.rb +15 -0
- data/generators/kete_trackable_items_migrations/templates/create_on_loan_organizations.rb +14 -0
- data/generators/kete_trackable_items_migrations/templates/create_repositories.rb +14 -0
- data/generators/kete_trackable_items_migrations/templates/create_shelf_locations.rb +15 -0
- data/generators/kete_trackable_items_migrations/templates/create_trackable_item_shelf_locations.rb +16 -0
- data/generators/kete_trackable_items_migrations/templates/create_tracked_items.rb +15 -0
- data/generators/kete_trackable_items_migrations/templates/create_tracking_lists.rb +15 -0
- data/kete_trackable_items.gemspec +25 -0
- data/lib/kete_trackable_items.rb +0 -0
- data/lib/kete_trackable_items/controller_helpers.rb +7 -0
- data/lib/kete_trackable_items/extensions/helpers/application_helper.rb +29 -0
- data/lib/kete_trackable_items/extensions/models/basket.rb +4 -0
- data/lib/kete_trackable_items/extensions/models/topic.rb +6 -0
- data/lib/kete_trackable_items/matching_trackable_items_controller_helpers.rb +42 -0
- data/lib/kete_trackable_items/trackable_item.rb +80 -0
- data/lib/kete_trackable_items/version.rb +3 -0
- data/lib/kete_trackable_items/workflow_utilities.rb +91 -0
- data/rails/init.rb +68 -0
- metadata +166 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
class TrackableItemShelfLocationsController < ApplicationController
|
2
|
+
# Prevents the following error from showing up, common in Rails engines
|
3
|
+
# A copy of ApplicationController has been removed from the module tree but is still active!
|
4
|
+
unloadable
|
5
|
+
|
6
|
+
def new
|
7
|
+
if params[:trackable_item].present?
|
8
|
+
@trackable_item = params[:trackable_item][:type].constantize.find(params[:trackable_item][:id])
|
9
|
+
end
|
10
|
+
|
11
|
+
@repositories = appropriate_repositories_for_basket
|
12
|
+
|
13
|
+
@trackable_item_shelf_location = @trackable_item ? @trackable_item.trackable_item_shelf_locations.build : TrackableItemShelfLocation.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
repository_id = params[:trackable_item_shelf_location].delete(:repository_id)
|
18
|
+
code = params[:trackable_item_shelf_location].delete(:code)
|
19
|
+
|
20
|
+
if repository_id.present?
|
21
|
+
@repository = Repository.find(repository_id)
|
22
|
+
@repositories = [@repository]
|
23
|
+
end
|
24
|
+
|
25
|
+
if @repository.present? && code.present?
|
26
|
+
@shelf_location = @repository.shelf_locations.find_by_code(code)
|
27
|
+
params[:trackable_item_shelf_location][:shelf_location_id] = @shelf_location ? @shelf_location.id : nil
|
28
|
+
end
|
29
|
+
|
30
|
+
@trackable_item_shelf_location = TrackableItemShelfLocation.new(params[:trackable_item_shelf_location])
|
31
|
+
@trackable_item = @trackable_item_shelf_location.trackable_item
|
32
|
+
|
33
|
+
if @trackable_item_shelf_location.save
|
34
|
+
redirect_to url_for_dc_identifier(@trackable_item)
|
35
|
+
else
|
36
|
+
render :action => 'new'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def update
|
41
|
+
@trackable_item_shelf_location = TrackableItemShelfLocation.find(params[:id])
|
42
|
+
|
43
|
+
if params[:event]
|
44
|
+
original_state = @trackable_item_shelf_location.current_state
|
45
|
+
event_method = params[:event] + '!'
|
46
|
+
@trackable_item_shelf_location.send(event_method)
|
47
|
+
@successful = @trackable_item_shelf_location.current_state != original_state
|
48
|
+
@state_change_failed = @succesful
|
49
|
+
else
|
50
|
+
@successful = @trackable_item_shelf_location.update_attributes(params[:shelf_location])
|
51
|
+
end
|
52
|
+
|
53
|
+
if @successful || @state_change_failed
|
54
|
+
flash[:notice] = t('shelf_locations.update.state_change_failed', :event_transition => params[:event].humanize) if @state_change_failed
|
55
|
+
|
56
|
+
url = repository_shelf_location_url(:id => @trackable_item_shelf_location.shelf_location,
|
57
|
+
:repository_id => @trackable_item_shelf_location.shelf_location.repository)
|
58
|
+
redirect_to url
|
59
|
+
else
|
60
|
+
render :action => 'edit'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class TrackedItemsController < ApplicationController
|
2
|
+
# Prevents the following error from showing up, common in Rails engines
|
3
|
+
# A copy of ApplicationController has been removed from the module tree but is still active!
|
4
|
+
unloadable
|
5
|
+
|
6
|
+
before_filter :get_tracked_item, :except => [:create]
|
7
|
+
before_filter :get_trackable_item
|
8
|
+
before_filter :get_tracking_list
|
9
|
+
|
10
|
+
def create
|
11
|
+
tracked_item = @trackable_item.tracked_items.build(@tracking_list)
|
12
|
+
|
13
|
+
if tracked_item.save
|
14
|
+
redirect_to tracking_list_url(:id => @tracking_list)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroy
|
19
|
+
tracked_item = @trackable_item.tracked_items.find(@tracked_item)
|
20
|
+
tracked_item.destroy unless tracked_item.nil?
|
21
|
+
|
22
|
+
# TODO: this redirect may need to redirect a different place in some contexts
|
23
|
+
redirect_to repository_tracking_list_url(:id => @tracking_list, :repository_id => @tracking_list.repository)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def get_tracked_item
|
29
|
+
@tracked_item = TrackedItem.find(params[:id])
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_trackable_item
|
33
|
+
if @tracked_item
|
34
|
+
@trackable_item = @tracked_item.trackable_item
|
35
|
+
else
|
36
|
+
type = params[:tracked_item_type]
|
37
|
+
@trackable_item ||= type.classify.constantize.find(params[:tracked_item_id])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_tracking_list
|
42
|
+
@tracking_list ||= TrackingList.find(params[:tracking_list_id])
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
class TrackingListsController < ApplicationController
|
2
|
+
# Prevents the following error from showing up, common in Rails engines
|
3
|
+
# A copy of ApplicationController has been removed from the module tree but is still active!
|
4
|
+
unloadable
|
5
|
+
|
6
|
+
include KeteTrackableItems::MatchingTrackableItemsControllerHelpers
|
7
|
+
|
8
|
+
before_filter :set_repository
|
9
|
+
before_filter :set_tracking_list, :except => [:index, :create]
|
10
|
+
|
11
|
+
def index
|
12
|
+
@tracking_lists = TrackingList.all
|
13
|
+
end
|
14
|
+
|
15
|
+
def show
|
16
|
+
unless params[:format] == 'xls'
|
17
|
+
@possible_events = @tracking_list.current_state.events.keys.collect(&:to_s).sort
|
18
|
+
end
|
19
|
+
|
20
|
+
# xls support as outlined in http://www.arydjmal.com/blog/export-to-excel-in-rails-2
|
21
|
+
respond_to do |format|
|
22
|
+
format.html # index.html.erb
|
23
|
+
format.xls { render :layout => false } if params[:format] == 'xls' # blog post noted that otherwise always interpretted as xls
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# unused at this point
|
28
|
+
def new
|
29
|
+
set_matching_trackable_items
|
30
|
+
|
31
|
+
build_items_for_matching_trackable_items_for(@tracking_list, :tracked_items)
|
32
|
+
end
|
33
|
+
|
34
|
+
def create
|
35
|
+
@tracking_list = @repository.tracking_lists.build(params[:tracking_list])
|
36
|
+
|
37
|
+
if @tracking_list.save
|
38
|
+
redirect_to repository_tracking_list_url(:id => @tracking_list,
|
39
|
+
:repository_id => @repository)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def edit
|
44
|
+
set_matching_trackable_items
|
45
|
+
|
46
|
+
build_items_for_matching_trackable_items_for(@tracking_list, :tracked_items)
|
47
|
+
end
|
48
|
+
|
49
|
+
# update tracked_items (i.e. add them based on a search)
|
50
|
+
# or run state change
|
51
|
+
def update
|
52
|
+
if params[:event]
|
53
|
+
original_state = @tracking_list.current_state
|
54
|
+
event_method = params[:event] + '!'
|
55
|
+
@tracking_list.send(event_method)
|
56
|
+
@successful = @tracking_list.current_state != original_state
|
57
|
+
@state_change_failed = @succesful
|
58
|
+
else
|
59
|
+
@successful = @tracking_list.update_attributes(params[:tracking_list])
|
60
|
+
end
|
61
|
+
|
62
|
+
if @successful || @state_change_failed
|
63
|
+
flash[:notice] = t('tracking_lists.update.state_change_failed', :event_transition => params[:event].humanize) if @state_change_failed
|
64
|
+
|
65
|
+
redirect_to repository_tracking_list_url(:id => @tracking_list,
|
66
|
+
:repository_id => @repository)
|
67
|
+
else
|
68
|
+
render :action => 'edit'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def destroy
|
73
|
+
@tracking_list.destroy
|
74
|
+
|
75
|
+
# TODO: may need to redirect a different place in some contexts
|
76
|
+
redirect_to repository_tracking_lists_url(:repository_id => @repository)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def set_repository
|
82
|
+
@repository = Repository.find(params[:repository_id])
|
83
|
+
end
|
84
|
+
|
85
|
+
def set_tracking_list
|
86
|
+
@tracking_list = @repository.tracking_lists.find(params[:id])
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module TrackableItemShelfLocationsHelper
|
2
|
+
def javascript_repository_id_observer_and_adjust_code_autocomplete(urlified_name)
|
3
|
+
javascript_tag("jQuery(document).ready(function(){
|
4
|
+
jQuery(\"#trackable_item_shelf_location_repository_id\").change(
|
5
|
+
function() {
|
6
|
+
jQuery(\"#trackable_item_shelf_location_code\").val('');
|
7
|
+
|
8
|
+
var repository_id = jQuery(\"#trackable_item_shelf_location_repository_id\").val();
|
9
|
+
var new_shelf_locations_url = \"/#{urlified_name}/repositories/\" + repository_id + \"/shelf_locations.json\";
|
10
|
+
|
11
|
+
trackable_item_shelf_location_code_auto_completer.url = new_shelf_locations_url;
|
12
|
+
|
13
|
+
});
|
14
|
+
|
15
|
+
});")
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module TrackableItemsHelper
|
2
|
+
# wrapped in a div to allow for styling the form to be inline
|
3
|
+
def button_to_place_in_shelf_location(trackable_item, additional = false)
|
4
|
+
# whether we should redirect to site basket or not
|
5
|
+
# if no repositories are associated with this basket, specify site
|
6
|
+
|
7
|
+
options = { :trackable_item => { :id => trackable_item.id,
|
8
|
+
:type => trackable_item.class.name } }
|
9
|
+
|
10
|
+
options[:urlified_name] = @site_basket.urlified_name if @current_basket.repositories.count < 1
|
11
|
+
|
12
|
+
button_text = if additional
|
13
|
+
button_text = t('trackable_items_helper.add_to_additional_shelf_location')
|
14
|
+
else
|
15
|
+
button_text = t('trackable_items_helper.add_to_shelf_location')
|
16
|
+
end
|
17
|
+
"<div class=\"add-to-shelf-location\">" +
|
18
|
+
button_to(button_text,
|
19
|
+
new_trackable_item_shelf_location_url(options)) +
|
20
|
+
"</div>"
|
21
|
+
end
|
22
|
+
|
23
|
+
def shelf_locations_or_appropriate_action(trackable_item)
|
24
|
+
html = String.new
|
25
|
+
|
26
|
+
additional = false
|
27
|
+
if trackable_item.has_shelf_locations?
|
28
|
+
additional = true
|
29
|
+
|
30
|
+
html += '<ul class="shelf-locations">'
|
31
|
+
shelf_locations_count = 1
|
32
|
+
trackable_item.shelf_locations.each do |shelf_location|
|
33
|
+
html += '<li'
|
34
|
+
html += ' class="first"'if shelf_locations_count == 1
|
35
|
+
html += '>'
|
36
|
+
|
37
|
+
html += link_to(shelf_location.code, repository_shelf_location_url(:repository_id => shelf_location.repository_id,
|
38
|
+
:id => shelf_location,
|
39
|
+
:urlified_name => shelf_location.repository.basket.urlified_name))
|
40
|
+
html += '</li>'
|
41
|
+
shelf_locations_count += 1
|
42
|
+
end
|
43
|
+
|
44
|
+
html += '</ul>'
|
45
|
+
end
|
46
|
+
|
47
|
+
html += button_to_place_in_shelf_location(trackable_item, additional)
|
48
|
+
|
49
|
+
html
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# name
|
3
|
+
# address, contact details?
|
4
|
+
# used in Item when current_location is on_loan
|
5
|
+
|
6
|
+
# quote from spec: When archives are tracked to “On Loan” additional information is required i.e. to what organization / office they will be loaned to. This is a list that will need to be maintained by Staff as it could be continually added to. This list may need to be separate for each Archives Repository as to prevent clutter for the other councils.
|
7
|
+
class OnLoanOrganization < ActiveRecord::Base
|
8
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# name Archives Central, PNCC, WDC
|
2
|
+
# other contact details?
|
3
|
+
class Repository < ActiveRecord::Base
|
4
|
+
# we inherit security from our basket
|
5
|
+
# site basket == can see all repositories
|
6
|
+
# otherwise must be associated to the basket we are within
|
7
|
+
belongs_to :basket
|
8
|
+
|
9
|
+
has_many :shelf_locations, :dependent => :destroy
|
10
|
+
has_many :tracking_lists, :dependent => :destroy
|
11
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class ShelfLocation < ActiveRecord::Base
|
2
|
+
include KeteTrackableItems::WorkflowUtilities
|
3
|
+
|
4
|
+
belongs_to :repository
|
5
|
+
has_many :trackable_item_shelf_locations, :dependent => :destroy
|
6
|
+
|
7
|
+
validates_uniqueness_of :code, :case_sensitive => false, :scope => :repository_id
|
8
|
+
|
9
|
+
workflow do
|
10
|
+
state :available do
|
11
|
+
event :allocate, :transitions_to => :allocated
|
12
|
+
event :deactivate, :transitions_to => :deactivated
|
13
|
+
end
|
14
|
+
|
15
|
+
state :allocated do
|
16
|
+
# probably want to create an instance method for clear_out
|
17
|
+
# that deactivates all trackable_item_shelf_locations
|
18
|
+
event :clear_out, :transitions_to => :available
|
19
|
+
event :deallocate, :transitions_to => :available
|
20
|
+
end
|
21
|
+
|
22
|
+
state :deactivated do
|
23
|
+
event :reactivate, :transitions_to => :available
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
set_up_workflow_named_scopes.call
|
28
|
+
|
29
|
+
# returns a hash with trackable_item_type as key
|
30
|
+
# and array of ids for that type as value
|
31
|
+
def trackable_items_types_and_ids
|
32
|
+
@trackable_items_types_and_ids = trackable_item_shelf_locations.with_state_active.inject(Hash.new) do |result, mapping_object|
|
33
|
+
type_key = mapping_object.trackable_item_type
|
34
|
+
item_id = mapping_object.trackable_item_id
|
35
|
+
|
36
|
+
values = result[type_key] || Array.new
|
37
|
+
values << item_id
|
38
|
+
|
39
|
+
result[type_key] = values
|
40
|
+
result
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# good enough for our purposes
|
45
|
+
# WARNING: this is not a full association, but a hacked together collection
|
46
|
+
def trackable_items
|
47
|
+
@trackable_items = Array.new
|
48
|
+
|
49
|
+
trackable_items_types_and_ids.each do |k,v|
|
50
|
+
@trackable_items += k.constantize.find(v)
|
51
|
+
end
|
52
|
+
|
53
|
+
@trackable_items
|
54
|
+
end
|
55
|
+
|
56
|
+
def new_allocation
|
57
|
+
allocate!
|
58
|
+
end
|
59
|
+
|
60
|
+
def mapping_deactivated_or_destroyed
|
61
|
+
deallocate! if allocated? && trackable_items.size == 0
|
62
|
+
end
|
63
|
+
|
64
|
+
def clear_out
|
65
|
+
trackable_item_shelf_locations.each do |mapping|
|
66
|
+
mapping.make_deactivated
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class TrackableItemShelfLocation < ActiveRecord::Base
|
2
|
+
include KeteTrackableItems::WorkflowUtilities
|
3
|
+
|
4
|
+
after_create :update_state_of_shelf_location_and_trackable_item
|
5
|
+
|
6
|
+
# after destroy, change state of trackable_item and shelf_location
|
7
|
+
after_destroy :send_deactivated_to_associations
|
8
|
+
|
9
|
+
belongs_to :shelf_location
|
10
|
+
belongs_to :trackable_item, :polymorphic => true
|
11
|
+
|
12
|
+
validates_presence_of :shelf_location, :message => lambda { I18n.t('trackable_item_shelf_location.shelf_location_blank_or_does_not_match') }
|
13
|
+
validates_presence_of :trackable_item, :message => lambda { I18n.t('trackable_item_shelf_location.trackable_item_blank_or_does_not_match') }
|
14
|
+
|
15
|
+
# needs to be unique to shelf_location to trackable_item
|
16
|
+
validates_uniqueness_of :shelf_location_id, :scope => [:trackable_item_type, :trackable_item_id], :message => lambda { I18n.t('trackable_item_shelf_location.previously_allocated_reactivate_instead') }
|
17
|
+
|
18
|
+
delegate :repository, :to => :shelf_location, :allow_nil => true
|
19
|
+
delegate :repository_id, :to => :shelf_location, :allow_nil => true
|
20
|
+
delegate :code, :to => :shelf_location, :allow_nil => true
|
21
|
+
delegate :description_for_tracked_item, :to => :trackable_item, :allow_nil => true
|
22
|
+
|
23
|
+
workflow do
|
24
|
+
state :active do
|
25
|
+
event :deactivate, :transitions_to => :deactivated
|
26
|
+
end
|
27
|
+
|
28
|
+
state :deactivated do
|
29
|
+
event :reactivate, :transitions_to => :active
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
set_up_workflow_named_scopes.call
|
34
|
+
|
35
|
+
def tell_associations_deactivated_or_destroyed
|
36
|
+
shelf_location.mapping_deactivated_or_destroyed
|
37
|
+
trackable_item.mapping_deactivated_or_destroyed
|
38
|
+
end
|
39
|
+
|
40
|
+
def deactivate
|
41
|
+
tell_associations_deactivated_or_destroyed
|
42
|
+
end
|
43
|
+
|
44
|
+
def make_deactivated
|
45
|
+
deactivate!
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def update_state_of_shelf_location_and_trackable_item
|
51
|
+
shelf_location.new_allocation
|
52
|
+
trackable_item.new_allocation
|
53
|
+
end
|
54
|
+
|
55
|
+
def send_deactivated_to_associations
|
56
|
+
tell_associations_deactivated_or_destroyed
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class TrackedItem < ActiveRecord::Base
|
2
|
+
belongs_to :tracking_list
|
3
|
+
belongs_to :trackable_item, :polymorphic => true
|
4
|
+
|
5
|
+
delegate :description_for_tracked_item, :to => :trackable_item
|
6
|
+
|
7
|
+
validates_presence_of :tracking_list, :message => lambda { I18n.t('tracked_item.tracking_list_blank_or_does_not_match') }
|
8
|
+
validates_presence_of :trackable_item, :message => lambda { I18n.t('tracked_item.trackable_item_blank_or_does_not_match') }
|
9
|
+
|
10
|
+
# needs to be unique to tracking_list
|
11
|
+
validates_uniqueness_of :tracking_list_id, :scope => [:trackable_item_type, :trackable_item_id]
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def validate
|
16
|
+
errors.add(:tracking_list, I18n.t('tracked_item.already_in_tracking_list')) if tracking_list.tracked_items.include?(self)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class TrackingList < ActiveRecord::Base
|
2
|
+
include Workflow
|
3
|
+
include KeteTrackableItems::WorkflowUtilities
|
4
|
+
|
5
|
+
belongs_to :repository
|
6
|
+
|
7
|
+
has_many :tracked_items, :dependent => :destroy
|
8
|
+
accepts_nested_attributes_for :tracked_items, :allow_destroy => true
|
9
|
+
|
10
|
+
# set up workflow states, some are shared with trackable_items
|
11
|
+
shared_code_as_string = shared_tracking_workflow_specs_as_string
|
12
|
+
|
13
|
+
specification = Proc.new {
|
14
|
+
state :new do
|
15
|
+
event :display, :transitions_to => :displayed
|
16
|
+
event :hold_out, :transitions_to => :held_out
|
17
|
+
event :loan, :transitions_to => :on_loan_to_organization
|
18
|
+
event :queue_for_refiling, :transitions_to => :to_be_refiled
|
19
|
+
event :cancel, :transitions_to => :cancelled
|
20
|
+
end
|
21
|
+
|
22
|
+
eval(shared_code_as_string)
|
23
|
+
|
24
|
+
# we replace to_be_refiled transitions with complete event only
|
25
|
+
state :to_be_refiled do
|
26
|
+
event :refile, :transitions_to => :completed
|
27
|
+
end
|
28
|
+
|
29
|
+
state :cancelled
|
30
|
+
state :completed
|
31
|
+
}
|
32
|
+
|
33
|
+
workflow(&specification)
|
34
|
+
|
35
|
+
set_up_workflow_named_scopes.call
|
36
|
+
|
37
|
+
# send workflow event, except cancel, to tracked_items
|
38
|
+
# upon event being called on tracking_list
|
39
|
+
workflow_event_names.each do |event_name|
|
40
|
+
unless event_name == 'cancel'
|
41
|
+
code = Proc.new {
|
42
|
+
tracked_items.each do |tracked_item|
|
43
|
+
tracked_item.trackable_item.send("#{event_name}!")
|
44
|
+
end
|
45
|
+
}
|
46
|
+
|
47
|
+
define_method(event_name, &code)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|