extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Blood.java

Code
Comments
Other
Rev Date Author Line
1518 23 Jan 12 nicklas 1 package net.sf.basedb.reggie.dao;
1518 23 Jan 12 nicklas 2
1518 23 Jan 12 nicklas 3 import java.util.ArrayList;
5138 22 Nov 18 nicklas 4 import java.util.Collection;
1518 23 Jan 12 nicklas 5 import java.util.List;
1518 23 Jan 12 nicklas 6
1518 23 Jan 12 nicklas 7 import net.sf.basedb.core.DbControl;
1518 23 Jan 12 nicklas 8 import net.sf.basedb.core.Include;
1518 23 Jan 12 nicklas 9 import net.sf.basedb.core.InvalidDataException;
1518 23 Jan 12 nicklas 10 import net.sf.basedb.core.ItemQuery;
1518 23 Jan 12 nicklas 11 import net.sf.basedb.core.PermissionDeniedException;
1518 23 Jan 12 nicklas 12 import net.sf.basedb.core.Sample;
1518 23 Jan 12 nicklas 13 import net.sf.basedb.core.Type;
1614 24 Apr 12 nicklas 14 import net.sf.basedb.core.query.Annotations;
1518 23 Jan 12 nicklas 15 import net.sf.basedb.core.query.Expressions;
1518 23 Jan 12 nicklas 16 import net.sf.basedb.core.query.Hql;
1518 23 Jan 12 nicklas 17 import net.sf.basedb.core.query.Orders;
1518 23 Jan 12 nicklas 18 import net.sf.basedb.core.query.Restrictions;
2917 11 Nov 14 nicklas 19 import net.sf.basedb.reggie.Reggie;
1518 23 Jan 12 nicklas 20
1518 23 Jan 12 nicklas 21 /**
1518 23 Jan 12 nicklas 22   Class for loading information that is related to blood referral forms.
1518 23 Jan 12 nicklas 23   
1518 23 Jan 12 nicklas 24   @author nicklas
1518 23 Jan 12 nicklas 25   @since 2.2
1518 23 Jan 12 nicklas 26 */
1518 23 Jan 12 nicklas 27 public class Blood
1518 23 Jan 12 nicklas 28   extends ReggieItem<Sample>
1518 23 Jan 12 nicklas 29 {
1518 23 Jan 12 nicklas 30
1518 23 Jan 12 nicklas 31   /**
1518 23 Jan 12 nicklas 32     Find blood information by case name. This method will check for 
1518 23 Jan 12 nicklas 33     {@link Subtype#BLOOD} samples with a name matching the case name (eg. xxx.b)
1614 24 Apr 12 nicklas 34     If useBlodSampleAnnotation is set the lookup will use the 'BloodSample' annotation
1614 24 Apr 12 nicklas 35     when searching for samples. If the case name has a suffix 'C' only samples annotated 
1614 24 Apr 12 nicklas 36     with BloodSample=PreNeo are considered. If no suffix is specified PreNeo samples 
1614 24 Apr 12 nicklas 37     are ignored.
1614 24 Apr 12 nicklas 38     <p>
1614 24 Apr 12 nicklas 39     If exactly one match is found this is the search for blood sample. More than one
1614 24 Apr 12 nicklas 40     match is an error condition. No match indicates a case that has not yet been
1614 24 Apr 12 nicklas 41     registered (null is returned).
1518 23 Jan 12 nicklas 42   */
1614 24 Apr 12 nicklas 43   public static Blood findByCaseName(DbControl dc, String name, boolean useBloodSampleAnnotation)
1518 23 Jan 12 nicklas 44   {
1518 23 Jan 12 nicklas 45     Blood bloodCase = null;
1518 23 Jan 12 nicklas 46     
1614 24 Apr 12 nicklas 47     boolean preNeo = name.endsWith("C");
1614 24 Apr 12 nicklas 48     if (name.length() > 7) name = name.substring(0, 7);    
1614 24 Apr 12 nicklas 49     name += ".b%";
1518 23 Jan 12 nicklas 50     
1518 23 Jan 12 nicklas 51     // Look for a blood case with the given name 
1518 23 Jan 12 nicklas 52     ItemQuery<Sample> bloodQuery = Sample.getQuery();
1518 23 Jan 12 nicklas 53     Subtype.BLOOD.addFilter(dc, bloodQuery);
1614 24 Apr 12 nicklas 54     bloodQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", name, Type.STRING)));
1614 24 Apr 12 nicklas 55     
1614 24 Apr 12 nicklas 56     if (useBloodSampleAnnotation)
1614 24 Apr 12 nicklas 57     {
2601 27 Aug 14 nicklas 58       bloodQuery.join(Annotations.leftJoin(Annotationtype.BLOOD_SAMPLE.load(dc), "bs"));
1614 24 Apr 12 nicklas 59       if (preNeo)
1614 24 Apr 12 nicklas 60       {
1614 24 Apr 12 nicklas 61         // Only look for samples with annotation BloodSample=PreNeo
2601 27 Aug 14 nicklas 62         bloodQuery.restrict(Restrictions.eq(Hql.alias("bs"), Expressions.string("PreNeo")));
1614 24 Apr 12 nicklas 63       }
1614 24 Apr 12 nicklas 64       else
1614 24 Apr 12 nicklas 65       {
2601 27 Aug 14 nicklas 66         // Only look for samples with annotation BloodSample=PreOp or missing
2601 27 Aug 14 nicklas 67         bloodQuery.restrict(
2601 27 Aug 14 nicklas 68           Restrictions.or(
2601 27 Aug 14 nicklas 69             Restrictions.eq(Hql.alias("bs"), null),
2601 27 Aug 14 nicklas 70             Restrictions.eq(Hql.alias("bs"), Expressions.string("PreOp"))
2601 27 Aug 14 nicklas 71           ));
1614 24 Apr 12 nicklas 72       }
1614 24 Apr 12 nicklas 73     }
1614 24 Apr 12 nicklas 74     
1518 23 Jan 12 nicklas 75     List<Sample> bloodCases = bloodQuery.list(dc);
1518 23 Jan 12 nicklas 76     
1518 23 Jan 12 nicklas 77     // ...if more than one is found, something is incorrectly registered... abort
1518 23 Jan 12 nicklas 78     if (bloodCases.size() > 1)
1518 23 Jan 12 nicklas 79     {
1518 23 Jan 12 nicklas 80       throw new InvalidDataException(
1518 23 Jan 12 nicklas 81         "Found " + bloodCases.size() + " cases with the same name (" + name + 
1518 23 Jan 12 nicklas 82         "). This wizard can't be used until that is corrected.");
1518 23 Jan 12 nicklas 83     }
1518 23 Jan 12 nicklas 84     
1518 23 Jan 12 nicklas 85     if (bloodCases.size() == 1)
1518 23 Jan 12 nicklas 86     {
1518 23 Jan 12 nicklas 87       bloodCase = new Blood(bloodCases.get(0));
1518 23 Jan 12 nicklas 88     }
1518 23 Jan 12 nicklas 89     
1518 23 Jan 12 nicklas 90     return bloodCase;
1518 23 Jan 12 nicklas 91
1518 23 Jan 12 nicklas 92   }
1518 23 Jan 12 nicklas 93   
1518 23 Jan 12 nicklas 94   /**
1821 06 Feb 13 nicklas 95     Find all blood information by case name without filtering on the 'BloodSample' annotation.
1821 06 Feb 13 nicklas 96     This method will check for  {@link Subtype#BLOOD} samples with a name matching the case name 
1821 06 Feb 13 nicklas 97     (eg. xxx.b).
1821 06 Feb 13 nicklas 98     @since 2.11
1821 06 Feb 13 nicklas 99   */
1821 06 Feb 13 nicklas 100   public static List<Blood> findAllByCaseName(DbControl dc, String name)
1821 06 Feb 13 nicklas 101   {
1821 06 Feb 13 nicklas 102     Blood bloodCase = null;
1821 06 Feb 13 nicklas 103     
1821 06 Feb 13 nicklas 104     // Get rid of suffixes in the name (eg. 'C' which is used for pre-neoadjuvant forms)
1821 06 Feb 13 nicklas 105     if (name.length() > 7) name = name.substring(0, 7);    
1831 08 Feb 13 nicklas 106   
1821 06 Feb 13 nicklas 107     // Look for a blood case with the given name 
1821 06 Feb 13 nicklas 108     ItemQuery<Sample> bloodQuery = Sample.getQuery();
1821 06 Feb 13 nicklas 109     Subtype.BLOOD.addFilter(dc, bloodQuery);
2917 11 Nov 14 nicklas 110     bloodQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
1831 08 Feb 13 nicklas 111     bloodQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", name+".%", Type.STRING)));
2917 11 Nov 14 nicklas 112     bloodQuery.order(Orders.asc(Hql.property("name")));
2917 11 Nov 14 nicklas 113
1821 06 Feb 13 nicklas 114     List<Sample> tmp = bloodQuery.list(dc);
1821 06 Feb 13 nicklas 115     List<Blood> blood = new ArrayList<Blood>(tmp.size());
1821 06 Feb 13 nicklas 116     for (Sample s : tmp)
1821 06 Feb 13 nicklas 117     {
1821 06 Feb 13 nicklas 118       blood.add(new Blood(s));
1821 06 Feb 13 nicklas 119     }
1821 06 Feb 13 nicklas 120     return blood;
1821 06 Feb 13 nicklas 121   }
1821 06 Feb 13 nicklas 122
1821 06 Feb 13 nicklas 123   /**
4075 05 Sep 16 nicklas 124      Find a blood item with the given external ID.
4075 05 Sep 16 nicklas 125      @return A blood item, or null if not found
4075 05 Sep 16 nicklas 126      @since 4.7
4075 05 Sep 16 nicklas 127   */
4075 05 Sep 16 nicklas 128   public static Blood findByExternalId(DbControl dc, String externalId)
4075 05 Sep 16 nicklas 129   {
4075 05 Sep 16 nicklas 130     Blood item = null;
4075 05 Sep 16 nicklas 131     
4075 05 Sep 16 nicklas 132     ItemQuery<Sample> query = Sample.getQuery();
4075 05 Sep 16 nicklas 133     Subtype.BLOOD.addFilter(dc, query);
4075 05 Sep 16 nicklas 134     query.restrict(Restrictions.eq(Hql.property("externalId"), Expressions.string(externalId)));
4075 05 Sep 16 nicklas 135     query.order(Orders.desc(Hql.property("name")));
4075 05 Sep 16 nicklas 136     query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
4075 05 Sep 16 nicklas 137     
4075 05 Sep 16 nicklas 138     List<Sample> items = query.list(dc);
4075 05 Sep 16 nicklas 139     if (items.size() > 1)
4075 05 Sep 16 nicklas 140     {
4075 05 Sep 16 nicklas 141       throw new InvalidDataException(
4075 05 Sep 16 nicklas 142           "More than one blood item with the external id '" + externalId + "' was found. " +
4075 05 Sep 16 nicklas 143           "This wizard can't be used until that is corrected.");
4075 05 Sep 16 nicklas 144     }
4075 05 Sep 16 nicklas 145     if (items.size() == 1)
4075 05 Sep 16 nicklas 146     {
4075 05 Sep 16 nicklas 147       item = new Blood(items.get(0));
4075 05 Sep 16 nicklas 148     }
4075 05 Sep 16 nicklas 149     return item;
4075 05 Sep 16 nicklas 150   }
4075 05 Sep 16 nicklas 151
4075 05 Sep 16 nicklas 152   
4075 05 Sep 16 nicklas 153   /**
1518 23 Jan 12 nicklas 154     Find all blood information linked with a patient. A patient can have any
1518 23 Jan 12 nicklas 155     number of blood cases.
1518 23 Jan 12 nicklas 156   */
1518 23 Jan 12 nicklas 157   public static List<Blood> findByPatient(DbControl dc, Patient patient)
1518 23 Jan 12 nicklas 158   {
1821 06 Feb 13 nicklas 159     ItemQuery<Sample> bloodQuery = patient.getBioSource().getSamples();
1821 06 Feb 13 nicklas 160     Subtype.BLOOD.addFilter(dc, bloodQuery);
1821 06 Feb 13 nicklas 161     bloodQuery.include(Include.ALL);
1821 06 Feb 13 nicklas 162     bloodQuery.order(Orders.asc(Hql.property("name")));
1821 06 Feb 13 nicklas 163     List<Sample> tmp = bloodQuery.list(dc);
1821 06 Feb 13 nicklas 164     List<Blood> blood = new ArrayList<Blood>(tmp.size());
1821 06 Feb 13 nicklas 165     for (Sample s : tmp)
1518 23 Jan 12 nicklas 166     {
1821 06 Feb 13 nicklas 167       blood.add(new Blood(s));
1518 23 Jan 12 nicklas 168     }
1821 06 Feb 13 nicklas 169     return blood;
1518 23 Jan 12 nicklas 170   }
1518 23 Jan 12 nicklas 171   
1614 24 Apr 12 nicklas 172   /**
2023 19 Sep 13 olle 173     Find blood information by RCCID number. This method will check for 
2023 19 Sep 13 olle 174     {@link Subtype#BLOOD} samples annotated with BloodRccidNumber=name.
2023 19 Sep 13 olle 175     <p>
2023 19 Sep 13 olle 176     If exactly one match is found this is the search for blood sample. More than one
2023 19 Sep 13 olle 177     match is an error condition. No match indicates an RCCID number that has not yet been
2023 19 Sep 13 olle 178     registered (null is returned).
2023 19 Sep 13 olle 179     
2023 19 Sep 13 olle 180     @param dc DbControl The DbControl to use to connect to the database.
2023 19 Sep 13 olle 181     @param name String The RCCID number to find a blood sample for.
2023 19 Sep 13 olle 182     @return Blood A blood item with the input RCCID number, or null if not found.
2023 19 Sep 13 olle 183     @since 2.13
2023 19 Sep 13 olle 184    */
2023 19 Sep 13 olle 185   public static Blood findByRccidNumber(DbControl dc, String name)
2023 19 Sep 13 olle 186   {
2023 19 Sep 13 olle 187     Blood blood = null;
2023 19 Sep 13 olle 188
2023 19 Sep 13 olle 189     // Only follow-up blood samples have non-blank RCCID numbers.
2023 19 Sep 13 olle 190     // Return null if input RCCID number is null or empty string.
2023 19 Sep 13 olle 191     if (name == null || name.equals(""))
2023 19 Sep 13 olle 192     {
2023 19 Sep 13 olle 193       return null;
2023 19 Sep 13 olle 194     }
2023 19 Sep 13 olle 195
2023 19 Sep 13 olle 196     // Look for a blood sample with annotation BloodRccidNumber=name
2023 19 Sep 13 olle 197     ItemQuery<Sample> bloodQuery = Sample.getQuery();
2023 19 Sep 13 olle 198     Subtype.BLOOD.addFilter(dc, bloodQuery);
6801 11 Aug 22 nicklas 199     bloodQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
6801 11 Aug 22 nicklas 200     bloodQuery.join(Annotations.innerJoin(Annotationtype.BLOOD_RCCIDNUMBER.get(dc), "rcc"));
6801 11 Aug 22 nicklas 201     bloodQuery.restrict(Restrictions.eq(Hql.alias("rcc"), Expressions.string(name)));
2023 19 Sep 13 olle 202     
2023 19 Sep 13 olle 203     List<Sample> bloodSamples = bloodQuery.list(dc);
2023 19 Sep 13 olle 204   
2023 19 Sep 13 olle 205     // ...if more than one is found, something is incorrectly registered... abort
2023 19 Sep 13 olle 206     if (bloodSamples.size() > 1)
2023 19 Sep 13 olle 207     {
2023 19 Sep 13 olle 208       throw new InvalidDataException(
2023 19 Sep 13 olle 209           "Found " + bloodSamples.size() + " blood samples with same RCCID number (" + name + 
2023 19 Sep 13 olle 210           "). This wizard can't be used until that is corrected.");
2023 19 Sep 13 olle 211     }
2023 19 Sep 13 olle 212   
2023 19 Sep 13 olle 213     if (bloodSamples.size() == 1)
2023 19 Sep 13 olle 214     {
2023 19 Sep 13 olle 215       blood = new Blood(bloodSamples.get(0));
2023 19 Sep 13 olle 216     }
2023 19 Sep 13 olle 217   
2023 19 Sep 13 olle 218     return blood;
2023 19 Sep 13 olle 219   }
2023 19 Sep 13 olle 220
2023 19 Sep 13 olle 221   /**
2023 19 Sep 13 olle 222     Find all blood information by base RCCID number, i.e. the RCCID number disregarding the suffix
2023 19 Sep 13 olle 223     letter 'B', 'C', or 'D'. This method will check for {@link Subtype#BLOOD} samples annotated
2023 19 Sep 13 olle 224     with BloodRccidNumber=rccidNumber, where rccidNumber is input name string with suffix letter
2023 19 Sep 13 olle 225     exchanged for 'B', 'C', and 'D'.
2023 19 Sep 13 olle 226     <p>
6801 11 Aug 22 nicklas 227     If the given RCCID number doesn't have a suffix (eg. the new pattern NNNN-NNNNNNNN),
6801 11 Aug 22 nicklas 228     it is used as it is and no suffixes are added.
6801 11 Aug 22 nicklas 229     <p>
2023 19 Sep 13 olle 230     No match indicates an RCCID number that has not yet been registered (null is returned).
2023 19 Sep 13 olle 231     
2023 19 Sep 13 olle 232     @param dc DbControl The DbControl to use to connect to the database.
2023 19 Sep 13 olle 233     @param name String The RCCID number to find a blood sample for.
2023 19 Sep 13 olle 234     @return Blood A blood item with the input RCCID number, or null if not found.
2023 19 Sep 13 olle 235     @since 2.13
2023 19 Sep 13 olle 236    */
2023 19 Sep 13 olle 237   public static List<Blood> findAllByBaseRccidNumber(DbControl dc, String name)
2023 19 Sep 13 olle 238   {
2023 19 Sep 13 olle 239     // Only follow-up blood samples have non-blank RCCID numbers.
2023 19 Sep 13 olle 240     // Return null if input RCCID number is null or empty string.
2023 19 Sep 13 olle 241     if (name == null || name.equals(""))
2023 19 Sep 13 olle 242     {
2023 19 Sep 13 olle 243       return null;
2023 19 Sep 13 olle 244     }
2023 19 Sep 13 olle 245
6801 11 Aug 22 nicklas 246     // Get base RCCID number if it follows the 10 digits + 'B', 'C' or 'D' suffix format
6801 11 Aug 22 nicklas 247     // Otherwise we just use the given name without suffix
2023 19 Sep 13 olle 248     String baseRccidNumber = name;
6801 11 Aug 22 nicklas 249     String[] suffixes = { "" };
6801 11 Aug 22 nicklas 250     if (name.matches("\\d{10}(B|C|D)"))
2023 19 Sep 13 olle 251     {
2023 19 Sep 13 olle 252       // Set base RCCID number as name with last character removed
2023 19 Sep 13 olle 253       baseRccidNumber = name.substring(0, name.length() - 1);
6801 11 Aug 22 nicklas 254       suffixes = new String[] {"B", "C", "D"};
2023 19 Sep 13 olle 255     }
6801 11 Aug 22 nicklas 256     
2023 19 Sep 13 olle 257     // Check for blood samples with base RCCID number 
6801 11 Aug 22 nicklas 258     ItemQuery<Sample> bloodQuery = Sample.getQuery();
6801 11 Aug 22 nicklas 259     Subtype.BLOOD.addFilter(dc, bloodQuery);
6801 11 Aug 22 nicklas 260     bloodQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
6801 11 Aug 22 nicklas 261     bloodQuery.join(Annotations.innerJoin(Annotationtype.BLOOD_RCCIDNUMBER.get(dc), "rcc"));
6801 11 Aug 22 nicklas 262     bloodQuery.restrict(Restrictions.eq(Hql.alias("rcc"), Expressions.parameter("rccId", Type.STRING)));
6801 11 Aug 22 nicklas 263     
6801 11 Aug 22 nicklas 264     List<Blood> bloodList = new ArrayList<Blood>();
6801 11 Aug 22 nicklas 265     for (String suffix : suffixes)
2023 19 Sep 13 olle 266     {
2023 19 Sep 13 olle 267       // Look for a blood sample with annotation BloodRccidNumber=rccidNumber
6801 11 Aug 22 nicklas 268       bloodQuery.setParameter("rccId", baseRccidNumber + suffix, Type.STRING);
6801 11 Aug 22 nicklas 269       bloodList.addAll(Blood.toList(bloodQuery.list(dc)));
2023 19 Sep 13 olle 270     }
2023 19 Sep 13 olle 271     // Return null if no blood samples were found with input base RCCID number 
6801 11 Aug 22 nicklas 272     return bloodList.size() == 0 ? null : bloodList;
2023 19 Sep 13 olle 273   }
2023 19 Sep 13 olle 274
6835 05 Sep 22 nicklas 275   /**
6835 05 Sep 22 nicklas 276     Find all blood information by BD47_ID. This method will check for {@link Subtype#BLOOD} 
6835 05 Sep 22 nicklas 277     samples annotated with BD47_ID=idString, where idString is input name string.
6835 05 Sep 22 nicklas 278     
6835 05 Sep 22 nicklas 279     @param dc DbControl The DbControl to use to connect to the database.
6835 05 Sep 22 nicklas 280     @param name String The BD47_ID to find a blood sample for.
6835 05 Sep 22 nicklas 281     @return Blood A blood item with the input BD47_ID, or null if not found.
6835 05 Sep 22 nicklas 282     @since 4.39.2
6835 05 Sep 22 nicklas 283    */
6835 05 Sep 22 nicklas 284   public static List<Blood> findAllByBD47Id(DbControl dc, String name)
6835 05 Sep 22 nicklas 285   {
6835 05 Sep 22 nicklas 286     // Return null if input is null or empty string.
6835 05 Sep 22 nicklas 287     if (name == null || name.equals(""))
6835 05 Sep 22 nicklas 288     {
6835 05 Sep 22 nicklas 289       return null;
6835 05 Sep 22 nicklas 290     }
4900 10 Jul 18 nicklas 291   
6835 05 Sep 22 nicklas 292     // Check for blood samples with base RCCID number 
6835 05 Sep 22 nicklas 293     ItemQuery<Sample> bloodQuery = Sample.getQuery();
6835 05 Sep 22 nicklas 294     Subtype.BLOOD.addFilter(dc, bloodQuery);
6835 05 Sep 22 nicklas 295     bloodQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
6835 05 Sep 22 nicklas 296     bloodQuery.join(Annotations.innerJoin(Annotationtype.BD47_ID.get(dc), "bd47"));
6835 05 Sep 22 nicklas 297     bloodQuery.restrict(Restrictions.eq(Hql.alias("bd47"), Expressions.string(name)));
6835 05 Sep 22 nicklas 298     
6835 05 Sep 22 nicklas 299     List<Blood> bloodList = Blood.toList(bloodQuery.list(dc));
6835 05 Sep 22 nicklas 300     // Return null if no blood samples were found 
6835 05 Sep 22 nicklas 301     return bloodList.size() == 0 ? null : bloodList;
6835 05 Sep 22 nicklas 302   }
6835 05 Sep 22 nicklas 303
6835 05 Sep 22 nicklas 304   
2023 19 Sep 13 olle 305   /**
4900 10 Jul 18 nicklas 306     Find the next name to give a "Blood" item. This assumes that
4900 10 Jul 18 nicklas 307     all items are using the naming convention: foo.b, foo.b2, and
4900 10 Jul 18 nicklas 308     so on. NOTE! The first child item have no number!
4900 10 Jul 18 nicklas 309     @return The next unused name
4900 10 Jul 18 nicklas 310     @since 4.19
1614 24 Apr 12 nicklas 311   */
4900 10 Jul 18 nicklas 312   public static String getNextBloodName(DbControl dc, String caseName)
1614 24 Apr 12 nicklas 313   {
4900 10 Jul 18 nicklas 314     ItemQuery<Sample> query = Sample.getQuery();
4900 10 Jul 18 nicklas 315     query.setIncludes(Include.ALL);
4900 10 Jul 18 nicklas 316     Subtype.BLOOD.addFilter(dc, query);
4900 10 Jul 18 nicklas 317     query.restrict(Restrictions.like(Hql.property("name"), Expressions.string(caseName + ".%")));
4900 10 Jul 18 nicklas 318     return ReggieItem.getNextChildItemName(dc, caseName, query, Subtype.BLOOD.getItemSuffix(), false);
1614 24 Apr 12 nicklas 319   }
4070 02 Sep 16 nicklas 320   
1614 24 Apr 12 nicklas 321   /**
4070 02 Sep 16 nicklas 322     Generate the next auto-generated external ID. This method will search all blood
4070 02 Sep 16 nicklas 323     starting with the given prefix and find the one with the highest numeric suffix. 
4902 10 Jul 18 nicklas 324     The returned string is the found blood + 1.
4070 02 Sep 16 nicklas 325     twice.
4902 10 Jul 18 nicklas 326     @since 4.19
4070 02 Sep 16 nicklas 327   */
4902 10 Jul 18 nicklas 328   public static String getNextExternalId(DbControl dc)
4070 02 Sep 16 nicklas 329   {
4070 02 Sep 16 nicklas 330     ItemQuery<Sample> bloodQuery = Sample.getQuery();
5088 13 Nov 18 nicklas 331     return ReggieItem.getNextExternalId(dc, bloodQuery, Subtype.BLOOD.getExternalIdPrefix());
4070 02 Sep 16 nicklas 332   }
4070 02 Sep 16 nicklas 333
4070 02 Sep 16 nicklas 334   /**
1614 24 Apr 12 nicklas 335     Load a blood sample given the exact name of the item.
1614 24 Apr 12 nicklas 336     @since 2.5
1614 24 Apr 12 nicklas 337   */
1614 24 Apr 12 nicklas 338   public static Blood getByName(DbControl dc, String name)
1614 24 Apr 12 nicklas 339   {
1614 24 Apr 12 nicklas 340     Blood blood = null;
1614 24 Apr 12 nicklas 341     
1614 24 Apr 12 nicklas 342     // Look for a blood case with the given name 
1614 24 Apr 12 nicklas 343     ItemQuery<Sample> bloodQuery = Sample.getQuery();
1614 24 Apr 12 nicklas 344     Subtype.BLOOD.addFilter(dc, bloodQuery);
1614 24 Apr 12 nicklas 345     bloodQuery.restrict(Restrictions.eq(Hql.property("name"), Expressions.parameter("name", name, Type.STRING)));
1614 24 Apr 12 nicklas 346     
1614 24 Apr 12 nicklas 347     List<Sample> bloodSamples = bloodQuery.list(dc);
1614 24 Apr 12 nicklas 348     
1614 24 Apr 12 nicklas 349     // ...if more than one is found, something is incorrectly registered... abort
1614 24 Apr 12 nicklas 350     if (bloodSamples.size() > 1)
1614 24 Apr 12 nicklas 351     {
1614 24 Apr 12 nicklas 352       throw new InvalidDataException(
1614 24 Apr 12 nicklas 353         "Found " + bloodSamples.size() + " blood samples with the same name (" + name + 
1614 24 Apr 12 nicklas 354         "). This wizard can't be used until that is corrected.");
1614 24 Apr 12 nicklas 355     }
1614 24 Apr 12 nicklas 356     
1614 24 Apr 12 nicklas 357     if (bloodSamples.size() == 1)
1614 24 Apr 12 nicklas 358     {
1614 24 Apr 12 nicklas 359       blood = new Blood(bloodSamples.get(0));
1614 24 Apr 12 nicklas 360     }
1614 24 Apr 12 nicklas 361     
1614 24 Apr 12 nicklas 362     return blood;
1614 24 Apr 12 nicklas 363   }
1614 24 Apr 12 nicklas 364   
1518 23 Jan 12 nicklas 365   public static Blood getById(DbControl dc, int caseId)
1518 23 Jan 12 nicklas 366   {
1518 23 Jan 12 nicklas 367     Sample s = Sample.getById(dc, caseId);
1518 23 Jan 12 nicklas 368     return s == null ? null : new Blood(s);
1518 23 Jan 12 nicklas 369   }
1518 23 Jan 12 nicklas 370   
5138 22 Nov 18 nicklas 371   public static List<Blood> toList(Collection<Sample> samples)
5138 22 Nov 18 nicklas 372   {
5138 22 Nov 18 nicklas 373     List<Blood> blood = new ArrayList<Blood>(samples.size());
5138 22 Nov 18 nicklas 374     for (Sample s : samples)
5138 22 Nov 18 nicklas 375     {
5138 22 Nov 18 nicklas 376       blood.add(new Blood(s));
5138 22 Nov 18 nicklas 377     }
5138 22 Nov 18 nicklas 378     return blood;
5138 22 Nov 18 nicklas 379   }
5138 22 Nov 18 nicklas 380   
1518 23 Jan 12 nicklas 381   private Blood(Sample sample)
1518 23 Jan 12 nicklas 382   {
1518 23 Jan 12 nicklas 383     super(sample);
1518 23 Jan 12 nicklas 384   }
1518 23 Jan 12 nicklas 385   
1518 23 Jan 12 nicklas 386   
1518 23 Jan 12 nicklas 387   /**
1518 23 Jan 12 nicklas 388     Get the real sample that represents this case in BASE.
1518 23 Jan 12 nicklas 389   */
1518 23 Jan 12 nicklas 390   public Sample getSample()
1518 23 Jan 12 nicklas 391   {
1518 23 Jan 12 nicklas 392     return getItem();
1518 23 Jan 12 nicklas 393   }
1518 23 Jan 12 nicklas 394   
1518 23 Jan 12 nicklas 395   /**
1518 23 Jan 12 nicklas 396     Verify that the patient has given their permission to participate in the
1518 23 Jan 12 nicklas 397     study. Due to the order that things get registered, a non-existing "Consent"
1518 23 Jan 12 nicklas 398     annotation is accepted. If the annotation exists the answer must be "Yes",
1518 23 Jan 12 nicklas 399     or an exception is thrown.
1518 23 Jan 12 nicklas 400   */
1610 23 Apr 12 nicklas 401   public void verifyConsent(DbControl dc, Annotationtype consentType)
1518 23 Jan 12 nicklas 402   {
1518 23 Jan 12 nicklas 403     if (consentType == null)
1518 23 Jan 12 nicklas 404     {
1610 23 Apr 12 nicklas 405       consentType = Annotationtype.CONSENT;
1518 23 Jan 12 nicklas 406     }
1610 23 Apr 12 nicklas 407     String consent = (String)consentType.getAnnotationValue(dc, getItem());
1518 23 Jan 12 nicklas 408     if (consent != null && !consent.equals("Yes"))
1518 23 Jan 12 nicklas 409     {
1518 23 Jan 12 nicklas 410       throw new PermissionDeniedException("The case (" + getName() + 
1518 23 Jan 12 nicklas 411         ") has not agreed to participate in the study.");
1518 23 Jan 12 nicklas 412     }
1518 23 Jan 12 nicklas 413
1518 23 Jan 12 nicklas 414   }
1518 23 Jan 12 nicklas 415   
1518 23 Jan 12 nicklas 416 }