kuality-coeus 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/Gemfile.lock +16 -18
- data/chromedriver.log +46 -0
- data/features/grants_gov/grants_gov_forms/code_and_form_mapping.feature +26 -0
- data/features/grants_gov/grants_gov_forms/forms_validation.feature +1 -0
- data/features/grants_gov/grants_gov_forms/s2s_questionnaire.feature +19 -0
- data/features/grants_gov/s2s_submission.feature +30 -0
- data/features/grants_gov/s2s_validation.feature +36 -0
- data/features/proposal_development/create_budget_versions.feature +31 -0
- data/features/proposal_development/create_proposal.feature +25 -0
- data/features/proposal_development/key_personnel_validations.feature +41 -0
- data/features/proposal_development/proposal_actions_validations.feature +46 -0
- data/features/proposal_development/proposal_permissions.feature +73 -0
- data/features/proposal_development/proposal_workflow.feature +105 -0
- data/features/proposal_development/special_review_validations.feature +12 -0
- data/features/step_definitions/action_list.rb +12 -0
- data/features/step_definitions/awards/create_award.rb +3 -0
- data/features/step_definitions/grants_gov/forms.rb +34 -0
- data/features/step_definitions/grants_gov/s2s_submission.rb +51 -0
- data/features/step_definitions/institutional_proposals/create_institutional_proposal.rb +3 -0
- data/features/step_definitions/proposal_development/budget_versions.rb +102 -0
- data/features/step_definitions/proposal_development/create_proposal.rb +157 -0
- data/features/step_definitions/proposal_development/edit_proposal.rb +79 -0
- data/features/step_definitions/proposal_development/institute_rates.rb +21 -0
- data/features/step_definitions/proposal_development/key_personnel_validations.rb +74 -0
- data/features/step_definitions/proposal_development/proposal_actions_validations.rb +73 -0
- data/features/step_definitions/proposal_development/proposal_permissions.rb +141 -0
- data/features/step_definitions/proposal_development/proposal_workflow.rb +81 -0
- data/features/step_definitions/proposal_development/s2s_validation.rb +30 -0
- data/features/step_definitions/proposal_development/special_review_validations.rb +7 -0
- data/features/step_definitions/test.rb +3 -0
- data/features/step_definitions/users.rb +65 -0
- data/features/support/env.rb +35 -0
- data/features/test.feature +13 -0
- data/kuality-coeus.gemspec +1 -1
- data/lib/chromedriver.log +4483 -0
- data/lib/kuality-coeus.rb +5 -2
- data/lib/kuality-coeus/core_extensions.rb +10 -0
- data/lib/kuality-coeus/data_objects/award/award.rb +126 -0
- data/lib/kuality-coeus/data_objects/award/award_transaction.rb +57 -0
- data/lib/kuality-coeus/data_objects/budget/budget_periods.rb +114 -0
- data/lib/kuality-coeus/data_objects/budget/budget_versions.rb +221 -0
- data/lib/kuality-coeus/data_objects/budget/subaward_budget.rb +65 -0
- data/lib/kuality-coeus/data_objects/committee_document/committee_document.rb +65 -0
- data/lib/kuality-coeus/data_objects/committee_document/committee_members.rb +30 -0
- data/lib/kuality-coeus/data_objects/committee_document/committee_schedule.rb +27 -0
- data/lib/kuality-coeus/data_objects/committee_document/member_roles.rb +28 -0
- data/lib/kuality-coeus/data_objects/conflict_of_interest/financial_entity.rb +48 -0
- data/lib/kuality-coeus/data_objects/grants_gov/phs_fellowship_questionnaire.rb +90 -0
- data/lib/kuality-coeus/data_objects/grants_gov/phs_training_budget_questionnaire.rb +5 -0
- data/lib/kuality-coeus/data_objects/institutional_proposal/institutional_proposal.rb +20 -0
- data/lib/kuality-coeus/data_objects/institutional_proposal/intellectual_property_review.rb +62 -0
- data/lib/kuality-coeus/data_objects/navigation.rb +64 -0
- data/lib/kuality-coeus/data_objects/proposal_development/compliance_questions.rb +47 -0
- data/lib/kuality-coeus/data_objects/proposal_development/custom_data.rb +41 -0
- data/lib/kuality-coeus/data_objects/proposal_development/degrees.rb +40 -0
- data/lib/kuality-coeus/data_objects/proposal_development/key_personnel.rb +299 -0
- data/lib/kuality-coeus/data_objects/proposal_development/kuali_university_questions.rb +58 -0
- data/lib/kuality-coeus/data_objects/proposal_development/permissions.rb +107 -0
- data/lib/kuality-coeus/data_objects/proposal_development/personnel_attachments.rb +46 -0
- data/lib/kuality-coeus/data_objects/proposal_development/proposal_attachments.rb +41 -0
- data/lib/kuality-coeus/data_objects/proposal_development/proposal_development.rb +301 -0
- data/lib/kuality-coeus/data_objects/proposal_development/proposal_questions.rb +52 -0
- data/lib/kuality-coeus/data_objects/proposal_development/s2s_questionnaire.rb +129 -0
- data/lib/kuality-coeus/data_objects/proposal_development/special_review.rb +79 -0
- data/lib/kuality-coeus/data_objects/rates/institute_rate.rb +209 -0
- data/lib/kuality-coeus/data_objects/user.rb +303 -33
- data/lib/kuality-coeus/gem_extensions.rb +26 -0
- data/lib/kuality-coeus/page_objects/000_base_page.rb +196 -14
- data/lib/kuality-coeus/page_objects/action_list.rb +32 -0
- data/lib/kuality-coeus/page_objects/award/award.rb +25 -0
- data/lib/kuality-coeus/page_objects/award/award_actions.rb +7 -0
- data/lib/kuality-coeus/page_objects/award/award_budget_versions.rb +9 -0
- data/lib/kuality-coeus/page_objects/award/commitments.rb +27 -0
- data/lib/kuality-coeus/page_objects/award/contacts.rb +19 -0
- data/lib/kuality-coeus/page_objects/award/custom_data.rb +6 -0
- data/lib/kuality-coeus/page_objects/award/payment_reports_terms.rb +26 -0
- data/lib/kuality-coeus/page_objects/award/special_review.rb +7 -0
- data/lib/kuality-coeus/page_objects/award/time_and_money.rb +36 -0
- data/lib/kuality-coeus/page_objects/budget/budget_actions.rb +31 -0
- data/lib/kuality-coeus/page_objects/budget/budget_versions.rb +13 -0
- data/lib/kuality-coeus/page_objects/budget/modular_budget.rb +16 -0
- data/lib/kuality-coeus/page_objects/budget/non-personnel.rb +11 -0
- data/lib/kuality-coeus/page_objects/budget/parameters.rb +65 -0
- data/lib/kuality-coeus/page_objects/budget/personnel.rb +56 -0
- data/lib/kuality-coeus/page_objects/budget/rates.rb +7 -0
- data/lib/kuality-coeus/page_objects/budget/summary.rb +5 -0
- data/lib/kuality-coeus/page_objects/budget_document.rb +19 -0
- data/lib/kuality-coeus/page_objects/central_admin.rb +4 -2
- data/lib/kuality-coeus/page_objects/committee/committee.rb +10 -10
- data/lib/kuality-coeus/page_objects/committee/members.rb +4 -4
- data/lib/kuality-coeus/page_objects/committee_document.rb +1 -6
- data/lib/kuality-coeus/page_objects/confirmation.rb +16 -0
- data/lib/kuality-coeus/page_objects/disclosure/disclosure.rb +56 -0
- data/lib/kuality-coeus/page_objects/disclosure/disclosure_actions.rb +9 -0
- data/lib/kuality-coeus/page_objects/document_header.rb +5 -0
- data/lib/kuality-coeus/page_objects/financial_entities.rb +1 -4
- data/lib/kuality-coeus/page_objects/financial_entities/my_financial_entities.rb +6 -0
- data/lib/kuality-coeus/page_objects/financial_entities/new_financial_entity.rb +11 -0
- data/lib/kuality-coeus/page_objects/financial_entities/reporter.rb +5 -3
- data/lib/kuality-coeus/page_objects/identity/person.rb +57 -0
- data/lib/kuality-coeus/page_objects/institute_rates_maintenance.rb +18 -0
- data/lib/kuality-coeus/page_objects/institutional_proposal.rb +18 -0
- data/lib/kuality-coeus/page_objects/institutional_proposal/contacts.rb +32 -0
- data/lib/kuality-coeus/page_objects/institutional_proposal/custom_data.rb +6 -0
- data/lib/kuality-coeus/page_objects/institutional_proposal/distribution.rb +20 -0
- data/lib/kuality-coeus/page_objects/institutional_proposal/institutional_proposal.rb +27 -0
- data/lib/kuality-coeus/page_objects/institutional_proposal/institutional_proposal_actions.rb +7 -0
- data/lib/kuality-coeus/page_objects/institutional_proposal/intellectual_property_review.rb +20 -0
- data/lib/kuality-coeus/page_objects/institutional_proposal/special_review.rb +6 -0
- data/lib/kuality-coeus/page_objects/kc_awards.rb +48 -0
- data/lib/kuality-coeus/page_objects/kc_protocol.rb +15 -0
- data/lib/kuality-coeus/page_objects/login.rb +4 -5
- data/lib/kuality-coeus/page_objects/lookup_pages/000_lookups.rb +10 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/action_list_filter.rb +6 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/address_book_lookup.rb +4 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/development_proposal_lookup.rb +3 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/document_search.rb +10 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/group_lookup.rb +3 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/institute_rates_lookup.rb +12 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/opportunity_lookup.rb +6 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/organization_lookup.rb +5 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/person_extended_attributes.rb +5 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/person_lookup.rb +10 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/role_lookup.rb +6 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/sponsor_lookup.rb +9 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/unit_admin_lookup.rb +3 -0
- data/lib/kuality-coeus/page_objects/lookup_pages/unit_lookup.rb +3 -0
- data/lib/kuality-coeus/page_objects/maintenance.rb +7 -0
- data/lib/kuality-coeus/page_objects/notification_editor.rb +6 -0
- data/lib/kuality-coeus/page_objects/proposal_development.rb +7 -2
- data/lib/kuality-coeus/page_objects/proposal_development/abstracts_and_attachments.rb +54 -0
- data/lib/kuality-coeus/page_objects/proposal_development/key_personnel.rb +126 -0
- data/lib/kuality-coeus/page_objects/proposal_development/pd_custom_data.rb +6 -0
- data/lib/kuality-coeus/page_objects/proposal_development/permissions.rb +44 -0
- data/lib/kuality-coeus/page_objects/proposal_development/phs_fellowship_questionnaire.rb +44 -0
- data/lib/kuality-coeus/page_objects/proposal_development/phs_training_budget_questionnaire.rb +50 -0
- data/lib/kuality-coeus/page_objects/proposal_development/proposal.rb +47 -8
- data/lib/kuality-coeus/page_objects/proposal_development/proposal_actions.rb +62 -0
- data/lib/kuality-coeus/page_objects/proposal_development/proposal_summary.rb +9 -0
- data/lib/kuality-coeus/page_objects/proposal_development/questions.rb +111 -0
- data/lib/kuality-coeus/page_objects/proposal_development/s2s.rb +35 -0
- data/lib/kuality-coeus/page_objects/proposal_development/special_review.rb +6 -0
- data/lib/kuality-coeus/page_objects/protocol/custom_data.rb +6 -0
- data/lib/kuality-coeus/page_objects/protocol/permissions.rb +5 -0
- data/lib/kuality-coeus/page_objects/protocol/personnel.rb +5 -0
- data/lib/kuality-coeus/page_objects/protocol/protocol.rb +11 -0
- data/lib/kuality-coeus/page_objects/protocol/questionnaire.rb +5 -0
- data/lib/kuality-coeus/page_objects/protocol/special_review.rb +6 -0
- data/lib/kuality-coeus/page_objects/rejection_confirmation.rb +5 -0
- data/lib/kuality-coeus/page_objects/researcher.rb +4 -2
- data/lib/kuality-coeus/page_objects/shared/unit_administrator.rb +13 -0
- data/lib/kuality-coeus/page_objects/system/person_extended_attributes.rb +18 -0
- data/lib/kuality-coeus/page_objects/system_admin.rb +7 -0
- data/lib/kuality-coeus/page_objects/unit.rb +2 -4
- data/lib/kuality-coeus/utilities.rb +39 -0
- data/libpeerconnection.log +0 -0
- metadata +140 -5
- data/lib/kuality-coeus/data_objects/committee_document.rb +0 -65
- data/lib/kuality-coeus/data_objects/proposal_development.rb +0 -53
- data/lib/kuality-coeus/navigation.rb +0 -3
@@ -0,0 +1,64 @@
|
|
1
|
+
module Navigation
|
2
|
+
|
3
|
+
include Utilities
|
4
|
+
|
5
|
+
def open_document doc_header
|
6
|
+
doc_search unless on_document?(doc_header)
|
7
|
+
end
|
8
|
+
|
9
|
+
def on_document?(doc_header)
|
10
|
+
begin
|
11
|
+
on(DocumentHeader).document_id==@document_id && @browser.frm.div(id: 'headerarea').h1.text==doc_header
|
12
|
+
rescue Watir::Exception::UnknownObjectException, Selenium::WebDriver::Error::StaleElementReferenceError
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def doc_search
|
18
|
+
visit DocumentSearch do |search|
|
19
|
+
search.close_parents
|
20
|
+
search.document_id.set @document_id
|
21
|
+
search.search
|
22
|
+
search.open_doc @document_id
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_page? element
|
27
|
+
begin
|
28
|
+
element.exist?
|
29
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Use in the #create method of your data objects for filling out
|
35
|
+
# fields. This method eliminates the need to write repetitive
|
36
|
+
# lines of code, with one line for every field needing to be
|
37
|
+
# filled in.
|
38
|
+
#
|
39
|
+
# Requirement: The field method name and the class instance variable
|
40
|
+
# must be the same!
|
41
|
+
#
|
42
|
+
def fill_out(page, *fields)
|
43
|
+
methods={
|
44
|
+
'Watir::TextField' => lambda{|p, f| p.send(f).fit(get f)},
|
45
|
+
'Watir::Select' => lambda{|p, f| p.send(f).pick!(get f)},
|
46
|
+
'Watir::Radio' => lambda{|p, f| p.send(f, get(f)) unless get(f)==nil },
|
47
|
+
'Watir::CheckBox' => lambda{|p, f| p.send(f).fit(get f) }
|
48
|
+
}
|
49
|
+
fields.shuffle.each do |field|
|
50
|
+
# TODO: Someday see if there's a way to fix things so this rescue isn't necessary...
|
51
|
+
# It's here because the radio button "element" definitions are *actions* that
|
52
|
+
# require a parameter, so just sending the method to the page
|
53
|
+
# is not going to work.
|
54
|
+
begin
|
55
|
+
key = page.send(field).class.to_s
|
56
|
+
rescue NoMethodError
|
57
|
+
key = 'Watir::Radio'
|
58
|
+
end
|
59
|
+
methods[key].call(page, field)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
alias_method :fill_in, :fill_out
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class ComplianceQuestionsObject
|
2
|
+
|
3
|
+
include Foundry
|
4
|
+
include DataFactory
|
5
|
+
include DateFactory
|
6
|
+
include Navigation
|
7
|
+
|
8
|
+
attr_accessor :document_id, :agree_to_ethical_conduct, :conduct_review_date
|
9
|
+
|
10
|
+
def initialize(browser, opts={})
|
11
|
+
@browser = browser
|
12
|
+
# PLEASE NOTE:
|
13
|
+
# This is an unusual data object class in that
|
14
|
+
# it breaks the typical model for radio button
|
15
|
+
# methods and their associated class instance variables
|
16
|
+
#
|
17
|
+
# In general, it's not workable to set up radio button elements
|
18
|
+
# to use "Y" and "N" as the instance variables associated with them.
|
19
|
+
defaults = {
|
20
|
+
agree_to_ethical_conduct: 'Y',
|
21
|
+
conduct_review_date: right_now[:date_w_slashes],
|
22
|
+
}
|
23
|
+
set_options(defaults.merge(opts))
|
24
|
+
requires :document_id
|
25
|
+
end
|
26
|
+
|
27
|
+
def create
|
28
|
+
navigate
|
29
|
+
on Questions do |cq|
|
30
|
+
cq.show_compliance_questions
|
31
|
+
fill_out cq, :agree_to_ethical_conduct, :conduct_review_date
|
32
|
+
cq.save
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# =======
|
37
|
+
private
|
38
|
+
# =======
|
39
|
+
|
40
|
+
# Nav Aids...
|
41
|
+
|
42
|
+
def navigate
|
43
|
+
open_document @doc_type
|
44
|
+
on(Proposal).questions unless on_page?(on(Questions).questions_header)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class CustomDataObject
|
2
|
+
|
3
|
+
include Foundry
|
4
|
+
include DataFactory
|
5
|
+
include Navigation
|
6
|
+
include StringFactory
|
7
|
+
|
8
|
+
attr_accessor :document_id, :graduate_student_count, :billing_element, :doc_type
|
9
|
+
|
10
|
+
def initialize(browser, opts={})
|
11
|
+
@browser = browser
|
12
|
+
|
13
|
+
defaults = {
|
14
|
+
graduate_student_count: rand(50).to_s,
|
15
|
+
billing_element: random_alphanums(40)
|
16
|
+
}
|
17
|
+
set_options(defaults.merge(opts))
|
18
|
+
requires :document_id, :doc_type
|
19
|
+
end
|
20
|
+
|
21
|
+
def create
|
22
|
+
navigate
|
23
|
+
on PDCustomData do |create|
|
24
|
+
create.expand_all
|
25
|
+
fill_out create, :graduate_student_count, :billing_element
|
26
|
+
create.save
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# =======
|
31
|
+
private
|
32
|
+
# =======
|
33
|
+
|
34
|
+
# Nav Aids...
|
35
|
+
|
36
|
+
def navigate
|
37
|
+
open_document @doc_type
|
38
|
+
on(Proposal).custom_data unless on_page?(on(PDCustomData).asdf_tab)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class DegreeObject
|
2
|
+
|
3
|
+
include Foundry
|
4
|
+
include DataFactory
|
5
|
+
include StringFactory
|
6
|
+
|
7
|
+
attr_accessor :type, :description, :graduation_year, :school,
|
8
|
+
:document_id, :person
|
9
|
+
|
10
|
+
def initialize(browser, opts={})
|
11
|
+
@browser = browser
|
12
|
+
|
13
|
+
defaults = {
|
14
|
+
type: '::random::',
|
15
|
+
description: random_alphanums_plus,
|
16
|
+
graduation_year: Time.random(year_range: 35).strftime('%Y')
|
17
|
+
}
|
18
|
+
set_options(defaults.merge(opts))
|
19
|
+
requires :document_id, :person
|
20
|
+
end
|
21
|
+
|
22
|
+
def create
|
23
|
+
# This method assumes navigation was performed by the parent object
|
24
|
+
on KeyPersonnel do |degrees|
|
25
|
+
degrees.expand_all
|
26
|
+
degrees.degree_type(@person).pick! @type
|
27
|
+
degrees.degree_description(@person).fit @description
|
28
|
+
degrees.graduation_year(@person).fit @graduation_year
|
29
|
+
degrees.school(@person).fit @school
|
30
|
+
degrees.add_degree(@person)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
class DegreesCollection < Array
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,299 @@
|
|
1
|
+
class KeyPersonObject
|
2
|
+
|
3
|
+
include Foundry
|
4
|
+
include DataFactory
|
5
|
+
include StringFactory
|
6
|
+
include Navigation
|
7
|
+
|
8
|
+
attr_accessor :first_name, :last_name, :role, :document_id, :key_person_role,
|
9
|
+
:full_name, :user_name, :home_unit, :units, :responsibility,
|
10
|
+
:financial, :recognition, :certified, :certify_info_true,
|
11
|
+
:potential_for_conflicts, :submitted_financial_disclosures,
|
12
|
+
:lobbying_activities, :excluded_from_transactions, :familiar_with_pla,
|
13
|
+
:space, :other_key_persons, :era_commons_name, :degrees
|
14
|
+
|
15
|
+
# Note that you must pass in both first and last names (or neither).
|
16
|
+
def initialize(browser, opts={})
|
17
|
+
@browser = browser
|
18
|
+
|
19
|
+
defaults = {
|
20
|
+
role: 'Principal Investigator',
|
21
|
+
units: [],
|
22
|
+
degrees: DegreesCollection.new,
|
23
|
+
certified: true, # Set this to false if you do not want any Proposal Person Certification Questions answered
|
24
|
+
certify_info_true: 'Y',
|
25
|
+
potential_for_conflict: 'Y',
|
26
|
+
submitted_financial_disclosures: 'Y',
|
27
|
+
lobbying_activities: 'Y',
|
28
|
+
excluded_from_transactions: 'Y',
|
29
|
+
familiar_with_pla: 'Y'
|
30
|
+
}
|
31
|
+
|
32
|
+
set_options(defaults.merge(opts))
|
33
|
+
requires :document_id
|
34
|
+
@full_name="#{@first_name} #{@last_name}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def create
|
38
|
+
navigate
|
39
|
+
on(KeyPersonnel).employee_search
|
40
|
+
if @last_name==nil
|
41
|
+
on PersonLookup do |look|
|
42
|
+
look.search
|
43
|
+
look.return_random
|
44
|
+
end
|
45
|
+
on KeyPersonnel do |person|
|
46
|
+
@full_name=person.person_name
|
47
|
+
@first_name=@full_name[/^\w+/]
|
48
|
+
@last_name=@full_name[/\w+$/]
|
49
|
+
end
|
50
|
+
else
|
51
|
+
on PersonLookup do |look|
|
52
|
+
look.last_name.set @last_name
|
53
|
+
look.search
|
54
|
+
look.return_value @full_name
|
55
|
+
end
|
56
|
+
end
|
57
|
+
on KeyPersonnel do |person|
|
58
|
+
# This conditional exists to deal with the fact that
|
59
|
+
# a Principal Investigator can also be called a "PI/Contact",
|
60
|
+
# in cases where it's an NIH proposal.
|
61
|
+
if person.proposal_role.include? @role
|
62
|
+
person.proposal_role.select @role
|
63
|
+
else
|
64
|
+
person.proposal_role.select_value role_value[@role]
|
65
|
+
@role = person.proposal_role.selected_options[0].text
|
66
|
+
end
|
67
|
+
person.key_person_role.fit @key_person_role
|
68
|
+
person.add_person
|
69
|
+
break unless person.add_person_errors.empty? # ..we've thrown an error, so no need to continue this method...
|
70
|
+
person.expand_all
|
71
|
+
@user_name=person.user_name @full_name
|
72
|
+
@home_unit=person.home_unit @full_name
|
73
|
+
if @units.empty? # No units in @units, so we're not setting units
|
74
|
+
# ...so, get the units from the UI:
|
75
|
+
@units=person.units @full_name if @key_person_role==nil
|
76
|
+
|
77
|
+
else # We have Units to add and update...
|
78
|
+
# Temporarily store any existing units...
|
79
|
+
person.add_unit_details(@full_name) unless @key_person_role==nil
|
80
|
+
|
81
|
+
units=person.units @full_name
|
82
|
+
# Note that this assumes we're adding
|
83
|
+
# Unit(s) that aren't already present
|
84
|
+
# in the list, so be careful!
|
85
|
+
@units.each do |unit|
|
86
|
+
person.unit_number(@full_name).set unit[:number]
|
87
|
+
person.add_unit @full_name
|
88
|
+
end
|
89
|
+
break if person.unit_details_errors_div(@full_name).present?
|
90
|
+
# Now add the previously existing units to
|
91
|
+
# @units
|
92
|
+
units.each { |unit| @units << unit }
|
93
|
+
end
|
94
|
+
|
95
|
+
# Now we groom the Unit Hashes, to include
|
96
|
+
# the Combined Credit Split numbers...
|
97
|
+
#
|
98
|
+
# NOTE: Commenting out this code until we
|
99
|
+
# determine either we need it or else we come up with
|
100
|
+
# a better way to do this...
|
101
|
+
#@units.each do |unit|
|
102
|
+
# [:space, :responsibility, :financial, :recognition].each do |item|
|
103
|
+
# unit[item] ||= unit.store(item, rand_num)
|
104
|
+
# # Then we update the UI with the values...
|
105
|
+
# person.send("unit_#{item.to_s}".to_sym, @full_name, unit[:number]).set unit[item]
|
106
|
+
# end
|
107
|
+
#end
|
108
|
+
|
109
|
+
# If it's a key person without units then they won't have credit splits,
|
110
|
+
# otherwise, the person will, so fill them out...
|
111
|
+
if @key_person_role==nil || !@units.empty?
|
112
|
+
person.space(@full_name).fit @space
|
113
|
+
person.responsibility(@full_name).fit @responsibility
|
114
|
+
person.financial(@full_name).fit @financial
|
115
|
+
person.recognition(@full_name).fit @recognition
|
116
|
+
end
|
117
|
+
|
118
|
+
# Proposal Person Certification
|
119
|
+
if @certified
|
120
|
+
person.include_certification_questions(@full_name) unless @key_person_role==nil
|
121
|
+
cert_questions.each { |q| person.send(q, full_name, get(q)) }
|
122
|
+
else
|
123
|
+
cert_questions.each { |q| set(q, nil) }
|
124
|
+
end
|
125
|
+
|
126
|
+
# Add gathering/setting of more attributes here as needed
|
127
|
+
person.era_commons_name(@full_name).fit @era_commons_name
|
128
|
+
person.save
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# IMPORTANT NOTE:
|
133
|
+
# Add edit options to this method as needed.
|
134
|
+
#
|
135
|
+
# HOWEVER:
|
136
|
+
# Do NOT add updating of Unit Credit Splits here.
|
137
|
+
# Those require special handling and
|
138
|
+
# thus have their own method: #update_unit_credit_splits
|
139
|
+
def edit opts={}
|
140
|
+
navigate
|
141
|
+
on KeyPersonnel do |update|
|
142
|
+
update.expand_all
|
143
|
+
# Note: This is a dangerous short cut, as it may not
|
144
|
+
# apply to every field that could be edited with this
|
145
|
+
# method...
|
146
|
+
opts.each do |field, value|
|
147
|
+
update.send(field, @full_name).fit value
|
148
|
+
end
|
149
|
+
update.save
|
150
|
+
end
|
151
|
+
update_options(opts)
|
152
|
+
end
|
153
|
+
|
154
|
+
# This method requires a parameter that is an Array
|
155
|
+
# of Hashes. Though it defaults to the person object's
|
156
|
+
# @units variable.
|
157
|
+
#
|
158
|
+
# Example:
|
159
|
+
# [{:number=>"UNIT NUMBER", :responsibility=>"33.33"}]
|
160
|
+
def update_unit_credit_splits(units=@units)
|
161
|
+
splits=[:responsibility, :financial, :recognition, :space]
|
162
|
+
units.each do |unit|
|
163
|
+
on KeyPersonnel do |update|
|
164
|
+
update.unit_space(@full_name, unit[:number]).fit unit[:space]
|
165
|
+
update.unit_responsibility(@full_name, unit[:number]).fit unit[:responsibility]
|
166
|
+
update.unit_financial(@full_name, unit[:number]).fit unit[:financial]
|
167
|
+
update.unit_recognition(@full_name, unit[:number]).fit unit[:recognition]
|
168
|
+
update.save
|
169
|
+
end
|
170
|
+
splits.each do |split|
|
171
|
+
unless unit[split]==nil
|
172
|
+
@units[@units.find_index{|u| u[:number]==unit[:number]}][split]=unit[split]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def add_degree_info opts={}
|
180
|
+
defaults = { document_id: @document_id,
|
181
|
+
person: @full_name }
|
182
|
+
degree = make DegreeObject, defaults.merge(opts)
|
183
|
+
degree.create
|
184
|
+
@degrees << degree
|
185
|
+
end
|
186
|
+
|
187
|
+
def delete
|
188
|
+
navigate
|
189
|
+
on KeyPersonnel do |person|
|
190
|
+
person.check_person @full_name
|
191
|
+
person.delete_selected
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def delete_units
|
196
|
+
@units.each do |unit|
|
197
|
+
on KeyPersonnel do |units|
|
198
|
+
units.delete_unit(@full_name, unit[:number])
|
199
|
+
end
|
200
|
+
end
|
201
|
+
@units=[]
|
202
|
+
end
|
203
|
+
|
204
|
+
# =======
|
205
|
+
private
|
206
|
+
# =======
|
207
|
+
|
208
|
+
# Nav Aids...
|
209
|
+
|
210
|
+
def navigate
|
211
|
+
open_document @doc_type
|
212
|
+
on(Proposal).key_personnel unless on_page?
|
213
|
+
end
|
214
|
+
|
215
|
+
def on_page?
|
216
|
+
# Note, the rescue clause should be
|
217
|
+
# removed when the Selenium bug with
|
218
|
+
# firefox elements gets fixed. This is
|
219
|
+
# still broken in selenium-webdriver 2.29
|
220
|
+
begin
|
221
|
+
on(KeyPersonnel).proposal_role.exist?
|
222
|
+
rescue
|
223
|
+
false
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def cert_questions
|
228
|
+
[:certify_info_true,
|
229
|
+
:potential_for_conflict,
|
230
|
+
:submitted_financial_disclosures,
|
231
|
+
:lobbying_activities,
|
232
|
+
:excluded_from_transactions,
|
233
|
+
:familiar_with_pla]
|
234
|
+
end
|
235
|
+
|
236
|
+
def role_value
|
237
|
+
{
|
238
|
+
'Principal Investigator' => 'PI',
|
239
|
+
'PI/Contact' => 'PI',
|
240
|
+
'Co-Investigator' => 'COI',
|
241
|
+
'Key Person' => 'KP'
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
245
|
+
end # KeyPersonObject
|
246
|
+
|
247
|
+
class KeyPersonnelCollection < Array
|
248
|
+
|
249
|
+
def names
|
250
|
+
self.collect { |person| person.full_name }
|
251
|
+
end
|
252
|
+
|
253
|
+
def roles
|
254
|
+
self.collect{ |person| person.role }.uniq
|
255
|
+
end
|
256
|
+
|
257
|
+
def unit_names
|
258
|
+
units.collect{ |unit| unit[:name] }.uniq
|
259
|
+
end
|
260
|
+
|
261
|
+
def unit_numbers
|
262
|
+
units.collect{ |unit| unit[:number] }.uniq
|
263
|
+
end
|
264
|
+
|
265
|
+
def units
|
266
|
+
self.collect{ |person| person.units }.flatten
|
267
|
+
end
|
268
|
+
|
269
|
+
def person(full_name)
|
270
|
+
self.find { |person| person.full_name==full_name }
|
271
|
+
end
|
272
|
+
|
273
|
+
# returns an array of KeyPersonObjects who have associated
|
274
|
+
# units
|
275
|
+
def with_units
|
276
|
+
self.find_all { |person| person.units.size > 0 }
|
277
|
+
end
|
278
|
+
|
279
|
+
def principal_investigator
|
280
|
+
self.find { |person| person.role=='Principal Investigator' || person.role=='PI/Contact' }
|
281
|
+
end
|
282
|
+
|
283
|
+
def co_investigator
|
284
|
+
self.find { |person| person.role=='Co-Investigator' }
|
285
|
+
end
|
286
|
+
|
287
|
+
def key_person(role)
|
288
|
+
self.find { |person| person.key_person_role==role }
|
289
|
+
end
|
290
|
+
|
291
|
+
# IMPORTANT: This method returns a KeyPersonObject--meaning that if there
|
292
|
+
# are multiple key persons in the collection that match this search only
|
293
|
+
# the first one will be returned. If you need a collection of multiple persons
|
294
|
+
# write the method for that.
|
295
|
+
def uncertified_person(role)
|
296
|
+
self.find { |person| person.certified==false && person.role==role }
|
297
|
+
end
|
298
|
+
|
299
|
+
end # KeyPersonnelCollection
|