<commit_before># TODO: B - check error handling and exceptions in controller tasks, especially xhr actions.
class ItemController < ApplicationController

	include Inflector

	# Displays a list of items for a particular item type (e.g. Person, Role).
	#
	# The controller name is used to determine the type of item that needs to be returned in the find method.
	# The variables are set and used in the rendering of the list view.	 The render method is used here to specify exactly
	# where to find the view.	 This is because the URL will be different based on the type of item being listed
	# (e.g. /role/list) and the 'list' view does not exist for every type of item.
	def list
		@items = (Object.const_get singularize(camelize(controller_name))).find(:all, :order => 'title')
		@page_title = "#{humanize controller_name} list"
		render :template => '/item/list', :layout => 'simple'
	end
	
	# Displays the details about the item.
	#
	# The item id is passed through as a parameter to this method.	The variables are set and used in the
	# rendering of the show view.	 The render method is used here to specify exactly where to find the view and 
	# the layout.	 This is because the URL will be different based on the type of item being displayed
	# (e.g. /role/40) and the 'show' view does not exist for every type of item.
	def show
		@item = item_from_id
		@page_title = @item.title
		
		@all_child_collection_details = child_collections
		
		render :template => 'item/show'
	end
	
	# Displays the details about the item in edit mode so that the user can modify the item's details.
	# TODO: A - exclude the changer from favourites notification.
	def edit
	  queries.label = 'edit'

		# If the 'Show' button is selected on the Edit page, the user will be redirected to the show page for that same object.
		if params[:commit] == 'Show'
			redirect_to :action => 'show'
			return
		end
		
		# If the URL contains 'item' as the controller name, redirect the user to the correct type of item (e.g. Role)
		# based on the value selected in the 'New' select list. The controller will be item because the view lacks the 
		# sophistication to set it correctly - it is easiest to correct it here. See item/_navigation.rhtml for the problem.
		if controller_name == 'item'
			redirect_to :overwrite_params => { :controller => params[:new_object].underscore }
			return 
		end
		
		# If the item_id has been passed through as a parameter, find the existing item.	Otherwise, the item is considered
		# a new item and the item attributes defaulted.
		if item_from_id
			@page_title = @item.title
		else
			@item = (Object.const_get controller_name.camelize).new
			@item.person_id = session[:person].id
			@item.due_on = 1.day.from_now
			@item.status_id = Status.find_by_type_name_and_generic_stage(@item.class.name, Status::NIL).id
			@page_title = "#{humanize controller_name}"
			# TODO: C - check if params[project_id] is session[:person].current_project_ids.includes?(params[:project_id]) 
			@item.project_id = params[:project_id]
			@item.role_id = Project.find(params[:project_id]).role_id
		end
		@old_item = @item.clone
		@old_item.id = @item.id
		@old_item.detail = @item.detail.clone

		# Saves the item and the associated details.
		# If the item is a new item, redirect the user to the Edit page for the newly created item, otherwise
		# remain on the Edit page.
		if request.post?
		  @item.build_detail if @item.detail.nil?
			
			@item.attributes = @item.attributes.merge(params[:item] || {})
			# TODO: C - Integrate Chronic - but for all dates
			#new_due_on = Chronic.parse(params[:item][:due_on])
			#@item.due_on = new_due_on.to_date if new_due_on
		  
			@item.project_id = nil if '0' == params[:item][:project_id]
			@item.project_id_escalation = @item.project_id if '0' == params[:item][:project_id_escalation]

			@item.detail.attributes = @item.detail.attributes.merge(params[:detail] || {})
			change_errors = ActiveRecord::Errors.new(@item)
		  ItemController.validate_authority_to_change(session[:person], @item, 
		    overwritten_attrs(@old_item.attributes, @item.attributes), 
		    overwritten_attrs(@old_item.detail.attributes, @item.detail.attributes),
		    change_errors)
						
			@item.person_id_updated_by = session[:person].id

			item_was_new_record = @item.new_record?
			
			if @item.valid? && change_errors.empty?
  	    begin
    			Item.transaction do
        		@item.save!
        		@item.detail.save!
        				    
    				# shuffle in hierarchy if moved
    				@item.update_nested_sets(@old_item, item_was_new_record)
    							  
    			  # link to referrer if requested  			   
    			  Association.new(:item_id_from => @item.id, :item_id_to => params[:item_id_created_from]).save! if params[:link_to_referrer]
			  
    			  if Project == @item.class && @item.project_id.nil? && item_was_new_record 			  	
      				# If new root project then place current user in an administrator role.
      				admin_role = Role.new(
      			    :title => "#{@item.title} Administrator",
                :status_id => Status.find_by_type_name_and_enabled('Role', true, :order => 'generic_stage').id,
                :code_id_priority => Code.find_by_type_name_and_name_and_enabled('Role', 'Priority', true, :order => 'value').id,
                :role_id => 0,
                :person_id => session[:person].id,
                :person_id_updated_by => session[:person].id,
                :project_id => @item.id,
                :project_id_escalation => @item.id
      				)
				
      				security_profile_code = Code.find_by_type_name_and_name_and_value(Role.name, 'Security profile', 
                SystemSetting.system_setting('Administration', 'Administrator security profile value', 'Administrator') )
				    
      				admin_role.detail.attributes = {
                :code_id_security_profile => security_profile_code.id
              }
        
      				admin_role.save_with_validation false
      				admin_role.role_id = admin_role.id
      				admin_role.save!
    				
    				  RolePlacement.new(
                :person_id => session[:person].id,
                :role_id => admin_role.id,
                :start_on => Date.today,
                :end_on => 10.years.from_now.to_date,
                :committed_hours => 0,
                :normal_hourly_rate => 0
              ).save!<commit_msg>auto link goes both ways<commit_after># TODO: B - check error handling and exceptions in controller tasks, especially xhr actions.
class ItemController < ApplicationController

	include Inflector

	# Displays a list of items for a particular item type (e.g. Person, Role).
	#
	# The controller name is used to determine the type of item that needs to be returned in the find method.
	# The variables are set and used in the rendering of the list view.	 The render method is used here to specify exactly
	# where to find the view.	 This is because the URL will be different based on the type of item being listed
	# (e.g. /role/list) and the 'list' view does not exist for every type of item.
	def list
		@items = (Object.const_get singularize(camelize(controller_name))).find(:all, :order => 'title')
		@page_title = "#{humanize controller_name} list"
		render :template => '/item/list', :layout => 'simple'
	end
	
	# Displays the details about the item.
	#
	# The item id is passed through as a parameter to this method.	The variables are set and used in the
	# rendering of the show view.	 The render method is used here to specify exactly where to find the view and 
	# the layout.	 This is because the URL will be different based on the type of item being displayed
	# (e.g. /role/40) and the 'show' view does not exist for every type of item.
	def show
		@item = item_from_id
		@page_title = @item.title
		
		@all_child_collection_details = child_collections
		
		render :template => 'item/show'
	end
	
	# Displays the details about the item in edit mode so that the user can modify the item's details.
	# TODO: A - exclude the changer from favourites notification.
	def edit
	  queries.label = 'edit'

		# If the 'Show' button is selected on the Edit page, the user will be redirected to the show page for that same object.
		if params[:commit] == 'Show'
			redirect_to :action => 'show'
			return
		end
		
		# If the URL contains 'item' as the controller name, redirect the user to the correct type of item (e.g. Role)
		# based on the value selected in the 'New' select list. The controller will be item because the view lacks the 
		# sophistication to set it correctly - it is easiest to correct it here. See item/_navigation.rhtml for the problem.
		if controller_name == 'item'
			redirect_to :overwrite_params => { :controller => params[:new_object].underscore }
			return 
		end
		
		# If the item_id has been passed through as a parameter, find the existing item.	Otherwise, the item is considered
		# a new item and the item attributes defaulted.
		if item_from_id
			@page_title = @item.title
		else
			@item = (Object.const_get controller_name.camelize).new
			@item.person_id = session[:person].id
			@item.due_on = 1.day.from_now
			@item.status_id = Status.find_by_type_name_and_generic_stage(@item.class.name, Status::NIL).id
			@page_title = "#{humanize controller_name}"
			# TODO: C - check if params[project_id] is session[:person].current_project_ids.includes?(params[:project_id]) 
			@item.project_id = params[:project_id]
			@item.role_id = Project.find(params[:project_id]).role_id
		end
		@old_item = @item.clone
		@old_item.id = @item.id
		@old_item.detail = @item.detail.clone

		# Saves the item and the associated details.
		# If the item is a new item, redirect the user to the Edit page for the newly created item, otherwise
		# remain on the Edit page.
		if request.post?
		  @item.build_detail if @item.detail.nil?
			
			@item.attributes = @item.attributes.merge(params[:item] || {})
			# TODO: C - Integrate Chronic - but for all dates
			#new_due_on = Chronic.parse(params[:item][:due_on])
			#@item.due_on = new_due_on.to_date if new_due_on
		  
			@item.project_id = nil if '0' == params[:item][:project_id]
			@item.project_id_escalation = @item.project_id if '0' == params[:item][:project_id_escalation]

			@item.detail.attributes = @item.detail.attributes.merge(params[:detail] || {})
			change_errors = ActiveRecord::Errors.new(@item)
		  ItemController.validate_authority_to_change(session[:person], @item, 
		    overwritten_attrs(@old_item.attributes, @item.attributes), 
		    overwritten_attrs(@old_item.detail.attributes, @item.detail.attributes),
		    change_errors)
						
			@item.person_id_updated_by = session[:person].id

			item_was_new_record = @item.new_record?
			
			if @item.valid? && change_errors.empty?
  	    begin
    			Item.transaction do
        		@item.save!
        		@item.detail.save!
        				    
    				# shuffle in hierarchy if moved
    				@item.update_nested_sets(@old_item, item_was_new_record)
    							  
    			  # link to referrer if requested  			   
    			  if params[:link_to_referrer]
    			    Association.create!(:item_id_from => @item.id, :item_id_to => params[:item_id_created_from]) 
    			    Association.create!(:item_id_to => @item.id, :item_id_from => params[:item_id_created_from]) 
    			  end
			  
    			  if Project == @item.class && @item.project_id.nil? && item_was_new_record 			  	
      				# If new root project then place current user in an administrator role.
      				admin_role = Role.new(
      			    :title => "#{@item.title} Administrator",
                :status_id => Status.find_by_type_name_and_enabled('Role', true, :order => 'generic_stage').id,
                :code_id_priority => Code.find_by_type_name_and_name_and_enabled('Role', 'Priority', true, :order => 'value').id,
                :role_id => 0,
                :person_id => session[:person].id,
                :person_id_updated_by => session[:person].id,
                :project_id => @item.id,
                :project_id_escalation => @item.id
      				)
				
      				security_profile_code = Code.find_by_type_name_and_name_and_value(Role.name, 'Security profile', 
                SystemSetting.system_setting('Administration', 'Administrator security profile value', 'Administrator') )
				    
      				admin_role.detail.attributes = {
                :code_id_security_profile => security_profile_code.id
              }
        
      				admin_role.save_with_validation false
      				admin_role.role_id = admin_role.id
      				admin_role.save!
    				
    				  RolePlacement.new(
                :person_id => session[:person].id,
                :role_id => admin_role.id,
                :start_on => Date.today-1,
                :end_on => 10.years.from_now.to_date,
                :committed_hours => 0,
                :normal_hourly_rate => 0
              ).save!
{'fraction_non_alphanumeric': 0.09689711486118671, 'fraction_numerical': 0.001633097441480675, 'mean_word_length': 2.963020030816641, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2117245', 'n_tokens_mistral': 4324, 'n_tokens_neox': 3877, 'n_words': 1178}