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 |
// 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 |
// 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 |
// 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 |
// Generate a name for first specimen tube and get the index number |
4898 |
10 Jul 18 |
nicklas |
// If there are more than one tube, the following names will be generated |
4898 |
10 Jul 18 |
nicklas |
// 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 |
// 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 |
// 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 |
// Find a given number of storage positions. The process |
2890 |
03 Nov 14 |
nicklas |
// is complicated by the fact that "old" boxes still may have empty |
3327 |
11 May 15 |
nicklas |
// locations so we need to find the 'Sp*' box that was used the last time |
3327 |
11 May 15 |
nicklas |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// If the Case doesn't belong to a patient yet |
2890 |
03 Nov 14 |
nicklas |
// it is a free-floating consent registration only and |
2890 |
03 Nov 14 |
nicklas |
// we should not link the specimen since the case may |
2890 |
03 Nov 14 |
nicklas |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
} |