Skip to content

Commit

Permalink
Initial code versioning
Browse files Browse the repository at this point in the history
  • Loading branch information
Dalibor Nasevic and Sachin Ranchod authored and dalibor committed Sep 28, 2012
1 parent 34461d0 commit 384f901
Show file tree
Hide file tree
Showing 21 changed files with 128 additions and 19 deletions.
6 changes: 6 additions & 0 deletions app/assets/stylesheets/partials/_lists.sass
Original file line number Diff line number Diff line change
Expand Up @@ -322,10 +322,14 @@ ul.activity_tree
&.expanded
background: #fff
color: red
position: relative
top: 9px
+border-radius(10px)
&.collapsed
background: #fff
color: green
position: relative
top: 9px
+border-radius(10px)

ul
Expand All @@ -339,6 +343,8 @@ ul.activity_tree
.clearfix
border-bottom: $primary_border3 1px solid
border-left: $primary_border3 1px solid
.collapsed, .expanded
position: static

.values
margin-right: 5px
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/admin/codes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ def sort_direction
end

def scoped_codes
Code.with_types("Code::#{params[:filter].upcase}".constantize)
code_types = "Code::#{params[:filter].upcase}".constantize
last_version = Code.with_types(code_types).maximum(:version)
Code.with_types(code_types).with_version(last_version)
end
end
5 changes: 5 additions & 0 deletions app/helpers/shared/outlays_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,9 @@ def tabs(outlay)
Shared::OutlaysHelper::INDIRECT_COST_TABS
end
end

def last_version_beneficiaries
last_version = Beneficiary.maximum(:version)
Beneficiary.with_version(last_version)
end
end
7 changes: 4 additions & 3 deletions app/models/code.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ def type_string
has_many :activities, :through => :code_splits

### Named scope
scope :with_type, lambda { |type| {:conditions => ["codes.type = ?", type]} }
scope :with_types, lambda { |types| {:conditions => ["codes.type IN (?)", types]} }
scope :purposes, :conditions => ["codes.type in (?)", PURPOSES]
scope :with_type, lambda { |type| where(["codes.type = ?", type]) }
scope :with_types, lambda { |types| where(["codes.type IN (?)", types]) }
scope :with_version, lambda { |version| where(version: version) }
scope :purposes, where(["codes.type in (?)", PURPOSES])

# is this still needed - especially given it has some complex Mtef/NHa etc logic ??!
def self.deepest_nesting
Expand Down
10 changes: 7 additions & 3 deletions app/models/coding_tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,15 @@ def valid?
def root_codes
case @coding_klass.to_s
when 'PurposeBudgetSplit', 'PurposeSpendSplit'
Code.purposes.roots
last_version = Code.purposes.maximum(:version)
Code.purposes.with_version(last_version).roots
when 'InputBudgetSplit', 'InputSpendSplit'
Input.roots
last_version = Input.maximum(:version)
Input.with_version(last_version).roots
when 'LocationBudgetSplit', 'LocationSpendSplit'
Location.national_level + Location.without_national_level.sorted.all
last_version = Location.maximum(:version)
Location.with_version(last_version).national_level +
Location.with_version(last_version).without_national_level.sorted.all
else
raise "Invalid coding_klass #{@coding_klass.to_s}".to_yaml
end
Expand Down
2 changes: 1 addition & 1 deletion app/views/admin/codes/_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
%li.last
%ul.section_form.first
= f.input :type_string, :collection => ['Beneficiary', 'Code', 'Input', 'Location', 'Mtef', 'Nasa', 'Nha', 'Nsp'], :as => :select, :label => 'Type', :required => false, :hint => "Type of code"
= f.input :parent, :collection => Code.all, :as => :select, :required => false, :hint => "The code this one falls underneath"
= f.input :parent, :collection => Code.with_type(@code.type).with_version(@code.version).all, :as => :select, :required => false, :hint => "The code this one falls underneath"
= f.input :short_display, :required => false, :hint => "Short text detailing the code"
= f.input :long_display, :required => false, :hint => "Text detailing the code"
= f.input :description, :required => false, :hint => "Text detailing the specifics of this code"
Expand Down
4 changes: 2 additions & 2 deletions app/views/shared/outlays/_classification.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
- if @budget_coding_tree.root_codes.present?
%p#expl
%span.spend
%span Past Expenditure%
%span Past Expenditure %
= link_to image_tag("tooltip.png"), "#", title: heading_hint, class: 'tooltip'
- alt_txt = "Copy across Expenditure classifications to Budget classifications"
= link_to image_tag("icon_s2b.png", alt: alt_txt, title: alt_txt, class: "click"), '#', id: 'js_spend_to_budget'
%span.budget
- alt_txt = "Copy across Budget classifications to Expenditure classifications"
= link_to image_tag("icon_b2s.png", alt: alt_txt, title: alt_txt, class: "click"), '#', id: 'js_budget_to_spend'
%span Current Budget%
%span Current Budget %
= link_to image_tag("tooltip.png"), "#", title: heading_hint, class: 'tooltip right'

%ul.activity_tree{activity_budget: outlay.total_budget, activity_spend: outlay.total_spend, activity_currency: outlay.currency}
Expand Down
2 changes: 1 addition & 1 deletion app/views/shared/outlays/_outputs_targets_benefs.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
.column2.borderless
%h3 Beneficiaries
%ul.section_form.last
= f.input :beneficiaries, :label => false, :as => :check_boxes, :wrapper_html => { :class => 'borderless beneficiaries_boxes' }
= f.input :beneficiaries, collection: last_version_beneficiaries, label: false, as: :check_boxes, wrapper_html: { :class => 'borderless beneficiaries_boxes' }
= f.input :other_beneficiaries, :label => 'Other Beneficiaries' , :input_html => { :rows => 2 }, :as => :text, :required => false, :wrapper_html => { :class => 'other_beneficiaries' }

.column2.last.borderless
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20120927085429_add_version_to_codes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class AddVersionToCodes < ActiveRecord::Migration

def change
add_column :codes, :version, :integer

Code.all.each do |code|
code.version = 1
code.save!
end
end
end
9 changes: 9 additions & 0 deletions db/migrate/20120927091946_load_new_codes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class LoadNewCodes < ActiveRecord::Migration
def up
load 'db/seed_files/inputs_v2.rb'
end

def down
puts 'irreversible migration'
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20120926144014) do
ActiveRecord::Schema.define(:version => 20120927091946) do

create_table "activities", :force => true do |t|
t.string "name"
Expand Down Expand Up @@ -71,6 +71,7 @@
t.string "sub_account"
t.string "nha_code"
t.string "nasa_code"
t.integer "version"
end

create_table "comments", :force => true do |t|
Expand Down
4 changes: 3 additions & 1 deletion db/seed_files/inputs.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require 'csv'

puts "\n Loading inputs.csv..."
Input.delete_all

CSV.foreach("db/seed_files/inputs.csv", :headers=>true) do |row|
c = Input.find_or_initialize_by_external_id(row["id"])
p = Input.find_by_external_id(row["parent_id"])
Expand Down
25 changes: 25 additions & 0 deletions db/seed_files/inputs_v2.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"id","parent_id","short_display","description"
"v2_1","","In service training and workshops","It includes all costs related to the implementation of the training (per diems, transport allowances, hall rent, coffee breaks), workshops and similar activities. On-the-job training and/or recurrent training for professionals"
"v2_2","","Pre service training and workshops","Targeted at student and others enrolled in universities, professional schools and similar"
"v2_3","","Advertising, Campaigns and Communication for Health","Costs related to printed, multimedia or electronic material, radio/TV messages, used both for programme communication (like IEC, BCC, sensitization messages) and visibility"
"v2_4","","Salaries: Government personnel (GoR)","Gross salary of personnel directly employed and paid for by GoR ('on statute')"
"v2_5","","Contracted personnel (for GoR)","Gross salary of personnel employed to work in government positions (both clinical and program implementation), not paid for by GoR directly ('contract' or project)"
"v2_6","","Not-government personnel","Gross salary of local and expatriate employees of any other organization/agency (like private sector, not for profit sector, in country TA ...)"
"v2_61","v2_6","TA","Technical assistance"
"v2_62","v2_6","Service Provision","Program implementation and service provision"
"v2_7","","Short term consultants","External consultants not working full time in country"
"v2_8","","Incentives for CHW","Incentives for Community health workers (and related cooperatives)"
"v2_9","","PBF","Performance based financing"
"v2_10","","Drugs","Drugs"
"v2_11","","Commodities and consummable","Mosquito nets, lab consumables, gloves ..."
"v2_12","","Nutritional support","Nutritional support"
"v2_13","","Infrastructure","Infrastructure"
"v2_14","","Non-medical equipment","Non-medical equipment"
"v2_15","","Medical equipment","Medical equipment"
"v2_16","","Vehicles, Transportation & Travel","Vehicles, Transportation & Travel"
"v2_161","v2_16","Vehicles & maintenance","Capital costs of vehicles and maintenance costs"
"v2_162","v2_16","Domestic travel costs","All costs associated with in country travel (i.e. fuel, insurance for vehicles, service hire, travel allowances)"
"v2_163","v2_16","International travel costs","International travel costs"
"v2_17","","Direct financial support","Budget support, CDPF funds, and other direct financial transfer to GoR (national or lower level)"
"v2_18","","OH / General administrative costs","Admin and overhead costs (office rent, utilities, internal communication costs, fringe benefits, security, cleaning...)"
"v2_19","","Other","It refers to all the input that are not explicitly mentioned in the above categories."
14 changes: 14 additions & 0 deletions db/seed_files/inputs_v2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'csv'

puts "\n Loading inputs_v2.csv..."

CSV.foreach("db/seed_files/inputs_v2.csv", headers: true) do |row|
code = Input.find_or_initialize_by_external_id(row["id"])
parent_code = Input.find_by_external_id(row["parent_id"])
code.parent_id = parent_code.id if parent_code
code.description = row["description"]
code.short_display = row["short_display"]
code.version = 2
code.save!
print "."
end
1 change: 1 addition & 0 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
load 'db/seed_files/codes.rb'

load 'db/seed_files/inputs.rb'
load 'db/seed_files/inputs_v2.rb'

load 'db/seed_files/beneficiaries.rb'

Expand Down
6 changes: 4 additions & 2 deletions lib/reports/detailed/classification_split.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ def initialize(request, amount_type, classification_type, filetype)
classification_type)
@code_deepest_nesting = case classification_type
when :purpose
Code.deepest_nesting
last_version = Code.purposes.maximum(:version)
Code.purposes.with_version(last_version).deepest_nesting
when :input
Input.deepest_nesting
last_version = Input.maximum(:version)
Input.with_version(last_version).deepest_nesting
else
1
end
Expand Down
3 changes: 2 additions & 1 deletion lib/reports/detailed/dynamic_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ class Reports::Detailed::DynamicQuery
attr_accessor :builder

def initialize(request, amount_type, filetype)
@deepest_nesting = Code.deepest_nesting
last_version = Code.purposes.maximum(:version)
@deepest_nesting = Code.purposes.with_version(last_version).deepest_nesting
@amount_type = amount_type
@implementer_splits = ImplementerSplit.find :all,
:joins => { :activity => :data_response },
Expand Down
3 changes: 2 additions & 1 deletion lib/reports/detailed/response_overview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ class Reports::Detailed::ResponseOverview < Reports::Detailed::DynamicQuery
attr_accessor :builder, :response, :amount_type

def initialize(response, amount_type, filetype)
@deepest_nesting = Code.deepest_nesting
last_version = Code.purposes.maximum(:version)
@deepest_nesting = Code.purposes.with_version(last_version).deepest_nesting
@amount_type = amount_type
@response = response
@implementer_splits = ImplementerSplit.find :all,
Expand Down
21 changes: 21 additions & 0 deletions spec/controllers/admin/codes_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require 'spec_helper'

describe Admin::CodesController do

describe "#index" do
before :each do
login_as_admin
end

it "shows latest version only" do
version1 = FactoryGirl.create(:input, version: 1)
version2 = FactoryGirl.create(:input, version: 2)

get :index, filter: 'Inputs'

codes = assigns(:codes)
codes.should include(version2)
codes.should_not include(version1)
end
end
end
1 change: 1 addition & 0 deletions spec/models/code_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
it { should allow_mass_assignment_of(:parent_id) }
it { should allow_mass_assignment_of(:official_name) }
it { should allow_mass_assignment_of(:external_id) }
it { should_not allow_mass_assignment_of(:version) }
end

describe "Associations" do
Expand Down
6 changes: 4 additions & 2 deletions spec/models/coding_tree_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,8 @@
end

it "returns codes for simple activity and 'PurposeBudgetSplit' type" do
Code.stub_chain(:purposes, :roots).and_return(@fake_codes)
Code.stub_chain(:purposes, :maximum)
Code.stub_chain(:purposes, :with_version, :roots).and_return(@fake_codes)

ct = CodingTree.new(@activity, PurposeBudgetSplit)
ct.root_codes.should == @fake_codes
Expand All @@ -348,7 +349,8 @@
end

it "returns codes for simple activity and 'PurposeSpendSplit' type" do
Code.stub_chain(:purposes, :roots).and_return(@fake_codes)
Code.stub_chain(:purposes, :maximum)
Code.stub_chain(:purposes, :with_version, :roots).and_return(@fake_codes)

ct = CodingTree.new(@activity, PurposeSpendSplit)
ct.root_codes.should == @fake_codes
Expand Down

0 comments on commit 384f901

Please sign in to comment.