[#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:
1 parent
c17e8eaf1b
commit
a2b810a4d8
18 files changed
+110
-31
No files matched your search
@@ -75,6 +75,6 @@ module ContractsHelper
|
|||||||
|
|
||||||
def format_payment_terms(value)
|
def format_payment_terms(value)
|
||||||
return '' if value.blank?
|
return '' if value.blank?
|
||||||
return l(Contract::PaymentTerms[value.to_sym])
|
return h(value.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
+2
-14
@@ -4,6 +4,7 @@ class Contract < ActiveRecord::Base
|
|||||||
# Associations
|
# Associations
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :account_executive, :class_name => 'User', :foreign_key => 'account_executive_id'
|
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
|
has_many :deliverables, :dependent => :destroy
|
||||||
|
|
||||||
# Validations
|
# Validations
|
||||||
@@ -24,7 +25,7 @@ class Contract < ActiveRecord::Base
|
|||||||
attr_accessible :billable_rate
|
attr_accessible :billable_rate
|
||||||
attr_accessible :discount
|
attr_accessible :discount
|
||||||
attr_accessible :discount_note
|
attr_accessible :discount_note
|
||||||
attr_accessible :payment_terms
|
attr_accessible :payment_term_id
|
||||||
attr_accessible :client_ap_contact_information
|
attr_accessible :client_ap_contact_information
|
||||||
attr_accessible :po_number
|
attr_accessible :po_number
|
||||||
attr_accessible :client_point_of_contact
|
attr_accessible :client_point_of_contact
|
||||||
@@ -91,19 +92,6 @@ class Contract < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
alias_method :profit_spent, :profit_left
|
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
|
def after_initialize
|
||||||
self.executed = false unless self.executed.present?
|
self.executed = false unless self.executed.present?
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% form.inputs :name => l(:text_account_legend) do %>
|
<% 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 :po_number %>
|
||||||
<%= form.input :client_ap_contact_information, :input_html => {:class => 'wiki-edit', :rows => '5'} %>
|
<%= 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'} %>
|
<%= form.input :client_point_of_contact, :input_html => {:class => 'wiki-edit', :rows => '5'} %>
|
||||||
|
|||||||
@@ -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, :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, :executed, :html_options => {:class => 'contract-executed'}) %>
|
||||||
<%= show_field(resource, :discount_note, :format => :textilizable, :raw => true, :html_options => {:class => 'contract-discount-note'}) %>
|
<%= 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, :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, :po_number, :html_options => {:class => 'contract-po-number'}) %>
|
||||||
<%= show_field(resource, :details, :format => :textilizable, :raw => true, :html_options => {:class => 'contract-details'}) %>
|
<%= show_field(resource, :details, :format => :textilizable, :raw => true, :html_options => {:class => 'contract-details'}) %>
|
||||||
|
|||||||
@@ -13,14 +13,10 @@ en:
|
|||||||
field_discount: "Discount"
|
field_discount: "Discount"
|
||||||
field_discount_hint: "$, %"
|
field_discount_hint: "$, %"
|
||||||
field_discount_note: "Discounts Notes"
|
field_discount_note: "Discounts Notes"
|
||||||
field_payment_terms: "Payment Terms"
|
field_payment_term: "Payment Terms"
|
||||||
field_client_ap_contact_information: "AP Contact Info"
|
field_client_ap_contact_information: "AP Contact Info"
|
||||||
field_po_number: "PO Number"
|
field_po_number: "PO Number"
|
||||||
field_details: "Details"
|
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
|
button_add_new: Add New
|
||||||
text_new_deliverable: New Deliverable
|
text_new_deliverable: New Deliverable
|
||||||
text_edit_deliverable_title: "Edit {{title}}"
|
text_edit_deliverable_title: "Edit {{title}}"
|
||||||
@@ -60,4 +56,5 @@ en:
|
|||||||
text_account_legend: "Account Management"
|
text_account_legend: "Account Management"
|
||||||
text_deliverable_details_legend: "Deliverable Details"
|
text_deliverable_details_legend: "Deliverable Details"
|
||||||
text_save_contract: "Save Contract"
|
text_save_contract: "Save Contract"
|
||||||
|
enumeration_payment_term: "Payment Terms"
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -58,6 +58,8 @@ Dispatcher.to_prepare :redmine_contracts do
|
|||||||
|
|
||||||
Formtastic::SemanticFormBuilder.all_fields_required_by_default = false
|
Formtastic::SemanticFormBuilder.all_fields_required_by_default = false
|
||||||
Formtastic::SemanticFormBuilder.required_string = "<span class='required'> *</span>"
|
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'
|
require_dependency 'project'
|
||||||
Project.send(:include, RedmineContracts::Patches::ProjectPatch)
|
Project.send(:include, RedmineContracts::Patches::ProjectPatch)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class ContractsDeleteTest < ActionController::IntegrationTest
|
|||||||
|
|
||||||
def setup
|
def setup
|
||||||
@project = Project.generate!(:identifier => 'main')
|
@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
|
end
|
||||||
|
|
||||||
should "allow admins to delete the contract" do
|
should "allow admins to delete the contract" do
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class ContractsEditTest < ActionController::IntegrationTest
|
|||||||
@account_executive = User.generate!
|
@account_executive = User.generate!
|
||||||
@role = Role.generate!
|
@role = Role.generate!
|
||||||
User.add_to_project(@account_executive, @project, @role)
|
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
|
end
|
||||||
|
|
||||||
should "allow any user to edit the contract" do
|
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 "h2", :text => /#{@contract.name}/
|
||||||
assert_select "form#edit_contract_#{@contract.id}.contract" do
|
assert_select "form#edit_contract_#{@contract.id}.contract" do
|
||||||
assert_select "input[value=?]", /#{@contract.name}/
|
assert_select "input[value=?]", /#{@contract.name}/
|
||||||
assert_select "select#contract_payment_terms" do
|
assert_select "select#contract_payment_term_id"
|
||||||
assert_select "option[selected=selected][value=net_15]"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
fill_in "Name", :with => 'An updated name'
|
fill_in "Name", :with => 'An updated name'
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ class ContractsNewTest < ActionController::IntegrationTest
|
|||||||
|
|
||||||
def setup
|
def setup
|
||||||
@project = Project.generate!(:identifier => 'main')
|
@project = Project.generate!(:identifier => 'main')
|
||||||
|
PaymentTerm.generate!(:type => 'PaymentTerm', :name => 'Net 15')
|
||||||
|
PaymentTerm.generate!(:type => 'PaymentTerm', :name => 'Net 30')
|
||||||
end
|
end
|
||||||
|
|
||||||
should "allow any user to open the new contracts form" do
|
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 @account_executive, @contract.account_executive
|
||||||
assert_equal '2010-01-01', @contract.start_date.to_s
|
assert_equal '2010-01-01', @contract.start_date.to_s
|
||||||
assert_equal '2010-12-31', @contract.end_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
|
||||||
end
|
end
|
||||||
@@ -5,7 +5,7 @@ class DeliverablesDeleteTest < ActionController::IntegrationTest
|
|||||||
|
|
||||||
def setup
|
def setup
|
||||||
@project = Project.generate!(:identifier => 'main')
|
@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!
|
@manager = User.generate!
|
||||||
@deliverable = FixedDeliverable.generate!(:contract => @contract, :manager => @manager)
|
@deliverable = FixedDeliverable.generate!(:contract => @contract, :manager => @manager)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class DeliverablesEditTest < ActionController::IntegrationTest
|
|||||||
|
|
||||||
def setup
|
def setup
|
||||||
@project = Project.generate!(:identifier => 'main')
|
@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!
|
@manager = User.generate!
|
||||||
@role = Role.generate!
|
@role = Role.generate!
|
||||||
User.add_to_project(@manager, @project, @role)
|
User.add_to_project(@manager, @project, @role)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ require 'test_helper'
|
|||||||
class OverheadPluginIntegrationTest < ActionController::IntegrationTest
|
class OverheadPluginIntegrationTest < ActionController::IntegrationTest
|
||||||
def setup
|
def setup
|
||||||
@project = Project.generate!(:identifier => 'main')
|
@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!
|
@manager = User.generate!
|
||||||
@role = Role.generate!
|
@role = Role.generate!
|
||||||
User.add_to_project(@manager, @project, @role)
|
User.add_to_project(@manager, @project, @role)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ require File.dirname(__FILE__) + '/../test_helper'
|
|||||||
class ContractTest < ActiveSupport::TestCase
|
class ContractTest < ActiveSupport::TestCase
|
||||||
should_belong_to :account_executive
|
should_belong_to :account_executive
|
||||||
should_belong_to :project
|
should_belong_to :project
|
||||||
|
should_belong_to :payment_term
|
||||||
should_have_many :deliverables
|
should_have_many :deliverables
|
||||||
|
|
||||||
should_validate_presence_of :name
|
should_validate_presence_of :name
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in new issue
Block a user