diff --git a/app/helpers/contracts_helper.rb b/app/helpers/contracts_helper.rb index 588a1e9..2bc20f5 100644 --- a/app/helpers/contracts_helper.rb +++ b/app/helpers/contracts_helper.rb @@ -75,6 +75,6 @@ module ContractsHelper def format_payment_terms(value) return '' if value.blank? - return l(Contract::PaymentTerms[value.to_sym]) + return h(value.name) end end diff --git a/app/models/contract.rb b/app/models/contract.rb index ba23fdf..2ca4c13 100644 --- a/app/models/contract.rb +++ b/app/models/contract.rb @@ -4,6 +4,7 @@ class Contract < ActiveRecord::Base # Associations belongs_to :project belongs_to :account_executive, :class_name => 'User', :foreign_key => 'account_executive_id' + belongs_to :payment_term, :class_name => "PaymentTerm", :foreign_key => "payment_term_id" has_many :deliverables, :dependent => :destroy # Validations @@ -24,7 +25,7 @@ class Contract < ActiveRecord::Base attr_accessible :billable_rate attr_accessible :discount attr_accessible :discount_note - attr_accessible :payment_terms + attr_accessible :payment_term_id attr_accessible :client_ap_contact_information attr_accessible :po_number attr_accessible :client_point_of_contact @@ -91,19 +92,6 @@ class Contract < ActiveRecord::Base end alias_method :profit_spent, :profit_left - PaymentTerms = { - :net_0 => :text_payment_terms_net_0, - :net_15 => :text_payment_terms_net_15, - :net_30 => :text_payment_terms_net_30, - :net_45 => :text_payment_terms_net_45 - } - - def payment_terms_for_select - PaymentTerms.collect {|value, label| - [l(label), value.to_s] - } - end - def after_initialize self.executed = false unless self.executed.present? end diff --git a/app/models/payment_term.rb b/app/models/payment_term.rb new file mode 100644 index 0000000..4c76f64 --- /dev/null +++ b/app/models/payment_term.rb @@ -0,0 +1,19 @@ +class PaymentTerm < Enumeration + unloadable + + has_many :contracts, :foreign_key => 'payment_term_id' + + OptionName = :enumeration_payment_term + + def option_name + OptionName + end + + def objects_count + contracts.count + end + + def transfer_relations(to) + contracts.update_all("payment_term_id = #{to.id}") + end +end diff --git a/app/views/contracts/_form.html.erb b/app/views/contracts/_form.html.erb index 224b40c..0a8c204 100644 --- a/app/views/contracts/_form.html.erb +++ b/app/views/contracts/_form.html.erb @@ -18,7 +18,7 @@ <% end %> <% form.inputs :name => l(:text_account_legend) do %> - <%= form.input :payment_terms, :as => :select, :collection => resource.payment_terms_for_select %> + <%= form.input :payment_term %> <%= form.input :po_number %> <%= form.input :client_ap_contact_information, :input_html => {:class => 'wiki-edit', :rows => '5'} %> <%= form.input :client_point_of_contact, :input_html => {:class => 'wiki-edit', :rows => '5'} %> diff --git a/app/views/contracts/show.html.erb b/app/views/contracts/show.html.erb index d191b21..0267b65 100644 --- a/app/views/contracts/show.html.erb +++ b/app/views/contracts/show.html.erb @@ -33,7 +33,7 @@ <%= show_field(resource, :client_point_of_contact, :format => :textilizable, :raw => true, :html_options => {:class => 'contract-client-point-of-contact padd'}, :label_html_options => {:width => '25%'}) %> <%= show_field(resource, :executed, :html_options => {:class => 'contract-executed'}) %> <%= show_field(resource, :discount_note, :format => :textilizable, :raw => true, :html_options => {:class => 'contract-discount-note'}) %> - <%= show_field(resource, :payment_terms, :format => :format_payment_terms, :html_options => {:class => 'contract-payment-terms'}) %> + <%= show_field(resource, :payment_term, :format => :format_payment_terms, :html_options => {:class => 'contract-payment-terms'}) %> <%= show_field(resource, :client_ap_contact_information, :format => :textilizable, :raw => true, :html_options => {:class => 'contract-client-ap-contact-information'}) %> <%= show_field(resource, :po_number, :html_options => {:class => 'contract-po-number'}) %> <%= show_field(resource, :details, :format => :textilizable, :raw => true, :html_options => {:class => 'contract-details'}) %> diff --git a/config/locales/en.yml b/config/locales/en.yml index ccd70b2..85cdfd1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -13,14 +13,10 @@ en: field_discount: "Discount" field_discount_hint: "$, %" field_discount_note: "Discounts Notes" - field_payment_terms: "Payment Terms" + field_payment_term: "Payment Terms" field_client_ap_contact_information: "AP Contact Info" field_po_number: "PO Number" field_details: "Details" - text_payment_terms_net_0: "Net 0" - text_payment_terms_net_15: "Net 15" - text_payment_terms_net_30: "Net 30" - text_payment_terms_net_45: "Net 45" button_add_new: Add New text_new_deliverable: New Deliverable text_edit_deliverable_title: "Edit {{title}}" @@ -60,4 +56,5 @@ en: text_account_legend: "Account Management" text_deliverable_details_legend: "Deliverable Details" text_save_contract: "Save Contract" + enumeration_payment_term: "Payment Terms" diff --git a/db/migrate/008_add_payment_term_id_to_contracts.rb b/db/migrate/008_add_payment_term_id_to_contracts.rb new file mode 100644 index 0000000..99ec0a5 --- /dev/null +++ b/db/migrate/008_add_payment_term_id_to_contracts.rb @@ -0,0 +1,9 @@ +class AddPaymentTermIdToContracts < ActiveRecord::Migration + def self.up + add_column :contracts, :payment_term_id, :integer + end + + def self.down + remove_column :contracts, :payment_term_id + end +end diff --git a/db/migrate/009_remove_payment_terms_from_contracts.rb b/db/migrate/009_remove_payment_terms_from_contracts.rb new file mode 100644 index 0000000..4760555 --- /dev/null +++ b/db/migrate/009_remove_payment_terms_from_contracts.rb @@ -0,0 +1,9 @@ +class RemovePaymentTermsFromContracts < ActiveRecord::Migration + def self.up + remove_column :contracts, :payment_terms + end + + def self.down + add_column :contracts, :payment_terms, :string + end +end diff --git a/db/migrate/010_populate_payment_terms.rb b/db/migrate/010_populate_payment_terms.rb new file mode 100644 index 0000000..84b91e3 --- /dev/null +++ b/db/migrate/010_populate_payment_terms.rb @@ -0,0 +1,14 @@ +class PopulatePaymentTerms < ActiveRecord::Migration + def self.up + [0, 15, 30, 45, 60, 75, 90].each_with_index do |days, index| + name = "Net #{days}" + unless PaymentTerm.find_by_name(name) + PaymentTerm.create!(:name => name, :position => index + 1) + end + end + end + + def self.down + # No-op + end +end diff --git a/init.rb b/init.rb index 9c0e75d..b7a590a 100644 --- a/init.rb +++ b/init.rb @@ -58,6 +58,8 @@ Dispatcher.to_prepare :redmine_contracts do Formtastic::SemanticFormBuilder.all_fields_required_by_default = false Formtastic::SemanticFormBuilder.required_string = " *" + + require_dependency 'payment_term' # Load so Enumeration will pick up the subclass in dev require_dependency 'project' Project.send(:include, RedmineContracts::Patches::ProjectPatch) diff --git a/test/integration/contracts_delete_test.rb b/test/integration/contracts_delete_test.rb index f46c2f2..f40d1a2 100644 --- a/test/integration/contracts_delete_test.rb +++ b/test/integration/contracts_delete_test.rb @@ -5,7 +5,7 @@ class ContractsDeleteTest < ActionController::IntegrationTest def setup @project = Project.generate!(:identifier => 'main') - @contract = Contract.generate!(:project => @project, :name => 'A Contract', :payment_terms => 'net_15') + @contract = Contract.generate!(:project => @project, :name => 'A Contract') end should "allow admins to delete the contract" do diff --git a/test/integration/contracts_edit_test.rb b/test/integration/contracts_edit_test.rb index 38c5ecf..8931b56 100644 --- a/test/integration/contracts_edit_test.rb +++ b/test/integration/contracts_edit_test.rb @@ -8,7 +8,7 @@ class ContractsEditTest < ActionController::IntegrationTest @account_executive = User.generate! @role = Role.generate! User.add_to_project(@account_executive, @project, @role) - @contract = Contract.generate!(:project => @project, :name => 'A Contract', :payment_terms => 'net_15', :account_executive => @account_executive) + @contract = Contract.generate!(:project => @project, :name => 'A Contract', :account_executive => @account_executive) end should "allow any user to edit the contract" do @@ -23,9 +23,7 @@ class ContractsEditTest < ActionController::IntegrationTest assert_select "h2", :text => /#{@contract.name}/ assert_select "form#edit_contract_#{@contract.id}.contract" do assert_select "input[value=?]", /#{@contract.name}/ - assert_select "select#contract_payment_terms" do - assert_select "option[selected=selected][value=net_15]" - end + assert_select "select#contract_payment_term_id" end fill_in "Name", :with => 'An updated name' diff --git a/test/integration/contracts_new_test.rb b/test/integration/contracts_new_test.rb index 872da4e..d84ecaf 100644 --- a/test/integration/contracts_new_test.rb +++ b/test/integration/contracts_new_test.rb @@ -5,6 +5,8 @@ class ContractsNewTest < ActionController::IntegrationTest def setup @project = Project.generate!(:identifier => 'main') + PaymentTerm.generate!(:type => 'PaymentTerm', :name => 'Net 15') + PaymentTerm.generate!(:type => 'PaymentTerm', :name => 'Net 30') end should "allow any user to open the new contracts form" do @@ -40,7 +42,7 @@ class ContractsNewTest < ActionController::IntegrationTest assert_equal @account_executive, @contract.account_executive assert_equal '2010-01-01', @contract.start_date.to_s assert_equal '2010-12-31', @contract.end_date.to_s - assert_equal 'net_30', @contract.payment_terms + assert_equal 'Net 30', @contract.payment_term.name end end diff --git a/test/integration/deliverables_delete_test.rb b/test/integration/deliverables_delete_test.rb index 795e2c4..bc377ad 100644 --- a/test/integration/deliverables_delete_test.rb +++ b/test/integration/deliverables_delete_test.rb @@ -5,7 +5,7 @@ class DeliverablesDeleteTest < ActionController::IntegrationTest def setup @project = Project.generate!(:identifier => 'main') - @contract = Contract.generate!(:project => @project, :name => 'A Contract', :payment_terms => 'net_15') + @contract = Contract.generate!(:project => @project, :name => 'A Contract') @manager = User.generate! @deliverable = FixedDeliverable.generate!(:contract => @contract, :manager => @manager) end diff --git a/test/integration/deliverables_edit_test.rb b/test/integration/deliverables_edit_test.rb index 5ac2173..c00dfc3 100644 --- a/test/integration/deliverables_edit_test.rb +++ b/test/integration/deliverables_edit_test.rb @@ -5,7 +5,7 @@ class DeliverablesEditTest < ActionController::IntegrationTest def setup @project = Project.generate!(:identifier => 'main') - @contract = Contract.generate!(:project => @project, :name => 'A Contract', :payment_terms => 'net_15') + @contract = Contract.generate!(:project => @project, :name => 'A Contract') @manager = User.generate! @role = Role.generate! User.add_to_project(@manager, @project, @role) diff --git a/test/integration/overhead_plugin_integration_test.rb b/test/integration/overhead_plugin_integration_test.rb index 4e39211..d6401cc 100644 --- a/test/integration/overhead_plugin_integration_test.rb +++ b/test/integration/overhead_plugin_integration_test.rb @@ -3,7 +3,7 @@ require 'test_helper' class OverheadPluginIntegrationTest < ActionController::IntegrationTest def setup @project = Project.generate!(:identifier => 'main') - @contract = Contract.generate!(:project => @project, :name => 'A Contract', :payment_terms => 'net_15') + @contract = Contract.generate!(:project => @project, :name => 'A Contract') @manager = User.generate! @role = Role.generate! User.add_to_project(@manager, @project, @role) diff --git a/test/unit/contract_test.rb b/test/unit/contract_test.rb index bb02ef0..50e950b 100644 --- a/test/unit/contract_test.rb +++ b/test/unit/contract_test.rb @@ -3,6 +3,7 @@ require File.dirname(__FILE__) + '/../test_helper' class ContractTest < ActiveSupport::TestCase should_belong_to :account_executive should_belong_to :project + should_belong_to :payment_term should_have_many :deliverables should_validate_presence_of :name diff --git a/test/unit/payment_term_test.rb b/test/unit/payment_term_test.rb new file mode 100644 index 0000000..6f10325 --- /dev/null +++ b/test/unit/payment_term_test.rb @@ -0,0 +1,40 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class PaymentTermTest < ActiveSupport::TestCase + include Redmine::I18n + + should_have_many(:contracts) + + should "be a subclass of Enumeration" do + assert_equal Enumeration, PaymentTerm.superclass + end + + context "#option_name" do + should "be Payment Terms" do + assert_equal "Payment Terms", l(PaymentTerm.new.option_name) + end + end + + context "#objects_count" do + should "count the number of contracts with this payment term" do + @payment_term = PaymentTerm.generate!(:type => 'PaymentTerm') + Contract.generate!(:payment_term => @payment_term) + Contract.generate!(:payment_term => @payment_term) + + assert_equal 2, @payment_term.objects_count + end + end + + context "#transfer_relations" do + should "update all contracts to use a new PaymentTerm" do + @old_payment_term = PaymentTerm.generate!(:type => 'PaymentTerm') + @new_payment_term = PaymentTerm.generate!(:type => 'PaymentTerm') + @contract1 = Contract.generate!(:payment_term => @old_payment_term) + @contract2 = Contract.generate!(:payment_term => @old_payment_term) + + @old_payment_term.transfer_relations(@new_payment_term) + assert_equal @new_payment_term, @contract1.reload.payment_term + assert_equal @new_payment_term, @contract2.reload.payment_term + end + end +end