acts_as_journalized for variable_cost_object

* removed from cost_object as acts_as_journalized does not play well with subclasses
* create migration for recreating initial journals
pull/6827/head
Jens Ulferts 13 years ago
parent cdb2e8e54d
commit 5027a42a8d
  1. 15
      app/models/cost_object.rb
  2. 18
      app/models/variable_cost_object.rb
  3. 34
      db/migrate/20120313152442_create_initial_variable_cost_object_journals.rb
  4. 29
      features/activity.feature
  5. 24
      features/step_definitions/cost_steps.rb
  6. 5
      init.rb
  7. 3
      spec/factories/varibale_cost_object_factory.rb

@ -13,15 +13,12 @@ class CostObject < ActiveRecord::Base
attr_protected :author attr_protected :author
acts_as_attachable :after_remove => :attachment_removed acts_as_attachable :after_remove => :attachment_removed
acts_as_event :title => Proc.new {|o| "#{l(:label_cost_object)} ##{o.id}: #{o.subject}"},
:url => Proc.new {|o| {:controller => 'cost_objects', :action => 'show', :id => o.id}} unless respond_to? :acts_as_journalized
acts_as_event :title => Proc.new {|o| "#{l(:label_cost_object)} ##{o.id}: #{o.subject}"},
if respond_to? :acts_as_journalized :url => Proc.new {|o| {:controller => 'cost_objects', :action => 'show', :id => o.id}}
acts_as_journalized :activity_find_options => {:include => [:project, :author]},
:activity_timestamp => "#{table_name}.updated_on",
:activity_author_key => :author_id
else
acts_as_activity_provider :find_options => {:include => [:project, :author]}, acts_as_activity_provider :find_options => {:include => [:project, :author]},
:timestamp => "#{table_name}.updated_on", :timestamp => "#{table_name}.updated_on",
:author_key => :author_id :author_key => :author_id

@ -10,6 +10,22 @@ class VariableCostObject < CostObject
after_update :save_material_budget_items after_update :save_material_budget_items
after_update :save_labor_budget_items after_update :save_labor_budget_items
if respond_to? :acts_as_journalized
acts_as_journalized :event_type => 'cost-object',
:event_title => Proc.new {|o| "#{l(:label_cost_object)} ##{o.journaled.id}: #{o.subject}"},
:event_url => Proc.new {|o| {:controller => 'cost_objects', :action => 'show', :id => o.journaled.id}},
:activity_type => superclass.plural_name,
:activity_find_options => {:include => [:project, :author]},
:activity_timestamp => "#{table_name}.updated_on",
:activity_author_key => :author_id,
:activity_permission => :view_cost_objects
end
# override acts_as_journalized method
def activity_type
self.class.superclass.plural_name
end
def copy_from(arg) def copy_from(arg)
cost_object = arg.is_a?(VariableCostObject) ? arg : VariableCostObject.find(arg) cost_object = arg.is_a?(VariableCostObject) ? arg : VariableCostObject.find(arg)
self.attributes = cost_object.attributes.dup self.attributes = cost_object.attributes.dup
@ -111,4 +127,4 @@ class VariableCostObject < CostObject
labor_budget_item.save(false) labor_budget_item.save(false)
end end
end end
end end

@ -0,0 +1,34 @@
class CreateInitialVariableCostObjectJournals < ActiveRecord::Migration
def self.up
[VariableCostObject].each do |p|
say_with_time("Building initial journals for #{p.class_name}") do
# avoid touching the journaled object on journal creation
p.journal_class.class_exec {
def touch_journaled_after_creation
end
}
# Create initial journals
p.find(:all).each do |o|
# Using rescue and save! here because either the Journal or the
# touched record could fail. This will catch either error and continue
begin
new_journal = o.recreate_initial_journal!
rescue ActiveRecord::RecordInvalid => ex
if new_journal.errors.count == 1 && new_journal.errors.first[0] == "version"
# Skip, only error was from creating the initial journal for a record that already had one.
else
puts "ERROR: errors creating the initial journal for #{o.class.to_s}##{o.id.to_s}:"
puts " #{ex.message}"
end
end
end
end
end
end
def self.down
VariableCostObjectJournal.destroy_all
end
end

@ -0,0 +1,29 @@
Feature: Cost Object activities
Background:
Given there is a standard cost control project named "project1"
And I am admin
Scenario: cost object is a selectable activity type
When I go to the activity page of the project "project1"
Then I should see "Budgets" within "#sidebar"
Scenario: Generating a cost object creates an activity
Given there is a variable cost object with the following:
| project | project1 |
| subject | Cost Object Subject |
| created_on | Time.now - 1.day |
When I go to the activity page of the project "project1"
Then I should see "Cost Object Subject"
Scenario: Updating a cost object creates an activity
Given there is a variable cost object with the following:
| project | project1 |
| subject | cost_object1 |
| created_on | Time.now - 40.days |
And I update the variable cost object "cost_object1" with the following:
| subject | cost_object1_new_title |
When I go to the activity page of the project "project1"
Then I should see "cost_object1_new_title"

@ -166,3 +166,27 @@ Given /^users have times and the cost type "([^\"]*)" logged on the issue "([^\"
end end
end end
Given /^there is a variable cost object with the following:$/ do |table|
cost_object = Factory.build(:variable_cost_object)
table_hash = table.rows_hash
cost_object.created_on = table_hash.has_key?("created_on") ?
eval(table_hash["created_on"]) :
Time.now
cost_object.fixed_date = cost_object.created_on.to_date
cost_object.project = (Project.find_by_identifier(table_hash["project"]) || Project.find_by_name(table_hash ["project"])) if table_hash.has_key? "project"
cost_object.author = User.current
cost_object.subject = table_hash["subject"] if table_hash.has_key? "subject"
cost_object.save!
cost_object.journals.first.update_attribute(:created_at, eval(table_hash["created_on"])) if table_hash.has_key?("created_on")
end
Given /^I update the variable cost object "([^"]*)" with the following:$/ do |subject, table|
cost_object = VariableCostObject.find_by_subject(subject)
cost_object.subject = table.rows_hash["subject"]
cost_object.save!
end

@ -48,6 +48,8 @@ Dispatcher.to_prepare do
require_dependency 'costs_issue_observer' require_dependency 'costs_issue_observer'
# loading the class so that acts_as_journalized gets registered
VariableCostObject
end end
# Hooks # Hooks
@ -131,9 +133,6 @@ Redmine::Plugin.register :redmine_costs do
menu :project_menu, :new_budget, {:action => 'new', :controller => 'cost_objects' }, :param => :project_id, :caption => :label_cost_object_new, :parent => :cost_objects menu :project_menu, :new_budget, {:action => 'new', :controller => 'cost_objects' }, :param => :project_id, :caption => :label_cost_object_new, :parent => :cost_objects
menu :project_menu, :show_all, {:action => 'index', :controller => 'cost_objects' }, :param => :project_id, :caption => :label_view_all_cost_objects, :parent => :cost_objects menu :project_menu, :show_all, {:action => 'index', :controller => 'cost_objects' }, :param => :project_id, :caption => :label_view_all_cost_objects, :parent => :cost_objects
# Activities
activity_provider :cost_objects
end end
# Observers # Observers

@ -0,0 +1,3 @@
Factory.define :variable_cost_object do |co|
end
Loading…
Cancel
Save