[#4410] Replace Payment Terms with an Enumeration

Instead of using a hard coded value for Payment Terms, they will use
Redmine's Enumeration table.  This provides an admin gui to managing
the value as well as ordering them.
This commit is contained in:
Eric Davis
2010-08-12 09:26:09 -07:00
parent c17e8eaf1b
commit a2b810a4d8
18 changed files with 110 additions and 31 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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'} %>

View File

@@ -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'}) %>

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -58,6 +58,8 @@ Dispatcher.to_prepare :redmine_contracts do
Formtastic::SemanticFormBuilder.all_fields_required_by_default = false
Formtastic::SemanticFormBuilder.required_string = "<span class='required'> *</span>"
require_dependency 'payment_term' # Load so Enumeration will pick up the subclass in dev
require_dependency 'project'
Project.send(:include, RedmineContracts::Patches::ProjectPatch)

View File

@@ -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

View File

@@ -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'

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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