caruby-tissue 1.5.6 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (255) hide show
  1. data/Gemfile +17 -0
  2. data/History.md +5 -1
  3. data/README.md +2 -2
  4. data/bin/crtdump +2 -8
  5. data/bin/crtexample +2 -5
  6. data/bin/crtmigrate +3 -6
  7. data/bin/crtsmoke +3 -8
  8. data/conf/wustl/{log4j.properties → linux/log4j.properties} +3 -3
  9. data/conf/wustl/windows/log4j.properties +40 -0
  10. data/examples/galena/Gemfile +16 -0
  11. data/examples/galena/Gemfile.lock +88 -0
  12. data/examples/galena/README.md +16 -16
  13. data/examples/galena/Rakefile +30 -0
  14. data/examples/galena/bin/seed +5 -11
  15. data/examples/galena/conf/annotation/defaults.yaml +2 -0
  16. data/examples/galena/conf/{migration/annotation_fields.yaml → annotation/fields.yaml} +2 -4
  17. data/examples/galena/conf/defaults.yaml +9 -0
  18. data/examples/galena/conf/{migration/filter_fields.yaml → filter/fields.yaml} +0 -1
  19. data/examples/galena/conf/filter/values.yaml +8 -0
  20. data/examples/galena/conf/{migration/frozen_defaults.yaml → frozen/defaults.yaml} +0 -0
  21. data/examples/galena/conf/{migration/frozen_fields.yaml → frozen/fields.yaml} +0 -2
  22. data/examples/galena/conf/{migration/general_fields.yaml → general/fields.yaml} +0 -24
  23. data/examples/galena/conf/registration/fields.yaml +6 -0
  24. data/examples/galena/conf/{migration/simple_fields.yaml → simple/fields.yaml} +1 -6
  25. data/examples/galena/data/annotation.csv +1 -1
  26. data/examples/galena/data/filter.csv +1 -1
  27. data/examples/galena/data/frozen.csv +1 -1
  28. data/examples/galena/data/general.csv +1 -1
  29. data/examples/galena/data/registration.csv +1 -1
  30. data/examples/galena/data/simple.csv +1 -1
  31. data/examples/galena/galena.gemspec +24 -0
  32. data/examples/galena/lib/galena/filter.rb +25 -0
  33. data/examples/galena/lib/galena/{tissue/migration/frozen_shims.rb → frozen.rb} +6 -10
  34. data/examples/galena/lib/galena/seed.rb +126 -0
  35. data/examples/galena/lib/galena/version.rb +3 -0
  36. data/examples/galena/lib/galena.rb +18 -7
  37. data/examples/galena/log/galena.log +37351 -0
  38. data/examples/galena/log/galena.log.0 +147830 -0
  39. data/examples/galena/spec/annotation_spec.rb +46 -0
  40. data/examples/galena/spec/filter_spec.rb +94 -0
  41. data/examples/galena/spec/frozen_spec.rb +39 -0
  42. data/examples/galena/spec/general_spec.rb +62 -0
  43. data/examples/galena/spec/registration_spec.rb +37 -0
  44. data/examples/galena/spec/seed.rb +107 -0
  45. data/examples/galena/spec/simple_spec.rb +58 -0
  46. data/examples/galena/spec/spec_helper.rb +11 -0
  47. data/examples/galena/spec/support/migration.rb +70 -0
  48. data/lib/catissue/annotation/annotatable.rb +10 -8
  49. data/lib/catissue/annotation/annotation.rb +7 -7
  50. data/lib/catissue/annotation/de_integration.rb +9 -20
  51. data/lib/catissue/annotation/importer.rb +148 -0
  52. data/lib/catissue/annotation/introspector.rb +32 -0
  53. data/lib/catissue/annotation/metadata.rb +422 -0
  54. data/lib/catissue/annotation/proxy.rb +2 -2
  55. data/lib/catissue/annotation/proxy_class.rb +45 -30
  56. data/lib/catissue/annotation/record_entry_proxy.rb +2 -2
  57. data/lib/catissue/cli/command.rb +14 -24
  58. data/lib/catissue/cli/example.rb +5 -3
  59. data/lib/catissue/cli/migrate.rb +45 -37
  60. data/lib/catissue/cli/smoke.rb +2 -3
  61. data/lib/catissue/database/annotation/annotation_service.rb +8 -17
  62. data/lib/catissue/database/annotation/entity_facade.rb +33 -30
  63. data/lib/catissue/database/annotation/id_generator.rb +1 -1
  64. data/lib/catissue/database/annotation/integration_service.rb +11 -4
  65. data/lib/catissue/database/annotation/reference_writer.rb +38 -38
  66. data/lib/catissue/database/controlled_value_finder.rb +13 -28
  67. data/lib/catissue/database/controlled_values.rb +73 -45
  68. data/lib/catissue/database.rb +637 -277
  69. data/lib/catissue/domain/abstract_domain_object.rb +5 -0
  70. data/lib/catissue/domain/abstract_position.rb +3 -5
  71. data/lib/catissue/domain/abstract_specimen.rb +79 -65
  72. data/lib/catissue/domain/abstract_specimen_collection_group.rb +3 -6
  73. data/lib/catissue/domain/address.rb +0 -2
  74. data/lib/catissue/domain/cancer_research_group.rb +0 -3
  75. data/lib/catissue/domain/capacity.rb +2 -4
  76. data/lib/catissue/domain/check_in_check_out_event_parameter.rb +0 -3
  77. data/lib/catissue/domain/collection_event_parameters.rb +2 -7
  78. data/lib/catissue/domain/collection_protocol.rb +11 -16
  79. data/lib/catissue/domain/collection_protocol_event.rb +19 -12
  80. data/lib/catissue/domain/collection_protocol_registration.rb +8 -12
  81. data/lib/catissue/domain/consent_tier_response.rb +0 -4
  82. data/lib/catissue/domain/consent_tier_status.rb +1 -4
  83. data/lib/catissue/domain/container.rb +10 -10
  84. data/lib/catissue/domain/container_position.rb +4 -7
  85. data/lib/catissue/domain/container_type.rb +4 -7
  86. data/lib/catissue/domain/department.rb +0 -3
  87. data/lib/catissue/domain/disposal_event_parameters.rb +5 -5
  88. data/lib/catissue/domain/embedded_event_parameters.rb +1 -4
  89. data/lib/catissue/domain/external_identifier.rb +0 -12
  90. data/lib/catissue/domain/frozen_event_parameters.rb +1 -4
  91. data/lib/catissue/domain/institution.rb +0 -3
  92. data/lib/catissue/domain/new_specimen_array_order_item.rb +0 -5
  93. data/lib/catissue/domain/order_details.rb +0 -2
  94. data/lib/catissue/domain/participant/clinical/chemotherapy.rb +1 -3
  95. data/lib/catissue/domain/participant/clinical/duration.rb +2 -4
  96. data/lib/catissue/domain/participant/clinical/radiation_therapy.rb +2 -4
  97. data/lib/catissue/domain/participant.rb +22 -24
  98. data/lib/catissue/domain/participant_medical_identifier.rb +0 -4
  99. data/lib/catissue/domain/password.rb +0 -4
  100. data/lib/catissue/domain/race.rb +0 -3
  101. data/lib/catissue/domain/received_event_parameters.rb +3 -6
  102. data/lib/catissue/domain/site.rb +1 -4
  103. data/lib/catissue/domain/specimen/pathology/additional_finding.rb +12 -0
  104. data/lib/catissue/domain/specimen/pathology/details.rb +12 -0
  105. data/lib/catissue/domain/specimen/pathology/gleason_score.rb +12 -0
  106. data/lib/catissue/domain/specimen/pathology/histologic_grade.rb +12 -0
  107. data/lib/catissue/domain/specimen/pathology/histologic_type.rb +19 -0
  108. data/lib/catissue/domain/specimen/pathology/histologic_variant_type.rb +12 -0
  109. data/lib/catissue/domain/specimen/pathology/invasion.rb +12 -0
  110. data/lib/catissue/domain/specimen/pathology/prostate_specimen_gleason_score.rb +5 -11
  111. data/lib/catissue/domain/specimen/pathology/prostate_specimen_pathology_annotation.rb +12 -12
  112. data/lib/catissue/domain/specimen/pathology/specimen_additional_finding.rb +5 -14
  113. data/lib/catissue/domain/specimen/pathology/specimen_base_solid_tissue_pathology_annotation.rb +6 -21
  114. data/lib/catissue/domain/specimen/pathology/specimen_details.rb +4 -10
  115. data/lib/catissue/domain/specimen/pathology/specimen_histologic_grade.rb +4 -10
  116. data/lib/catissue/domain/specimen/pathology/specimen_histologic_type.rb +6 -14
  117. data/lib/catissue/domain/specimen/pathology/specimen_histologic_variant_type.rb +5 -11
  118. data/lib/catissue/domain/specimen/pathology/specimen_invasion.rb +5 -11
  119. data/lib/catissue/domain/specimen.rb +113 -76
  120. data/lib/catissue/domain/specimen_array.rb +0 -3
  121. data/lib/catissue/domain/specimen_array_content.rb +1 -4
  122. data/lib/catissue/domain/specimen_array_type.rb +1 -4
  123. data/lib/catissue/domain/specimen_characteristics.rb +0 -3
  124. data/lib/catissue/domain/specimen_collection_group/pathology/base_pathology_annotation.rb +2 -4
  125. data/lib/catissue/domain/specimen_collection_group/pathology/base_solid_tissue_pathology_annotation.rb +2 -4
  126. data/lib/catissue/domain/specimen_collection_group.rb +43 -53
  127. data/lib/catissue/domain/specimen_event_parameters.rb +24 -32
  128. data/lib/catissue/domain/specimen_position.rb +8 -5
  129. data/lib/catissue/domain/specimen_protocol.rb +3 -6
  130. data/lib/catissue/domain/specimen_requirement.rb +22 -20
  131. data/lib/catissue/domain/storage_container.rb +9 -12
  132. data/lib/catissue/domain/storage_type.rb +6 -10
  133. data/lib/catissue/domain/transfer_event_parameters.rb +3 -6
  134. data/lib/catissue/domain/user.rb +22 -29
  135. data/lib/catissue/{util → helpers}/collectible.rb +23 -18
  136. data/lib/catissue/helpers/collectible_event_parameters.rb +68 -0
  137. data/lib/catissue/helpers/controlled_value.rb +35 -0
  138. data/lib/catissue/{domain → helpers}/hash_code.rb +0 -0
  139. data/lib/catissue/{util → helpers}/location.rb +6 -5
  140. data/lib/catissue/helpers/log.rb +4 -0
  141. data/lib/catissue/{util → helpers}/person.rb +1 -1
  142. data/lib/catissue/{util → helpers}/position.rb +10 -8
  143. data/lib/catissue/helpers/properties_loader.rb +143 -0
  144. data/lib/catissue/{util → helpers}/storable.rb +2 -1
  145. data/lib/catissue/{util → helpers}/storage_type_holder.rb +9 -3
  146. data/lib/catissue/{annotation/annotatable_class.rb → metadata.rb} +73 -95
  147. data/lib/catissue/migration/migratable.rb +93 -44
  148. data/lib/catissue/migration/migrator.rb +26 -42
  149. data/lib/catissue/migration/shims.rb +1 -1
  150. data/lib/catissue/migration/unique.rb +76 -0
  151. data/lib/catissue/resource.rb +16 -20
  152. data/lib/catissue/version.rb +1 -1
  153. data/lib/catissue/wustl/logger.rb +52 -32
  154. data/lib/catissue.rb +38 -20
  155. data/test/lib/catissue/database/controlled_values_test.rb +22 -27
  156. data/test/lib/catissue/database/database_test.rb +18 -0
  157. data/test/lib/catissue/domain/address_test.rb +9 -11
  158. data/test/lib/catissue/domain/ca_tissue_test_defaults_test.rb +5 -16
  159. data/test/lib/catissue/domain/capacity_test.rb +2 -2
  160. data/test/lib/catissue/domain/collection_event_parameters_test.rb +16 -8
  161. data/test/lib/catissue/domain/collection_protocol_event_test.rb +1 -1
  162. data/test/lib/catissue/domain/collection_protocol_registration_test.rb +26 -16
  163. data/test/lib/catissue/domain/collection_protocol_test.rb +2 -2
  164. data/test/lib/catissue/domain/container_position_test.rb +7 -4
  165. data/test/lib/catissue/domain/department_test.rb +3 -3
  166. data/test/lib/catissue/domain/disposal_event_parameters_test.rb +1 -1
  167. data/test/lib/catissue/domain/external_identifier_test.rb +5 -1
  168. data/test/lib/catissue/domain/location_test.rb +4 -4
  169. data/test/lib/catissue/domain/participant_medical_identifier_test.rb +3 -3
  170. data/test/lib/catissue/domain/participant_test.rb +33 -20
  171. data/test/lib/catissue/domain/received_event_parameters_test.rb +19 -0
  172. data/test/lib/catissue/domain/site_test.rb +2 -2
  173. data/test/lib/catissue/domain/specimen_array_test.rb +3 -3
  174. data/test/lib/catissue/domain/specimen_array_type_test.rb +6 -6
  175. data/test/lib/catissue/domain/specimen_characteristics_test.rb +1 -1
  176. data/test/lib/catissue/domain/specimen_collection_group_test.rb +49 -13
  177. data/test/lib/catissue/domain/specimen_event_parameters_test.rb +4 -4
  178. data/test/lib/catissue/domain/specimen_position_test.rb +1 -1
  179. data/test/lib/catissue/domain/specimen_requirement_test.rb +2 -2
  180. data/test/lib/catissue/domain/specimen_test.rb +58 -24
  181. data/test/lib/catissue/domain/storage_container_test.rb +3 -16
  182. data/test/lib/catissue/domain/storage_type_test.rb +3 -3
  183. data/test/lib/catissue/domain/transfer_event_parameters_test.rb +17 -17
  184. data/test/lib/catissue/domain/user_test.rb +32 -34
  185. data/test/lib/catissue/helpers/properties_loader_test.rb +19 -0
  186. data/test/lib/catissue/migration/{test_case.rb → helpers/test_case.rb} +30 -20
  187. data/test/lib/examples/galena/tissue/domain/examples_test.rb +28 -38
  188. data/test/lib/examples/galena/tissue/helpers/test_case.rb +24 -0
  189. metadata +175 -99
  190. data/bin/crtextract +0 -47
  191. data/examples/galena/conf/extract/simple_fields.yaml +0 -4
  192. data/examples/galena/conf/migration/annotation_defaults.yaml +0 -2
  193. data/examples/galena/conf/migration/filter_defaults.yaml +0 -1
  194. data/examples/galena/conf/migration/filter_values.yaml +0 -13
  195. data/examples/galena/conf/migration/participant_fields.yaml +0 -4
  196. data/examples/galena/conf/migration/registration_fields.yaml +0 -5
  197. data/examples/galena/data/participant.csv +0 -1
  198. data/examples/galena/lib/galena/tissue/migration/filter_shims.rb +0 -41
  199. data/examples/galena/lib/galena/tissue/seed/defaults.rb +0 -127
  200. data/examples/psbin/README.md +0 -45
  201. data/examples/psbin/conf/adjuvant_hormone_defaults.yaml +0 -2
  202. data/examples/psbin/conf/adjuvant_radiation_defaults.yaml +0 -3
  203. data/examples/psbin/conf/biopsy_defaults.yaml +0 -3
  204. data/examples/psbin/conf/biopsy_fields.yaml +0 -9
  205. data/examples/psbin/conf/neoadjuvant_hormone_defaults.yaml +0 -2
  206. data/examples/psbin/conf/neoadjuvant_radiation_defaults.yaml +0 -3
  207. data/examples/psbin/conf/patient_defaults.yaml +0 -3
  208. data/examples/psbin/conf/patient_fields.yaml +0 -5
  209. data/examples/psbin/conf/surgery_defaults.yaml +0 -4
  210. data/examples/psbin/conf/surgery_fields.yaml +0 -15
  211. data/examples/psbin/conf/t_stage_defaults.yaml +0 -1
  212. data/examples/psbin/conf/t_stage_fields.yaml +0 -4
  213. data/examples/psbin/conf/therapy_fields.yaml +0 -5
  214. data/examples/psbin/data/adjuvant_hormone.csv +0 -1
  215. data/examples/psbin/data/adjuvant_radiation.csv +0 -1
  216. data/examples/psbin/data/biopsy.csv +0 -1
  217. data/examples/psbin/data/neoadjuvant_hormone.csv +0 -1
  218. data/examples/psbin/data/neoadjuvant_radiation.csv +0 -1
  219. data/examples/psbin/data/patient.csv +0 -1
  220. data/examples/psbin/data/surgery.csv +0 -1
  221. data/examples/psbin/data/t_stage.csv +0 -1
  222. data/examples/psbin/lib/psbin/biopsy_shims.rb +0 -15
  223. data/examples/psbin/lib/psbin/surgery_shims.rb +0 -15
  224. data/lib/catissue/annotation/annotation_class.rb +0 -406
  225. data/lib/catissue/annotation/annotation_module.rb +0 -106
  226. data/lib/catissue/domain.rb +0 -26
  227. data/lib/catissue/extract/command.rb +0 -31
  228. data/lib/catissue/extract/delta.rb +0 -58
  229. data/lib/catissue/extract/extractor.rb +0 -99
  230. data/lib/catissue/migration/uniquify.rb +0 -2
  231. data/lib/catissue/util/collectible_event_parameters.rb +0 -71
  232. data/lib/catissue/util/controlled_value.rb +0 -29
  233. data/lib/catissue/util/uniquify.rb +0 -86
  234. data/test/fixtures/catissue/domain/conf/catissue_override.yaml +0 -9
  235. data/test/fixtures/catissue/extract/conf/scg_extract.yaml +0 -3
  236. data/test/fixtures/catissue/extract/conf/scg_fields.yaml +0 -3
  237. data/test/fixtures/catissue/extract/conf/spc_extract.yaml +0 -3
  238. data/test/fixtures/catissue/extract/conf/spc_fields.yaml +0 -4
  239. data/test/fixtures/lib/catissue/defaults_test_fixture.rb +0 -206
  240. data/test/fixtures/lib/examples/galena/migration/alt_key_shims.rb +0 -7
  241. data/test/lib/catissue/domain/base_haemotology_pathology_test.rb +0 -24
  242. data/test/lib/catissue/extract/delta_test.rb +0 -25
  243. data/test/lib/catissue/extract/extractor_test.rb +0 -43
  244. data/test/lib/catissue/import/importable_module_test.rb +0 -14
  245. data/test/lib/catissue/test_case.rb +0 -247
  246. data/test/lib/examples/galena/tissue/migration/annotation_test.rb +0 -29
  247. data/test/lib/examples/galena/tissue/migration/filter_test.rb +0 -29
  248. data/test/lib/examples/galena/tissue/migration/frozen_test.rb +0 -36
  249. data/test/lib/examples/galena/tissue/migration/general_test.rb +0 -56
  250. data/test/lib/examples/galena/tissue/migration/participant_test.rb +0 -61
  251. data/test/lib/examples/galena/tissue/migration/registration_test.rb +0 -17
  252. data/test/lib/examples/galena/tissue/migration/seedify.rb +0 -119
  253. data/test/lib/examples/galena/tissue/migration/simple_test.rb +0 -30
  254. data/test/lib/examples/galena/tissue/migration/test_case.rb +0 -72
  255. data/test/lib/examples/psbin/migration_test.rb +0 -153
@@ -1,10 +1,6 @@
1
1
 
2
2
 
3
3
  module CaTissue
4
- # import the Java class
5
- resource_import Java::edu.wustl.catissuecore.domain.ParticipantMedicalIdentifier
6
-
7
-
8
4
  # The ParticipantMedicalIdentifier domain class.
9
5
  class ParticipantMedicalIdentifier
10
6
  # Sets this ParticipantMedicalIdentifier's medical record number to the given value.
@@ -1,9 +1,5 @@
1
1
  module CaTissue
2
- # import the Java class
3
- resource_import Java::edu.wustl.catissuecore.domain.Password
4
-
5
2
  class Password
6
3
  qualify_attribute(:update_date, :unsaved)
7
-
8
4
  end
9
5
  end
@@ -1,7 +1,4 @@
1
1
  module CaTissue
2
- # import the Java class
3
- resource_import Java::edu.wustl.catissuecore.domain.Race
4
-
5
2
  class Race
6
3
  add_attribute_aliases(:name => :race_name)
7
4
 
@@ -1,10 +1,7 @@
1
- require 'catissue/util/collectible_event_parameters'
1
+ require 'catissue/helpers/collectible_event_parameters'
2
2
 
3
3
  module CaTissue
4
- # import the Java class
5
- resource_import Java::edu.wustl.catissuecore.domain.ReceivedEventParameters
6
-
7
- class ReceivedEventParameters < CaTissue::SpecimenEventParameters
4
+ class ReceivedEventParameters
8
5
  include CollectibleEventParameters
9
6
 
10
7
  add_attribute_aliases(:receiver => :user)
@@ -14,7 +11,7 @@ module CaTissue
14
11
  add_mandatory_attributes(:received_quality)
15
12
 
16
13
  # An auto-generated REP must fetch the user.
17
- qualify_attribute(:user, :saved_fetch)
14
+ qualify_attribute(:user, :fetch_saved)
18
15
 
19
16
  private
20
17
 
@@ -1,7 +1,4 @@
1
1
  module CaTissue
2
- # import the Java class
3
- resource_import Java::edu.wustl.catissuecore.domain.Site
4
-
5
2
  # The Site domain class.
6
3
  class Site
7
4
  # @quirk caTissue the Site SCG collection is ignored, since it is not fetched with the Site,
@@ -12,7 +9,7 @@ module CaTissue
12
9
 
13
10
  # @quirk caTissue caTissue 1.2 Site has a facility_id Java property, but caTissue throws an
14
11
  # UnsupportedOperationException if they are called.
15
- if attribute_defined?(:facility_id) then remove_attribute(:facility_id) end
12
+ if property_defined?(:facility_id) then remove_attribute(:facility_id) end
16
13
 
17
14
  set_secondary_key_attributes(:name)
18
15
 
@@ -0,0 +1,12 @@
1
+ module CaTissue
2
+ class Specimen
3
+ # @quirk caTissue The 1.1.2 class AdditionalFinding is renamed to SpecimenAdditionalFinding in 1.2.
4
+ # Alias the AdditionalFinding Ruby class constant to SpecimenAdditionalFinding for forward compatibility.
5
+ module Pathology
6
+ class AdditionalFinding
7
+ Pathology.const_set(:SpecimenAdditionalFinding, self)
8
+ logger.debug { "Aliased the caTissue 1.1.2 Specimen pathology annotation class AdditionalFinding class to the renamed 1.2 SpecimenAdditionalFinding." }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module CaTissue
2
+ class Specimen
3
+ module Pathology
4
+ # @quirk caTissue The 1.1 class Details is renamed to SpecimenDetails in 1.2.
5
+ # Alias the Details Ruby class to SpecimenDetails for forward compatibility.
6
+ class Details
7
+ Pathology.const_set(:SpecimenDetails, self)
8
+ logger.debug { "Aliased the Specimen pathology annotation class Details to SpecimenDetails." }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module CaTissue
2
+ class Specimen
3
+ module Pathology
4
+ # @quirk caTissue The 1.1 class GleasonScore is renamed to ProstateSpecimenGleasonScore in 1.2.
5
+ # Alias the GleasonScore Ruby class constant to ProstateSpecimenGleasonScore forward compatibility.
6
+ class GleasonScore
7
+ Pathology.const_set(:ProstateSpecimenGleasonScore, self)
8
+ logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class GleasonScore class to the renamed 1.2 ProstateSpecimenGleasonScore." }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module CaTissue
2
+ class Specimen
3
+ module Pathology
4
+ # @quirk caTissue The 1.1.2 class HistologicGrade is renamed to SpecimenHistologicGrade in 1.2.
5
+ # Alias the HistologicGrade Ruby class to SpecimenHistologicGrade for forward compatibility.
6
+ class HistologicGrade
7
+ Pathology.const_set(:SpecimenHistologicGrade, self)
8
+ logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class HistologicGrade class to the renamed 1.2 SpecimenHistologicGrade." }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ module CaTissue
2
+ class Specimen
3
+ module Pathology
4
+ # @quirk caTissue The 1.1.2 class HistologicType is renamed to SpecimenHistologicType in 1.2.
5
+ # Alias the HistologicType Ruby class to SpecimenHistologicType for forward compatibility.
6
+ class HistologicType
7
+ Pathology.const_set(:SpecimenHistologicType, self)
8
+ logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class HistologicType class to the renamed 1.2 SpecimenHistologicType." }
9
+
10
+ # @quirk caTissue The HistologicType => HistologicVariantType collection
11
+ # property is misnamed as histologicVariantType rather than histologicVariantTypeCollection.
12
+ # This misnaming prevents caRuby from inferring the attribute domain type and inverse.
13
+ # Work-around is to set these attribute features manually.
14
+ set_attribute_type(:histologic_variant_type, CaTissue::Specimen::Pathology::HistologicVariantType)
15
+ set_attribute_inverse(:histologic_variant_type, :histologic_type)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ module CaTissue
2
+ class Specimen
3
+ module Pathology
4
+ # @quirk caTissue The 1.1.2 class HistologicVariantType is renamed to SpecimenHistologicVariantType in 1.2.
5
+ # Alias the HistologicVariantType Ruby class to SpecimenHistologicVariantType for forward compatibility.
6
+ class HistologicVariantType
7
+ Pathology.const_set(:SpecimenHistologicVariantType, self)
8
+ logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class HistologicVariantType class to the renamed 1.2 SpecimenHistologicVariantType." }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module CaTissue
2
+ class Specimen
3
+ module Pathology
4
+ # @quirk caTissue The 1.1.2 class Invasion is renamed to SpecimenInvasion in 1.2.
5
+ # Alias the Invasion Ruby class to SpecimenInvasion for forward compatibility.
6
+ class Invasion
7
+ Pathology.const_set(:SpecimenInvasion, self)
8
+ logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class Invasion class to the renamed 1.2 SpecimenInvasion." }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,17 +1,11 @@
1
1
  module CaTissue
2
2
  class Specimen
3
- class Pathology
4
- # @quirk caTissue The 1.1 class GleasonScore is renamed to ProstateSpecimenGleasonScore in 1.2.
5
- # Alias the Ruby class constant for forward and backaward compatibility.
6
- begin
7
- resource_import Java::pathology_specimen.ProstateSpecimenGleasonScore
8
- const_set(:GleasonScore, ProstateSpecimenGleasonScore)
3
+ module Pathology
4
+ # @quirk caTissue The 1.1.2 class GleasonScore is renamed to ProstateSpecimenGleasonScore in 1.2.
5
+ # Alias the ProstateSpecimenGleasonScore Ruby class to GleasonScore for backward compatibility.
6
+ class ProstateSpecimenGleasonScore
7
+ Pathology.const_set(:GleasonScore, self)
9
8
  logger.debug { "Aliased the Specimen pathology annotation class ProstateSpecimenGleasonScore to GleasonScore." }
10
- rescue NameError
11
- logger.debug { "SpecimenGleasonScore pathology annotation class not found; attempting to import the caTissue 1.1 GleasonScore variant..." }
12
- resource_import Java::pathology_specimen.GleasonScore
13
- const_set(:ProstateSpecimenGleasonScore, GleasonScore)
14
- logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class GleasonScore class to the renamed 1.2 ProstateSpecimenGleasonScore." }
15
9
  end
16
10
  end
17
11
  end
@@ -1,18 +1,18 @@
1
1
  module CaTissue
2
2
  class Specimen
3
- class Pathology
4
- begin
5
- resource_import Java::pathology_specimen.ProstateSpecimenPathologyAnnotation
6
- const_set(:ProstatePathologyAnnotation, ProstateSpecimenPathologyAnnotation)
3
+ module Pathology
4
+ class ProstateSpecimenPathologyAnnotation
5
+ # @quirk caTissue the 'Specimen' in the ProstateSpecimenPathologyAnnotation class name is redundant
6
+ # and inconsisent. Alias to ProstatePathologyAnnotation.
7
+ Pathology.const_set(:ProstatePathologyAnnotation, self)
7
8
  logger.debug { "Aliased the Specimen pathology annotation class ProstateSpecimenPathologyAnnotation to ProstatePathologyAnnotation." }
8
- class ProstateSpecimenPathologyAnnotation
9
- # @quirk caTissue the Specimen prostate annotation 1.1 method gleasonScore is renamed to
10
- # prostateSpecimenGleasonScore in 1.2. Alias the JRuby wrapper method for backward compatibility.
11
- if attribute_defined?(:prostate_specimen_gleason_score) then
12
- add_attribute_aliases(:gleason_score => :prostate_specimen_gleason_score)
13
- else
14
- add_attribute_aliases(:prostate_specimen_gleason_score => :gleason_score)
15
- end
9
+
10
+ # @quirk caTissue the Specimen prostate annotation 1.1.2 method gleasonScore is renamed to
11
+ # prostateSpecimenGleasonScore in 1.2. Alias the JRuby wrapper method for backward compatibility.
12
+ if property_defined?(:prostate_specimen_gleason_score) then
13
+ add_attribute_aliases(:gleason_score => :prostate_specimen_gleason_score)
14
+ else
15
+ add_attribute_aliases(:prostate_specimen_gleason_score => :gleason_score)
16
16
  end
17
17
  end
18
18
  end
@@ -1,20 +1,11 @@
1
1
  module CaTissue
2
2
  class Specimen
3
- # @quirk caTissue The 1.1 class AdditionalFinding is renamed to SpecimenAdditionalFinding in 1.2.
4
- # Alias the Ruby class constant for forward and backaward compatibility.
5
- #
6
- # @quirk caTissue the Specimen additional finding annotation 1.1 method 'details' is renamed to
7
- # 'specimenDetails' in 1.2.
8
- class Pathology
9
- begin
10
- resource_import Java::pathology_specimen.SpecimenAdditionalFinding
11
- const_set(:AdditionalFinding, SpecimenAdditionalFinding)
3
+ # @quirk caTissue The 1.1.2 class AdditionalFinding is renamed to SpecimenAdditionalFinding in 1.2.
4
+ # Alias the SpecimenAdditionalFinding Ruby class to AdditionalFinding for backward compatibility.
5
+ module Pathology
6
+ class SpecimenAdditionalFinding
7
+ Pathology.const_set(:AdditionalFinding, self)
12
8
  logger.debug { "Aliased the Specimen pathology annotation class SpecimenAdditionalFinding to AdditionalFinding." }
13
- rescue NameError
14
- logger.debug { "SpecimenAdditionalFinding pathology annotation class not found; attempting to import the caTissue 1.1 AdditionalFinding variant..." }
15
- resource_import Java::pathology_specimen.AdditionalFinding
16
- const_set(:SpecimenAdditionalFinding, AdditionalFinding)
17
- logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class AdditionalFinding class to the renamed 1.2 SpecimenAdditionalFinding." }
18
9
  end
19
10
  end
20
11
  end
@@ -1,36 +1,21 @@
1
- require File.join(File.dirname(__FILE__), 'specimen_histologic_grade')
2
- require File.join(File.dirname(__FILE__), 'specimen_histologic_type')
3
-
4
1
  module CaTissue
5
2
  class Specimen
6
- class Pathology
7
- # @quirk caTissue The 1.1 specimen pathology annotation class BaseSolidTissuePathologyAnnotation
8
- # is renamed to SpecimenBaseSolidTissuePathologyAnnotation in 1.2.
9
- # Alias the Ruby class constant for forward and backaward compatibility.
10
- begin
11
- resource_import Java::pathology_specimen.SpecimenBaseSolidTissuePathologyAnnotation
12
- const_set(:BaseSolidTissuePathologyAnnotation, SpecimenBaseSolidTissuePathologyAnnotation)
13
- logger.debug { "Aliased the Specimen pathology annotation class SpecimenBaseSolidTissuePathologyAnnotation to BaseSolidTissuePathologyAnnotation." }
14
- rescue NameError
15
- logger.debug { "SpecimenBaseSolidTissuePathologyAnnotation pathology annotation class not found; attempting to import the caTissue 1.1 BaseSolidTissuePathologyAnnotation variant..." }
16
- resource_import Java::pathology_specimen.BaseSolidTissuePathologyAnnotation
17
- const_set(:SpecimenBaseSolidTissuePathologyAnnotation, BaseSolidTissuePathologyAnnotation)
18
- logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class BaseSolidTissuePathologyAnnotation class to the renamed 1.2 SpecimenBaseSolidTissuePathologyAnnotation." }
19
- end
20
-
3
+ module Pathology
21
4
  class SpecimenBaseSolidTissuePathologyAnnotation
22
5
  # @quirk caTissue The SpecimenBaseSolidTissuePathologyAnnotation => SpecimenHistologicGrade collection
23
6
  # property is misnamed as histologicGrade rather than histologicGradeCollection. This misnaming
24
7
  # prevents caRuby from inferring the attribute domain type and inverse. Work-around is to set
25
8
  # these attribute features manually.
26
- set_attribute_type(:histologic_grade, CaTissue::Specimen::Pathology::SpecimenHistologicGrade)
9
+ klass = Pathology::SpecimenHistologicGrade rescue Pathology::HistologicGrade
10
+ set_attribute_type(:histologic_grade, klass)
27
11
  set_attribute_inverse(:histologic_grade, :specimen_base_solid_tissue_pathology_annotation)
28
-
12
+
29
13
  # @quirk caTissue The SpecimenBaseSolidTissuePathologyAnnotation => SpecimenHistologicType collection
30
14
  # property is misnamed as histologicType rather than histologicTypeCollection. This misnaming
31
15
  # prevents caRuby from inferring the attribute domain type and inverse. Work-around is to set
32
16
  # these attribute features manually.
33
- set_attribute_type(:histologic_type, CaTissue::Specimen::Pathology::SpecimenHistologicType)
17
+ klass = Pathology::SpecimenHistologicType rescue Pathology::HistologicType
18
+ set_attribute_type(:histologic_type, klass)
34
19
  set_attribute_inverse(:histologic_type, :specimen_base_solid_tissue_pathology_annotation)
35
20
  end
36
21
  end
@@ -1,17 +1,11 @@
1
1
  module CaTissue
2
2
  class Specimen
3
- class Pathology
3
+ module Pathology
4
4
  # @quirk caTissue The 1.1 class Details is renamed to SpecimenDetails in 1.2.
5
- # Alias the Ruby class constant for forward and backaward compatibility.
6
- begin
7
- resource_import Java::pathology_specimen.SpecimenDetails
8
- const_set(:Details, SpecimenDetails)
5
+ # Alias the SpecimenDetails Ruby class to Details for backward compatibility.
6
+ class SpecimenDetails
7
+ Pathology.const_set(:Details, self)
9
8
  logger.debug { "Aliased the Specimen pathology annotation class SpecimenDetails to Details." }
10
- rescue NameError
11
- logger.debug { "SpecimenDetails pathology annotation class not found; attempting to import the caTissue 1.1 Details variant..." }
12
- resource_import Java::pathology_specimen.Details
13
- const_set(:SpecimenDetails, Details)
14
- logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class Details class to the renamed 1.2 SpecimenDetails." }
15
9
  end
16
10
  end
17
11
  end
@@ -1,17 +1,11 @@
1
1
  module CaTissue
2
2
  class Specimen
3
- class Pathology
3
+ module Pathology
4
4
  # @quirk caTissue The 1.1 class HistologicGrade is renamed to SpecimenHistologicGrade in 1.2.
5
- # Alias the Ruby class constant for forward and backaward compatibility.
6
- begin
7
- resource_import Java::pathology_specimen.SpecimenHistologicGrade
8
- const_set(:HistologicGrade, SpecimenHistologicGrade)
5
+ # Alias the SpecimenHistologicGrade Ruby class constant to HistologicGrade backward compatibility.
6
+ class SpecimenHistologicGrade
7
+ Pathology.const_set(:HistologicGrade, self)
9
8
  logger.debug { "Aliased the Specimen pathology annotation class SpecimenHistologicGrade to HistologicGrade." }
10
- rescue NameError
11
- logger.debug { "SpecimenHistologicGrade pathology annotation class not found; attempting to import the caTissue 1.1 HistologicGrade variant..." }
12
- resource_import Java::pathology_specimen.HistologicGrade
13
- const_set(:SpecimenHistologicGrade, HistologicGrade)
14
- logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class HistologicGrade class to the renamed 1.2 SpecimenHistologicGrade." }
15
9
  end
16
10
  end
17
11
  end
@@ -2,21 +2,13 @@ require File.join(File.dirname(__FILE__), 'specimen_histologic_variant_type')
2
2
 
3
3
  module CaTissue
4
4
  class Specimen
5
- class Pathology
6
- # @quirk caTissue The 1.1 class HistologicType is renamed to SpecimenHistologicType in 1.2.
7
- # Alias the Ruby class constant for forward and backaward compatibility.
8
- begin
9
- resource_import Java::pathology_specimen.SpecimenHistologicType
10
- const_set(:HistologicType, SpecimenHistologicType)
11
- logger.debug { "Aliased the Specimen pathology annotation class SpecimenHistologicType to HistologicType." }
12
- rescue NameError
13
- logger.debug { "SpecimenHistologicType pathology annotation class not found; attempting to import the caTissue 1.1 HistologicType variant..." }
14
- resource_import Java::pathology_specimen.HistologicType
15
- const_set(:SpecimenHistologicType, HistologicType)
16
- logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class HistologicType class to the renamed 1.2 SpecimenHistologicType." }
17
- end
18
-
5
+ module Pathology
6
+ # @quirk caTissue The 1.1.2 class HistologicType is renamed to SpecimenHistologicType in 1.2.
7
+ # Alias the SpecimenHistologicType Ruby class to HistologicType for backward compatibility.
19
8
  class SpecimenHistologicType
9
+ Pathology.const_set(:HistologicType, self)
10
+ logger.debug { "Aliased the Specimen pathology annotation class SpecimenHistologicType to HistologicType." }
11
+
20
12
  # @quirk caTissue The SpecimenHistologicType => SpecimenHistologicVariantType collection
21
13
  # property is misnamed as histologicVariantType rather than histologicVariantTypeCollection.
22
14
  # This misnaming prevents caRuby from inferring the attribute domain type and inverse.
@@ -1,17 +1,11 @@
1
1
  module CaTissue
2
2
  class Specimen
3
- class Pathology
4
- # @quirk caTissue The 1.1 class HistologicVariantType is renamed to SpecimenHistologicVariantType in 1.2.
5
- # Alias the Ruby class constant for forward and backaward compatibility.
6
- begin
7
- resource_import Java::pathology_specimen.SpecimenHistologicVariantType
8
- const_set(:HistologicVariantType, SpecimenHistologicVariantType)
3
+ module Pathology
4
+ # @quirk caTissue The 1.1.2 class HistologicVariantType is renamed to SpecimenHistologicVariantType in 1.2.
5
+ # Alias the SpecimenHistologicVariantType Ruby class to HistologicVariantType for backward compatibility.
6
+ class SpecimenHistologicVariantType
7
+ Pathology.const_set(:HistologicVariantType, self)
9
8
  logger.debug { "Aliased the Specimen pathology annotation class SpecimenHistologicVariantType to HistologicVariantType." }
10
- rescue NameError
11
- logger.debug { "SpecimenHistologicVariantType pathology annotation class not found; attempting to import the caTissue 1.1 HistologicVariantType variant..." }
12
- resource_import Java::pathology_specimen.HistologicVariantType
13
- const_set(:SpecimenHistologicVariantType, HistologicVariantType)
14
- logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class HistologicVariantType class to the renamed 1.2 SpecimenHistologicVariantType." }
15
9
  end
16
10
  end
17
11
  end
@@ -1,17 +1,11 @@
1
1
  module CaTissue
2
2
  class Specimen
3
- class Pathology
4
- # @quirk caTissue The 1.1 class Invasion is renamed to SpecimenInvasion in 1.2.
5
- # Alias the Ruby class constant for forward and backaward compatibility.
6
- begin
7
- resource_import Java::pathology_specimen.SpecimenInvasion
8
- const_set(:Invasion, SpecimenInvasion)
3
+ module Pathology
4
+ # @quirk caTissue The 1.1.2 class Invasion is renamed to SpecimenInvasion in 1.2.
5
+ # Alias the SpecimenInvasion Ruby class constant to Invasion for backward compatibility.
6
+ class SpecimenInvasion
7
+ Pathology.const_set(:Invasion, self)
9
8
  logger.debug { "Aliased the Specimen pathology annotation class SpecimenInvasion to Invasion." }
10
- rescue NameError
11
- logger.debug { "SpecimenInvasion pathology annotation class not found; attempting to import the caTissue 1.1 Invasion variant..." }
12
- resource_import Java::pathology_specimen.Invasion
13
- const_set(:SpecimenInvasion, Invasion)
14
- logger.debug { "Aliased the caTissue 1.1 Specimen pathology annotation class Invasion class to the renamed 1.2 SpecimenInvasion." }
15
9
  end
16
10
  end
17
11
  end
@@ -1,16 +1,14 @@
1
- require 'caruby/util/inflector'
2
- require 'caruby/util/uniquifier'
3
- require 'caruby/util/validation'
4
- require 'catissue/util/storable'
5
- require 'catissue/util/collectible'
1
+ require 'jinx/helpers/hashable'
2
+ require 'jinx/helpers/inflector'
3
+ require 'jinx/helpers/uniquifier'
4
+ require 'jinx/helpers/validation'
5
+ require 'catissue/helpers/storable'
6
+ require 'catissue/helpers/collectible'
6
7
 
7
8
  module CaTissue
8
- # import the Java class
9
- resource_import Java::edu.wustl.catissuecore.domain.Specimen
10
-
11
9
  # The Specimen domain class.
12
- class Specimen < CaTissue::AbstractSpecimen
13
- include Storable, Collectible
10
+ class Specimen
11
+ include Collectible, Storable
14
12
 
15
13
  # @quirk caTissue Bug #64: Some domain collection properties not initialized.
16
14
  # Initialize consent_tier_statuses if necessary.
@@ -33,9 +31,8 @@ module CaTissue
33
31
  add_mandatory_attributes(:initial_quantity, :available_quantity)
34
32
 
35
33
  set_secondary_key_attributes(:label)
36
-
37
- # The Specimen-SpecimenRequirement association is bi-directional.
38
- set_attribute_inverse(:specimen_requirement, :specimens)
34
+
35
+ set_alternate_key_attributes(:barcode)
39
36
 
40
37
  # Specimen children are constrained to Specimen.
41
38
  set_attribute_type(:child_specimens, Specimen)
@@ -72,17 +69,21 @@ module CaTissue
72
69
  # TransferEventParameters proxy instead. SpecimenPosition work-around is to
73
70
  # designate a save proxy.
74
71
  add_dependent_attribute(:specimen_position)
72
+
73
+ # @quirk caTissue Even though the Specimen SCG is not fetched and cannot be changed,
74
+ # Specimen update requires that the Specimen reference an SCG.
75
+ qualify_attribute(:specimen_collection_group, :include_in_save_template)
75
76
 
76
- # Although label is the key, it is auto-generated if not provided in the create.
77
+ # Although label is the secondary key, it is auto-generated if not provided in the create.
77
78
  qualify_attribute(:label, :optional)
79
+
80
+ # Although barcode is the alternate key, it is auto-generated if not provided in the create.
81
+ qualify_attribute(:barcode, :optional)
78
82
 
79
- # A default available flag is set on the server.
80
- qualify_attribute(:is_available, :volatile)
81
-
82
- # A default available quantity is set on the server.
83
- qualify_attribute(:available_quantity, :volatile)
83
+ # The Specimen-SpecimenRequirement association is bi-directional.
84
+ set_attribute_inverse(:specimen_requirement, :specimens)
84
85
 
85
- # A default created_on is set on the server.
86
+ # @quirk caTissue The Specimen save argument created_on flag is ignored and set by caTissue instead.
86
87
  qualify_attribute(:created_on, :volatile)
87
88
 
88
89
  # Oddly, the seldom-used biohazards are fetched along with Specimen.
@@ -92,26 +93,43 @@ module CaTissue
92
93
  # or create Specimen argument and is set on the server. Mark the attribute as unsaved.
93
94
  qualify_attribute(:parent_changed, :unsaved)
94
95
 
95
- # @quirk caTissue Bug #159: Update pending Specimen ignores availableQuantity.
96
- # available_quantity is not reflected in the caCORE create or update result.
97
- # This is true even though the caTissue GUI supports available_quantity update.
98
- # Work-around is to set the :autogenerated flag, which will refetch a saved Specimen
99
- # if there is a change to the available_quantity value and will reupdate the Specimen
100
- # if the fetched available_quantity differs from the save argument value.
101
- qualify_attribute(:available_quantity, :autogenerated)
96
+ # @quirk caTissue Bug #159: caTissue update of a pending Specimen ignores the available
97
+ # quantity in the update argument. The available quantity is not accurately reflected
98
+ # in the caCORE create or update result. This is true even though the caTissue GUI
99
+ # supports available_ uantity update. The caRuby work-around is to set the
100
+ # +:autogenerated+ flag, which will refetch a saved Specimen if there is a change
101
+ # to the available quantity value and will reupdate the Specimen if the fetched
102
+ # available quantity differs from the save argument value.
103
+ #
104
+ # @quirk caTissue caTissue sporadically updates the available quantity when the
105
+ # initial quantity is changed as follows:
106
+ #
107
+ # * Precondition: Available Quantity is less than the Initial Quantity
108
+ # Action: User sets Available Quantity to the Initial Quantity
109
+ # Result: Available Quantity is unchanged
110
+ #
111
+ # * Action: User increases Initial Quantity
112
+ # Result: Available Quantity is incremented by the same amount
113
+ #
114
+ # * Action: User decreases Initial Quantity
115
+ # Result: Available Quantity is unchanged
116
+ #
117
+ # The caRuby work-around is to mark available quantity as +volatile+, implying that
118
+ # all bets are off as to how a saved available quantity is reflected in the database.
119
+ qualify_attribute(:available_quantity, :autogenerated, :volatile)
102
120
 
103
121
  # @quirk caTissue An auto-generated Specimen auto-generates the collection and received events.
104
122
  # Therefore, CPR create must match the complete auto-generated SCG-Specimen-Event hierarchy.
105
123
  # However, SpecimenRequirement events are not auto-generated. Therefore, the AbstractSpecimen
106
124
  # events behavior must be specialized for Specimen but not SpecimenRequirement.
107
- qualify_attribute(:specimen_events, :autogenerated)
108
-
109
- # The Specimen proxy class.
110
- self.annotation_proxy_class_name = 'SpecimenRecordEntry'
125
+ qualify_attribute(:specimen_event_parameters, :autogenerated, :fetch_saved)
111
126
 
112
127
  # The Specimen pathology annotation.
113
128
  add_annotation('Pathology', :package => 'pathology_specimen', :service => 'pathologySpecimen')
114
129
 
130
+ # The preferred owner attribute evaluation order is the parent specimen, then the SCG.
131
+ order_owner_attributes(:parent_specimen, :specimen_collection_group)
132
+
115
133
  # Specimen storage is constrained on the basis of the +specimen_class+.
116
134
  alias :storable_type :specimen_class
117
135
 
@@ -120,11 +138,6 @@ module CaTissue
120
138
  # work around caTissue Bug #64
121
139
  self.consent_tier_statuses ||= Java::JavaUtil::LinkedHashSet.new
122
140
  end
123
-
124
- # Overrides {Resource#owner} to return the parent_specimen, if it exists, or the specimen_collection_group otherwise.
125
- def owner
126
- parent_specimen or specimen_collection_group
127
- end
128
141
 
129
142
  # @return [Boolean] whether this Specimen collection status is +Pending+
130
143
  def pending?
@@ -136,7 +149,7 @@ module CaTissue
136
149
  collection_status == 'Collected'
137
150
  end
138
151
 
139
- # Relaxes the {CaRuby::Persistable#fetch_saved?} condition for a Specimen as follows:
152
+ # Relaxes the +CaRuby::Persistable.fetch_saved?+ condition for a Specimen as follows:
140
153
  # * If the Specimen available_quantity was updated, then fetch the saved Specimen.
141
154
  #
142
155
  # @return (see CaRuby::Persistable#fetch_saved)
@@ -154,11 +167,11 @@ module CaTissue
154
167
  CaTissue::CheckInCheckOutEventParameter.new(:specimen => self, :storage_status => Status.CHECKED_IN)
155
168
  end
156
169
 
157
- # @quirk caTissue remove the autogenerated blank ExternalIdentifier.
158
- # cf. https://cabig-kc.nci.nih.gov/Biospecimen/forums/viewtopic.php?f=19&t=436&sid=ef98f502fc0ab242781b7759a0eaff36
170
+ # Overrides +CaRuby::Mergable.merge_attribute+ to work around the caTissue
171
+ # bugs described in {CaTissue::Specimen.remove_phantom_external_identifier}.
159
172
  def merge_attribute(attribute, newval, matches=nil)
160
173
  if attribute == :external_identifiers and newval then
161
- CaTissue::Specimen.remove_empty_external_identifier(newval)
174
+ CaTissue::Specimen.remove_phantom_external_identifier(newval)
162
175
  end
163
176
  super
164
177
  end
@@ -175,7 +188,7 @@ module CaTissue
175
188
  # update
176
189
  # end
177
190
 
178
- # Override default {CaRuby::Resource#merge_attributes} to ignore a source SpecimenRequirement parent_specimen.
191
+ # Override default +Jinx::Resource.merge_attributes+ to ignore a source SpecimenRequirement parent_specimen.
179
192
  def merge_attributes(other, attributes=nil)
180
193
  case other
181
194
  when SpecimenRequirement then
@@ -185,7 +198,7 @@ module CaTissue
185
198
  # copy the requirement characteristics
186
199
  sc = other.specimen_characteristics
187
200
  self.specimen_characteristics ||= sc.copy(MERGEABLE_SPC_CHR_ATTRS) if sc
188
- when Hashable then
201
+ when Jinx::Hashable then
189
202
  # the requirement template
190
203
  rqmt = other[:specimen_requirement] || other[:requirement]
191
204
  # merge the attribute => value hash
@@ -198,7 +211,7 @@ module CaTissue
198
211
  end
199
212
 
200
213
  # Returns the Specimen in others which matches this Specimen in the scope of an owner SCG.
201
- # This method relaxes {CaRuby::Resource#match_in_owner_scope} to include a match on at least
214
+ # This method relaxes +Jinx::Resource.match_in_owner_scope+ to include a match on at least
202
215
  # one external identifier.
203
216
  def match_in_owner_scope(others)
204
217
  super or others.detect do |other|
@@ -211,8 +224,8 @@ module CaTissue
211
224
  # its auto-generated counterpart but a new specimen can be created even if it matches an
212
225
  # existing specimen on the features described in {AbstractSpecimen#minimal_match?}.
213
226
  #
214
- # @param (see CaRuby::Resource#minimal_match?)
215
- # @return (see CaRuby::Resource#minimal_match?)
227
+ # @param (see Jinx::Resource#minimal_match?)
228
+ # @return (see Jinx::Resource#minimal_match?)
216
229
  def minimal_match?(other)
217
230
  super and other.collection_status == 'Pending'
218
231
  end
@@ -231,17 +244,17 @@ module CaTissue
231
244
  #
232
245
  # The default class is inferred from the _class_ parameter, if given, or inherited
233
246
  # from this parent specimen otherwise. The inferred class is the camel-case parameter value
234
- # with +Specimen+ appended, e.g. :tissue => +TissueSpecimen+. This class name is resolved to
247
+ # with +Specimen+ appended, e.g. +:tissue+ => +TissueSpecimen+. This class name is resolved to
235
248
  # a class in the CaTissue module context.
236
249
  #
237
- # The supported :type parameter value includes the permissible caTissue specimen type String
238
- # values as well as the shortcut tissue type symbols :fresh, :fixed and :frozen.
250
+ # The supported +:type+ parameter value includes the permissible caTissue specimen type String
251
+ # values as well as the shortcut tissue type symbols :fresh, :fixed and +:frozen+.
239
252
  #
240
253
  # If a SpecimenRequirement parameter is provided, then that SpecimenRequirement's attribute
241
254
  # values are merged into the new Specimen after the other parameters are merged. Thus, params
242
255
  # takes precedence over the SpecimenRequirement.
243
256
  #
244
- # If the :count parameter is set to a number greater than one, then the specimen is aliquoted
257
+ # If the +:count+ parameter is set to a number greater than one, then the specimen is aliquoted
245
258
  # into the specified number of samples.
246
259
  #
247
260
  # This method is a convenience method to create either a Specimen or CaTissue::SpecimenRequirement.
@@ -306,18 +319,18 @@ module CaTissue
306
319
  # Otherwise an exception is thrown.
307
320
  #
308
321
  # @param [CaTissue::ConsentTier, nil] optional consent tier of the SCG CaTissue::ConsentTierStatus to withdraw
309
- # @raise [ValidationError] if an unambiguous SCG CaTissue::ConsentTierStatus to withdraw could not be determined
322
+ # @raise [Jinx::ValidationError] if an unambiguous SCG CaTissue::ConsentTierStatus to withdraw could not be determined
310
323
  def withdraw_consent(consent_tier=nil)
311
324
  statuses = specimen_collection_group.consent_tier_statuses
312
325
  status = if consent_tier then
313
326
  statuses.detect { |cts| cts.consent_tier.identifier == consent_tier.identifier } or
314
- raise ValidationError.new("SCG #{specimen_collection_group} consent status not found for consent '#{consent_tier.statement}'")
327
+ raise Jinx::ValidationError.new("SCG #{specimen_collection_group} consent status not found for consent '#{consent_tier.statement}'")
315
328
  elsif specimen_collection_group.consent_tier_statuses.size == 1 then
316
329
  statuses.first
317
330
  elsif specimen_collection_group.consent_tier_statuses.size == 0 then
318
- raise ValidationError.new("Specimen #{self} SCG does not have a consent tier status")
331
+ raise Jinx::ValidationError.new("Specimen #{self} SCG does not have a consent tier status")
319
332
  else
320
- raise ValidationError.new("Specimen #{self} SCG consent tier is ambiguous:#{consent_tier_statuses.select { |cts| "\n #{cts.statement}" }.to_series('or')}")
333
+ raise Jinx::ValidationError.new("Specimen #{self} SCG consent tier is ambiguous:#{consent_tier_statuses.select { |cts| "\n #{cts.statement}" }.to_series('or')}")
321
334
  end
322
335
  ct = status.consent_tier
323
336
  cts = consent_tier_statuses.detect { |item| item.consent_tier == ct }
@@ -325,7 +338,12 @@ module CaTissue
325
338
  cts.status = 'Withdrawn'
326
339
  end
327
340
 
328
- # Permanently dispose of this specimen with status 'Closed'.
341
+ # @return [Boolean] whether this specimen includes a {CaTissue::DisposalEventParameters}
342
+ def disposed?
343
+ specimen_event_parameters.any? { |ep| CaTissue::DisposalEventParameters === ep }
344
+ end
345
+
346
+ # Permanently dispose of this specimen.
329
347
  #
330
348
  # @param [String, nil] reason the optional disposal reason
331
349
  # @return [CaTissue::DisposalEventParameters] the disposal event
@@ -335,14 +353,18 @@ module CaTissue
335
353
 
336
354
  protected
337
355
 
338
- def self.remove_empty_external_identifier(eids)
339
- bogus = eids.detect { |eid| eid.name.nil? }
340
- if bogus then
341
- logger.debug { "Work around caTissue bug by removing empty fetched #{bogus.specimen.qp} #{bogus.qp} from #{eids.qp}..." }
356
+ # @quirk caTissue Specimen auto-generates a phantom ExternalIdentifier.
357
+ # cf. https://cabig-kc.nci.nih.gov/Biospecimen/forums/viewtopic.php?f=19&t=436&sid=ef98f502fc0ab242781b7759a0eaff36
358
+ #
359
+ # @param [<CaTissue::ExternalIdentifier>] eids the ExternalIndentifiers to clean up
360
+ def self.remove_phantom_external_identifier(eids)
361
+ phantom = eids.detect { |eid| eid.name.nil? }
362
+ if phantom then
363
+ logger.debug { "Work around caTissue bug by removing the phantom fetched #{phantom.specimen.qp} #{phantom.qp} from #{eids.qp}..." }
342
364
  # dissociate the specimen
343
- bogus.specimen = nil
344
- # remove the bogus eid
345
- eids.delete(bogus)
365
+ phantom.specimen = nil
366
+ # remove the phantom eid
367
+ eids.delete(phantom)
346
368
  end
347
369
  eids
348
370
  end
@@ -362,24 +384,24 @@ module CaTissue
362
384
  # Updating Specimen with the availablity flag set and available_quantity zero
363
385
  # silently leaves the availablity flag unset.
364
386
  #
365
- # @raise [ValidationError] if the validation fails
387
+ # @raise [Jinx::ValidationError] if the validation fails
366
388
  def validate_local
367
389
  super
368
390
  if parent.nil? and specimen_collection_group.nil? then
369
- raise ValidationError.new("Top-level specimen #{self} is missing specimen collection group")
391
+ raise Jinx::ValidationError.new("Top-level specimen #{self} is missing specimen collection group")
370
392
  end
371
393
  if available_quantity and initial_quantity and available_quantity > initial_quantity then
372
- raise ValidationError.new("#{self} available quantity #{available_quantity} cannot exceed initial quantity #{initial_quantity}")
394
+ raise Jinx::ValidationError.new("#{self} available quantity #{available_quantity} cannot exceed initial quantity #{initial_quantity}")
373
395
  end
374
396
  if available? and available_quantity.zero? then
375
- raise ValidationError.new("#{self} availablility flag cannot be set when the avaialble quantity is zero")
397
+ raise Jinx::ValidationError.new("#{self} availablility flag cannot be set when the avaialble quantity is zero")
376
398
  end
377
399
  if collected? then
378
400
  unless event_parameters.detect { |ep| CaTissue::CollectionEventParameters === ep } then
379
- raise ValidationError.new("#{self} is missing CollectionEventParameters")
401
+ raise Jinx::ValidationError.new("#{self} is missing CollectionEventParameters")
380
402
  end
381
403
  unless event_parameters.detect { |ep| CaTissue::ReceivedEventParameters === ep } then
382
- raise ValidationError.new("#{self} is missing ReceivedEventParameters")
404
+ raise Jinx::ValidationError.new("#{self} is missing ReceivedEventParameters")
383
405
  end
384
406
  end
385
407
  end
@@ -439,7 +461,8 @@ module CaTissue
439
461
  if is_available.nil? then
440
462
  self.is_available = default_availablility
441
463
  elsif is_available == false then
442
- # Reset is_available value from false to nil to work around caTissue bug but described in method doc.
464
+ # Reset is_available value from false to nil to work around caTissue bug but described in
465
+ # the method rubydoc above.
443
466
  self.is_available = nil
444
467
  end
445
468
  end
@@ -464,34 +487,48 @@ module CaTissue
464
487
 
465
488
  # @return [CaTissue::ReceivedEventParameters] the default REP
466
489
  def create_default_received_event_parameters
467
- user = specimen_collection_group.receiver || default_scg_coordinator || return
490
+ rep = parent.received_event_parameters if parent
491
+ user = rep.user if rep
492
+ user ||= scg_receiver || return
468
493
  rep = CaTissue::ReceivedEventParameters.new(:specimen => self, :user => user)
469
494
  logger.debug { "Created default #{qp} received event #{rep.qp}." }
470
495
  rep
471
496
  end
472
497
 
498
+ # The default CEP user is, by order of preference:
499
+ # * this specimen's parent specimen collector
500
+ # * this specimen's SCG collector
501
+ # * the receiver
502
+ #
473
503
  # @param [CaTissue::ReceivedEventParameters] the required REP
474
504
  # @return [CaTissue::CollectionEventParameters] the default CEP
475
505
  def create_default_collection_event_parameters(rep)
476
- user = scg_collector || rep.user || return
506
+ cep = parent.collection_event_parameters if parent
507
+ user = cep.user if cep
508
+ user ||= scg_collector || rep.user || return
477
509
  cep = CaTissue::CollectionEventParameters.new(:specimen => self, :user => user)
478
510
  logger.debug { "Created default #{qp} collection event #{cep.qp}." }
479
511
  cep
480
512
  end
481
513
 
514
+ # @return [CaTissue::User, nil] the SCG receiver, if any
515
+ def scg_receiver
516
+ scg = specimen_collection_group || return
517
+ scg.receiver or default_scg_coordinator(scg)
518
+ end
519
+
482
520
  # @return [CaTissue::User, nil] the SCG collector, if any
483
521
  def scg_collector
484
522
  specimen_collection_group.collector if specimen_collection_group
485
523
  end
486
524
 
487
525
  # @return [CaTissue::User, nil] the first SCG protocol coordinator
488
- def default_scg_coordinator
489
- scg = specimen_collection_group || return
526
+ def default_scg_coordinator(scg)
490
527
  cp = scg.collection_protocol || return
491
528
  cp.coordinators.first
492
529
  end
493
530
 
494
- # Sets the :specimen_class parameter to a permissible caTissue value.
531
+ # Sets the +:specimen_class+ parameter to a permissible caTissue value.
495
532
  def self.standardize_class_parameter(params)
496
533
  opt = params[:specimen_class]
497
534
  if opt.nil? then
@@ -545,15 +582,15 @@ module CaTissue
545
582
  def decrement_derived_quantity(child)
546
583
  return unless specimen_type == child.specimen_type and child.initial_quantity
547
584
  if available_quantity.nil? then
548
- raise ValidationError.new("Derived specimen has an initial quantity #{child.initial_quantity} but the parent is missing an available quantity")
585
+ raise Jinx::ValidationError.new("Derived specimen has an initial quantity #{child.initial_quantity} but the parent is missing an available quantity")
549
586
  elsif (available_quantity - child.initial_quantity).abs < 0.00000001 then
550
587
  # rounding error
551
588
  self.available_quantity = 0.0
552
589
  elsif child.initial_quantity <= available_quantity then
553
590
  self.available_quantity -= child.initial_quantity
554
591
  else
555
- raise ValidationError.new("Derived specimen initial quantity #{child.initial_quantity} exceeds parent available quantity #{available_quantity}")
592
+ raise Jinx::ValidationError.new("Derived specimen initial quantity #{child.initial_quantity} exceeds parent available quantity #{available_quantity}")
556
593
  end
557
594
  end
558
595
  end
559
- end
596
+ end