caruby-tissue 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. data/History.txt +4 -0
  2. data/LICENSE +1 -1
  3. data/README.md +79 -30
  4. data/bin/crtmigrate +2 -2
  5. data/{examples/galena/bin → bin}/migrate.rb +0 -0
  6. data/bin/seed +26 -0
  7. data/bin/seed.rb +43 -0
  8. data/conf/extract/simple_fields.yaml +4 -0
  9. data/conf/migration/filter_fields.yaml +7 -0
  10. data/{examples/galena/conf → conf}/migration/filter_migration.yaml +0 -0
  11. data/conf/migration/frozen_fields.yaml +11 -0
  12. data/{examples/galena/conf → conf}/migration/frozen_migration.yaml +0 -0
  13. data/conf/migration/general_fields.yaml +44 -0
  14. data/{examples/galena/conf → conf}/migration/general_migration.yaml +0 -0
  15. data/conf/migration/simple_fields.yaml +30 -0
  16. data/{examples/galena/conf → conf}/migration/simple_migration.yaml +0 -0
  17. data/{examples/galena/conf → conf}/migration/small_fields.yaml +0 -0
  18. data/{examples/galena/conf → conf}/migration/small_migration.yaml +0 -0
  19. data/examples/galena/README.md +46 -6
  20. data/examples/galena/bin/seed +26 -0
  21. data/examples/galena/conf/migration/frozen_fields.yaml +1 -0
  22. data/examples/galena/conf/migration/general_fields.yaml +2 -0
  23. data/examples/galena/data/filter.csv +1 -1
  24. data/examples/galena/data/frozen.csv +1 -1
  25. data/examples/galena/data/general.csv +1 -1
  26. data/examples/galena/doc/CaTissue.html +2 -2
  27. data/examples/galena/doc/CaTissue/Participant.html +1 -1
  28. data/examples/galena/doc/CaTissue/SpecimenCollectionGroup.html +1 -1
  29. data/examples/galena/doc/CaTissue/StorageContainer.html +6 -6
  30. data/examples/galena/doc/CaTissue/TissueSpecimen.html +1 -1
  31. data/examples/galena/doc/Galena.html +4 -122
  32. data/examples/galena/doc/Galena/Seed.html +1 -1
  33. data/examples/galena/doc/Galena/Seed/Defaults.html +28 -24
  34. data/examples/galena/doc/_index.html +1 -8
  35. data/examples/galena/doc/class_list.html +1 -1
  36. data/examples/galena/doc/file.README.html +52 -7
  37. data/examples/galena/doc/index.html +52 -7
  38. data/examples/galena/doc/method_list.html +9 -25
  39. data/examples/galena/doc/top-level-namespace.html +1 -1
  40. data/examples/galena/lib/galena/migration/frozen_shims.rb +4 -15
  41. data/examples/galena/lib/galena/seed/defaults.rb +16 -4
  42. data/{examples/galena/lib → lib}/README.html +0 -0
  43. data/lib/catissue/cli/command.rb +6 -9
  44. data/lib/catissue/cli/migrate.rb +11 -10
  45. data/lib/catissue/cli/smoke.rb +5 -5
  46. data/lib/catissue/database.rb +31 -8
  47. data/lib/catissue/domain/abstract_specimen.rb +1 -1
  48. data/lib/catissue/domain/collection_protocol.rb +29 -13
  49. data/lib/catissue/domain/participant_medical_identifier.rb +1 -1
  50. data/lib/catissue/domain/site.rb +3 -0
  51. data/lib/catissue/domain/specimen.rb +17 -14
  52. data/lib/catissue/domain/specimen_collection_group.rb +2 -5
  53. data/lib/catissue/extract/delta.rb +2 -6
  54. data/lib/catissue/migration/migrator.rb +6 -0
  55. data/lib/catissue/resource.rb +5 -2
  56. data/lib/catissue/util/log.rb +3 -3
  57. data/lib/catissue/version.rb +1 -1
  58. data/{examples/galena/lib → lib}/galena.rb +0 -0
  59. data/{examples/galena/bin → lib/galena/cli}/seed.rb +1 -1
  60. data/lib/galena/migration/filter_shims.rb +43 -0
  61. data/lib/galena/migration/frozen_shims.rb +53 -0
  62. data/lib/galena/seed/defaults.rb +109 -0
  63. metadata +27 -17
  64. data/examples/galena/doc/CaTissue/CollectionProtocolRegistration.html +0 -181
@@ -70,8 +70,8 @@ The use cases illustrate several common migration impediments:</p>
70
70
  <li><p>Copy the example into a location of your choosing.</p></li>
71
71
  <li><p>Configure a caTissue client to connect to a test caTissue instance, as described in the
72
72
  caTissue Technical Guide.</p></li>
73
- <li><p>Define the caRuby Tissue access property file as described in
74
- <a href="FAQ">http://caruby.tenderapp.com/faqs/getting-started/tissue_config</a>.</p></li>
73
+ <li><p>Define the caRuby Tissue access property file as described in the configuration
74
+ <a href="how-do-i-configure-caruby-to-work-with-catissue">FAQ</a>.</p></li>
75
75
  </ol>
76
76
 
77
77
 
@@ -90,16 +90,61 @@ For example, the <code>simple.csv</code> input file is migrated into caTissue us
90
90
  <li><p>Open a console in the copied Galena example location.</p></li>
91
91
  <li><p>Run the following:</p>
92
92
 
93
- <p> crtmigrate --file conf/migration/simple.yaml data/simple.yaml</p></li>
94
- <li><p>Check the test database and verify that a there is a collection protocol
95
- named `Galena CP.</p></li>
93
+ <p> bin/seed</p>
94
+
95
+ <p>This command initializes the administrative objects in the Galena test database,
96
+ including the Galena collection protocol, site, cancer center, tissue bank and coordinator.</p></li>
97
+ <li><p>Run the following:</p>
98
+
99
+ <p> crtmigrate --target TissueSpecimen --mapping conf/migration/simple_fields.yaml data/simple.csv</p>
100
+
101
+ <p>This command migrates the CSV record in the <code>simple.csv</code> input file into a caTissue
102
+ <code>TissueSpecimen</code> based on the <code>simple_fields.yaml</code> mapping file.
103
+ The command will take a couple of minutes to finish, since the less information
104
+ you provide caRuby the more it works to fill in the missing bits. In the meantime,
105
+ peruse the configuration and data files to see which data are migrated and
106
+ where this data ends up in caTissue.</p></li>
107
+ <li><p>Open the caTissue application on the test server and verify the content of the
108
+ Galena CP collection protocol.</p></li>
96
109
  </ol>
97
110
 
98
111
 
99
- <p>The other examples are run in a similar manner.</p></div></div>
112
+ <p>The other examples are run in a similar manner. Each example demonstrates different
113
+ features of the caRuby Migration utility as follows:</p>
114
+
115
+ <ul>
116
+ <li>simple - a good starting point with limited input fields</li>
117
+ <li>minimal - the fewest possible input fields without writing custom Ruby shim code</li>
118
+ <li>general - lots of input fields, no custom Ruby code</li>
119
+ <li>filter - a smattering of custom Ruby shim code to convert input values to caTissue values</li>
120
+ <li>frozen - an example demonstrating how to import storage locations</li>
121
+ </ul>
122
+
123
+
124
+ <p>Try running an example with the <code>--debug</code> flag and look at the <code>log/migration.log</code> file to see
125
+ what caRuby is up to behind the scenes (hint: a lot!).</p>
126
+
127
+ <h2>Input data</h2>
128
+
129
+ <p>The sample Galena Tissue Bank CSV input files hold one row for each specimen.
130
+ Common fields are as follows:</p>
131
+
132
+ <ul>
133
+ <li>MRN - Patient Medical Record Number</li>
134
+ <li>Initials - Patient name initials</li>
135
+ <li>Frozen? - Flag indicating whether the specimen is frozen</li>
136
+ <li>SPN - Surgical Pathology Number</li>
137
+ <li>Collection Date - Date the specimen was acquired by the tissue bank</li>
138
+ <li>Received Date - Date the specimen was donated by the participant</li>
139
+ <li>Quantity - Amount collected</li>
140
+ <li>Box - Tissue storage container</li>
141
+ <li>X - the tissue box column</li>
142
+ <li>Y - the tissue box row</li>
143
+ </ul>
144
+ </div></div>
100
145
 
101
146
  <div id="footer">
102
- Generated on Tue Nov 23 11:38:42 2010 by
147
+ Generated on Tue Nov 30 11:09:42 2010 by
103
148
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
104
149
  0.6.1 (ruby-1.8.6).
105
150
  </div>
@@ -77,14 +77,6 @@
77
77
 
78
78
 
79
79
  <li class="r1 ">
80
- <span class='object_link'><a href="CaTissue/TissueSpecimen.html#migrate-instance_method" title="CaTissue::TissueSpecimen#migrate (method)">#migrate</a></span>
81
-
82
- <small>CaTissue::TissueSpecimen</small>
83
-
84
- </li>
85
-
86
-
87
- <li class="r2 ">
88
80
  <span class='object_link'><a href="CaTissue/StorageContainer.html#migrate-instance_method" title="CaTissue::StorageContainer#migrate (method)">#migrate</a></span>
89
81
 
90
82
  <small>CaTissue::StorageContainer</small>
@@ -92,15 +84,15 @@
92
84
  </li>
93
85
 
94
86
 
95
- <li class="r1 ">
96
- <span class='object_link'><a href="CaTissue/CollectionProtocolRegistration.html#migrate-instance_method" title="CaTissue::CollectionProtocolRegistration#migrate (method)">#migrate</a></span>
87
+ <li class="r2 ">
88
+ <span class='object_link'><a href="CaTissue/TissueSpecimen.html#migrate-instance_method" title="CaTissue::TissueSpecimen#migrate (method)">#migrate</a></span>
97
89
 
98
- <small>CaTissue::CollectionProtocolRegistration</small>
90
+ <small>CaTissue::TissueSpecimen</small>
99
91
 
100
92
  </li>
101
93
 
102
94
 
103
- <li class="r2 ">
95
+ <li class="r1 ">
104
96
  <span class='object_link'><a href="CaTissue/Participant.html#migrate_first_name-instance_method" title="CaTissue::Participant#migrate_first_name (method)">#migrate_first_name</a></span>
105
97
 
106
98
  <small>CaTissue::Participant</small>
@@ -108,7 +100,7 @@
108
100
  </li>
109
101
 
110
102
 
111
- <li class="r1 ">
103
+ <li class="r2 ">
112
104
  <span class='object_link'><a href="CaTissue/TissueSpecimen.html#migrate_initial_quantity-instance_method" title="CaTissue::TissueSpecimen#migrate_initial_quantity (method)">#migrate_initial_quantity</a></span>
113
105
 
114
106
  <small>CaTissue::TissueSpecimen</small>
@@ -116,7 +108,7 @@
116
108
  </li>
117
109
 
118
110
 
119
- <li class="r2 ">
111
+ <li class="r1 ">
120
112
  <span class='object_link'><a href="CaTissue/Participant.html#migrate_last_name-instance_method" title="CaTissue::Participant#migrate_last_name (method)">#migrate_last_name</a></span>
121
113
 
122
114
  <small>CaTissue::Participant</small>
@@ -124,7 +116,7 @@
124
116
  </li>
125
117
 
126
118
 
127
- <li class="r1 ">
119
+ <li class="r2 ">
128
120
  <span class='object_link'><a href="CaTissue/TissueSpecimen.html#migrate_specimen_type-instance_method" title="CaTissue::TissueSpecimen#migrate_specimen_type (method)">#migrate_specimen_type</a></span>
129
121
 
130
122
  <small>CaTissue::TissueSpecimen</small>
@@ -132,7 +124,7 @@
132
124
  </li>
133
125
 
134
126
 
135
- <li class="r2 ">
127
+ <li class="r1 ">
136
128
  <span class='object_link'><a href="CaTissue/SpecimenCollectionGroup.html#migration_valid%3F-instance_method" title="CaTissue::SpecimenCollectionGroup#migration_valid? (method)">#migration_valid?</a></span>
137
129
 
138
130
  <small>CaTissue::SpecimenCollectionGroup</small>
@@ -140,7 +132,7 @@
140
132
  </li>
141
133
 
142
134
 
143
- <li class="r1 ">
135
+ <li class="r2 ">
144
136
  <span class='object_link'><a href="Galena/Seed/Defaults.html#protocol-instance_method" title="Galena::Seed::Defaults#protocol (method)">#protocol</a></span>
145
137
 
146
138
  <small>Galena::Seed::Defaults</small>
@@ -148,14 +140,6 @@
148
140
  </li>
149
141
 
150
142
 
151
- <li class="r2 ">
152
- <span class='object_link'><a href="Galena.html#resource-class_method" title="Galena.resource (method)">resource</a></span>
153
-
154
- <small>Galena</small>
155
-
156
- </li>
157
-
158
-
159
143
  <li class="r1 ">
160
144
  <span class='object_link'><a href="Galena.html#seed-class_method" title="Galena.seed (method)">seed</a></span>
161
145
 
@@ -103,7 +103,7 @@ the default log file
103
103
  </div>
104
104
 
105
105
  <div id="footer">
106
- Generated on Tue Nov 23 11:38:43 2010 by
106
+ Generated on Tue Nov 30 11:09:43 2010 by
107
107
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
108
108
  0.6.1 (ruby-1.8.6).
109
109
  </div>
@@ -1,7 +1,7 @@
1
- require 'galena/seed/defaults'
1
+ # load the defaults file in the seed directory
2
+ require File.join(File.dirname(__FILE__), '..', 'seed', 'defaults')
2
3
 
3
4
  module CaTissue
4
-
5
5
  # Declares the classes modified for migration.
6
6
  shims TissueSpecimen, CollectionProtocolRegistration, StorageContainer
7
7
 
@@ -14,16 +14,6 @@ module CaTissue
14
14
  self.specimen_type = 'Frozen Tissue'
15
15
  end
16
16
  end
17
-
18
- class CollectionProtocolRegistration
19
- # Sets this CPR's protocol to the pre-defined {Galena::Migration::Defaults#protocol}.
20
- #
21
- # @param (see CaRuby::Migratable#migrate)
22
- def migrate(row, migrated)
23
- super
24
- self.protocol = Galena::Seed.defaults.protocol
25
- end
26
- end
27
17
 
28
18
  class StorageContainer
29
19
  # Creates the migrated box in the database, if necessary.
@@ -36,14 +26,13 @@ module CaTissue
36
26
 
37
27
  private
38
28
 
39
- # Creates a new box of type {Galena::Migration::Defaults#box_type} in a
40
- # freezer of type {Galena::Migration::Defaults#freezer_type}.
29
+ # Creates a new box of type {Galena::Seed::Defaults#box_type} in a freezer of type
30
+ # {Galena::Seed::Defaults#freezer_type}.
41
31
  #
42
32
  # @return [StorageContainer] the new box
43
33
  def create_box
44
34
  defs = Galena::Seed.defaults
45
35
  self.storage_type = defs.box_type
46
- self.site = defs.tissue_bank
47
36
  # A freezer with a spot for the box
48
37
  frz = defs.freezer_type.find_available(site, :create)
49
38
  if frz.nil? then raise CaRuby::MigrationError.new("Freezer not available to place #{self}") end
@@ -23,7 +23,8 @@ module Galena
23
23
  # In that case, it is only necessary to define the object secondary key rather than content, e.g.:
24
24
  # pcl = CaTissue::CollectionProtocol.new(:short_title => 'Galena CP')
25
25
  # The complete definitions are included in this method for convenience in order to seed the
26
- # example in a test database.
26
+ # example in a test database. A real-world migration might find it useful to create a similar
27
+ # defaults file in order to rapidly seed an empty test or staging database.
27
28
  class Defaults
28
29
  include Singleton
29
30
 
@@ -39,7 +40,8 @@ module Galena
39
40
  def ensure_exists
40
41
  @protocol.find(:create)
41
42
  @hospital.find(:create)
42
- @freezer_type.find(:create)
43
+ @surgeon.find(:create)
44
+ @box.find(:create)
43
45
  end
44
46
 
45
47
  private
@@ -74,7 +76,12 @@ module Galena
74
76
  :last_name => 'Gator', :first_name => 'Vesta', :address => addr.copy,
75
77
  :institution => galena, :department => dept, :cancer_research_group => crg)
76
78
 
77
- @protocol = CaTissue::CollectionProtocol.new(:short_title => 'Galena CP',
79
+ @surgeon = CaTissue::User.new(
80
+ :email_address => 'serge.on@galena.edu',
81
+ :first_name => 'Serge', :last_name => 'On', :address => addr.copy,
82
+ :institution => galena, :department => dept, :cancer_research_group => crg)
83
+
84
+ @protocol = CaTissue::CollectionProtocol.new(:short_title => 'Galena Migration',
78
85
  :principal_investigator => pi, :sites => [@tissue_bank])
79
86
 
80
87
  # CPE has default 1.0 event point and label
@@ -84,13 +91,18 @@ module Galena
84
91
  # sets the CPE requirement inverse attribute in caRuby.
85
92
  CaTissue::TissueSpecimenRequirement.new(:collection_event => cpe, :specimen_type => 'Fixed Tissue')
86
93
 
87
- # a storage container
94
+ # the storage container type hierarchy
88
95
  @freezer_type = CaTissue::StorageType.new(:name => 'GTB Freezer', :columns => 10, :rows => 1, :column_label => 'Rack')
89
96
  rack_type = CaTissue::StorageType.new(:name => 'GTB Rack', :columns => 10, :rows => 10)
90
97
  @box_type = CaTissue::StorageType.new(:name => 'GTB Box', :columns => 10, :rows => 10)
91
98
  @freezer_type << rack_type
92
99
  rack_type << box_type
93
100
  @box_type << 'Tissue'
101
+
102
+ # a sample freezer and box
103
+ frz = CaTissue::StorageContainer.new(:name => 'GTB Freezer 1', :storage_type=>@freezer_type, :site=>@tissue_bank)
104
+ @box = CaTissue::StorageContainer.new(:name => 'GTB Box 1', :storage_type=>@box_type)
105
+ frz << @box
94
106
  end
95
107
  end
96
108
  end
File without changes
@@ -18,19 +18,22 @@ module CaTissue
18
18
  # Augments {CaRuby::CLI::Command} with caTissue-specific command line option handlers.
19
19
  class Command < CaRuby::CLI::Command
20
20
  # @see {CaRuby::CLI::Command#initialize}
21
- def initialize(specs=[], &executor)
21
+ def initialize(specs=[])
22
22
  specs << VERSION_OPT
23
- super { |opts| handle_catissue_options(opts, &executor) }
23
+ super
24
24
  end
25
25
 
26
26
  private
27
27
 
28
+ VERSION_OPT = [:version, "--version", "Prints the version of caRuby Tissue and the supported caTissue releases and exits"]
29
+
28
30
  # If the version option is set, then prints the version and exits.
29
31
  # Otherwise, extracts the connection command line options, adds them
30
32
  # to {CaTissue.access_properties}, and yields to the executor block.
31
33
  #
32
34
  # @param [{Symbol => Object}] opts the command line argument and option symbol => value hash
33
- def handle_catissue_options(opts)
35
+ def handle_options(opts)
36
+ super
34
37
  if opts[:version] then
35
38
  puts "#{CaTissue::VERSION} for caTissue v#{CaTissue::CATISSUE_VERSIONS}"
36
39
  else
@@ -38,14 +41,8 @@ module CaTissue
38
41
  value = opts.delete(opt)
39
42
  CaTissue.access_properties[opt] = value if value
40
43
  end
41
- yield(opts)
42
44
  end
43
45
  end
44
-
45
- private
46
-
47
- VERSION_OPT = [:version, "--version", "Prints the version of caRuby Tissue and the supported caTissue releases and exits"]
48
-
49
46
  end
50
47
  end
51
48
  end
@@ -26,24 +26,25 @@ module CaTissue
26
26
  # as well as the {SPECS} command line specifications.
27
27
  #
28
28
  # @param (see CaRuby::CLI::Command#initialize)
29
- def initialize(specs={}, &factory)
30
- super(specs.merge(SPECS)) { |opts| migrate(opts, &factory) }
29
+ # @yield [opts] optional migrator factory
30
+ # @yieldparam [{Symbol => Object}] the {CaTissue::Migrator#initialize} creation options
31
+ # @see CaRuby::Command#run
32
+ def initialize(&factory)
33
+ super(SPECS) { |opts| migrate(opts, &factory) }
31
34
  end
32
35
 
36
+ private
37
+
33
38
  # Starts a Migrator with the command-line options.
34
39
  #
35
40
  # @yield [target] operation on the migration target
36
41
  # @yieldparam [CaRuby::Resource] the migrated domain object
37
42
  # @see CaRuby::Command#run
38
- def migrate(opts, &factory)
39
- super do |opts|
40
- validate(opts)
41
- migrator = block_given ? yield(opts) : Migrator.new(opts)
42
- migrator.migrate
43
- end
43
+ def migrate(opts)
44
+ validate(opts)
45
+ migrator = block_given? ? yield(opts) : CaTissue::Migrator.new(opts)
46
+ migrator.migrate_to_database
44
47
  end
45
-
46
- private
47
48
 
48
49
  def validate(opts)
49
50
  tgt = opts[:target]
@@ -6,12 +6,12 @@ module CaTissue
6
6
  class Smoke < Command
7
7
  # Creates a new Smoke command.
8
8
  def initialize
9
- super { |opts| execute(opts) }
9
+ super { |opts| execute }
10
10
  end
11
11
 
12
12
  private
13
13
 
14
- DB_MSG = "Verifying database access by searching for the pre-defined 'In Transit' Site..."
14
+ DB_MSG = "Verifying database access by searching for the pre-defined #{CaTissue::Site::DEF_SITE_NAME} Site..."
15
15
 
16
16
  # Runs the smoke test.
17
17
  def execute
@@ -23,7 +23,7 @@ module CaTissue
23
23
 
24
24
  def find_in_transit_site
25
25
  begin
26
- site = CaTissue::Site.new(:name => 'In Transit').find
26
+ site = CaTissue::Site.new(:name => CaTissue::Site::DEF_SITE_NAME).find
27
27
  rescue Exception => e
28
28
  logger.error("caTissue database access was unsuccessful - #{e}:\n#{e.backtrace.qp}")
29
29
  puts "caTissue database access was unsuccessful - #{e}."
@@ -31,11 +31,11 @@ module CaTissue
31
31
  end
32
32
 
33
33
  if site then
34
- puts "The 'In Transit' Site was found with identifier #{site.identifier}."
34
+ puts "The #{CaTissue::Site::DEF_SITE_NAME} Site was found with identifier #{site.identifier}."
35
35
  puts "Smoke test successful."
36
36
  exit 0
37
37
  else
38
- puts "The 'In Transit' Site was not found."
38
+ puts "The #{CaTissue::Site::DEF_SITE_NAME} Site was not found."
39
39
  puts "Smoke test unsuccessful."
40
40
  exit 69 # service unavailable error status
41
41
  end
@@ -270,14 +270,20 @@ module CaTissue
270
270
  # * caTissue alert - Bug #161: Specimen API disposal not reflected in result activity status.
271
271
  # DisposalEventParameters create sets the owner Specimen activity_status to +Closed+ as a side-effect.
272
272
  # Reflect this side-effect in the submitted DisposalEventParameters owner Specimen object.
273
+ # * Ensure that a {CaTissue::Participant} obj registrations reference an existing protocol.
274
+ # This compensates for a hole in the storable template logic which does not recognize the
275
+ # CPR CP references as a pre-requisite. TODO - isolate, report and fix.
273
276
  def create_object(obj)
274
277
  # if CaTissue::SCGEventParameters === obj and obj.specimen_collection_group then
275
278
  # return create_scg_event_parameters(obj) { super }
276
279
  # elsif CaTissue::Specimen === obj and obj.is_available == false then
277
- if CaTissue::Specimen === obj and not obj.available? then
278
- # Note that the obj.is_available == false test is required as opposed to obj.is_available?,
279
- # since a nil is_available flag does not imply an unavailable specimen.
280
- return create_unavailable_specimen(obj) { super }
280
+ if CaTissue::Specimen === obj then
281
+ obj.add_defaults
282
+ if obj.is_available == false or obj.available_quantity.zero? then
283
+ # Note that the obj.is_available == false test is required as opposed to obj.is_available?,
284
+ # since a nil is_available flag does not imply an unavailable specimen.
285
+ return create_unavailable_specimen(obj) { super }
286
+ end
281
287
  end
282
288
 
283
289
  # standard create
@@ -418,11 +424,28 @@ module CaTissue
418
424
  end
419
425
 
420
426
  def fetch_participant_using_mrn(pnt)
421
- mid = pnt.medical_identifiers.first
422
- return if mid.nil?
427
+ pmi = pnt.medical_identifiers.first
428
+ return if pmi.nil?
423
429
  logger.debug { "Using alternative Participant fetch strategy to find Participant by medical record number..." }
424
- return unless exists?(mid)
425
- candidates = query(mid.copy, :participant)
430
+
431
+ #
432
+ # TODO - hack to work around intricate add_default logic; ties in with the create participant hack in this class.
433
+ # FIX THIS!!
434
+ #
435
+ if pmi.site.nil? then
436
+ # fetch Participant CPR protocols if necessary
437
+ pnt.registrations.each do |reg|
438
+ pcl = reg.protocol || next
439
+ pcl.find unless pcl.identifier
440
+ reg.add_defaults
441
+ end
442
+ pnt.add_defaults
443
+ end
444
+
445
+ # END OF HACK
446
+
447
+ return unless exists?(pmi)
448
+ candidates = query(pmi.copy, :participant)
426
449
  candidates.first if candidates.size == 1
427
450
  end
428
451