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.
Files changed (161) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +16 -18
  3. data/chromedriver.log +46 -0
  4. data/features/grants_gov/grants_gov_forms/code_and_form_mapping.feature +26 -0
  5. data/features/grants_gov/grants_gov_forms/forms_validation.feature +1 -0
  6. data/features/grants_gov/grants_gov_forms/s2s_questionnaire.feature +19 -0
  7. data/features/grants_gov/s2s_submission.feature +30 -0
  8. data/features/grants_gov/s2s_validation.feature +36 -0
  9. data/features/proposal_development/create_budget_versions.feature +31 -0
  10. data/features/proposal_development/create_proposal.feature +25 -0
  11. data/features/proposal_development/key_personnel_validations.feature +41 -0
  12. data/features/proposal_development/proposal_actions_validations.feature +46 -0
  13. data/features/proposal_development/proposal_permissions.feature +73 -0
  14. data/features/proposal_development/proposal_workflow.feature +105 -0
  15. data/features/proposal_development/special_review_validations.feature +12 -0
  16. data/features/step_definitions/action_list.rb +12 -0
  17. data/features/step_definitions/awards/create_award.rb +3 -0
  18. data/features/step_definitions/grants_gov/forms.rb +34 -0
  19. data/features/step_definitions/grants_gov/s2s_submission.rb +51 -0
  20. data/features/step_definitions/institutional_proposals/create_institutional_proposal.rb +3 -0
  21. data/features/step_definitions/proposal_development/budget_versions.rb +102 -0
  22. data/features/step_definitions/proposal_development/create_proposal.rb +157 -0
  23. data/features/step_definitions/proposal_development/edit_proposal.rb +79 -0
  24. data/features/step_definitions/proposal_development/institute_rates.rb +21 -0
  25. data/features/step_definitions/proposal_development/key_personnel_validations.rb +74 -0
  26. data/features/step_definitions/proposal_development/proposal_actions_validations.rb +73 -0
  27. data/features/step_definitions/proposal_development/proposal_permissions.rb +141 -0
  28. data/features/step_definitions/proposal_development/proposal_workflow.rb +81 -0
  29. data/features/step_definitions/proposal_development/s2s_validation.rb +30 -0
  30. data/features/step_definitions/proposal_development/special_review_validations.rb +7 -0
  31. data/features/step_definitions/test.rb +3 -0
  32. data/features/step_definitions/users.rb +65 -0
  33. data/features/support/env.rb +35 -0
  34. data/features/test.feature +13 -0
  35. data/kuality-coeus.gemspec +1 -1
  36. data/lib/chromedriver.log +4483 -0
  37. data/lib/kuality-coeus.rb +5 -2
  38. data/lib/kuality-coeus/core_extensions.rb +10 -0
  39. data/lib/kuality-coeus/data_objects/award/award.rb +126 -0
  40. data/lib/kuality-coeus/data_objects/award/award_transaction.rb +57 -0
  41. data/lib/kuality-coeus/data_objects/budget/budget_periods.rb +114 -0
  42. data/lib/kuality-coeus/data_objects/budget/budget_versions.rb +221 -0
  43. data/lib/kuality-coeus/data_objects/budget/subaward_budget.rb +65 -0
  44. data/lib/kuality-coeus/data_objects/committee_document/committee_document.rb +65 -0
  45. data/lib/kuality-coeus/data_objects/committee_document/committee_members.rb +30 -0
  46. data/lib/kuality-coeus/data_objects/committee_document/committee_schedule.rb +27 -0
  47. data/lib/kuality-coeus/data_objects/committee_document/member_roles.rb +28 -0
  48. data/lib/kuality-coeus/data_objects/conflict_of_interest/financial_entity.rb +48 -0
  49. data/lib/kuality-coeus/data_objects/grants_gov/phs_fellowship_questionnaire.rb +90 -0
  50. data/lib/kuality-coeus/data_objects/grants_gov/phs_training_budget_questionnaire.rb +5 -0
  51. data/lib/kuality-coeus/data_objects/institutional_proposal/institutional_proposal.rb +20 -0
  52. data/lib/kuality-coeus/data_objects/institutional_proposal/intellectual_property_review.rb +62 -0
  53. data/lib/kuality-coeus/data_objects/navigation.rb +64 -0
  54. data/lib/kuality-coeus/data_objects/proposal_development/compliance_questions.rb +47 -0
  55. data/lib/kuality-coeus/data_objects/proposal_development/custom_data.rb +41 -0
  56. data/lib/kuality-coeus/data_objects/proposal_development/degrees.rb +40 -0
  57. data/lib/kuality-coeus/data_objects/proposal_development/key_personnel.rb +299 -0
  58. data/lib/kuality-coeus/data_objects/proposal_development/kuali_university_questions.rb +58 -0
  59. data/lib/kuality-coeus/data_objects/proposal_development/permissions.rb +107 -0
  60. data/lib/kuality-coeus/data_objects/proposal_development/personnel_attachments.rb +46 -0
  61. data/lib/kuality-coeus/data_objects/proposal_development/proposal_attachments.rb +41 -0
  62. data/lib/kuality-coeus/data_objects/proposal_development/proposal_development.rb +301 -0
  63. data/lib/kuality-coeus/data_objects/proposal_development/proposal_questions.rb +52 -0
  64. data/lib/kuality-coeus/data_objects/proposal_development/s2s_questionnaire.rb +129 -0
  65. data/lib/kuality-coeus/data_objects/proposal_development/special_review.rb +79 -0
  66. data/lib/kuality-coeus/data_objects/rates/institute_rate.rb +209 -0
  67. data/lib/kuality-coeus/data_objects/user.rb +303 -33
  68. data/lib/kuality-coeus/gem_extensions.rb +26 -0
  69. data/lib/kuality-coeus/page_objects/000_base_page.rb +196 -14
  70. data/lib/kuality-coeus/page_objects/action_list.rb +32 -0
  71. data/lib/kuality-coeus/page_objects/award/award.rb +25 -0
  72. data/lib/kuality-coeus/page_objects/award/award_actions.rb +7 -0
  73. data/lib/kuality-coeus/page_objects/award/award_budget_versions.rb +9 -0
  74. data/lib/kuality-coeus/page_objects/award/commitments.rb +27 -0
  75. data/lib/kuality-coeus/page_objects/award/contacts.rb +19 -0
  76. data/lib/kuality-coeus/page_objects/award/custom_data.rb +6 -0
  77. data/lib/kuality-coeus/page_objects/award/payment_reports_terms.rb +26 -0
  78. data/lib/kuality-coeus/page_objects/award/special_review.rb +7 -0
  79. data/lib/kuality-coeus/page_objects/award/time_and_money.rb +36 -0
  80. data/lib/kuality-coeus/page_objects/budget/budget_actions.rb +31 -0
  81. data/lib/kuality-coeus/page_objects/budget/budget_versions.rb +13 -0
  82. data/lib/kuality-coeus/page_objects/budget/modular_budget.rb +16 -0
  83. data/lib/kuality-coeus/page_objects/budget/non-personnel.rb +11 -0
  84. data/lib/kuality-coeus/page_objects/budget/parameters.rb +65 -0
  85. data/lib/kuality-coeus/page_objects/budget/personnel.rb +56 -0
  86. data/lib/kuality-coeus/page_objects/budget/rates.rb +7 -0
  87. data/lib/kuality-coeus/page_objects/budget/summary.rb +5 -0
  88. data/lib/kuality-coeus/page_objects/budget_document.rb +19 -0
  89. data/lib/kuality-coeus/page_objects/central_admin.rb +4 -2
  90. data/lib/kuality-coeus/page_objects/committee/committee.rb +10 -10
  91. data/lib/kuality-coeus/page_objects/committee/members.rb +4 -4
  92. data/lib/kuality-coeus/page_objects/committee_document.rb +1 -6
  93. data/lib/kuality-coeus/page_objects/confirmation.rb +16 -0
  94. data/lib/kuality-coeus/page_objects/disclosure/disclosure.rb +56 -0
  95. data/lib/kuality-coeus/page_objects/disclosure/disclosure_actions.rb +9 -0
  96. data/lib/kuality-coeus/page_objects/document_header.rb +5 -0
  97. data/lib/kuality-coeus/page_objects/financial_entities.rb +1 -4
  98. data/lib/kuality-coeus/page_objects/financial_entities/my_financial_entities.rb +6 -0
  99. data/lib/kuality-coeus/page_objects/financial_entities/new_financial_entity.rb +11 -0
  100. data/lib/kuality-coeus/page_objects/financial_entities/reporter.rb +5 -3
  101. data/lib/kuality-coeus/page_objects/identity/person.rb +57 -0
  102. data/lib/kuality-coeus/page_objects/institute_rates_maintenance.rb +18 -0
  103. data/lib/kuality-coeus/page_objects/institutional_proposal.rb +18 -0
  104. data/lib/kuality-coeus/page_objects/institutional_proposal/contacts.rb +32 -0
  105. data/lib/kuality-coeus/page_objects/institutional_proposal/custom_data.rb +6 -0
  106. data/lib/kuality-coeus/page_objects/institutional_proposal/distribution.rb +20 -0
  107. data/lib/kuality-coeus/page_objects/institutional_proposal/institutional_proposal.rb +27 -0
  108. data/lib/kuality-coeus/page_objects/institutional_proposal/institutional_proposal_actions.rb +7 -0
  109. data/lib/kuality-coeus/page_objects/institutional_proposal/intellectual_property_review.rb +20 -0
  110. data/lib/kuality-coeus/page_objects/institutional_proposal/special_review.rb +6 -0
  111. data/lib/kuality-coeus/page_objects/kc_awards.rb +48 -0
  112. data/lib/kuality-coeus/page_objects/kc_protocol.rb +15 -0
  113. data/lib/kuality-coeus/page_objects/login.rb +4 -5
  114. data/lib/kuality-coeus/page_objects/lookup_pages/000_lookups.rb +10 -0
  115. data/lib/kuality-coeus/page_objects/lookup_pages/action_list_filter.rb +6 -0
  116. data/lib/kuality-coeus/page_objects/lookup_pages/address_book_lookup.rb +4 -0
  117. data/lib/kuality-coeus/page_objects/lookup_pages/development_proposal_lookup.rb +3 -0
  118. data/lib/kuality-coeus/page_objects/lookup_pages/document_search.rb +10 -0
  119. data/lib/kuality-coeus/page_objects/lookup_pages/group_lookup.rb +3 -0
  120. data/lib/kuality-coeus/page_objects/lookup_pages/institute_rates_lookup.rb +12 -0
  121. data/lib/kuality-coeus/page_objects/lookup_pages/opportunity_lookup.rb +6 -0
  122. data/lib/kuality-coeus/page_objects/lookup_pages/organization_lookup.rb +5 -0
  123. data/lib/kuality-coeus/page_objects/lookup_pages/person_extended_attributes.rb +5 -0
  124. data/lib/kuality-coeus/page_objects/lookup_pages/person_lookup.rb +10 -0
  125. data/lib/kuality-coeus/page_objects/lookup_pages/role_lookup.rb +6 -0
  126. data/lib/kuality-coeus/page_objects/lookup_pages/sponsor_lookup.rb +9 -0
  127. data/lib/kuality-coeus/page_objects/lookup_pages/unit_admin_lookup.rb +3 -0
  128. data/lib/kuality-coeus/page_objects/lookup_pages/unit_lookup.rb +3 -0
  129. data/lib/kuality-coeus/page_objects/maintenance.rb +7 -0
  130. data/lib/kuality-coeus/page_objects/notification_editor.rb +6 -0
  131. data/lib/kuality-coeus/page_objects/proposal_development.rb +7 -2
  132. data/lib/kuality-coeus/page_objects/proposal_development/abstracts_and_attachments.rb +54 -0
  133. data/lib/kuality-coeus/page_objects/proposal_development/key_personnel.rb +126 -0
  134. data/lib/kuality-coeus/page_objects/proposal_development/pd_custom_data.rb +6 -0
  135. data/lib/kuality-coeus/page_objects/proposal_development/permissions.rb +44 -0
  136. data/lib/kuality-coeus/page_objects/proposal_development/phs_fellowship_questionnaire.rb +44 -0
  137. data/lib/kuality-coeus/page_objects/proposal_development/phs_training_budget_questionnaire.rb +50 -0
  138. data/lib/kuality-coeus/page_objects/proposal_development/proposal.rb +47 -8
  139. data/lib/kuality-coeus/page_objects/proposal_development/proposal_actions.rb +62 -0
  140. data/lib/kuality-coeus/page_objects/proposal_development/proposal_summary.rb +9 -0
  141. data/lib/kuality-coeus/page_objects/proposal_development/questions.rb +111 -0
  142. data/lib/kuality-coeus/page_objects/proposal_development/s2s.rb +35 -0
  143. data/lib/kuality-coeus/page_objects/proposal_development/special_review.rb +6 -0
  144. data/lib/kuality-coeus/page_objects/protocol/custom_data.rb +6 -0
  145. data/lib/kuality-coeus/page_objects/protocol/permissions.rb +5 -0
  146. data/lib/kuality-coeus/page_objects/protocol/personnel.rb +5 -0
  147. data/lib/kuality-coeus/page_objects/protocol/protocol.rb +11 -0
  148. data/lib/kuality-coeus/page_objects/protocol/questionnaire.rb +5 -0
  149. data/lib/kuality-coeus/page_objects/protocol/special_review.rb +6 -0
  150. data/lib/kuality-coeus/page_objects/rejection_confirmation.rb +5 -0
  151. data/lib/kuality-coeus/page_objects/researcher.rb +4 -2
  152. data/lib/kuality-coeus/page_objects/shared/unit_administrator.rb +13 -0
  153. data/lib/kuality-coeus/page_objects/system/person_extended_attributes.rb +18 -0
  154. data/lib/kuality-coeus/page_objects/system_admin.rb +7 -0
  155. data/lib/kuality-coeus/page_objects/unit.rb +2 -4
  156. data/lib/kuality-coeus/utilities.rb +39 -0
  157. data/libpeerconnection.log +0 -0
  158. metadata +140 -5
  159. data/lib/kuality-coeus/data_objects/committee_document.rb +0 -65
  160. data/lib/kuality-coeus/data_objects/proposal_development.rb +0 -53
  161. data/lib/kuality-coeus/navigation.rb +0 -3
@@ -0,0 +1,58 @@
1
+ class KualiUniversityQuestionsObject
2
+
3
+ include Foundry
4
+ include DataFactory
5
+ include Navigation
6
+
7
+ attr_accessor :document_id, :dual_dept_appointment, :dual_dept_review_date, :dual_dept_explanation,
8
+ :on_sabbatical, :sabbatical_review_date, :used_by_small_biz, :small_biz_review_date,
9
+ :understand_deadline, :deadline_review_date
10
+
11
+ def initialize(browser, opts={})
12
+ @browser = browser
13
+
14
+ # PLEASE NOTE:
15
+ # This is an unusual data object class in that
16
+ # it breaks the typical model for radio button
17
+ # methods and their associated class instance variables
18
+ #
19
+ # In general, it's not workable to set up radio button elements
20
+ # to use "Y" and "N" as the instance variables associated with them.
21
+ #
22
+ # These are set up in this way, however, because of how
23
+ # the HTML elements are being defined.
24
+ defaults = {
25
+ dual_dept_appointment: 'N',
26
+ on_sabbatical: 'N',
27
+ used_by_small_biz: 'N',
28
+ understand_deadline: 'Y'
29
+ }
30
+
31
+ set_options(defaults.merge(opts))
32
+ requires :document_id
33
+ end
34
+
35
+ def create
36
+ navigate
37
+ on Questions do |kuali|
38
+ kuali.show_kuali_university
39
+ fill_out kuali, :dual_dept_appointment, :dual_dept_review_date,
40
+ :dual_dept_explanation, :on_sabbatical, :sabbatical_review_date,
41
+ :used_by_small_biz, :small_biz_review_date, :understand_deadline,
42
+ :deadline_review_date
43
+ kuali.save
44
+ end
45
+ end
46
+
47
+ # =======
48
+ private
49
+ # =======
50
+
51
+ # Nav Aids...
52
+
53
+ def navigate
54
+ open_document @doc_type
55
+ on(Proposal).questions unless on_page?(on(Questions).questions_header)
56
+ end
57
+
58
+ end
@@ -0,0 +1,107 @@
1
+ class PermissionsObject
2
+
3
+ include Foundry
4
+ include DataFactory
5
+ include Navigation
6
+
7
+ attr_accessor :document_id, :aggregators, :budget_creators, :narrative_writers,
8
+ :viewers, :approvers, :delete_proposals
9
+
10
+ def initialize(browser, opts={})
11
+ @browser = browser
12
+
13
+ defaults = {
14
+ budget_creators: [], # Arrays should contain usernames
15
+ narrative_writers: [],
16
+ viewers: [],
17
+ delete_proposals: [],
18
+ approvers: []
19
+ }
20
+
21
+ set_options(defaults.merge(opts))
22
+ requires :document_id, :aggregators
23
+ end
24
+
25
+ # It's important to realize that this method assigns
26
+ # users to roles, but does not check who is already
27
+ # assigned. You need to make sure that the values
28
+ # used in the instantiation of the class are
29
+ # an accurate reflection of what exists in the site.
30
+ def assign
31
+ navigate
32
+ on Permissions do |add|
33
+ # See the roles method defined below...
34
+ roles.each do |inst_var, role|
35
+ get(inst_var).each do |username|
36
+ unless add.user_row(username).present? && add.assigned_role(username).include?(role)
37
+ add.user_name.set username
38
+ add.role.select role
39
+ add.add
40
+ add.user_row(username).wait_until_present
41
+ end
42
+ end
43
+ end
44
+ add.save
45
+ # TODO: Add some logic here to use in case the user is already added to the list (so use add_roles)
46
+ end
47
+ end
48
+
49
+ # This method is used when the user is already assigned a
50
+ # role and you need to assign them more roles.
51
+ def add_roles(username, *roles)
52
+ # get to the right page...
53
+ navigate
54
+ on Permissions do |page|
55
+ # click the edit role button for the right user...
56
+ page.edit_role username
57
+ # This opens a new window, so we have to use it...
58
+ page.windows.last.use
59
+ end
60
+ on Roles do |page|
61
+ roles.each do |role|
62
+ # Set the appropriate role checkbox...
63
+ page.send(snakify(role)).set
64
+ # Add the username to the correct role
65
+ # instance variable...
66
+ get(roles.invert[role]) << username
67
+ end
68
+ page.save
69
+ # Now we're done with the child window so we close it...
70
+ page.close
71
+ # Attach to the main window again...
72
+ page.windows.first.use
73
+ end
74
+ end
75
+
76
+ def delete username
77
+ navigate
78
+ on(Permissions).delete username
79
+ roles.each do |role|
80
+ get(role).delete_if { |name| name==username }
81
+ end
82
+ end
83
+
84
+ # =======
85
+ private
86
+ # =======
87
+
88
+ # Nav Aids...
89
+
90
+ def navigate
91
+ open_document @doc_type
92
+ on(Proposal).permissions unless on_page?(on(Permissions).user_name)
93
+ end
94
+
95
+ # Add/Remove roles here, as needed...
96
+ def roles
97
+ {
98
+ :@aggregators=>'Aggregator',
99
+ :@viewers=>'Viewer',
100
+ :@budget_creators=>'Budget Creator',
101
+ :@narrative_writers=>'Narrative Writer',
102
+ :@approvers=>'approver',
103
+ :@delete_proposals=>'Delete Proposal'
104
+ }
105
+ end
106
+
107
+ end
@@ -0,0 +1,46 @@
1
+ class PersonnelAttachmentObject
2
+
3
+ include Foundry
4
+ include DataFactory
5
+ include StringFactory
6
+ include Navigation
7
+
8
+ attr_accessor :person, :type, :file_name, :description, :document_id, :doc_type
9
+
10
+ def initialize(browser, opts={})
11
+ @browser = browser
12
+ defaults = {
13
+ person: '::random::',
14
+ type: '::random::',
15
+ description: random_alphanums(30)
16
+ }
17
+ set_options defaults.merge(opts)
18
+ requires :document_id, :file_name
19
+ end
20
+
21
+ def add
22
+ navigate
23
+ on AbstractsAndAttachments do |attach|
24
+ attach.expand_all
25
+ fill_out attach, :person
26
+ attach.personnel_attachment_description.fit @description
27
+ attach.personnel_attachment_type.fit @type
28
+ attach.personnel_attachment_file_name.set($file_folder+@file_name)
29
+ attach.add_personnel_attachment
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def navigate
36
+ open_document @doc_type
37
+ on(Proposal).abstracts_and_attachments unless on_page?(on(AbstractsAndAttachments).proposal_attachment_type)
38
+ end
39
+
40
+ end
41
+
42
+ class PersonnelAttachmentsCollection < Array
43
+
44
+
45
+
46
+ end
@@ -0,0 +1,41 @@
1
+ class ProposalAttachmentObject
2
+
3
+ include Foundry
4
+ include DataFactory
5
+ include Navigation
6
+
7
+ attr_accessor :type, :file_name, :status, :description, :document_id, :doc_type
8
+
9
+ def initialize(browser, opts={})
10
+ @browser = browser
11
+ set_options opts
12
+ requires :document_id, :type, :file_name
13
+ end
14
+
15
+ def add
16
+ navigate
17
+ on AbstractsAndAttachments do |attach|
18
+ attach.expand_all
19
+ attach.proposal_attachment_type.select @type
20
+ attach.proposal_attachment_description.fit @description
21
+ attach.proposal_attachment_file_name.set($file_folder+@file_name)
22
+ attach.attachment_status.fit @status
23
+ attach.add_proposal_attachment
24
+ raise "Unexpected attachment error" if attach.errors.size > 0
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def navigate
31
+ open_document @doc_type
32
+ on(Proposal).abstracts_and_attachments unless on_page?(on(AbstractsAndAttachments).proposal_attachment_type)
33
+ end
34
+
35
+ end
36
+
37
+ class ProposalAttachmentsCollection < Array
38
+
39
+
40
+
41
+ end
@@ -0,0 +1,301 @@
1
+ class ProposalDevelopmentObject
2
+
3
+ include Foundry
4
+ include DataFactory
5
+ include StringFactory
6
+ include DateFactory
7
+ include Navigation
8
+
9
+ attr_accessor :proposal_type, :lead_unit, :activity_type, :project_title, :proposal_number,
10
+ :sponsor_code, :sponsor_type_code, :project_start_date, :project_end_date, :document_id,
11
+ :status, :initiator, :created, :sponsor_deadline_date, :key_personnel,
12
+ :opportunity_id, # Maybe add competition_id and other stuff here...
13
+ :special_review, :budget_versions, :permissions, :s2s_questionnaire, :proposal_attachments,
14
+ :proposal_questions, :compliance_questions, :kuali_u_questions, :custom_data, :recall_reason,
15
+ :personnel_attachments, :mail_by, :mail_type
16
+
17
+ def initialize(browser, opts={})
18
+ @browser = browser
19
+
20
+ defaults = {
21
+ proposal_type: 'New',
22
+ lead_unit: '::random::',
23
+ activity_type: '::random::',
24
+ project_title: random_alphanums,
25
+ sponsor_code: '::random::',
26
+ sponsor_type_code: '::random::',
27
+ project_start_date: next_week[:date_w_slashes], # TODO: Think about using the date object here, and not the string
28
+ project_end_date: next_year[:date_w_slashes],
29
+ sponsor_deadline_date: next_week[:date_w_slashes],
30
+ mail_by: '::random::',
31
+ mail_type: '::random::',
32
+ key_personnel: KeyPersonnelCollection.new,
33
+ special_review: SpecialReviewCollection.new,
34
+ budget_versions: BudgetVersionsCollection.new,
35
+ personnel_attachments: PersonnelAttachmentsCollection.new,
36
+ proposal_attachments: ProposalAttachmentsCollection.new
37
+ }
38
+
39
+ set_options(defaults.merge(opts))
40
+ end
41
+
42
+ def create
43
+ on BasePage do |page|
44
+ if page.windows.size > 1 && page.portal_window.exists?
45
+ page.return_to_portal
46
+ page.close_children
47
+ elsif page.windows.size > 1
48
+ page.use_new_tab
49
+ page.close_parents
50
+ end
51
+ end
52
+ visit(Researcher).create_proposal
53
+ on Proposal do |doc|
54
+ @doc_header=doc.doc_title
55
+ @document_id=doc.document_id
56
+ @status=doc.document_status
57
+ @initiator=doc.initiator
58
+ @created=doc.created
59
+ doc.expand_all
60
+ fill_out doc, :proposal_type, :activity_type,
61
+ :project_title, :project_start_date, :project_end_date,
62
+ :sponsor_deadline_date, :mail_by, :mail_type#, :description
63
+ set_sponsor_code
64
+ set_lead_unit
65
+ doc.save
66
+ @proposal_number=doc.proposal_number
67
+ @permissions = make PermissionsObject, document_id: @document_id, aggregators: [@initiator]
68
+ end
69
+ end
70
+
71
+ def edit opts={}
72
+ open_proposal
73
+ on Proposal do |edit|
74
+ edit.proposal
75
+ edit.expand_all
76
+ edit.project_start_date.fit opts[:project_start_date]
77
+ edit.opportunity_id.fit opts[:opportunity_id]
78
+ edit.proposal_type.fit opts[:proposal_type]
79
+ # TODO: Add more stuff here as necessary
80
+ edit.save
81
+ end
82
+ update_options(opts)
83
+ end
84
+
85
+ def add_key_person opts={}
86
+ @key_personnel << prep(KeyPersonObject, opts)
87
+ end
88
+ # This alias is recommended only for when
89
+ # using this method with no options.
90
+ alias_method :add_principal_investigator, :add_key_person
91
+
92
+
93
+ # This method simply sets all the credit splits to
94
+ # equal values based on how many persons and units
95
+ # are attached to the Proposal. If more complicated
96
+ # credit splits are needed, these will have to be
97
+ # coded in the step def, accessing the key person
98
+ # objects directly.
99
+ def set_valid_credit_splits
100
+ # calculate a "person" split value that will work
101
+ # based on the number of people attached...
102
+ split = (100.0/@key_personnel.with_units.size).round(2)
103
+
104
+ # Now make a hash to use for editing the person's splits...
105
+ splits = {responsibility: split, financial: split, recognition: split, space: split}
106
+
107
+ # Now we update the KeyPersonObjects' instance variables
108
+ # for their own splits as well as for their units
109
+ @key_personnel.with_units.each do |person|
110
+ person.edit splits
111
+ units_split = (100.0/person.units.size).round(2)
112
+ # Make a temp container for the units we're updating...
113
+ units = []
114
+ person.units.each { |unit| units << {:number=>unit[:number]} }
115
+ # Iterate through the units, updating their credit splits with the
116
+ # valid split amount...
117
+ units.each do |unit|
118
+ [:responsibility, :financial, :recognition, :space].each { |item| unit[item]=units_split }
119
+ end
120
+ person.update_unit_credit_splits units
121
+ end
122
+ end
123
+
124
+ def add_special_review opts={}
125
+ @special_review << prep(SpecialReviewObject, opts)
126
+ end
127
+
128
+ def add_budget_version opts={}
129
+ opts[:version] ||= (@budget_versions.size+1).to_s
130
+ @budget_versions << prep(BudgetVersionsObject, opts)
131
+ end
132
+
133
+ def add_custom_data opts={}
134
+ @custom_data = prep(CustomDataObject, opts)
135
+ end
136
+
137
+ def add_proposal_attachment opts={}
138
+ merge_settings(opts)
139
+ p_a = make ProposalAttachmentObject, opts
140
+ p_a.add
141
+ @proposal_attachments << p_a
142
+ end
143
+
144
+ def add_personnel_attachment opts={}
145
+ merge_settings(opts)
146
+ p_a = make PersonnelAttachmentObject, opts
147
+ p_a.add
148
+ @personnel_attachments << p_a
149
+ end
150
+
151
+ def complete_s2s_questionnaire opts={}
152
+ @s2s_questionnaire = prep(S2SQuestionnaireObject, opts)
153
+ end
154
+
155
+ def complete_phs_fellowship_questionnaire opts={}
156
+ @phs_fellowship_questionnaire = prep(PHSFellowshipQuestionnaireObject, opts)
157
+ end
158
+
159
+ def complete_phs_training_questionnaire opts={}
160
+ @phs_training_questionnaire = prep(PHSTrainingQuestionnaireObject, opts)
161
+ end
162
+
163
+ def make_institutional_proposal
164
+ # TODO: Write any preparatory web site functional steps and page scraping code
165
+ ip = make InstitutionalProposalObject, dev_proposal_number: @proposal_number,
166
+ proposal_type: @proposal_type,
167
+ activity_type: @activity_type,
168
+ project_title: @project_title,
169
+ project_personnel: Marshal::load(Marshal.dump(@key_personnel)),
170
+ special_review: Marshal::load(Marshal.dump(@special_review)),
171
+ custom_data: Marshal::load(Marshal.dump(@custom_data))
172
+ # TODO: Add more here as needed...
173
+ end
174
+
175
+ def delete
176
+ proposal_actions
177
+ on(ProposalActions).delete_proposal
178
+ on(Confirmation).yes
179
+ # Have to update the data object's status value
180
+ # in a valid way (getting it from the system)
181
+ visit DocumentSearch do |search|
182
+ search.document_id.set @document_id
183
+ search.search
184
+ @status=search.doc_status @document_id
185
+ end
186
+ end
187
+
188
+ def recall(type, reason=random_alphanums)
189
+ types={:revision=>:recall_to_action_list, :cancel=>:recall_and_cancel}
190
+ @recall_reason=reason
191
+ open_proposal
192
+ on(Proposal).recall
193
+ on Confirmation do |conf|
194
+ conf.reason.set @recall_reason
195
+ conf.send(types[type])
196
+ end
197
+ end
198
+
199
+ def close
200
+ open_proposal
201
+ on(Proposal).close
202
+ end
203
+
204
+ def view(tab)
205
+ open_proposal
206
+ unless @status=='CANCELED' || on(Proposal).send((tab.to_s+'_button').to_sym).parent.class_name=~/tabcurrent$/
207
+ on(Proposal).send(tab)
208
+ end
209
+ end
210
+
211
+ def submit(type=:s)
212
+ types={:s=>:submit, :ba=>:blanket_approve,
213
+ :to_sponsor=>:submit_to_sponsor, :to_s2s=>:submit_to_s2s}
214
+ proposal_actions
215
+ on(ProposalActions).send(types[type])
216
+ if type==:to_sponsor
217
+ on NotificationEditor do |page|
218
+ # A breaking of the design pattern, here,
219
+ # but we have no alternative...
220
+ @status=page.document_status
221
+ page.send_fyi
222
+ end
223
+ elsif type == :to_s2s
224
+ on S2S do |page|
225
+ @status=page.document_status
226
+ end
227
+ else
228
+ on ProposalActions do |page|
229
+ page.data_validation_header.wait_until_present
230
+ @status=page.document_status
231
+ end
232
+ end
233
+ end
234
+
235
+ # Note: This method does not navigate because
236
+ # the assumption is that the only time you need
237
+ # to save the proposal is when you are on the
238
+ # proposal. You will never need to open the
239
+ # proposal and then immediately save it.
240
+ def save
241
+ on(Proposal).save
242
+ end
243
+
244
+ def open_proposal
245
+ open_document @doc_header
246
+ end
247
+
248
+ def blanket_approve
249
+ submit :ba
250
+ end
251
+
252
+ # =======
253
+ private
254
+ # =======
255
+
256
+ def merge_settings(opts)
257
+ defaults = {
258
+ document_id: @document_id,
259
+ doc_type: @doc_header
260
+ }
261
+ opts.merge!(defaults)
262
+ end
263
+
264
+ def set_sponsor_code
265
+ if @sponsor_code=='::random::'
266
+ on(Proposal).find_sponsor_code
267
+ on SponsorLookup do |look|
268
+ look.sponsor_type_code.pick! @sponsor_type_code
269
+ look.search
270
+ look.page_links[rand(look.page_links.length)].click if look.page_links.size > 0
271
+ look.return_random
272
+ end
273
+ @sponsor_code=on(Proposal).sponsor_code.value
274
+ else
275
+ on(Proposal).sponsor_code.fit @sponsor_code
276
+ end
277
+ end
278
+
279
+ def set_lead_unit
280
+ on(Proposal)do |prop|
281
+ if prop.lead_unit.present?
282
+ prop.lead_unit.pick! @lead_unit
283
+ else
284
+ @lead_unit=prop.lead_unit_ro
285
+ end
286
+ end
287
+ end
288
+
289
+ def proposal_actions
290
+ open_proposal
291
+ on(Proposal).proposal_actions
292
+ end
293
+
294
+ def prep(object_class, opts)
295
+ merge_settings(opts)
296
+ object = make object_class, opts
297
+ object.create
298
+ object
299
+ end
300
+
301
+ end