extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/SpecimenTubeServlet.java

Code
Comments
Other
Rev Date Author Line
2890 03 Nov 14 nicklas 1 package net.sf.basedb.reggie.servlet;
2890 03 Nov 14 nicklas 2
2890 03 Nov 14 nicklas 3 import java.io.IOException;
4550 30 Jun 17 nicklas 4 import java.util.ArrayList;
5344 02 Apr 19 nicklas 5 import java.util.Collections;
2890 03 Nov 14 nicklas 6 import java.util.Date;
5344 02 Apr 19 nicklas 7 import java.util.HashSet;
2890 03 Nov 14 nicklas 8 import java.util.List;
5344 02 Apr 19 nicklas 9 import java.util.Set;
2890 03 Nov 14 nicklas 10
2890 03 Nov 14 nicklas 11 import javax.servlet.ServletException;
2890 03 Nov 14 nicklas 12 import javax.servlet.http.HttpServlet;
2890 03 Nov 14 nicklas 13 import javax.servlet.http.HttpServletRequest;
2890 03 Nov 14 nicklas 14 import javax.servlet.http.HttpServletResponse;
2890 03 Nov 14 nicklas 15
2890 03 Nov 14 nicklas 16 import net.sf.basedb.core.BioMaterialEvent;
2890 03 Nov 14 nicklas 17 import net.sf.basedb.core.BioPlate;
2890 03 Nov 14 nicklas 18 import net.sf.basedb.core.BioWell;
5344 02 Apr 19 nicklas 19 import net.sf.basedb.core.ClientDefaultSetting;
2890 03 Nov 14 nicklas 20 import net.sf.basedb.core.DbControl;
7188 22 May 23 nicklas 21 import net.sf.basedb.core.Hardware;
2890 03 Nov 14 nicklas 22 import net.sf.basedb.core.InvalidDataException;
2890 03 Nov 14 nicklas 23 import net.sf.basedb.core.ItemQuery;
2890 03 Nov 14 nicklas 24 import net.sf.basedb.core.Sample;
2890 03 Nov 14 nicklas 25 import net.sf.basedb.core.SessionControl;
5340 29 Mar 19 nicklas 26 import net.sf.basedb.core.Type;
5339 29 Mar 19 nicklas 27 import net.sf.basedb.core.query.Annotations;
2890 03 Nov 14 nicklas 28 import net.sf.basedb.core.query.Expressions;
2890 03 Nov 14 nicklas 29 import net.sf.basedb.core.query.Hql;
2890 03 Nov 14 nicklas 30 import net.sf.basedb.core.query.Orders;
2890 03 Nov 14 nicklas 31 import net.sf.basedb.core.query.Restrictions;
2890 03 Nov 14 nicklas 32 import net.sf.basedb.reggie.JsonUtil;
3327 11 May 15 nicklas 33 import net.sf.basedb.reggie.Reggie;
2890 03 Nov 14 nicklas 34 import net.sf.basedb.reggie.Site;
5384 26 Apr 19 nicklas 35 import net.sf.basedb.reggie.activity.ActivityDef;
2890 03 Nov 14 nicklas 36 import net.sf.basedb.reggie.converter.StringToDateConverter;
3059 19 Dec 14 nicklas 37 import net.sf.basedb.reggie.counter.CounterService;
2890 03 Nov 14 nicklas 38 import net.sf.basedb.reggie.dao.Annotationtype;
2890 03 Nov 14 nicklas 39 import net.sf.basedb.reggie.dao.Case;
5344 02 Apr 19 nicklas 40 import net.sf.basedb.reggie.dao.ClientApp;
4898 10 Jul 18 nicklas 41 import net.sf.basedb.reggie.dao.ReggieItem;
2890 03 Nov 14 nicklas 42 import net.sf.basedb.reggie.dao.ReggieRole;
2890 03 Nov 14 nicklas 43 import net.sf.basedb.reggie.dao.SpecimenTube;
2890 03 Nov 14 nicklas 44 import net.sf.basedb.reggie.dao.StoragePlate;
7140 28 Apr 23 nicklas 45 import net.sf.basedb.reggie.dao.StoragePlate.BoxType;
2890 03 Nov 14 nicklas 46 import net.sf.basedb.reggie.dao.Subtype;
2890 03 Nov 14 nicklas 47 import net.sf.basedb.util.Values;
2890 03 Nov 14 nicklas 48 import net.sf.basedb.util.error.ThrowableUtil;
5371 16 Apr 19 nicklas 49 import net.sf.basedb.util.excel.XlsxTableWriter;
5371 16 Apr 19 nicklas 50 import net.sf.basedb.util.excel.XlsxToCsvUtil;
5308 15 Feb 19 nicklas 51 import net.sf.basedb.util.export.TableWriter;
2890 03 Nov 14 nicklas 52 import net.sf.basedb.util.formatter.WellCoordinateFormatter;
2890 03 Nov 14 nicklas 53
7024 07 Feb 23 nicklas 54 import org.apache.commons.lang3.time.FastDateFormat;
2890 03 Nov 14 nicklas 55 import org.json.simple.JSONArray;
2890 03 Nov 14 nicklas 56 import org.json.simple.JSONObject;
2890 03 Nov 14 nicklas 57
2890 03 Nov 14 nicklas 58
2890 03 Nov 14 nicklas 59 public class SpecimenTubeServlet 
2890 03 Nov 14 nicklas 60   extends HttpServlet 
2890 03 Nov 14 nicklas 61 {  
2890 03 Nov 14 nicklas 62   private static final long serialVersionUID = -8107161732923753803L;
2890 03 Nov 14 nicklas 63
2890 03 Nov 14 nicklas 64   public SpecimenTubeServlet()
2890 03 Nov 14 nicklas 65   {}
2890 03 Nov 14 nicklas 66   
2890 03 Nov 14 nicklas 67   @Override
2890 03 Nov 14 nicklas 68   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
2890 03 Nov 14 nicklas 69     throws ServletException, IOException 
2890 03 Nov 14 nicklas 70   {
2890 03 Nov 14 nicklas 71     String cmd = req.getParameter("cmd");
2890 03 Nov 14 nicklas 72     JsonUtil.setJsonResponseHeaders(resp);
2890 03 Nov 14 nicklas 73     
2890 03 Nov 14 nicklas 74     JSONObject json = new JSONObject();
2890 03 Nov 14 nicklas 75     json.put("status", "ok");
2890 03 Nov 14 nicklas 76     
3975 26 May 16 nicklas 77     final SessionControl sc = Reggie.getSessionControl(req);
2890 03 Nov 14 nicklas 78     DbControl dc = null;
2890 03 Nov 14 nicklas 79     try
2890 03 Nov 14 nicklas 80     {
3059 19 Dec 14 nicklas 81       if ("GetCaseInfo".equals(cmd))
2890 03 Nov 14 nicklas 82       {
6330 14 Jun 21 nicklas 83         dc = sc.newDbControl(":Specimen tube registration");
2890 03 Nov 14 nicklas 84         
2890 03 Nov 14 nicklas 85         String caseName = req.getParameter("caseName");
2890 03 Nov 14 nicklas 86         Site site = Site.findByCaseName(caseName);
2890 03 Nov 14 nicklas 87         
2890 03 Nov 14 nicklas 88         // Check that no specimen exists already
2890 03 Nov 14 nicklas 89         List<SpecimenTube> specimenTubes = SpecimenTube.findByCaseName(dc, caseName, site.useCaseSuffixForPreNeoForms());
2890 03 Nov 14 nicklas 90         if (specimenTubes.size() > 0)
2890 03 Nov 14 nicklas 91         {
2890 03 Nov 14 nicklas 92           throw new InvalidDataException(specimenTubes.size() + 
2890 03 Nov 14 nicklas 93             " specimen tubes have already been registered for this case. This wizard can't be used for updating.");
2890 03 Nov 14 nicklas 94         }
2890 03 Nov 14 nicklas 95
2890 03 Nov 14 nicklas 96         
4898 10 Jul 18 nicklas 97         // Check if there are other specimen tubes for this case with other biopsy types to get the current laterality
2890 03 Nov 14 nicklas 98         String laterality = null;
2890 03 Nov 14 nicklas 99         if (site.useCaseSuffixForPreNeoForms())
2890 03 Nov 14 nicklas 100         {
2890 03 Nov 14 nicklas 101           List<SpecimenTube> existingSpecimen = SpecimenTube.findByCaseName(dc, caseName, false);
2890 03 Nov 14 nicklas 102           if (existingSpecimen.size() > 0)
2890 03 Nov 14 nicklas 103           {
2890 03 Nov 14 nicklas 104             laterality = (String)Annotationtype.LATERALITY.getAnnotationValue(dc, existingSpecimen.get(0).getItem());
2890 03 Nov 14 nicklas 105           }
2890 03 Nov 14 nicklas 106         }
2890 03 Nov 14 nicklas 107         
4964 03 Sep 18 nicklas 108         // Get rid of suffix in the case name
4964 03 Sep 18 nicklas 109         if (caseName.length() > 7) caseName = caseName.substring(0, 7);
4964 03 Sep 18 nicklas 110
4898 10 Jul 18 nicklas 111         // Generate a name for first specimen tube and get the index number
4898 10 Jul 18 nicklas 112         // If there are more than one tube, the following names will be generated
4898 10 Jul 18 nicklas 113         // in the javascript side
7000 20 Jan 23 nicklas 114         String specimenName = SpecimenTube.getNextSpecimenName(dc, caseName, false);
4964 03 Sep 18 nicklas 115         int specimenFirstIndex = Values.getInt(specimenName.split("\\.")[1]);
4898 10 Jul 18 nicklas 116       
2890 03 Nov 14 nicklas 117         // Check if we already have information about the case
2890 03 Nov 14 nicklas 118         JSONObject jsonCase = null;
2890 03 Nov 14 nicklas 119         Case theCase = Case.findByName(dc, caseName);
2890 03 Nov 14 nicklas 120
2890 03 Nov 14 nicklas 121         if (theCase != null)
2890 03 Nov 14 nicklas 122         {
2890 03 Nov 14 nicklas 123           // Verify that consent has been given
2890 03 Nov 14 nicklas 124           theCase.verifyConsent(dc, null);
2890 03 Nov 14 nicklas 125           jsonCase = theCase.asJSONObject();
2890 03 Nov 14 nicklas 126           if (laterality == null) laterality = (String)Annotationtype.LATERALITY.getAnnotationValue(dc, theCase.getItem());
2890 03 Nov 14 nicklas 127         }
2890 03 Nov 14 nicklas 128         else
2890 03 Nov 14 nicklas 129         {
2890 03 Nov 14 nicklas 130           jsonCase = new JSONObject();
2890 03 Nov 14 nicklas 131           jsonCase.put("name", caseName);
2890 03 Nov 14 nicklas 132           jsonCase.put("originalName", caseName);
2890 03 Nov 14 nicklas 133         }
4898 10 Jul 18 nicklas 134         jsonCase.put("specimenFirstIndex", specimenFirstIndex);
2890 03 Nov 14 nicklas 135         if (laterality != null) jsonCase.put("laterality", laterality);
2890 03 Nov 14 nicklas 136         json.put("caseInfo", jsonCase);
5345 02 Apr 19 nicklas 137         
5345 02 Apr 19 nicklas 138         JSONObject jsonSite = new JSONObject(site.asJSONObject()); 
5345 02 Apr 19 nicklas 139         jsonSite.put("paused", getPausedSites(dc).contains(site.getPrefix()));
5345 02 Apr 19 nicklas 140         json.put("siteInfo", jsonSite);
2890 03 Nov 14 nicklas 141       }
2890 03 Nov 14 nicklas 142       else if ("FindStoragePositions".equals(cmd))
2890 03 Nov 14 nicklas 143       {
2890 03 Nov 14 nicklas 144         // Find a given number of storage positions. The process
2890 03 Nov 14 nicklas 145         // is complicated by the fact that "old" boxes still may have empty
3327 11 May 15 nicklas 146         // locations so we need to find the 'Sp*' box that was used the last time
3327 11 May 15 nicklas 147         // and move on from there
2890 03 Nov 14 nicklas 148         Integer nofTubes = Values.getInt(req.getParameter("nofTubes"), 1);
5335 28 Mar 19 nicklas 149         boolean includePausePositions = Values.getBoolean(req.getParameter("includePausePositions"));
6330 14 Jun 21 nicklas 150         dc = sc.newDbControl(":Specimen tube registration");
5335 28 Mar 19 nicklas 151
5335 28 Mar 19 nicklas 152         json.put("nofTubes", nofTubes);
2890 03 Nov 14 nicklas 153         
3327 11 May 15 nicklas 154         // Find the specimen with the highest plate/row/column combination
7140 28 Apr 23 nicklas 155         SpecimenTube lastPlacedSpecimen = SpecimenTube.getLastPlacedSpecimen(dc, Subtype.SPECIMEN, "Sp");
7140 28 Apr 23 nicklas 156         List<StoragePlate> spBoxes = StoragePlate.findExistingStorageBoxes(dc, lastPlacedSpecimen, "Sp");
7138 26 Apr 23 nicklas 157         JSONArray jsonWells = findEmptyWells(dc, spBoxes, nofTubes, BoxType.NORMAL);
5335 28 Mar 19 nicklas 158         json.put("wells", jsonWells);
3327 11 May 15 nicklas 159         
5335 28 Mar 19 nicklas 160         if (includePausePositions)
5335 28 Mar 19 nicklas 161         {
5335 28 Mar 19 nicklas 162           // Also find the same number of empty wells in the paused storage boxes
7140 28 Apr 23 nicklas 163           SpecimenTube lastPausedSpecimen = SpecimenTube.getLastPlacedSpecimen(dc, Subtype.SPECIMEN, "PSp");
7140 28 Apr 23 nicklas 164           List<StoragePlate> pausedBoxes = StoragePlate.findExistingStorageBoxes(dc, lastPausedSpecimen, "PSp");
7138 26 Apr 23 nicklas 165           JSONArray jsonPausedWells = findEmptyWells(dc, pausedBoxes, nofTubes, BoxType.PAUSE);
5335 28 Mar 19 nicklas 166           json.put("pausedWells", jsonPausedWells);
5335 28 Mar 19 nicklas 167         }
2890 03 Nov 14 nicklas 168         
2890 03 Nov 14 nicklas 169       }
2890 03 Nov 14 nicklas 170       else if ("ValidateWell".equals(cmd))
2890 03 Nov 14 nicklas 171       {
6330 14 Jun 21 nicklas 172         dc = sc.newDbControl(":Specimen tube registration");
2890 03 Nov 14 nicklas 173         String box = Values.getStringOrNull(req.getParameter("box"));
5333 28 Mar 19 nicklas 174         boolean paused = Values.getBoolean(req.getParameter("paused"));
2890 03 Nov 14 nicklas 175         
2890 03 Nov 14 nicklas 176         String msg = null;
2890 03 Nov 14 nicklas 177         StoragePlate plate = StoragePlate.findByName(dc, box);
2890 03 Nov 14 nicklas 178         if (plate == null)
2890 03 Nov 14 nicklas 179         {
2890 03 Nov 14 nicklas 180           msg = "Can't find storage box with name '" + box + "'";
2890 03 Nov 14 nicklas 181           json.put("box", 1);
2890 03 Nov 14 nicklas 182         }
5333 28 Mar 19 nicklas 183         else if (!paused)
2890 03 Nov 14 nicklas 184         {
2890 03 Nov 14 nicklas 185           String lysBoxName = "Lys"+box.replace("Sp", "");
2890 03 Nov 14 nicklas 186           StoragePlate lysBox = StoragePlate.findByName(dc, lysBoxName);
2890 03 Nov 14 nicklas 187           if (lysBox == null)
2890 03 Nov 14 nicklas 188           {
2890 03 Nov 14 nicklas 189             msg = "There is no corresponding Lys-box for this Sp-box: " + lysBoxName;
2890 03 Nov 14 nicklas 190             json.put("box", 1);
2890 03 Nov 14 nicklas 191           }
2890 03 Nov 14 nicklas 192         }
2890 03 Nov 14 nicklas 193         
2890 03 Nov 14 nicklas 194         if (msg == null)
2890 03 Nov 14 nicklas 195         {
2890 03 Nov 14 nicklas 196           int rows = plate.getBioPlate().getRows();
2890 03 Nov 14 nicklas 197           int columns = plate.getBioPlate().getColumns();
2890 03 Nov 14 nicklas 198           
2890 03 Nov 14 nicklas 199           WellCoordinateFormatter wcfRow = new WellCoordinateFormatter(true);        
2890 03 Nov 14 nicklas 200           String rowString = req.getParameter("row");
2890 03 Nov 14 nicklas 201           int rowNumber = wcfRow.parseString(rowString);
2890 03 Nov 14 nicklas 202                   
2890 03 Nov 14 nicklas 203           Integer columnIndex = Integer.parseInt(req.getParameter("column")) - 1;
2890 03 Nov 14 nicklas 204           WellCoordinateFormatter wcfColumn = new WellCoordinateFormatter(false);
2890 03 Nov 14 nicklas 205           
2890 03 Nov 14 nicklas 206           if (rowNumber < 1 || rowNumber > rows) 
2890 03 Nov 14 nicklas 207           {
2890 03 Nov 14 nicklas 208             msg = "The row must be between "+ wcfRow.format(0) +" and " + wcfRow.format(rows-1);
2890 03 Nov 14 nicklas 209           }
2890 03 Nov 14 nicklas 210           else if (columnIndex < 0 || columnIndex > columns)
2890 03 Nov 14 nicklas 211           {
2890 03 Nov 14 nicklas 212             msg = "The column must be between " +  1 + " and " + columns;
2890 03 Nov 14 nicklas 213           }
2890 03 Nov 14 nicklas 214           else if (!plate.getBioPlate().getBioWell(rowNumber-1, columnIndex).isEmpty() )
2890 03 Nov 14 nicklas 215           {
2890 03 Nov 14 nicklas 216             msg = "Location '"+rowString+wcfColumn.format(columnIndex)+"' is already used.";
2890 03 Nov 14 nicklas 217           }
2890 03 Nov 14 nicklas 218           json.put("position", 1);
2890 03 Nov 14 nicklas 219         }
2890 03 Nov 14 nicklas 220         json.put("message", msg);
2890 03 Nov 14 nicklas 221       }
5340 29 Mar 19 nicklas 222       else if ("GetLastExistingStorageBoxes".equals(cmd))
4550 30 Jun 17 nicklas 223       {
6330 14 Jun 21 nicklas 224         dc = sc.newDbControl(":Storage box creation wizard");
5340 29 Mar 19 nicklas 225         ItemQuery<BioPlate> boxQuery = BioPlate.getQuery();
5340 29 Mar 19 nicklas 226         boxQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name")));
5340 29 Mar 19 nicklas 227         boxQuery.order(Orders.desc(Hql.property("name")));
5340 29 Mar 19 nicklas 228         boxQuery.setMaxResults(1);
4550 30 Jun 17 nicklas 229         
5340 29 Mar 19 nicklas 230         // Specimen storage boxes
5340 29 Mar 19 nicklas 231         boxQuery.setParameter("name", "Sp%", Type.STRING);
5340 29 Mar 19 nicklas 232         List<StoragePlate> boxes = StoragePlate.toStoragePlates(boxQuery.list(dc));
5340 29 Mar 19 nicklas 233         if (boxes.size() > 0) json.put("lastSpBox", boxes.get(0).asJSONObject());
4550 30 Jun 17 nicklas 234         
5340 29 Mar 19 nicklas 235         // Paused specimen storage boxes
5340 29 Mar 19 nicklas 236         boxQuery.setParameter("name", "PSp%", Type.STRING);
5340 29 Mar 19 nicklas 237         boxes = StoragePlate.toStoragePlates(boxQuery.list(dc));
5340 29 Mar 19 nicklas 238         if (boxes.size() > 0) json.put("lastPSpBox", boxes.get(0).asJSONObject());
5340 29 Mar 19 nicklas 239         
7138 26 Apr 23 nicklas 240         // Externally processed specimen
7188 22 May 23 nicklas 241         boxQuery.setParameter("name", "E-Sp%", Type.STRING);
7138 26 Apr 23 nicklas 242         boxes = StoragePlate.toStoragePlates(boxQuery.list(dc));
7188 22 May 23 nicklas 243         if (boxes.size() > 0) 
7188 22 May 23 nicklas 244         {
7188 22 May 23 nicklas 245           StoragePlate box = boxes.get(0);
7188 22 May 23 nicklas 246           Hardware freezer = box.getItem().getFreezer();
7188 22 May 23 nicklas 247           if (freezer != null)
7188 22 May 23 nicklas 248           {
7188 22 May 23 nicklas 249             box.setAnnotation("freezer", freezer.getId());
7188 22 May 23 nicklas 250           }
7188 22 May 23 nicklas 251           json.put("lastESpBox", box.asJSONObject());
7188 22 May 23 nicklas 252         }
7138 26 Apr 23 nicklas 253         
4550 30 Jun 17 nicklas 254         json.put("counts", CounterService.getInstance().getCurrentCounts());
4550 30 Jun 17 nicklas 255       }
4550 30 Jun 17 nicklas 256       else if ("GetStorageBoxLabels".equals(cmd))
4550 30 Jun 17 nicklas 257       {
4550 30 Jun 17 nicklas 258         json = null; // No JSON output
5308 15 Feb 19 nicklas 259         String format = Values.getString(req.getParameter("format"), "csv");
4550 30 Jun 17 nicklas 260         String[] boxNames = Values.getString(req.getParameter("boxes")).split(",");
5308 15 Feb 19 nicklas 261
5308 15 Feb 19 nicklas 262         String baseFilename = "Box_labels_" + boxNames[0];
5308 15 Feb 19 nicklas 263         TableWriter tw = null;
5308 15 Feb 19 nicklas 264         XlsxTableWriter xls = null;
5308 15 Feb 19 nicklas 265         if ("xlsx".equals(format))
5308 15 Feb 19 nicklas 266         {
5308 15 Feb 19 nicklas 267           resp.setHeader("Content-Disposition", "attachment; filename="+baseFilename+".xlsx");
5371 16 Apr 19 nicklas 268           resp.setContentType(XlsxToCsvUtil.XLSX_MIME_TYPE);
5308 15 Feb 19 nicklas 269           xls = new XlsxTableWriter("BoxLabels");
5308 15 Feb 19 nicklas 270           tw = xls;
5308 15 Feb 19 nicklas 271         }
5308 15 Feb 19 nicklas 272         else
5308 15 Feb 19 nicklas 273         {
5308 15 Feb 19 nicklas 274           resp.setHeader("Content-Disposition", "attachment; filename="+baseFilename+".csv");
5308 15 Feb 19 nicklas 275           resp.setContentType("text/plain");
5308 15 Feb 19 nicklas 276           resp.setCharacterEncoding("UTF-8");
5308 15 Feb 19 nicklas 277           tw = new TableWriter(resp.getWriter());
5308 15 Feb 19 nicklas 278           // The LABEL header is only required in the CSV format
5308 15 Feb 19 nicklas 279           tw.tablePrintData("LABEL");
5308 15 Feb 19 nicklas 280         }
5308 15 Feb 19 nicklas 281
4550 30 Jun 17 nicklas 282         for (String boxName : boxNames)
4550 30 Jun 17 nicklas 283         {
5308 15 Feb 19 nicklas 284           tw.tablePrintData(boxName);
5308 15 Feb 19 nicklas 285           tw.tablePrintData(boxName);
5308 15 Feb 19 nicklas 286           tw.tablePrintData(boxName);
4550 30 Jun 17 nicklas 287         }
4550 30 Jun 17 nicklas 288         
5308 15 Feb 19 nicklas 289         if (xls != null) 
5308 15 Feb 19 nicklas 290         {
5308 15 Feb 19 nicklas 291           xls.getSheet().setColumnWidth(0, 18*256);
5308 15 Feb 19 nicklas 292           xls.saveTo(resp.getOutputStream());
5308 15 Feb 19 nicklas 293           xls.close();
5308 15 Feb 19 nicklas 294         }
5308 15 Feb 19 nicklas 295
5308 15 Feb 19 nicklas 296         tw.flush();
4550 30 Jun 17 nicklas 297       }
5339 29 Mar 19 nicklas 298       else if ("GetSpecimenTubesToStore".equals(cmd))
5339 29 Mar 19 nicklas 299       {
6330 14 Jun 21 nicklas 300         dc = sc.newDbControl(":Store paused specimen wizard");
5339 29 Mar 19 nicklas 301         
5339 29 Mar 19 nicklas 302         ItemQuery<Sample> query = Sample.getQuery();
5339 29 Mar 19 nicklas 303         Subtype.SPECIMEN.addFilter(dc, query);
5339 29 Mar 19 nicklas 304         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
5339 29 Mar 19 nicklas 305         query.join(Hql.innerJoin("bioWell", "bw"));
5339 29 Mar 19 nicklas 306         query.join(Hql.innerJoin("bw", "bioPlate", "bp"));
5339 29 Mar 19 nicklas 307         // Located in PSpNNN storage box
5339 29 Mar 19 nicklas 308         query.restrict(Restrictions.like(Hql.property("bioWell.bioPlate.name"), Expressions.string("PSp%")));
5339 29 Mar 19 nicklas 309         // AutoProcessing = null
5339 29 Mar 19 nicklas 310         query.join(Annotations.leftJoin(null, Annotationtype.AUTO_PROCESSING.load(dc), "ap"));
5339 29 Mar 19 nicklas 311         query.restrict(Restrictions.eq(Hql.alias("ap"), null));
5339 29 Mar 19 nicklas 312         // Order by box, row and column
5339 29 Mar 19 nicklas 313         query.order(Orders.asc(Hql.property("bp", "name")));
5339 29 Mar 19 nicklas 314         query.order(Orders.asc(Hql.property("bw", "row")));
5339 29 Mar 19 nicklas 315         query.order(Orders.asc(Hql.property("bw", "column")));
5339 29 Mar 19 nicklas 316         
5339 29 Mar 19 nicklas 317         JSONArray jsonTubes = new JSONArray();
5339 29 Mar 19 nicklas 318         for (SpecimenTube tube : SpecimenTube.toList(query.list(dc)))
5339 29 Mar 19 nicklas 319         {
5339 29 Mar 19 nicklas 320           tube.loadBioPlateLocation();
5339 29 Mar 19 nicklas 321           tube.loadAnnotations(dc, "YellowLabel", Annotationtype.YELLOW_LABEL, null);
5339 29 Mar 19 nicklas 322           tube.loadAnnotations(dc, "ArrivalDate", Annotationtype.ARRIVAL_DATE, Reggie.CONVERTER_DATE_TO_STRING);
5339 29 Mar 19 nicklas 323           jsonTubes.add(tube.asJSONObject());
5339 29 Mar 19 nicklas 324         }
5339 29 Mar 19 nicklas 325         json.put("specimenTubes", jsonTubes);
5339 29 Mar 19 nicklas 326       }
5341 02 Apr 19 nicklas 327       else if ("GetPausedSpecimenTubes".equals(cmd))
5341 02 Apr 19 nicklas 328       {
6330 14 Jun 21 nicklas 329         dc = sc.newDbControl(":Paused specime wizard");
5341 02 Apr 19 nicklas 330         
5341 02 Apr 19 nicklas 331         ItemQuery<Sample> query = Sample.getQuery();
5341 02 Apr 19 nicklas 332         Subtype.SPECIMEN.addFilter(dc, query);
5341 02 Apr 19 nicklas 333         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
5341 02 Apr 19 nicklas 334         query.join(Hql.innerJoin("bioWell", "bw"));
5341 02 Apr 19 nicklas 335         query.join(Hql.innerJoin("bw", "bioPlate", "bp"));
5341 02 Apr 19 nicklas 336         // Located in PSpNNN storage box
5341 02 Apr 19 nicklas 337         query.restrict(Restrictions.like(Hql.property("bioWell.bioPlate.name"), Expressions.string("PSp%")));
5341 02 Apr 19 nicklas 338         // AutoProcessing = Disabled || ReProcess
5341 02 Apr 19 nicklas 339         query.join(Annotations.innerJoin(null, Annotationtype.AUTO_PROCESSING.load(dc), "ap"));
5341 02 Apr 19 nicklas 340         query.restrict(Restrictions.in(Hql.alias("ap"), Expressions.string("Disable"), Expressions.string("ReProcess")));
5341 02 Apr 19 nicklas 341         // Order by box, row and column
5341 02 Apr 19 nicklas 342         query.order(Orders.asc(Hql.property("bp", "name")));
5341 02 Apr 19 nicklas 343         query.order(Orders.asc(Hql.property("bw", "row")));
5341 02 Apr 19 nicklas 344         query.order(Orders.asc(Hql.property("bw", "column")));
5341 02 Apr 19 nicklas 345         
5341 02 Apr 19 nicklas 346         JSONArray jsonTubes = new JSONArray();
5341 02 Apr 19 nicklas 347         for (SpecimenTube tube : SpecimenTube.toList(query.list(dc)))
5341 02 Apr 19 nicklas 348         {
5341 02 Apr 19 nicklas 349           tube.loadBioPlateLocation();
5341 02 Apr 19 nicklas 350           tube.loadAnnotations(dc, "AutoProcessing", Annotationtype.AUTO_PROCESSING, null);
5341 02 Apr 19 nicklas 351           tube.loadAnnotations(dc, "YellowLabel", Annotationtype.YELLOW_LABEL, null);
5341 02 Apr 19 nicklas 352           tube.loadAnnotations(dc, "SamplingDate", Annotationtype.SAMPLING_DATETIME, Reggie.CONVERTER_DATE_TO_STRING);
5341 02 Apr 19 nicklas 353           tube.loadAnnotations(dc, "ArrivalDate", Annotationtype.ARRIVAL_DATE, Reggie.CONVERTER_DATE_TO_STRING);
5341 02 Apr 19 nicklas 354           Site site = Site.findByCaseName(tube.getName());
5341 02 Apr 19 nicklas 355           tube.setAnnotation("site", site.asJSONObject());
5341 02 Apr 19 nicklas 356           jsonTubes.add(tube.asJSONObject());
5341 02 Apr 19 nicklas 357         }
5341 02 Apr 19 nicklas 358         
5344 02 Apr 19 nicklas 359         json.put("sites", getSitesWithPauseInfo(dc));
5341 02 Apr 19 nicklas 360         json.put("specimenTubes", jsonTubes);
5341 02 Apr 19 nicklas 361       }
5344 02 Apr 19 nicklas 362       else if ("GetPauseSettings".equals(cmd))
5344 02 Apr 19 nicklas 363       {
6330 14 Jun 21 nicklas 364         dc = sc.newDbControl(":Paused specimen wizard");
5344 02 Apr 19 nicklas 365         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.ADMINISTRATOR);
5344 02 Apr 19 nicklas 366         json.put("sites", getSitesWithPauseInfo(dc));
5344 02 Apr 19 nicklas 367       }
5339 29 Mar 19 nicklas 368       else if ("GetSpecimenTubeLabels".equals(cmd))
5339 29 Mar 19 nicklas 369       {
5339 29 Mar 19 nicklas 370         json = null; // No JSON output
6330 14 Jun 21 nicklas 371         dc = sc.newDbControl(":Specimen tube registration");
5339 29 Mar 19 nicklas 372         
5339 29 Mar 19 nicklas 373         Integer[] ids = Values.getInt(req.getParameter("specimen").split(","));
5339 29 Mar 19 nicklas 374         String format = Values.getString(req.getParameter("format"), "csv");
5339 29 Mar 19 nicklas 375
5339 29 Mar 19 nicklas 376         // Send labels in a file to the client.
5339 29 Mar 19 nicklas 377         TableWriter tw = null;
5339 29 Mar 19 nicklas 378         XlsxTableWriter xls = null;
5339 29 Mar 19 nicklas 379         if ("xlsx".equals(format))
5339 29 Mar 19 nicklas 380         {
5339 29 Mar 19 nicklas 381           resp.setHeader("Content-Disposition", "attachment; filename=Specimen_labels.xlsx");
5371 16 Apr 19 nicklas 382           resp.setContentType(XlsxToCsvUtil.XLSX_MIME_TYPE);
5339 29 Mar 19 nicklas 383           xls = new XlsxTableWriter("PartitionLabels");
5339 29 Mar 19 nicklas 384           tw = xls;
5339 29 Mar 19 nicklas 385         }
5339 29 Mar 19 nicklas 386         else
5339 29 Mar 19 nicklas 387         {
5339 29 Mar 19 nicklas 388           resp.setHeader("Content-Disposition", "attachment; filename=Specimen_labels.csv");
5339 29 Mar 19 nicklas 389           resp.setContentType("text/plain");
5339 29 Mar 19 nicklas 390           resp.setCharacterEncoding("UTF-8");
5339 29 Mar 19 nicklas 391           tw = new TableWriter(resp.getWriter());
5339 29 Mar 19 nicklas 392           // The LABEL header is only required in the CSV format
5339 29 Mar 19 nicklas 393           tw.tablePrintData("LABEL");
5339 29 Mar 19 nicklas 394         }
5339 29 Mar 19 nicklas 395
5339 29 Mar 19 nicklas 396         for (Integer specimenId : ids)
5339 29 Mar 19 nicklas 397         {
5339 29 Mar 19 nicklas 398           SpecimenTube sp = SpecimenTube.getById(dc, specimenId);
5339 29 Mar 19 nicklas 399           tw.tablePrintData(sp.getName());
5339 29 Mar 19 nicklas 400         }
5339 29 Mar 19 nicklas 401         tw.flush();
5339 29 Mar 19 nicklas 402         
5339 29 Mar 19 nicklas 403         if (xls != null) 
5339 29 Mar 19 nicklas 404         {
5339 29 Mar 19 nicklas 405           xls.getSheet().setColumnWidth(0, 18*256);
5339 29 Mar 19 nicklas 406           xls.saveTo(resp.getOutputStream());
5339 29 Mar 19 nicklas 407           xls.close();
5339 29 Mar 19 nicklas 408         }
5339 29 Mar 19 nicklas 409       }
2890 03 Nov 14 nicklas 410     }
2890 03 Nov 14 nicklas 411     catch (Throwable t)
2890 03 Nov 14 nicklas 412     {
2890 03 Nov 14 nicklas 413       t.printStackTrace();
4550 30 Jun 17 nicklas 414       if (json != null)
4550 30 Jun 17 nicklas 415       {
4550 30 Jun 17 nicklas 416         json.clear();
4550 30 Jun 17 nicklas 417         json.put("status", "error");
4550 30 Jun 17 nicklas 418         json.put("message", t.getMessage());
4550 30 Jun 17 nicklas 419         json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
4550 30 Jun 17 nicklas 420       }
4550 30 Jun 17 nicklas 421       else
4550 30 Jun 17 nicklas 422       {
4550 30 Jun 17 nicklas 423         resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, t.getMessage());
4550 30 Jun 17 nicklas 424       }
2890 03 Nov 14 nicklas 425     }
2890 03 Nov 14 nicklas 426     finally
2890 03 Nov 14 nicklas 427     {
2890 03 Nov 14 nicklas 428       if (dc!=null) dc.close();
4550 30 Jun 17 nicklas 429       if (json != null)
4550 30 Jun 17 nicklas 430       {
4550 30 Jun 17 nicklas 431         json.writeJSONString(resp.getWriter());
4550 30 Jun 17 nicklas 432       }
2890 03 Nov 14 nicklas 433     }
2890 03 Nov 14 nicklas 434   }
2890 03 Nov 14 nicklas 435   
2890 03 Nov 14 nicklas 436   @Override
2890 03 Nov 14 nicklas 437   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
2890 03 Nov 14 nicklas 438     throws ServletException, IOException 
2890 03 Nov 14 nicklas 439   {  
2890 03 Nov 14 nicklas 440     String cmd = req.getParameter("cmd");
2890 03 Nov 14 nicklas 441     JsonUtil.setJsonResponseHeaders(resp);
2890 03 Nov 14 nicklas 442     
2890 03 Nov 14 nicklas 443     JSONObject json = new JSONObject();
2890 03 Nov 14 nicklas 444     json.put("status", "ok");
2890 03 Nov 14 nicklas 445     
2890 03 Nov 14 nicklas 446     JSONArray jsonMessages = new JSONArray();
3975 26 May 16 nicklas 447     final SessionControl sc = Reggie.getSessionControl(req);
2890 03 Nov 14 nicklas 448     DbControl dc = null;
2890 03 Nov 14 nicklas 449     
2890 03 Nov 14 nicklas 450     try
2890 03 Nov 14 nicklas 451     {
2890 03 Nov 14 nicklas 452       if ("CreateSpecimenTubes".equals(cmd))
2890 03 Nov 14 nicklas 453       {
6330 14 Jun 21 nicklas 454         dc = sc.newDbControl(":Specimen tube registration");
2890 03 Nov 14 nicklas 455         
2890 03 Nov 14 nicklas 456         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SAMPLE_PREP, ReggieRole.ADMINISTRATOR);
2890 03 Nov 14 nicklas 457         
3752 17 Feb 16 nicklas 458         JSONObject jsonReq = JsonUtil.parseRequest(req);
2890 03 Nov 14 nicklas 459         JSONObject jsonCase = (JSONObject)jsonReq.get("caseInfo");
2890 03 Nov 14 nicklas 460         
2890 03 Nov 14 nicklas 461         // Load the case if we already know which case the specimen belong to
2890 03 Nov 14 nicklas 462         Number caseId = (Number)jsonCase.get("id");
2890 03 Nov 14 nicklas 463         Sample theCase = null;
2890 03 Nov 14 nicklas 464         if (caseId != null)
2890 03 Nov 14 nicklas 465         {
2890 03 Nov 14 nicklas 466           theCase = Sample.getById(dc, caseId.intValue());
2890 03 Nov 14 nicklas 467           // If the Case doesn't belong to a patient yet
2890 03 Nov 14 nicklas 468           // it is a free-floating consent registration only and
2890 03 Nov 14 nicklas 469           // we should not link the specimen since the case may
2890 03 Nov 14 nicklas 470           // have to bve merged with another case of the same patient
2890 03 Nov 14 nicklas 471           if (!theCase.hasSingleParent()) theCase = null;
2890 03 Nov 14 nicklas 472         }
2890 03 Nov 14 nicklas 473
2890 03 Nov 14 nicklas 474         String laterality = Values.getStringOrNull((String)jsonCase.get("laterality"));        
2890 03 Nov 14 nicklas 475         String otherPathNote = Values.getStringOrNull((String)jsonCase.get("otherPathNote"));
7024 07 Feb 23 nicklas 476         StringToDateConverter dateTimeConverter = new StringToDateConverter(FastDateFormat.getInstance("yyyyMMdd HHmm"));
7024 07 Feb 23 nicklas 477         StringToDateConverter dateConverter = new StringToDateConverter(FastDateFormat.getInstance("yyyyMMdd"));        
2890 03 Nov 14 nicklas 478         Date samplingDateTime = dateTimeConverter.convert((String)jsonCase.get("samplingDate"));
2890 03 Nov 14 nicklas 479         Date createDate = dateConverter.convert((String)jsonCase.get("samplingDate"));
2890 03 Nov 14 nicklas 480         Date rnaLaterDate = dateTimeConverter.convert((String)jsonCase.get("rnaLaterDate"));
2890 03 Nov 14 nicklas 481         Date arrivalDate = dateConverter.convert((String)jsonCase.get("arrivalDate"));        
2890 03 Nov 14 nicklas 482         
2890 03 Nov 14 nicklas 483         JSONArray jsonSpecimen = (JSONArray)jsonCase.get("specimen");
2890 03 Nov 14 nicklas 484                 
2890 03 Nov 14 nicklas 485         if (jsonSpecimen != null && jsonSpecimen.size() > 0)
2890 03 Nov 14 nicklas 486         {
2890 03 Nov 14 nicklas 487           int nofTubes = jsonSpecimen.size();
2890 03 Nov 14 nicklas 488           for (int i=0; i < jsonSpecimen.size(); i++)
2890 03 Nov 14 nicklas 489           {
2890 03 Nov 14 nicklas 490             JSONObject jsonSpec = (JSONObject)jsonSpecimen.get(i);
2890 03 Nov 14 nicklas 491             Sample specimen = Sample.getNew(dc);
2890 03 Nov 14 nicklas 492             specimen.setItemSubtype(Subtype.SPECIMEN.load(dc));
4898 10 Jul 18 nicklas 493             specimen.setName(ReggieItem.ensureNonExistingItem(dc, Subtype.SPECIMEN,(String)jsonSpec.get("name")));
5088 13 Nov 18 nicklas 494             specimen.setExternalId(SpecimenTube.getNextExternalId(dc, Subtype.SPECIMEN));
2890 03 Nov 14 nicklas 495             dc.saveItem(specimen);
2890 03 Nov 14 nicklas 496             
2890 03 Nov 14 nicklas 497             BioMaterialEvent creationEvent = specimen.getCreationEvent();
2890 03 Nov 14 nicklas 498             if (theCase != null) creationEvent.setSource(theCase);
2890 03 Nov 14 nicklas 499             creationEvent.setEventDate(createDate);
2890 03 Nov 14 nicklas 500             String operatorComment = Values.getStringOrNull((String)jsonSpec.get("comment"));
2890 03 Nov 14 nicklas 501             String specimenTypeString = Values.getStringOrNull((String)jsonSpec.get("specimenType"));
2890 03 Nov 14 nicklas 502             String biopsyTypeString = Values.getStringOrNull((String)jsonSpec.get("biopsyType"));
3602 16 Nov 15 nicklas 503             boolean yellowLabel = Boolean.TRUE.equals(jsonSpec.get("yellowLabel"));
5333 28 Mar 19 nicklas 504             boolean paused = Boolean.TRUE.equals(jsonSpec.get("paused"));
2890 03 Nov 14 nicklas 505             
2890 03 Nov 14 nicklas 506             Annotationtype.NOF_DELIVERED_TUBES.setAnnotationValue(dc, specimen, nofTubes);
2890 03 Nov 14 nicklas 507             Annotationtype.ARRIVAL_DATE.setAnnotationValue(dc, specimen, arrivalDate);            
2890 03 Nov 14 nicklas 508             Annotationtype.LATERALITY.setAnnotationValue(dc, specimen, laterality);
2890 03 Nov 14 nicklas 509             Annotationtype.SAMPLING_DATETIME.setAnnotationValue(dc, specimen, samplingDateTime);
2890 03 Nov 14 nicklas 510             Annotationtype.RNALATER_DATETIME.setAnnotationValue(dc, specimen, rnaLaterDate);
2890 03 Nov 14 nicklas 511             Annotationtype.OTHER_PATH_NOTE.setAnnotationValue(dc, specimen, otherPathNote);
2890 03 Nov 14 nicklas 512             Annotationtype.SPECIMEN_TYPE.setAnnotationValue(dc, specimen, specimenTypeString);
2890 03 Nov 14 nicklas 513             Annotationtype.BIOPSY_TYPE.setAnnotationValue(dc, specimen, biopsyTypeString);
2890 03 Nov 14 nicklas 514             Annotationtype.OPERATOR_DELIVERY_COMMENT.setAnnotationValue(dc, specimen, operatorComment);  
3602 16 Nov 15 nicklas 515             if (yellowLabel)
3602 16 Nov 15 nicklas 516             {
3602 16 Nov 15 nicklas 517               Annotationtype.YELLOW_LABEL.setAnnotationValue(dc, specimen, "yellow");
3602 16 Nov 15 nicklas 518             }
2890 03 Nov 14 nicklas 519             
2890 03 Nov 14 nicklas 520             // Set biowell if it is specified for this tube
2890 03 Nov 14 nicklas 521             String box = (String)jsonSpec.get("box");
2890 03 Nov 14 nicklas 522             String rowString = (String)jsonSpec.get("row");
2890 03 Nov 14 nicklas 523             String columnString = (String)jsonSpec.get("column");
2890 03 Nov 14 nicklas 524             
2890 03 Nov 14 nicklas 525             StoragePlate spBox = StoragePlate.findByName(dc, box);
2890 03 Nov 14 nicklas 526
2890 03 Nov 14 nicklas 527             WellCoordinateFormatter wcfRow = new WellCoordinateFormatter(true);
2890 03 Nov 14 nicklas 528             Integer rowIndex = wcfRow.parseString(rowString)-1;
2890 03 Nov 14 nicklas 529             Integer columnIndex = Integer.parseInt(columnString)-1;              
2890 03 Nov 14 nicklas 530             BioPlate plate = spBox.getBioPlate();
2890 03 Nov 14 nicklas 531             BioWell well = plate.getBioWell(rowIndex, columnIndex);
3602 16 Nov 15 nicklas 532             specimen.setBioWell(well);
5333 28 Mar 19 nicklas 533             String msg = "Specimen tube '" + specimen.getName() + "' registered successfully ";
5333 28 Mar 19 nicklas 534             msg += "[" + box + " " + rowString + columnString+"]";
5333 28 Mar 19 nicklas 535             List<String> attr = new ArrayList<>();
5333 28 Mar 19 nicklas 536             if (yellowLabel) attr.add("yellow");
5333 28 Mar 19 nicklas 537             if (paused) attr.add("paused");
5333 28 Mar 19 nicklas 538             if (attr.size() > 0) msg += " (" + Values.getString(attr, ", ", true) +")";
3602 16 Nov 15 nicklas 539             jsonMessages.add(msg);
2890 03 Nov 14 nicklas 540           }
5421 13 May 19 nicklas 541           ActivityDef.REGISTERED_SPECIMEN.merge(dc, nofTubes);
2890 03 Nov 14 nicklas 542         }
5376 23 Apr 19 nicklas 543         
2890 03 Nov 14 nicklas 544         dc.commit();
4550 30 Jun 17 nicklas 545       }
5339 29 Mar 19 nicklas 546       else if ("RegisterPausedSpecimen".equals(cmd))
5339 29 Mar 19 nicklas 547       {
6330 14 Jun 21 nicklas 548         dc = sc.newDbControl(":Paused specimen wizard");
5339 29 Mar 19 nicklas 549         
5341 02 Apr 19 nicklas 550         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SAMPLE_PREP, ReggieRole.PREP_CURATOR, ReggieRole.ADMINISTRATOR);
5339 29 Mar 19 nicklas 551         
5339 29 Mar 19 nicklas 552         JSONObject jsonReq = JsonUtil.parseRequest(req);
5339 29 Mar 19 nicklas 553         JSONArray jsonSpecimen = (JSONArray)jsonReq.get("specimen");
5341 02 Apr 19 nicklas 554         int numChanged = 0;
5339 29 Mar 19 nicklas 555         for (int i=0; i < jsonSpecimen.size(); i++)
5339 29 Mar 19 nicklas 556         {
5339 29 Mar 19 nicklas 557           Number spId = (Number)jsonSpecimen.get(i);
5339 29 Mar 19 nicklas 558           Sample specimen = Sample.getById(dc, spId.intValue());
5341 02 Apr 19 nicklas 559           boolean changed = Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, specimen, "Disable");
5341 02 Apr 19 nicklas 560           if (changed) numChanged++;
5339 29 Mar 19 nicklas 561         }
5341 02 Apr 19 nicklas 562         jsonMessages.add(numChanged + " specimen tubes has been registered as paused");
5339 29 Mar 19 nicklas 563         
5339 29 Mar 19 nicklas 564         dc.commit();
5339 29 Mar 19 nicklas 565       }
5341 02 Apr 19 nicklas 566       else if ("SchedulePausedSpecimenForExtraction".equals(cmd))
5341 02 Apr 19 nicklas 567       {
6330 14 Jun 21 nicklas 568         dc = sc.newDbControl(":Paused specimen wizard");
5341 02 Apr 19 nicklas 569         
5341 02 Apr 19 nicklas 570         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.PREP_CURATOR, ReggieRole.ADMINISTRATOR);
5341 02 Apr 19 nicklas 571         
5341 02 Apr 19 nicklas 572         JSONObject jsonReq = JsonUtil.parseRequest(req);
5341 02 Apr 19 nicklas 573         JSONArray jsonSpecimen = (JSONArray)jsonReq.get("specimen");
5341 02 Apr 19 nicklas 574         int numChanged = 0;
5341 02 Apr 19 nicklas 575         for (int i=0; i < jsonSpecimen.size(); i++)
5341 02 Apr 19 nicklas 576         {
5341 02 Apr 19 nicklas 577           Number spId = (Number)jsonSpecimen.get(i);
5341 02 Apr 19 nicklas 578           Sample specimen = Sample.getById(dc, spId.intValue());
5341 02 Apr 19 nicklas 579           boolean changed = Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, specimen, "ReProcess");
5341 02 Apr 19 nicklas 580           if (changed) numChanged++;
5341 02 Apr 19 nicklas 581         }
5341 02 Apr 19 nicklas 582         jsonMessages.add(numChanged + " specimen tubes has been scheduled for extraction");
5341 02 Apr 19 nicklas 583         
5341 02 Apr 19 nicklas 584         dc.commit();
5341 02 Apr 19 nicklas 585       }
5344 02 Apr 19 nicklas 586       else if ("SavePauseSettings".equals(cmd))
5344 02 Apr 19 nicklas 587       {
6330 14 Jun 21 nicklas 588         dc = sc.newDbControl(":Paused specimen wizard");
5344 02 Apr 19 nicklas 589         
5344 02 Apr 19 nicklas 590         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.ADMINISTRATOR);
5344 02 Apr 19 nicklas 591         
5344 02 Apr 19 nicklas 592         JSONObject jsonReq = JsonUtil.parseRequest(req);
5344 02 Apr 19 nicklas 593         JSONArray jsonPausedSites = (JSONArray)jsonReq.get("pausedSites");
5344 02 Apr 19 nicklas 594         String pausedSites = Values.getString(jsonPausedSites, ",", true);
5344 02 Apr 19 nicklas 595         
5344 02 Apr 19 nicklas 596         ClientDefaultSetting pausedSitesSetting = ClientApp.REGGIE.getSetting(dc, "paused-sites", true);
5344 02 Apr 19 nicklas 597         pausedSitesSetting.setValue(pausedSites);
5344 02 Apr 19 nicklas 598         
5344 02 Apr 19 nicklas 599         jsonMessages.add(jsonPausedSites.size() + " sites are now paused");
5344 02 Apr 19 nicklas 600         dc.commit();
5344 02 Apr 19 nicklas 601       }
5339 29 Mar 19 nicklas 602
4550 30 Jun 17 nicklas 603       else if ("CreateStorageBoxes".equals(cmd))
4550 30 Jun 17 nicklas 604       {
6330 14 Jun 21 nicklas 605         dc = sc.newDbControl(":Storage box creation wizard");
4550 30 Jun 17 nicklas 606         
4550 30 Jun 17 nicklas 607         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SAMPLE_PREP, ReggieRole.ADMINISTRATOR);
4550 30 Jun 17 nicklas 608         
4550 30 Jun 17 nicklas 609         JSONObject jsonReq = JsonUtil.parseRequest(req);
4550 30 Jun 17 nicklas 610         
5340 29 Mar 19 nicklas 611         // Storage boxes for regular processing
5340 29 Mar 19 nicklas 612         int nofSpBoxes = ((Number)jsonReq.get("nofSpBoxes")).intValue();
5340 29 Mar 19 nicklas 613         if (nofSpBoxes > 0)
5340 29 Mar 19 nicklas 614         {
5340 29 Mar 19 nicklas 615           Number lastSpBoxId = (Number)jsonReq.get("lastSpBox");
5340 29 Mar 19 nicklas 616           BioPlate lastSpBox = lastSpBoxId == null ? null : BioPlate.getById(dc, lastSpBoxId.intValue());
7188 22 May 23 nicklas 617           List<BioPlate> created = StoragePlate.createNewStorageBoxes(dc, lastSpBox, nofSpBoxes, BoxType.NORMAL, null, false);
5340 29 Mar 19 nicklas 618           jsonMessages.add("Created " + created.size() + " new boxes of each type for regular processing");
5421 13 May 19 nicklas 619           ActivityDef.CREATED_STORAGEBOX.merge(dc, nofSpBoxes);
5340 29 Mar 19 nicklas 620         }
5340 29 Mar 19 nicklas 621
5340 29 Mar 19 nicklas 622         // Storage boxes for paused specimen
5340 29 Mar 19 nicklas 623         int nofPSpBoxes = ((Number)jsonReq.get("nofPSpBoxes")).intValue();
5340 29 Mar 19 nicklas 624         if (nofPSpBoxes > 0)
5340 29 Mar 19 nicklas 625         {
5340 29 Mar 19 nicklas 626           Number lastPSpBoxId = (Number)jsonReq.get("lastPSpBox");
5340 29 Mar 19 nicklas 627           BioPlate lastPSpBox = lastPSpBoxId == null ? null : BioPlate.getById(dc, lastPSpBoxId.intValue());
7188 22 May 23 nicklas 628           List<BioPlate> created = StoragePlate.createNewStorageBoxes(dc, lastPSpBox, nofPSpBoxes, BoxType.PAUSE, null, false);
5340 29 Mar 19 nicklas 629           jsonMessages.add("Created " + created.size() + " storage boxes for paused specimen");
5421 13 May 19 nicklas 630           ActivityDef.CREATED_PAUSEBOX.merge(dc, nofPSpBoxes);
5340 29 Mar 19 nicklas 631         }
7138 26 Apr 23 nicklas 632         
7138 26 Apr 23 nicklas 633         // Storage boxes for externally processed specimen
7138 26 Apr 23 nicklas 634         int nofESpBoxes = ((Number)jsonReq.get("nofESpBoxes")).intValue();
7138 26 Apr 23 nicklas 635         if (nofESpBoxes > 0)
7138 26 Apr 23 nicklas 636         {
7188 22 May 23 nicklas 637           Number freezerId = (Number)jsonReq.get("freezer");
7138 26 Apr 23 nicklas 638           Number lastESpBoxId = (Number)jsonReq.get("lastESpBox");
7138 26 Apr 23 nicklas 639           BioPlate lastESpBox = lastESpBoxId == null ? null : BioPlate.getById(dc, lastESpBoxId.intValue());
7188 22 May 23 nicklas 640           Hardware freezer = freezerId == null ? null : Hardware.getById(dc, freezerId.intValue());
7188 22 May 23 nicklas 641           List<BioPlate> created = StoragePlate.createNewStorageBoxes(dc, lastESpBox, nofESpBoxes, BoxType.EXTERNAL, freezer, false);
7138 26 Apr 23 nicklas 642           jsonMessages.add("Created " + created.size() + " storage boxes of each type for externally processed samples");
7138 26 Apr 23 nicklas 643           ActivityDef.CREATED_STORAGEBOX.merge(dc, nofESpBoxes);
7138 26 Apr 23 nicklas 644         }
4550 30 Jun 17 nicklas 645         dc.commit();
4550 30 Jun 17 nicklas 646       }
4550 30 Jun 17 nicklas 647       
3059 19 Dec 14 nicklas 648       json.put("messages", jsonMessages);
3059 19 Dec 14 nicklas 649       CounterService.getInstance().setForceCount();
2890 03 Nov 14 nicklas 650     }
2890 03 Nov 14 nicklas 651     catch (Throwable t)
2890 03 Nov 14 nicklas 652     {
2890 03 Nov 14 nicklas 653       t.printStackTrace();
2890 03 Nov 14 nicklas 654       json.clear();
2890 03 Nov 14 nicklas 655       json.put("status", "error");
2890 03 Nov 14 nicklas 656       json.put("message", t.getMessage());
2890 03 Nov 14 nicklas 657       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
2890 03 Nov 14 nicklas 658     }
2890 03 Nov 14 nicklas 659     finally
2890 03 Nov 14 nicklas 660     {
2890 03 Nov 14 nicklas 661       if (dc != null) dc.close();
2890 03 Nov 14 nicklas 662       json.writeJSONString(resp.getWriter());
2890 03 Nov 14 nicklas 663     }
2890 03 Nov 14 nicklas 664   }
2890 03 Nov 14 nicklas 665   
7138 26 Apr 23 nicklas 666   private JSONArray findEmptyWells(DbControl dc, List<StoragePlate> spBoxes, int nofTubes, BoxType boxType)
5333 28 Mar 19 nicklas 667   {
5333 28 Mar 19 nicklas 668     JSONArray jsonWells = new JSONArray();
7140 28 Apr 23 nicklas 669     List<BioWell> wells = StoragePlate.findEmptyWells(dc, spBoxes, nofTubes, boxType);
7140 28 Apr 23 nicklas 670     for (BioWell w : wells)
5333 28 Mar 19 nicklas 671     {
7140 28 Apr 23 nicklas 672       jsonWells.add(JsonUtil.getBioWellAsJSON(w, true));
5333 28 Mar 19 nicklas 673     }
5333 28 Mar 19 nicklas 674     return jsonWells;
5333 28 Mar 19 nicklas 675   }
5333 28 Mar 19 nicklas 676   
3640 02 Dec 15 nicklas 677   
5344 02 Apr 19 nicklas 678   private JSONArray getSitesWithPauseInfo(DbControl dc)
5344 02 Apr 19 nicklas 679   {
5344 02 Apr 19 nicklas 680     List<Site> sites = new ArrayList<>(Site.getAllSites());
5344 02 Apr 19 nicklas 681     Collections.sort(sites, Site.SORT_BY_NAME);
5345 02 Apr 19 nicklas 682     Set<String> pausedSites = getPausedSites(dc);
5345 02 Apr 19 nicklas 683     JSONArray jsonSites = new JSONArray();
5345 02 Apr 19 nicklas 684     for (Site s : sites)
5345 02 Apr 19 nicklas 685     {
5345 02 Apr 19 nicklas 686       JSONObject jsonSite = new JSONObject(s.asJSONObject()); 
5345 02 Apr 19 nicklas 687       jsonSite.put("paused", pausedSites.contains(s.getPrefix()));
5345 02 Apr 19 nicklas 688       jsonSites.add(jsonSite);
5345 02 Apr 19 nicklas 689     }
5345 02 Apr 19 nicklas 690     return jsonSites;
5345 02 Apr 19 nicklas 691   }
5345 02 Apr 19 nicklas 692   
5345 02 Apr 19 nicklas 693   private Set<String> getPausedSites(DbControl dc)
5345 02 Apr 19 nicklas 694   {
5344 02 Apr 19 nicklas 695     ClientDefaultSetting pausedSitesSetting = ClientApp.REGGIE.getSetting(dc, "paused-sites", false);
5344 02 Apr 19 nicklas 696     Set<String> pausedSites = new HashSet<>();
5344 02 Apr 19 nicklas 697     if (pausedSitesSetting != null)
5344 02 Apr 19 nicklas 698     {
5344 02 Apr 19 nicklas 699       for (String s : pausedSitesSetting.getValue().split(","))
5344 02 Apr 19 nicklas 700       {
5344 02 Apr 19 nicklas 701         pausedSites.add(s);
5344 02 Apr 19 nicklas 702       }
5344 02 Apr 19 nicklas 703     }
5345 02 Apr 19 nicklas 704     return pausedSites;
5344 02 Apr 19 nicklas 705   }
5344 02 Apr 19 nicklas 706   
7138 26 Apr 23 nicklas 707   
2890 03 Nov 14 nicklas 708 }