extensions/net.sf.basedb.reggie/trunk/resources/sampleproc/partitionform.js

Code
Comments
Other
Rev Date Author Line
2740 06 Oct 14 nicklas 1 var Partition = function()
2740 06 Oct 14 nicklas 2 {
2740 06 Oct 14 nicklas 3   var partition = {};
2853 23 Oct 14 nicklas 4   var debug = 0;
2740 06 Oct 14 nicklas 5   
3153 27 Feb 15 nicklas 6   var selectionIsValid = false;
2740 06 Oct 14 nicklas 7   var selectedSpecimen;
6721 03 May 22 nicklas 8   var tubeLabelAnnotationType;
2740 06 Oct 14 nicklas 9   
2740 06 Oct 14 nicklas 10   var spWeightsAreValid = [];
2740 06 Oct 14 nicklas 11   var apWeightsAreValid = [];
2740 06 Oct 14 nicklas 12   var hisWeightsAreValid = [];
2740 06 Oct 14 nicklas 13   var nofPiecesAreValid = [];
2740 06 Oct 14 nicklas 14
2740 06 Oct 14 nicklas 15   var APPEARANCE_OPTIONS = ['', 'HOMOGENEOUS', 'HETEROGENEOUS'];
2740 06 Oct 14 nicklas 16   var FAT_OPTIONS = [0, 20, 40, 60, 80, 100];
2740 06 Oct 14 nicklas 17   
2740 06 Oct 14 nicklas 18   // Page initialization
2740 06 Oct 14 nicklas 19   partition.initPage = function()
2740 06 Oct 14 nicklas 20   {
2740 06 Oct 14 nicklas 21     // Step 1
2740 06 Oct 14 nicklas 22     Events.addEventHandler('step-1', 'wizard-validate', partition.validateStep1);
3153 27 Feb 15 nicklas 23     Events.addEventHandler('specimentubes', 'change', partition.checkSelection);
3153 27 Feb 15 nicklas 24     Events.addEventHandler('reextraction', 'change', partition.checkSelection);
3145 25 Feb 15 nicklas 25     Buttons.addClickHandler('goprint', partition.printPickList);
2740 06 Oct 14 nicklas 26     
2740 06 Oct 14 nicklas 27     // Step 2
2740 06 Oct 14 nicklas 28     Events.addEventHandler('step-2', 'wizard-initialize', partition.initializeStep2);
2740 06 Oct 14 nicklas 29     Events.addEventHandler('step-2', 'wizard-validate', partition.validateStep2);
2740 06 Oct 14 nicklas 30     Events.addEventHandler('partitionDate', 'change', Wizard.validateDate);
5299 14 Feb 19 nicklas 31     Buttons.addClickHandler('downloadLabelsCsv', partition.downloadLabelFile);
5299 14 Feb 19 nicklas 32     Buttons.addClickHandler('downloadLabelsXlsx', partition.downloadLabelFile);
2740 06 Oct 14 nicklas 33     
2740 06 Oct 14 nicklas 34     // Navigation
2740 06 Oct 14 nicklas 35     Buttons.addClickHandler('gocancel', Wizard.cancelWizard);
2740 06 Oct 14 nicklas 36     Buttons.addClickHandler('gorestart', Wizard.restartWizard);
2740 06 Oct 14 nicklas 37     Buttons.addClickHandler('gonext', Wizard.goNextOnClick);
3149 26 Feb 15 nicklas 38     Buttons.addClickHandler('goregister', partition.verifyPositionsForReextraction);
2740 06 Oct 14 nicklas 39     
2740 06 Oct 14 nicklas 40     // Final registration
2740 06 Oct 14 nicklas 41     Events.addEventHandler('wizard', 'wizard-submit', partition.submit);
2740 06 Oct 14 nicklas 42     
2740 06 Oct 14 nicklas 43     var url = '../PartitionRegistration.servlet?ID='+App.getSessionId();
2740 06 Oct 14 nicklas 44     url += '&cmd=GetSpecimenTubes';
2740 06 Oct 14 nicklas 45     Wizard.showLoadingAnimation('Loading specimen tubes...');
2740 06 Oct 14 nicklas 46     Wizard.asyncJsonRequest(url, partition.specimenTubesLoaded);
2740 06 Oct 14 nicklas 47   }
2740 06 Oct 14 nicklas 48   
2740 06 Oct 14 nicklas 49   partition.specimenTubesLoaded = function(response)
2740 06 Oct 14 nicklas 50   {
2740 06 Oct 14 nicklas 51     var frm = document.forms['reggie'];  
2740 06 Oct 14 nicklas 52
6721 03 May 22 nicklas 53     tubeLabelAnnotationType = response.TubeLabelAnnotationType;
2740 06 Oct 14 nicklas 54     var specimenTubes = response.specimenTubes;
2740 06 Oct 14 nicklas 55     if (specimenTubes.length > 0)
2740 06 Oct 14 nicklas 56     {
5346 03 Apr 19 nicklas 57       specimenTubes.sort(partition.sortByPosition(false)); // Sort tubes, paused last
2740 06 Oct 14 nicklas 58       for (var i = 0; i < specimenTubes.length; i++)
2740 06 Oct 14 nicklas 59       {
2740 06 Oct 14 nicklas 60         var specimen = specimenTubes[i];
3738 11 Feb 16 nicklas 61         var isYellow = specimen.YellowLabel != null;
3145 25 Feb 15 nicklas 62         specimen.reprocess = specimen.AutoProcessing == 'ReProcess';
5335 28 Mar 19 nicklas 63         specimen.firstExtraction = !specimen.originalQuantity;
5335 28 Mar 19 nicklas 64         specimen.paused = specimen.reprocess && specimen.firstExtraction;
2740 06 Oct 14 nicklas 65         var storeInfo = partition.getStoredInfo(specimen.id);
4583 21 Sep 17 nicklas 66         var option = new Option(specimen.name, specimen.id, false, storeInfo ? true : false);
2740 06 Oct 14 nicklas 67         option.specimenTube = specimen;
3738 11 Feb 16 nicklas 68         if (isYellow) option.className = 'yellow';
3145 25 Feb 15 nicklas 69         if (specimen.reprocess)
3145 25 Feb 15 nicklas 70         {
5782 11 Dec 19 nicklas 71           option.text += ' - ' + (specimen.bioWell != null ? specimen.bioWell.bioPlate.name + ' ' + specimen.bioWell.location : 'no box');
5346 03 Apr 19 nicklas 72           frm.reextraction[frm.reextraction.length] = option;
3145 25 Feb 15 nicklas 73         }
3145 25 Feb 15 nicklas 74         else
3145 25 Feb 15 nicklas 75         {
3145 25 Feb 15 nicklas 76           frm.specimentubes[frm.specimentubes.length] = option;
3145 25 Feb 15 nicklas 77         }
3145 25 Feb 15 nicklas 78         if (storeInfo) option.text += ' [*]';
2740 06 Oct 14 nicklas 79       }
3145 25 Feb 15 nicklas 80       if (frm.specimentubes.length == 0) Doc.hide('regularFlowRow');
3153 27 Feb 15 nicklas 81       if (frm.reextraction.length > 0) Doc.show('reExtractionRow');
3153 27 Feb 15 nicklas 82       partition.checkSelection();
2740 06 Oct 14 nicklas 83     }
2740 06 Oct 14 nicklas 84     else
2740 06 Oct 14 nicklas 85     {
2740 06 Oct 14 nicklas 86       Wizard.setFatalError('No specimen available for partitioning');
2740 06 Oct 14 nicklas 87       return;
2740 06 Oct 14 nicklas 88     }
2740 06 Oct 14 nicklas 89     
2740 06 Oct 14 nicklas 90     Doc.show('step-1');
2740 06 Oct 14 nicklas 91     Doc.show('gonext');
2740 06 Oct 14 nicklas 92   }
2740 06 Oct 14 nicklas 93
3153 27 Feb 15 nicklas 94   partition.checkSelection = function()
3145 25 Feb 15 nicklas 95   {
3145 25 Feb 15 nicklas 96     var frm = document.forms['reggie'];
3153 27 Feb 15 nicklas 97     var numSpecimen = 0;
3153 27 Feb 15 nicklas 98     var numReextration = 0;
3739 11 Feb 16 nicklas 99     var numUnselectedYellow = 0;
3153 27 Feb 15 nicklas 100     selectionIsValid = false;
3153 27 Feb 15 nicklas 101     Wizard.setInputStatus('specimentubes');
3153 27 Feb 15 nicklas 102     Wizard.setInputStatus('reextraction');
3153 27 Feb 15 nicklas 103     
3153 27 Feb 15 nicklas 104     for (var i = 0; i < frm.specimentubes.length; i++)
3153 27 Feb 15 nicklas 105     {
3739 11 Feb 16 nicklas 106       var specimen = frm.specimentubes[i].specimenTube;
3739 11 Feb 16 nicklas 107       if (frm.specimentubes[i].selected)
3739 11 Feb 16 nicklas 108       {
3739 11 Feb 16 nicklas 109         numSpecimen++;
3739 11 Feb 16 nicklas 110       }
3739 11 Feb 16 nicklas 111       else if (specimen.YellowLabel != null)
3739 11 Feb 16 nicklas 112       {
3739 11 Feb 16 nicklas 113         numUnselectedYellow++;
3739 11 Feb 16 nicklas 114       }
3153 27 Feb 15 nicklas 115     }
3145 25 Feb 15 nicklas 116     for (var i = 0; i < frm.reextraction.length; i++)
3145 25 Feb 15 nicklas 117     {
3739 11 Feb 16 nicklas 118       var specimen = frm.reextraction[i].specimenTube;
3739 11 Feb 16 nicklas 119       if (frm.reextraction[i].selected)
3739 11 Feb 16 nicklas 120       {
3739 11 Feb 16 nicklas 121         numReextration++;
3739 11 Feb 16 nicklas 122       }
3739 11 Feb 16 nicklas 123       else if (specimen.YellowLabel != null)
3739 11 Feb 16 nicklas 124       {
3739 11 Feb 16 nicklas 125         numUnselectedYellow++;
3739 11 Feb 16 nicklas 126       }
3145 25 Feb 15 nicklas 127     }
3145 25 Feb 15 nicklas 128     
3153 27 Feb 15 nicklas 129     if (numReextration == 0 && numSpecimen == 0)
3145 25 Feb 15 nicklas 130     {
3153 27 Feb 15 nicklas 131       Wizard.setInputStatus('specimentubes', 'invalid', 'At least one specimen tube must be selected');
3153 27 Feb 15 nicklas 132       Wizard.setInputStatus('reextraction', 'invalid', 'At least one specimen tube must be selected');
3153 27 Feb 15 nicklas 133       return;
3153 27 Feb 15 nicklas 134     }
3153 27 Feb 15 nicklas 135     
3153 27 Feb 15 nicklas 136     selectionIsValid = true;
3739 11 Feb 16 nicklas 137     if (numUnselectedYellow > 0)
3153 27 Feb 15 nicklas 138     {
3739 11 Feb 16 nicklas 139       Wizard.setInputStatus('specimentubes', 'warning', 'Not all YellowLabel specimen are selected');
3739 11 Feb 16 nicklas 140     }
3739 11 Feb 16 nicklas 141     else if (numSpecimen > 0)
3739 11 Feb 16 nicklas 142     {
3153 27 Feb 15 nicklas 143       Wizard.setInputStatus('specimentubes', 'valid');
3153 27 Feb 15 nicklas 144     }
3153 27 Feb 15 nicklas 145     
3153 27 Feb 15 nicklas 146     if (numReextration > 0)
3153 27 Feb 15 nicklas 147     {
3145 25 Feb 15 nicklas 148       Doc.show('goprint');
3145 25 Feb 15 nicklas 149       Wizard.showGoNextConfirmation(true, 'Print the pick list protocol before continuing with the registration!');
3153 27 Feb 15 nicklas 150       
3153 27 Feb 15 nicklas 151       if (numSpecimen != frm.specimentubes.length)
3153 27 Feb 15 nicklas 152       {
3153 27 Feb 15 nicklas 153         var msg = 'Selecting specimen tubes for re-extraction without selecting all regular specimen may result in non-consecutive positioning in storage boxes';
3153 27 Feb 15 nicklas 154         Wizard.setInputStatus('reextraction', 'warning', msg);
3153 27 Feb 15 nicklas 155         Wizard.setInputStatus('specimentubes', 'warning', msg);
3153 27 Feb 15 nicklas 156       }
3153 27 Feb 15 nicklas 157       else
3153 27 Feb 15 nicklas 158       {
3153 27 Feb 15 nicklas 159         Wizard.setInputStatus('reextraction', 'valid');
3153 27 Feb 15 nicklas 160       }
3145 25 Feb 15 nicklas 161     }
3145 25 Feb 15 nicklas 162     else
3145 25 Feb 15 nicklas 163     {
3145 25 Feb 15 nicklas 164       Doc.hide('goprint');
3145 25 Feb 15 nicklas 165       Wizard.hideGoNextConfirmation();
3145 25 Feb 15 nicklas 166     }
3145 25 Feb 15 nicklas 167   }
3145 25 Feb 15 nicklas 168   
3145 25 Feb 15 nicklas 169   partition.printPickList = function()
3145 25 Feb 15 nicklas 170   {
3145 25 Feb 15 nicklas 171     var frm = document.forms['reggie'];
3145 25 Feb 15 nicklas 172     var selected = [];
3145 25 Feb 15 nicklas 173     for (var i = 0; i < frm.reextraction.length; i++)
3145 25 Feb 15 nicklas 174     {
3145 25 Feb 15 nicklas 175       if (frm.reextraction[i].selected) 
3145 25 Feb 15 nicklas 176       {
5346 03 Apr 19 nicklas 177         selected[selected.length] = frm.reextraction[i].specimenTube;
3145 25 Feb 15 nicklas 178       }
3145 25 Feb 15 nicklas 179     }
5346 03 Apr 19 nicklas 180     // Re-sort so that paused specime are first (to match the order on the partition protocol)
5346 03 Apr 19 nicklas 181     selected.sort(partition.sortByPosition(true)); 
3145 25 Feb 15 nicklas 182     
3145 25 Feb 15 nicklas 183     var url = 'reextract_picklist.jsp?ID='+App.getSessionId();
5346 03 Apr 19 nicklas 184     url += '&specimen='+selected.map(function(s){return s.id}).join(',');
6721 03 May 22 nicklas 185     url += '&tubeLabelAnnotationType='+tubeLabelAnnotationType;
3145 25 Feb 15 nicklas 186     window.open(url, '_blank');
3145 25 Feb 15 nicklas 187     Wizard.hideGoNextConfirmation();
3145 25 Feb 15 nicklas 188   }
3145 25 Feb 15 nicklas 189   
2740 06 Oct 14 nicklas 190   partition.validateStep1 = function(event)
2740 06 Oct 14 nicklas 191   {
3153 27 Feb 15 nicklas 192     if (!selectionIsValid)
2740 06 Oct 14 nicklas 193     {
3153 27 Feb 15 nicklas 194       event.preventDefault();
2740 06 Oct 14 nicklas 195     }
2740 06 Oct 14 nicklas 196   }
2740 06 Oct 14 nicklas 197
2740 06 Oct 14 nicklas 198   
2740 06 Oct 14 nicklas 199   partition.initializeStep2 = function()
2740 06 Oct 14 nicklas 200   {
2740 06 Oct 14 nicklas 201     var frm = document.forms['reggie'];
2740 06 Oct 14 nicklas 202     
2740 06 Oct 14 nicklas 203     selectedSpecimen = [];
2740 06 Oct 14 nicklas 204     for (var i = 0; i < frm.specimentubes.length; i++)
2740 06 Oct 14 nicklas 205     {
2740 06 Oct 14 nicklas 206       if (frm.specimentubes[i].selected) 
2740 06 Oct 14 nicklas 207       {
2740 06 Oct 14 nicklas 208         selectedSpecimen[selectedSpecimen.length] = frm.specimentubes[i].specimenTube;
2740 06 Oct 14 nicklas 209       }
2740 06 Oct 14 nicklas 210     }
3149 26 Feb 15 nicklas 211     
3149 26 Feb 15 nicklas 212     var numReextraction = 0;
3145 25 Feb 15 nicklas 213     for (var i = 0; i < frm.reextraction.length; i++)
3145 25 Feb 15 nicklas 214     {
3145 25 Feb 15 nicklas 215       if (frm.reextraction[i].selected) 
3145 25 Feb 15 nicklas 216       {
3145 25 Feb 15 nicklas 217         selectedSpecimen[selectedSpecimen.length] = frm.reextraction[i].specimenTube;
3149 26 Feb 15 nicklas 218         numReextraction++;
3145 25 Feb 15 nicklas 219       }
3145 25 Feb 15 nicklas 220     }
5346 03 Apr 19 nicklas 221     selectedSpecimen.sort(partition.sortByPosition(true)); // Sort tubes, paused between regular and other re-processing tubes
3149 26 Feb 15 nicklas 222     
3149 26 Feb 15 nicklas 223     if (numReextraction > 0)
3149 26 Feb 15 nicklas 224     {
3149 26 Feb 15 nicklas 225       var url = '../SpecimenTubeRegistration.servlet?ID='+App.getSessionId();
3149 26 Feb 15 nicklas 226       url += '&cmd=FindStoragePositions';  
3149 26 Feb 15 nicklas 227       url += '&nofTubes='+numReextraction;
2740 06 Oct 14 nicklas 228       
3149 26 Feb 15 nicklas 229       Wizard.showLoadingAnimation('Looking for empty box positions...');
3149 26 Feb 15 nicklas 230       Wizard.asyncJsonRequest(url, partition.storagePositionsLoaded);
3149 26 Feb 15 nicklas 231     }
3149 26 Feb 15 nicklas 232     else
3149 26 Feb 15 nicklas 233     {
3149 26 Feb 15 nicklas 234       partition.buildPartitionTable();
3149 26 Feb 15 nicklas 235     }
3149 26 Feb 15 nicklas 236   }
3149 26 Feb 15 nicklas 237   
3149 26 Feb 15 nicklas 238   
3149 26 Feb 15 nicklas 239   partition.storagePositionsLoaded = function(response)
3149 26 Feb 15 nicklas 240   {
3149 26 Feb 15 nicklas 241     var wells = response.wells;
3149 26 Feb 15 nicklas 242     if (wells.length < response.nofTubes)
3149 26 Feb 15 nicklas 243     {
3149 26 Feb 15 nicklas 244       var msg = 'Could not find enough free positions in storage box for re-extracted specimen.';
3149 26 Feb 15 nicklas 245       msg += ' Wanted ' + response.nofTubes + ', but found ' + wells.length + '.';
3149 26 Feb 15 nicklas 246       if (wells.length > 0)
3149 26 Feb 15 nicklas 247       {
3149 26 Feb 15 nicklas 248         var last = wells[wells.length-1];
3149 26 Feb 15 nicklas 249         msg += ' Last free: ' + Strings.encodeTags(last.bioPlate.name+' ['+last.location+']');
3149 26 Feb 15 nicklas 250       }
3149 26 Feb 15 nicklas 251       Wizard.setFatalError(msg); 
3149 26 Feb 15 nicklas 252       return;
3149 26 Feb 15 nicklas 253     }
3149 26 Feb 15 nicklas 254
3149 26 Feb 15 nicklas 255     var wellNo = 0;
3149 26 Feb 15 nicklas 256     for (var i = 0; i < selectedSpecimen.length; i++)
3149 26 Feb 15 nicklas 257     {
3149 26 Feb 15 nicklas 258       var specimen = selectedSpecimen[i];
3149 26 Feb 15 nicklas 259       if (specimen.reprocess)
3149 26 Feb 15 nicklas 260       {
3149 26 Feb 15 nicklas 261         specimen.newBioWell = wells[wellNo];
3149 26 Feb 15 nicklas 262         wellNo++;
3149 26 Feb 15 nicklas 263       }
3149 26 Feb 15 nicklas 264     }
3149 26 Feb 15 nicklas 265     partition.buildPartitionTable();
3149 26 Feb 15 nicklas 266   }
3149 26 Feb 15 nicklas 267   
3149 26 Feb 15 nicklas 268   partition.buildPartitionTable = function()
3149 26 Feb 15 nicklas 269   {
3149 26 Feb 15 nicklas 270     var frm = document.forms['reggie'];
2740 06 Oct 14 nicklas 271     var html = '<table id="weightsTable" class="step-form">';
5335 28 Mar 19 nicklas 272     if (selectedSpecimen[0].firstExtraction)
3145 25 Feb 15 nicklas 273     {
3145 25 Feb 15 nicklas 274       html += '<thead class="bg-filled-100" style="border-top-width: 2px; border-bottom-width: 2px;">';
3145 25 Feb 15 nicklas 275       // First header row
3145 25 Feb 15 nicklas 276       html += '<tr>';
3145 25 Feb 15 nicklas 277       html += '<th>Specimen</th>';
3145 25 Feb 15 nicklas 278       html += '<th class="dottedleft">Bloody</th>';
3145 25 Feb 15 nicklas 279       html += '<th>Appearance</th>';
3145 25 Feb 15 nicklas 280       html += '<th>Fat</th>';
3145 25 Feb 15 nicklas 281       html += '<th>Coloured</th>';
3145 25 Feb 15 nicklas 282       html += '<th>NofPieces</th>';
3145 25 Feb 15 nicklas 283       html += '<th>ApWeight</th>';
3145 25 Feb 15 nicklas 284       html += '<th>Mult¹</th>';
3145 25 Feb 15 nicklas 285       html += '<th>HisWeight</th>';
3145 25 Feb 15 nicklas 286       html += '<th>SpWeight</th>';
3145 25 Feb 15 nicklas 287       html += '<th></th>';
3145 25 Feb 15 nicklas 288       html += '</tr>';
3145 25 Feb 15 nicklas 289       // Second header row
3145 25 Feb 15 nicklas 290       html += '<tr>';
3145 25 Feb 15 nicklas 291       html += '<td>Storage box</td>';
3145 25 Feb 15 nicklas 292       html += '<td class="dottedleft"></td>';
3145 25 Feb 15 nicklas 293       html += '<td></td>';
3145 25 Feb 15 nicklas 294       html += '<td>%</td>';
3145 25 Feb 15 nicklas 295       html += '<td></td>';
3145 25 Feb 15 nicklas 296       html += '<td></td>';
3145 25 Feb 15 nicklas 297       html += '<td>(mg)</td>';
3145 25 Feb 15 nicklas 298       html += '<td></td>';
3145 25 Feb 15 nicklas 299       html += '<td>(mg)</td>';
3145 25 Feb 15 nicklas 300       html += '<td>(mg)</td>';
3145 25 Feb 15 nicklas 301       html += '<th></th>';
3145 25 Feb 15 nicklas 302       html += '</tr>';
3145 25 Feb 15 nicklas 303       html += '</thead>';
3145 25 Feb 15 nicklas 304     }
2740 06 Oct 14 nicklas 305     html += '<tbody>';
2740 06 Oct 14 nicklas 306
2740 06 Oct 14 nicklas 307     var appearance = partition.buildOptionsHtml(APPEARANCE_OPTIONS);
2740 06 Oct 14 nicklas 308     var fat = partition.buildOptionsHtml(FAT_OPTIONS);
3145 25 Feb 15 nicklas 309
3145 25 Feb 15 nicklas 310     var firstReprocess = true;
5335 28 Mar 19 nicklas 311     var firstPaused = true;
2740 06 Oct 14 nicklas 312     for (var i = 0; i < selectedSpecimen.length; i++)
2740 06 Oct 14 nicklas 313     {
3145 25 Feb 15 nicklas 314       var specimen = selectedSpecimen[i];
3738 11 Feb 16 nicklas 315       var isYellow = specimen.YellowLabel != null;
3738 11 Feb 16 nicklas 316       
2740 06 Oct 14 nicklas 317       spWeightsAreValid[i] = false;
2740 06 Oct 14 nicklas 318       apWeightsAreValid[i] = false;
5335 28 Mar 19 nicklas 319       hisWeightsAreValid[i] = !specimen.firstExtraction;
5335 28 Mar 19 nicklas 320       nofPiecesAreValid[i] = !specimen.firstExtraction;
5335 28 Mar 19 nicklas 321       if (specimen.paused && firstPaused)
3145 25 Feb 15 nicklas 322       {
5335 28 Mar 19 nicklas 323         html += '<tr style="border-top-width: 2px;">';
5782 11 Dec 19 nicklas 324         html += '<th class="bg-filled-100">Paused specimen &amp; external</th>';
5335 28 Mar 19 nicklas 325         html += '<th colspan="11" class="dottedleft"></th>';
5335 28 Mar 19 nicklas 326         html += '</tr>';
5335 28 Mar 19 nicklas 327         // Second header row
5335 28 Mar 19 nicklas 328         html += '<tr>';
5335 28 Mar 19 nicklas 329         html += '<td  class="bg-filled-100" style="border-bottom-width: 1px;">Old box <b>›</b> New box</td>';
6079 24 Nov 20 nicklas 330         html += '<td colspan="10" class="dottedleft"></td>';
5335 28 Mar 19 nicklas 331         html += '</tr>';
5335 28 Mar 19 nicklas 332         firstPaused = false;
5335 28 Mar 19 nicklas 333       }
5335 28 Mar 19 nicklas 334       
5335 28 Mar 19 nicklas 335       if (!specimen.firstExtraction && firstReprocess)
5335 28 Mar 19 nicklas 336       {
3146 25 Feb 15 nicklas 337         Doc.show('includeAllHisLabelsLbl', 'inline');
3145 25 Feb 15 nicklas 338         html += '<tr class="bg-filled-100" style="border-top-width: 2px;">';
3145 25 Feb 15 nicklas 339         html += '<th>Re-extraction</th>';
6079 24 Nov 20 nicklas 340         html += '<th colspan="3" class="dottedleft">OperatorPartitionComment</th>';
3145 25 Feb 15 nicklas 341         html += '<th>Weight</th>';
3145 25 Feb 15 nicklas 342         html += '<th>NofPieces</th>';
3145 25 Feb 15 nicklas 343         html += '<th>ApWeight</th>';
3145 25 Feb 15 nicklas 344         html += '<th>Mult¹</th>';
3145 25 Feb 15 nicklas 345         html += '<th>HisWeight</th>';
3145 25 Feb 15 nicklas 346         html += '<th>SpWeight</th>';
3145 25 Feb 15 nicklas 347         html += '<th></th>';
3145 25 Feb 15 nicklas 348         html += '</tr>';
3145 25 Feb 15 nicklas 349         // Second header row
3145 25 Feb 15 nicklas 350         html += '<tr class="bg-filled-100" style="border-bottom-width: 2px;">';
3145 25 Feb 15 nicklas 351         html += '<td>Old box <b>›</b> New box</td>';
6079 24 Nov 20 nicklas 352         html += '<td colspan="3" class="dottedleft"></td>';
3145 25 Feb 15 nicklas 353         html += '<td>(mg)</td>';
3145 25 Feb 15 nicklas 354         html += '<td></td>';
3145 25 Feb 15 nicklas 355         html += '<td>(mg)</td>';
3145 25 Feb 15 nicklas 356         html += '<td></td>';
3145 25 Feb 15 nicklas 357         html += '<td>(mg)</td>';
3145 25 Feb 15 nicklas 358         html += '<td>(mg)</td>';
3145 25 Feb 15 nicklas 359         html += '<th></th>';
3145 25 Feb 15 nicklas 360         html += '</tr>';
3145 25 Feb 15 nicklas 361         firstReprocess = false;
3145 25 Feb 15 nicklas 362       }
6721 03 May 22 nicklas 363       var prefix = isYellow ? '<img src="../images/yellow-label.png">' : '';
6721 03 May 22 nicklas 364       if (specimen.label)
6721 03 May 22 nicklas 365       {
6721 03 May 22 nicklas 366         prefix += Strings.encodeTags(specimen.label) + ' â€º ';
6721 03 May 22 nicklas 367       }
3738 11 Feb 16 nicklas 368       html += '<tr class="highlight'+(isYellow ? ' yellow-specimen' : '')+'">';
6721 03 May 22 nicklas 369       html += '<td class="prompt if-yellow">'+prefix+Strings.encodeTags(specimen.name)+'</td>';
3151 26 Feb 15 nicklas 370       var nextFocusAfterApWeight;
3145 25 Feb 15 nicklas 371       var nextFocusAfterSpWeight;
5335 28 Mar 19 nicklas 372       if (!specimen.firstExtraction)
3145 25 Feb 15 nicklas 373       {
6079 24 Nov 20 nicklas 374         html += '<td class="dottedleft" colspan="3" style="text-align: left;">'+Strings.encodeTags(specimen.OperatorPartitionComment)+'</td>';
3145 25 Feb 15 nicklas 375         html += '<td>'+Reggie.formatNumber(specimen.remainingQuantity/1000, '', 1)+'</td>';
3145 25 Feb 15 nicklas 376         html += '<td>'+specimen.NofPieces+'</td>';
3151 26 Feb 15 nicklas 377         nextFocusAfterApWeight = 'spWeight.'+i;
3151 26 Feb 15 nicklas 378         nextFocusAfterSpWeight = 'apWeight.'+(i+1);
3145 25 Feb 15 nicklas 379       }
3145 25 Feb 15 nicklas 380       else
3145 25 Feb 15 nicklas 381       {
3145 25 Feb 15 nicklas 382         html += '<td class="dottedleft"><input type="checkbox" name="bloody.'+i+'" id="bloody.'+i+'" data-next-focus="appearance.'+i+'" /></td>';
6079 24 Nov 20 nicklas 383         html += '<td><select name="appearance.'+i+'" id="appearance.'+i+'" data-next-focus="fat.'+i+'">'+appearance+'</select></td>';
3145 25 Feb 15 nicklas 384         html += '<td><select name="fat.'+i+'" id="fat.'+i+'" data-next-focus="coloured.'+i+'">'+fat+'</select></td>';
3145 25 Feb 15 nicklas 385         html += '<td><input type="checkbox" name="coloured.'+i+'" id="coloured.'+i+'" data-next-focus="nofPieces.'+i+'" /></td>'
3145 25 Feb 15 nicklas 386         html += '<td><input type="text" class="required" name="nofPieces.'+i+'" id="nofPieces.'+i+'" data-next-focus="apWeight.'+i+'" style="width: 2em;" maxlength="2" /></td>';
3151 26 Feb 15 nicklas 387         nextFocusAfterApWeight = 'hisWeight.'+i;
3151 26 Feb 15 nicklas 388         nextFocusAfterSpWeight = 'bloody.'+(i+1);
3145 25 Feb 15 nicklas 389       }
3151 26 Feb 15 nicklas 390       html += '<td><input type="text" class="required" name="apWeight.'+i+'" id="apWeight.'+i+'" data-next-focus="'+nextFocusAfterApWeight+'" style="width: 4em;" maxlength="5" /></td>';      
2740 06 Oct 14 nicklas 391       html += '<td><input type="checkbox" name="multPieces.'+i+'" id="multPieces.'+i+'" data-next-focus="hisWeight.'+i+'" /></td>'
2740 06 Oct 14 nicklas 392       html += '<td><input type="text" class="required" name="hisWeight.'+i+'" id="hisWeight.'+i+'" data-next-focus="spWeight.'+i+'" style="width: 4em;" maxlength="5" /></td>';
3151 26 Feb 15 nicklas 393       html += '<td><input type="text" class="required" name="spWeight.'+i+'" id="spWeight.'+i+'" data-next-focus="'+nextFocusAfterSpWeight+'" style="width: 4em;" maxlength="5" /></td>';
2740 06 Oct 14 nicklas 394       html += '<td class="status" id="specimen.'+i+'.status"></td>';
2740 06 Oct 14 nicklas 395       html += '</tr>';
2740 06 Oct 14 nicklas 396
3738 11 Feb 16 nicklas 397       html += '<tr class="'+(isYellow ? ' yellow-specimen' : '')+'" style="border-bottom-width: 1px; border-bottom-style: dotted;">';
3738 11 Feb 16 nicklas 398       html += '<td class="if-yellow">';
2740 06 Oct 14 nicklas 399       // Only show box information if there is something show.      
5782 11 Dec 19 nicklas 400       if (specimen.bioWell || specimen.newBioWell)
2740 06 Oct 14 nicklas 401       {
3145 25 Feb 15 nicklas 402         if (specimen.reprocess)
3145 25 Feb 15 nicklas 403         {
3151 26 Feb 15 nicklas 404           html += '<span class="old-location">'+partition.toLocation(specimen.bioWell)+'</span>';
3149 26 Feb 15 nicklas 405           html += ' <b>›</b> ';
3151 26 Feb 15 nicklas 406           html += '<span class="new-location" id="newlocation.'+i+'">'+partition.toLocation(specimen.newBioWell)+'</span>';
3145 25 Feb 15 nicklas 407         }
3149 26 Feb 15 nicklas 408         else
3149 26 Feb 15 nicklas 409         {
3151 26 Feb 15 nicklas 410           html += partition.toLocation(specimen.bioWell);
3149 26 Feb 15 nicklas 411         }
2740 06 Oct 14 nicklas 412       }
2740 06 Oct 14 nicklas 413       html += '</td>';
6079 24 Nov 20 nicklas 414       html += '<td colspan="10" class="help dottedleft"><span class="message" id="specimen.'+i+'.message"></span><span id="specimen.'+i+'.help">&nbsp;</span></td>';
2740 06 Oct 14 nicklas 415       html += '</tr>';
2740 06 Oct 14 nicklas 416     }
2740 06 Oct 14 nicklas 417     html += '</tbody>';
2740 06 Oct 14 nicklas 418     html += '</table>';
2740 06 Oct 14 nicklas 419     Doc.element('weightInputs').innerHTML = html;
2740 06 Oct 14 nicklas 420     
2740 06 Oct 14 nicklas 421     // Attach event handlers, restore from local storage, etc.
2740 06 Oct 14 nicklas 422     isRestoringFromLocalStorage = true;
2740 06 Oct 14 nicklas 423     for (var i = 0; i < selectedSpecimen.length; i++)
2740 06 Oct 14 nicklas 424     {
3145 25 Feb 15 nicklas 425       var specimen = selectedSpecimen[i];
3145 25 Feb 15 nicklas 426       
5335 28 Mar 19 nicklas 427       if (specimen.reprocess && !specimen.firstExtraction) frm['hisWeight.'+i].value = '0';
3145 25 Feb 15 nicklas 428       
6079 24 Nov 20 nicklas 429       var elements = ['bloody.'+i, 'appearance.'+i, 'fat.'+i, 'coloured.'+i, 'nofPieces.'+i, 'apWeight.'+i, 'multPieces.'+i, 'hisWeight.'+i, 'spWeight.'+i];
2740 06 Oct 14 nicklas 430       partition.addEventHandlers(elements, 'focus', partition.onFocusElement);
2740 06 Oct 14 nicklas 431       partition.addEventHandlers(elements, 'blur', partition.onFocusElement);
2740 06 Oct 14 nicklas 432       partition.addEventHandlers(elements, 'keypress', Wizard.focusOnEnter);
2740 06 Oct 14 nicklas 433       partition.addEventHandlers(elements, 'change', partition.saveToLocalStorage);
2740 06 Oct 14 nicklas 434       
2740 06 Oct 14 nicklas 435       Events.addEventHandler('nofPieces.'+i, 'keypress', Events.integerOnly);
2740 06 Oct 14 nicklas 436       Events.addEventHandler('nofPieces.'+i, 'change', partition.nofPiecesOnChange);
2740 06 Oct 14 nicklas 437       Events.addEventHandler('apWeight.'+i, 'keypress', Events.numberOnly);
2740 06 Oct 14 nicklas 438       Events.addEventHandler('apWeight.'+i, 'change', partition.apWeightOnChange);
2740 06 Oct 14 nicklas 439       Events.addEventHandler('hisWeight.'+i, 'keypress', Events.numberOnly);
2740 06 Oct 14 nicklas 440       Events.addEventHandler('hisWeight.'+i, 'change', partition.hisWeightOnChange);
2740 06 Oct 14 nicklas 441       Events.addEventHandler('spWeight.'+i, 'keypress', Events.numberOnly);
2740 06 Oct 14 nicklas 442       Events.addEventHandler('spWeight.'+i, 'change', partition.spWeightOnChange);
2740 06 Oct 14 nicklas 443
3145 25 Feb 15 nicklas 444       
2740 06 Oct 14 nicklas 445       var storeInfo = partition.getStoredInfo(specimen.id);
2740 06 Oct 14 nicklas 446       if (storeInfo)
2740 06 Oct 14 nicklas 447       {
5335 28 Mar 19 nicklas 448         if (specimen.firstExtraction)
3145 25 Feb 15 nicklas 449         {
3145 25 Feb 15 nicklas 450           frm['bloody.'+i].checked = storeInfo.bloody;
3145 25 Feb 15 nicklas 451           Forms.selectListOption(frm['appearance.'+i], storeInfo.appearance);
3145 25 Feb 15 nicklas 452           Forms.selectListOption(frm['fat.'+i], storeInfo.fat);
3145 25 Feb 15 nicklas 453           frm['coloured.'+i].checked = storeInfo.coloured;
3145 25 Feb 15 nicklas 454           frm['nofPieces.'+i].value = storeInfo.nofPieces;
3145 25 Feb 15 nicklas 455         }
3145 25 Feb 15 nicklas 456         
2740 06 Oct 14 nicklas 457         frm['spWeight.'+i].value = storeInfo.spWeight;
2740 06 Oct 14 nicklas 458         frm['hisWeight.'+i].value = storeInfo.hisWeight;
2740 06 Oct 14 nicklas 459         frm['apWeight.'+i].value = storeInfo.apWeight;
2740 06 Oct 14 nicklas 460         frm['multPieces.'+i].checked = storeInfo.multPieces;
2740 06 Oct 14 nicklas 461       
2740 06 Oct 14 nicklas 462         Events.sendChangeEvent('spWeight.'+i);
2740 06 Oct 14 nicklas 463         Events.sendChangeEvent('hisWeight.'+i);
2740 06 Oct 14 nicklas 464         Events.sendChangeEvent('apWeight.'+i);
5335 28 Mar 19 nicklas 465         if (specimen.firstExtraction)
3145 25 Feb 15 nicklas 466         {
3145 25 Feb 15 nicklas 467           Events.sendChangeEvent('nofPieces.'+i);
3145 25 Feb 15 nicklas 468         }
2740 06 Oct 14 nicklas 469       }
2740 06 Oct 14 nicklas 470     }
2740 06 Oct 14 nicklas 471     
2740 06 Oct 14 nicklas 472     isRestoringFromLocalStorage = false;
2740 06 Oct 14 nicklas 473     
2740 06 Oct 14 nicklas 474     Wizard.setCurrentStep(2);
2740 06 Oct 14 nicklas 475     frm.partitionDate.focus();
2740 06 Oct 14 nicklas 476     frm.partitionDate.select();
2740 06 Oct 14 nicklas 477   
2740 06 Oct 14 nicklas 478     Doc.show('goregister');
2740 06 Oct 14 nicklas 479     Doc.show('gocancel');
2745 07 Oct 14 nicklas 480     Wizard.keepSessionAlive();
2740 06 Oct 14 nicklas 481   }
2740 06 Oct 14 nicklas 482   
2740 06 Oct 14 nicklas 483   partition.addEventHandlers = function(elements, eventName, handler)
2740 06 Oct 14 nicklas 484   {
2740 06 Oct 14 nicklas 485     for (var i = 0; i < elements.length; i++)
2740 06 Oct 14 nicklas 486     {
2740 06 Oct 14 nicklas 487       Events.addEventHandler(elements[i], eventName, handler);
2740 06 Oct 14 nicklas 488     }
2740 06 Oct 14 nicklas 489   }
2740 06 Oct 14 nicklas 490   
5346 03 Apr 19 nicklas 491   /**
5346 03 Apr 19 nicklas 492     Sort specimen tubes. Regular processing (AutoProcessing=null) tubes are
5346 03 Apr 19 nicklas 493     always sorted first. Then, we can either sort paused specimen tubes before
5346 03 Apr 19 nicklas 494     re-processing or after.
5346 03 Apr 19 nicklas 495    */
5346 03 Apr 19 nicklas 496   partition.sortByPosition = function(pausedFirst)
2740 06 Oct 14 nicklas 497   {
5346 03 Apr 19 nicklas 498     
5346 03 Apr 19 nicklas 499     return function(t1, t2)
3145 25 Feb 15 nicklas 500     {
5346 03 Apr 19 nicklas 501       if (t1.AutoProcessing != t2.AutoProcessing)
5346 03 Apr 19 nicklas 502       {
5346 03 Apr 19 nicklas 503         // Re-extraction items are sorted last (eg. AutoProcessing=ReProcess)
5346 03 Apr 19 nicklas 504         return t1.AutoProcessing == null ? -1 : 1;
5346 03 Apr 19 nicklas 505       }
5782 11 Dec 19 nicklas 506       
5782 11 Dec 19 nicklas 507       if (t1.paused != t2.paused)
5782 11 Dec 19 nicklas 508       {
5782 11 Dec 19 nicklas 509         return t1.paused == pausedFirst ? -1 : 1;
5782 11 Dec 19 nicklas 510       }
5782 11 Dec 19 nicklas 511       
5782 11 Dec 19 nicklas 512       if (t1.bioWell == null || t2.bioWell == null)
5782 11 Dec 19 nicklas 513       {
5782 11 Dec 19 nicklas 514         // Tubes without a box position are sorted last, in name order
5782 11 Dec 19 nicklas 515         if (t1.bioWell != null) return -1;
5782 11 Dec 19 nicklas 516         if (t2.bioWell != null) return 1;
5782 11 Dec 19 nicklas 517         return t1.name < t2.name ? -1 : 1;
5782 11 Dec 19 nicklas 518       }
5782 11 Dec 19 nicklas 519       
5346 03 Apr 19 nicklas 520       var well1 = t1.bioWell;
5346 03 Apr 19 nicklas 521       var box1 = well1.bioPlate.name;
5346 03 Apr 19 nicklas 522       var well2 = t2.bioWell;
5346 03 Apr 19 nicklas 523       var box2 = well2.bioPlate.name;
5346 03 Apr 19 nicklas 524       if (box1 == box2)
5346 03 Apr 19 nicklas 525       {
5346 03 Apr 19 nicklas 526         return well1.row == well2.row ? well1.column - well2.column : well1.row - well2.row;
5346 03 Apr 19 nicklas 527       }
5346 03 Apr 19 nicklas 528       else
5346 03 Apr 19 nicklas 529       {
5346 03 Apr 19 nicklas 530         return box1 < box2 ? -1 : 1;
5346 03 Apr 19 nicklas 531       }
3145 25 Feb 15 nicklas 532     }
2740 06 Oct 14 nicklas 533   }
2740 06 Oct 14 nicklas 534
3151 26 Feb 15 nicklas 535   partition.toLocation = function(well)
3151 26 Feb 15 nicklas 536   {
5782 11 Dec 19 nicklas 537     return well ? Strings.encodeTags(well.bioPlate.name+' ['+well.location+']') : 'Unknown box';
3151 26 Feb 15 nicklas 538   }
3151 26 Feb 15 nicklas 539   
2740 06 Oct 14 nicklas 540   partition.buildOptionsHtml = function(a)
2740 06 Oct 14 nicklas 541   {
2740 06 Oct 14 nicklas 542     var html = '';
2740 06 Oct 14 nicklas 543     for (var i = 0; i < a.length; i++)
2740 06 Oct 14 nicklas 544     {
2740 06 Oct 14 nicklas 545       html += '<option value="'+a[i]+'">'+a[i]+'</option>';
2740 06 Oct 14 nicklas 546     }
2740 06 Oct 14 nicklas 547     return html;
2740 06 Oct 14 nicklas 548   }
2740 06 Oct 14 nicklas 549   
5299 14 Feb 19 nicklas 550   partition.downloadLabelFile = function(event)
2740 06 Oct 14 nicklas 551   {  
5299 14 Feb 19 nicklas 552     var format = Data.get(event.currentTarget, 'format');
3146 25 Feb 15 nicklas 553     var ids = [];
2740 06 Oct 14 nicklas 554     for (var i = 0; i < selectedSpecimen.length; i++)
2740 06 Oct 14 nicklas 555     {
3146 25 Feb 15 nicklas 556       ids[ids.length] = selectedSpecimen[i].id;
2740 06 Oct 14 nicklas 557     }
5299 14 Feb 19 nicklas 558     
5299 14 Feb 19 nicklas 559     var url = '../PartitionRegistration.servlet?ID='+App.getSessionId();
5299 14 Feb 19 nicklas 560     url += '&cmd=GetLabelFile';
3146 25 Feb 15 nicklas 561     url += '&specimen='+ids.join(',');
5813 22 Jan 20 nicklas 562     url += '&includeHisLabels='+(Doc.element('includeHisLabels').checked ? 1 : 0);
3146 25 Feb 15 nicklas 563     url += '&includeAllHisLabels='+(Doc.element('includeAllHisLabels').checked ? 1 : 0);
5299 14 Feb 19 nicklas 564     url += '&format='+encodeURIComponent(format);
3146 25 Feb 15 nicklas 565
2740 06 Oct 14 nicklas 566     window.open(url);
2740 06 Oct 14 nicklas 567   }
2740 06 Oct 14 nicklas 568
2740 06 Oct 14 nicklas 569   partition.onFocusElement = function(event)
2740 06 Oct 14 nicklas 570   {
2740 06 Oct 14 nicklas 571     var target = event.currentTarget;
2740 06 Oct 14 nicklas 572     var dotI = target.id.indexOf('.');
2740 06 Oct 14 nicklas 573     var col = target.id.substr(0, dotI);
2740 06 Oct 14 nicklas 574     var index = target.id.substr(dotI+1);
2740 06 Oct 14 nicklas 575     
2740 06 Oct 14 nicklas 576     var msg = '&nbsp;';
2740 06 Oct 14 nicklas 577     if (event.type == 'focus')
2740 06 Oct 14 nicklas 578     {
2740 06 Oct 14 nicklas 579       if (col == 'bloody')
2740 06 Oct 14 nicklas 580       {
2740 06 Oct 14 nicklas 581         msg = 'Check this if the partition is bloody. Unchecked is default.';
2740 06 Oct 14 nicklas 582       }
2740 06 Oct 14 nicklas 583       else if (col == 'appearance')
2740 06 Oct 14 nicklas 584       {
2740 06 Oct 14 nicklas 585         msg = 'Select appearance. Empty is default.';
2740 06 Oct 14 nicklas 586       }
2740 06 Oct 14 nicklas 587       else if (col == 'fat')
2740 06 Oct 14 nicklas 588       {
2740 06 Oct 14 nicklas 589         msg = 'Select percentage of fat. \'0\' is default.';
2740 06 Oct 14 nicklas 590       }
2740 06 Oct 14 nicklas 591       else if (col == 'coloured')
2740 06 Oct 14 nicklas 592       {
2740 06 Oct 14 nicklas 593         msg = 'Check this if the partition is coloured. Unchecked is default.';
2740 06 Oct 14 nicklas 594       }
2740 06 Oct 14 nicklas 595       else if (col == 'nofPieces')
2740 06 Oct 14 nicklas 596       {
2740 06 Oct 14 nicklas 597         msg = 'Number of pieces in this partition.';
2740 06 Oct 14 nicklas 598       }
2740 06 Oct 14 nicklas 599       else if (col == 'apWeight')
2740 06 Oct 14 nicklas 600       {
2740 06 Oct 14 nicklas 601         msg = 'Ap weight in [mg].';
2740 06 Oct 14 nicklas 602       }
2740 06 Oct 14 nicklas 603       else if (col == 'hisWeight')
2740 06 Oct 14 nicklas 604       {
2740 06 Oct 14 nicklas 605         msg = 'His weight in [mg].';
2740 06 Oct 14 nicklas 606       }
2740 06 Oct 14 nicklas 607       else if (col == 'spWeight')
2740 06 Oct 14 nicklas 608       {
2740 06 Oct 14 nicklas 609         msg = 'Sp weight in [mg].';
2740 06 Oct 14 nicklas 610       }
2740 06 Oct 14 nicklas 611       else if (col == 'multPieces')
2740 06 Oct 14 nicklas 612       {
2740 06 Oct 14 nicklas 613         msg = 'Check the box if multiple specimen pieces are sampled for the AllPrep piece.';
2740 06 Oct 14 nicklas 614       }
2745 07 Oct 14 nicklas 615       // So we get an error icon for empty required fields
2745 07 Oct 14 nicklas 616       if (target.value == '') Events.sendChangeEvent(event.target);
2740 06 Oct 14 nicklas 617     }
2740 06 Oct 14 nicklas 618     Doc.element('specimen.'+index+'.help').innerHTML = msg;
2740 06 Oct 14 nicklas 619   }
2740 06 Oct 14 nicklas 620
2740 06 Oct 14 nicklas 621   partition.nofPiecesOnChange = function(event)
2740 06 Oct 14 nicklas 622   {
2740 06 Oct 14 nicklas 623     var frm = document.forms['reggie'];
2740 06 Oct 14 nicklas 624     var target = event.currentTarget;
2740 06 Oct 14 nicklas 625     var dotI = target.id.indexOf('.');
2740 06 Oct 14 nicklas 626     var index = parseInt(target.id.substr(dotI+1));
2740 06 Oct 14 nicklas 627     
2740 06 Oct 14 nicklas 628     var nofPieces = parseInt(target.value);
2740 06 Oct 14 nicklas 629     if (nofPieces > 0)
2740 06 Oct 14 nicklas 630     {
2740 06 Oct 14 nicklas 631       nofPiecesAreValid[index] = true;
2740 06 Oct 14 nicklas 632       if (nofPieces == 1)
2740 06 Oct 14 nicklas 633       {
2740 06 Oct 14 nicklas 634         frm['multPieces.'+index].disabled = true;
2740 06 Oct 14 nicklas 635         frm['multPieces.'+index].checked = false;
2740 06 Oct 14 nicklas 636       }
2740 06 Oct 14 nicklas 637       else
2740 06 Oct 14 nicklas 638       {
2740 06 Oct 14 nicklas 639         frm['multPieces.'+index].disabled = false;
2740 06 Oct 14 nicklas 640       }
2740 06 Oct 14 nicklas 641     }
2740 06 Oct 14 nicklas 642     else
2740 06 Oct 14 nicklas 643     {
2740 06 Oct 14 nicklas 644       nofPiecesAreValid[index] = false;
2740 06 Oct 14 nicklas 645     }
2745 07 Oct 14 nicklas 646     partition.updateInputStatus(index);
2740 06 Oct 14 nicklas 647   }
2740 06 Oct 14 nicklas 648   
2740 06 Oct 14 nicklas 649   partition.apWeightOnChange = function(event)
2740 06 Oct 14 nicklas 650   {
2740 06 Oct 14 nicklas 651     var target = event.currentTarget;
2740 06 Oct 14 nicklas 652     var dotI = target.id.indexOf('.');
2740 06 Oct 14 nicklas 653     var index = parseInt(target.id.substr(dotI+1));
2740 06 Oct 14 nicklas 654
2740 06 Oct 14 nicklas 655     var apWeight = parseFloat(target.value);
2745 07 Oct 14 nicklas 656     apWeightsAreValid[index] = apWeight >= 0;
2745 07 Oct 14 nicklas 657     partition.updateInputStatus(index);
2740 06 Oct 14 nicklas 658   }
2740 06 Oct 14 nicklas 659
2740 06 Oct 14 nicklas 660   partition.spWeightOnChange = function(event)
2740 06 Oct 14 nicklas 661   {
2740 06 Oct 14 nicklas 662     var target = event.currentTarget;
2740 06 Oct 14 nicklas 663     var dotI = target.id.indexOf('.');
2740 06 Oct 14 nicklas 664     var index = parseInt(target.id.substr(dotI+1));
2740 06 Oct 14 nicklas 665
2740 06 Oct 14 nicklas 666     var spWeight = parseFloat(target.value);
2745 07 Oct 14 nicklas 667     spWeightsAreValid[index] = spWeight >= 0;
2745 07 Oct 14 nicklas 668     partition.updateInputStatus(index);
2740 06 Oct 14 nicklas 669   }
2740 06 Oct 14 nicklas 670   
2740 06 Oct 14 nicklas 671   partition.hisWeightOnChange = function(event)
2740 06 Oct 14 nicklas 672   {
2740 06 Oct 14 nicklas 673     var target = event.currentTarget;
2740 06 Oct 14 nicklas 674     var dotI = target.id.indexOf('.');
2740 06 Oct 14 nicklas 675     var index = parseInt(target.id.substr(dotI+1));
2740 06 Oct 14 nicklas 676
2740 06 Oct 14 nicklas 677     var hisWeight = parseFloat(target.value);
2745 07 Oct 14 nicklas 678     hisWeightsAreValid[index] = hisWeight >= 0;
2745 07 Oct 14 nicklas 679     partition.updateInputStatus(index);
2740 06 Oct 14 nicklas 680   }
2740 06 Oct 14 nicklas 681   
2740 06 Oct 14 nicklas 682   partition.updateInputStatus = function(index)
2740 06 Oct 14 nicklas 683   {
2740 06 Oct 14 nicklas 684     var frm = document.forms['reggie'];
2740 06 Oct 14 nicklas 685     
2745 07 Oct 14 nicklas 686     if (!nofPiecesAreValid[index])
2740 06 Oct 14 nicklas 687     {
2745 07 Oct 14 nicklas 688       Wizard.setInputStatus('specimen.'+index, 'invalid', 'NofPieces is invalid.');
2745 07 Oct 14 nicklas 689     }
2745 07 Oct 14 nicklas 690     else if (!apWeightsAreValid[index])
2745 07 Oct 14 nicklas 691     {
2745 07 Oct 14 nicklas 692       Wizard.setInputStatus('specimen.'+index, 'invalid', 'APWeight is invalid.');
2745 07 Oct 14 nicklas 693     }
2745 07 Oct 14 nicklas 694     else if (!hisWeightsAreValid[index])
2745 07 Oct 14 nicklas 695     {
2745 07 Oct 14 nicklas 696       Wizard.setInputStatus('specimen.'+index, 'invalid', 'HisWeight is invalid.');
2745 07 Oct 14 nicklas 697     }
2745 07 Oct 14 nicklas 698     else if (!spWeightsAreValid[index])
2745 07 Oct 14 nicklas 699     {
2745 07 Oct 14 nicklas 700       Wizard.setInputStatus('specimen.'+index, 'invalid', 'SpWeight is invalid.');
2745 07 Oct 14 nicklas 701     }
2745 07 Oct 14 nicklas 702     else
2745 07 Oct 14 nicklas 703     {
3145 25 Feb 15 nicklas 704       var specimen = selectedSpecimen[index];
2740 06 Oct 14 nicklas 705       var spWeightValue = parseFloat(frm.elements['spWeight.'+index].value);
2740 06 Oct 14 nicklas 706       var apWeightValue = parseFloat(frm.elements['apWeight.'+index].value);
2740 06 Oct 14 nicklas 707       var hisWeightValue = parseFloat(frm.elements['hisWeight.'+index].value);
3147 25 Feb 15 nicklas 708       var sumOfWeights = apWeightValue + hisWeightValue + spWeightValue;
3147 25 Feb 15 nicklas 709       
2740 06 Oct 14 nicklas 710       if (apWeightValue == 0)
2740 06 Oct 14 nicklas 711       {
2740 06 Oct 14 nicklas 712         Wizard.setInputStatus('specimen.'+index, 'warning', 'No Lysate item will be created!');
2740 06 Oct 14 nicklas 713       }
5335 28 Mar 19 nicklas 714       else if (hisWeightValue == 0 && specimen.firstExtraction)
2740 06 Oct 14 nicklas 715       {
2740 06 Oct 14 nicklas 716         Wizard.setInputStatus('specimen.'+index, 'warning', 'No Histology item will be created!');
2740 06 Oct 14 nicklas 717       }
3147 25 Feb 15 nicklas 718       else
2740 06 Oct 14 nicklas 719       {
5335 28 Mar 19 nicklas 720         var weightDiff = specimen.firstExtraction ? 0 : sumOfWeights-specimen.remainingQuantity/1000;
3147 25 Feb 15 nicklas 721         if (Math.abs(weightDiff) > 2)
3147 25 Feb 15 nicklas 722         {
3147 25 Feb 15 nicklas 723           Wizard.setInputStatus('specimen.'+index, 'warning', 'Sum of weights ' + sumOfWeights + (weightDiff > 0 ? ' &gt; ' : ' &lt; ') + Reggie.formatNumber(specimen.remainingQuantity/1000, '', 1));
3147 25 Feb 15 nicklas 724         }
3147 25 Feb 15 nicklas 725         else
3147 25 Feb 15 nicklas 726         {
3147 25 Feb 15 nicklas 727           Wizard.setInputStatus('specimen.'+index, 'valid');
3147 25 Feb 15 nicklas 728         }
2740 06 Oct 14 nicklas 729       }
2740 06 Oct 14 nicklas 730     }
2740 06 Oct 14 nicklas 731   }
2740 06 Oct 14 nicklas 732
2740 06 Oct 14 nicklas 733   partition.validateStep2 = function(event)
2740 06 Oct 14 nicklas 734   {
2740 06 Oct 14 nicklas 735     var valid = true;
2740 06 Oct 14 nicklas 736     valid &= Wizard.isValid('partitionDate');
2740 06 Oct 14 nicklas 737     
2740 06 Oct 14 nicklas 738     if (valid)
2740 06 Oct 14 nicklas 739     {
2740 06 Oct 14 nicklas 740       for (var i = 0; i < selectedSpecimen.length; i++)
2740 06 Oct 14 nicklas 741       {
2740 06 Oct 14 nicklas 742         valid &= spWeightsAreValid[i];
2740 06 Oct 14 nicklas 743         valid &= apWeightsAreValid[i];
2740 06 Oct 14 nicklas 744         valid &= hisWeightsAreValid[i];
2740 06 Oct 14 nicklas 745         valid &= nofPiecesAreValid[i];
2740 06 Oct 14 nicklas 746         if (!valid) 
2740 06 Oct 14 nicklas 747         {
2740 06 Oct 14 nicklas 748           Wizard.setInputStatus('specimen.'+i, 'invalid');
2740 06 Oct 14 nicklas 749           break;
2740 06 Oct 14 nicklas 750         }
2740 06 Oct 14 nicklas 751       }
2740 06 Oct 14 nicklas 752     }
2740 06 Oct 14 nicklas 753     
2740 06 Oct 14 nicklas 754     if (!valid) event.preventDefault();
2740 06 Oct 14 nicklas 755   }
2740 06 Oct 14 nicklas 756
3149 26 Feb 15 nicklas 757   /*
3149 26 Feb 15 nicklas 758     Linked to the 'Register' buttons since we want to check if
3149 26 Feb 15 nicklas 759     the generated positions for re-extracted specimen tubes are
3149 26 Feb 15 nicklas 760     still valid. We simply make the same request as we made when
3149 26 Feb 15 nicklas 761     creating the partition table. See also
3149 26 Feb 15 nicklas 762     partition.storagePositionsLoadedForVerification()
3149 26 Feb 15 nicklas 763   */
3149 26 Feb 15 nicklas 764   partition.verifyPositionsForReextraction = function()
3149 26 Feb 15 nicklas 765   {
3149 26 Feb 15 nicklas 766     Wizard.hideGoNextConfirmation();
3149 26 Feb 15 nicklas 767     var numReextraction = 0;
3149 26 Feb 15 nicklas 768     for (var i = 0; i < selectedSpecimen.length; i++)
3149 26 Feb 15 nicklas 769     {
3149 26 Feb 15 nicklas 770       if (selectedSpecimen[i].reprocess) numReextraction++
3149 26 Feb 15 nicklas 771     }
3149 26 Feb 15 nicklas 772     
3149 26 Feb 15 nicklas 773     if (numReextraction > 0)
3149 26 Feb 15 nicklas 774     {
3149 26 Feb 15 nicklas 775       var url = '../SpecimenTubeRegistration.servlet?ID='+App.getSessionId();
3149 26 Feb 15 nicklas 776       url += '&cmd=FindStoragePositions';  
3149 26 Feb 15 nicklas 777       url += '&nofTubes='+numReextraction;
3149 26 Feb 15 nicklas 778       
3149 26 Feb 15 nicklas 779       Wizard.showLoadingAnimation('Verifying empty box positions...');
3149 26 Feb 15 nicklas 780       Wizard.asyncJsonRequest(url, partition.storagePositionsLoadedForVerification);
3149 26 Feb 15 nicklas 781     }
3149 26 Feb 15 nicklas 782     else
3149 26 Feb 15 nicklas 783     {
3149 26 Feb 15 nicklas 784       Wizard.goRegister();
3149 26 Feb 15 nicklas 785     }
3149 26 Feb 15 nicklas 786   }
2740 06 Oct 14 nicklas 787   
3149 26 Feb 15 nicklas 788   /**
3149 26 Feb 15 nicklas 789     Verify that the second request for storage positions return the same positions as the
3149 26 Feb 15 nicklas 790     first request (when creating the partition table). If they match we simple continue
3149 26 Feb 15 nicklas 791     with registration by calling Wizard.goRegister(), otherwise we update the specimen
3149 26 Feb 15 nicklas 792     with new positions and display a notification that must be verified before registration
3149 26 Feb 15 nicklas 793     can continue.
3149 26 Feb 15 nicklas 794   */
3149 26 Feb 15 nicklas 795   partition.storagePositionsLoadedForVerification = function(response)
3149 26 Feb 15 nicklas 796   {
3149 26 Feb 15 nicklas 797     var wells = response.wells;
3149 26 Feb 15 nicklas 798     if (wells.length < response.nofTubes)
3149 26 Feb 15 nicklas 799     {
3149 26 Feb 15 nicklas 800       var msg = 'Could not find enough free positions in storage box for re-extracted specimen.';
3149 26 Feb 15 nicklas 801       msg += ' Wanted ' + response.nofTubes + ', but found ' + wells.length + '.';
3149 26 Feb 15 nicklas 802       if (wells.length > 0)
3149 26 Feb 15 nicklas 803       {
3149 26 Feb 15 nicklas 804         var last = wells[wells.length-1];
3149 26 Feb 15 nicklas 805         msg += ' Last free: ' + Strings.encodeTags(last.bioPlate.name+' ['+last.location+']');
3149 26 Feb 15 nicklas 806       }
3149 26 Feb 15 nicklas 807       Wizard.setFatalError(msg);
3149 26 Feb 15 nicklas 808       return;
3149 26 Feb 15 nicklas 809     }
3149 26 Feb 15 nicklas 810
3149 26 Feb 15 nicklas 811     var wellNo = 0;
3149 26 Feb 15 nicklas 812     var hasModified = false;
3149 26 Feb 15 nicklas 813     for (var i = 0; i < selectedSpecimen.length; i++)
3149 26 Feb 15 nicklas 814     {
3149 26 Feb 15 nicklas 815       var specimen = selectedSpecimen[i];
3149 26 Feb 15 nicklas 816       if (specimen.reprocess)
3149 26 Feb 15 nicklas 817       {
3149 26 Feb 15 nicklas 818         var w = wells[wellNo];
3149 26 Feb 15 nicklas 819         wellNo++;
3149 26 Feb 15 nicklas 820         if (specimen.newBioWell.id != w.id)
3149 26 Feb 15 nicklas 821         {
3149 26 Feb 15 nicklas 822           hasModified = true;
3149 26 Feb 15 nicklas 823           specimen.newBioWell = w;
3151 26 Feb 15 nicklas 824           Doc.element('newlocation.'+i).innerHTML = partition.toLocation(w);
5933 08 May 20 nicklas 825           Doc.addClass('newlocation.'+i, 'updated-location');
3149 26 Feb 15 nicklas 826         }
3149 26 Feb 15 nicklas 827       }
3149 26 Feb 15 nicklas 828     }
3149 26 Feb 15 nicklas 829     
3149 26 Feb 15 nicklas 830     if (hasModified)
3149 26 Feb 15 nicklas 831     {
3149 26 Feb 15 nicklas 832       Wizard.showGoNextConfirmation(true, 'Positions for re-extraction specimen has been updated. Confirm new positions before registration!');
3149 26 Feb 15 nicklas 833     }
3149 26 Feb 15 nicklas 834     else
3149 26 Feb 15 nicklas 835     {
3149 26 Feb 15 nicklas 836       Wizard.goRegister();
3149 26 Feb 15 nicklas 837     }
3149 26 Feb 15 nicklas 838   }
3149 26 Feb 15 nicklas 839
3149 26 Feb 15 nicklas 840   
2740 06 Oct 14 nicklas 841   partition.submit = function()
2740 06 Oct 14 nicklas 842   {
2740 06 Oct 14 nicklas 843     var frm = document.forms['reggie'];
2740 06 Oct 14 nicklas 844     
2740 06 Oct 14 nicklas 845     var submitInfo = {};
2740 06 Oct 14 nicklas 846     submitInfo.partitionDate = frm.partitionDate.value;
2740 06 Oct 14 nicklas 847     
2740 06 Oct 14 nicklas 848     var specimens = [];
2740 06 Oct 14 nicklas 849     for (var i = 0; i < selectedSpecimen.length; i++)
2740 06 Oct 14 nicklas 850     {
2740 06 Oct 14 nicklas 851       var specimen = selectedSpecimen[i];
2740 06 Oct 14 nicklas 852       
2740 06 Oct 14 nicklas 853       specimen.spWeight = parseFloat(frm['spWeight.'+i].value) || null;
2740 06 Oct 14 nicklas 854       specimen.apWeight = parseFloat(frm['apWeight.'+i].value) || null;
2740 06 Oct 14 nicklas 855       specimen.hisWeight = parseFloat(frm['hisWeight.'+i].value) || null;
2740 06 Oct 14 nicklas 856       specimen.multPieces = frm['multPieces.'+i].checked;
2740 06 Oct 14 nicklas 857
5335 28 Mar 19 nicklas 858       if (specimen.firstExtraction)
3149 26 Feb 15 nicklas 859       {
3149 26 Feb 15 nicklas 860         specimen.nofPieces = parseInt(frm['nofPieces.'+i].value);
3149 26 Feb 15 nicklas 861         // Generate partition comment string
3149 26 Feb 15 nicklas 862         var comment = [];  
3149 26 Feb 15 nicklas 863         if (frm['bloody.'+i].checked) comment[comment.length] = 'BLOODY';
3149 26 Feb 15 nicklas 864         if (frm['appearance.'+i].selectedIndex > 0) comment[comment.length] = frm['appearance.'+i].value;
3149 26 Feb 15 nicklas 865         if (frm['fat.'+i].selectedIndex > 0) comment[comment.length] = 'FAT'+frm['fat.'+i].value+'%';
3149 26 Feb 15 nicklas 866         if (frm['coloured.'+i].checked) comment[comment.length] = 'COLOURED';
3149 26 Feb 15 nicklas 867         specimen.operatorPartitionComment = comment.length > 0 ? comment.join(';') : null;
3149 26 Feb 15 nicklas 868       }
3149 26 Feb 15 nicklas 869
2740 06 Oct 14 nicklas 870       specimens[i] = specimen;    
2740 06 Oct 14 nicklas 871     }
2740 06 Oct 14 nicklas 872     submitInfo.specimens = specimens;
2740 06 Oct 14 nicklas 873     
2740 06 Oct 14 nicklas 874     var url = '../PartitionRegistration.servlet?ID='+App.getSessionId();
2740 06 Oct 14 nicklas 875     url += '&cmd=CreatePartitions';
2740 06 Oct 14 nicklas 876     Wizard.showLoadingAnimation('Performing registration...');
2740 06 Oct 14 nicklas 877     Wizard.asyncJsonRequest(url, partition.submissionResults, 'POST', JSON.stringify(submitInfo));
2740 06 Oct 14 nicklas 878   }
2740 06 Oct 14 nicklas 879   
2740 06 Oct 14 nicklas 880   partition.submissionResults = function(response)
2740 06 Oct 14 nicklas 881   {
2740 06 Oct 14 nicklas 882     for (var i = 0; i < response.partitioned.length; i++)
2740 06 Oct 14 nicklas 883     {
2740 06 Oct 14 nicklas 884       partition.removeFromLocalStorage(response.partitioned[i]);
2740 06 Oct 14 nicklas 885     }
2740 06 Oct 14 nicklas 886     
2740 06 Oct 14 nicklas 887     Wizard.showFinalMessage(response.messages);
2740 06 Oct 14 nicklas 888     Doc.show('gorestart');
2740 06 Oct 14 nicklas 889   }
2740 06 Oct 14 nicklas 890
2740 06 Oct 14 nicklas 891
2740 06 Oct 14 nicklas 892   /**
2740 06 Oct 14 nicklas 893     Save as much information as possible about the partitioned
2740 06 Oct 14 nicklas 894     specimen tube. The information is stored in the localStorage()
2740 06 Oct 14 nicklas 895     under the key 'reggie.specimen.<id>.partitionInfo' where
2740 06 Oct 14 nicklas 896     <id> is the ID of the specimen tube.
2740 06 Oct 14 nicklas 897   */
2740 06 Oct 14 nicklas 898   partition.saveToLocalStorage = function(event)
2740 06 Oct 14 nicklas 899   {
2740 06 Oct 14 nicklas 900     if (!isRestoringFromLocalStorage)
2740 06 Oct 14 nicklas 901     {
2740 06 Oct 14 nicklas 902       var target = event.currentTarget;
2740 06 Oct 14 nicklas 903       var dotI = target.id.indexOf('.');
2740 06 Oct 14 nicklas 904       var index = parseInt(target.id.substr(dotI+1));
2740 06 Oct 14 nicklas 905       
2740 06 Oct 14 nicklas 906       var specimen = selectedSpecimen[index];
2740 06 Oct 14 nicklas 907       var frm = document.forms['reggie'];
2740 06 Oct 14 nicklas 908       
2740 06 Oct 14 nicklas 909       var info = {};
2740 06 Oct 14 nicklas 910       info.id = specimen.id;
5335 28 Mar 19 nicklas 911       if (specimen.firstExtraction)
3145 25 Feb 15 nicklas 912       {
3145 25 Feb 15 nicklas 913         info.bloody = frm['bloody.'+index].checked;
3145 25 Feb 15 nicklas 914         info.appearance = frm['appearance.'+index].value;
3145 25 Feb 15 nicklas 915         info.fat = frm['fat.'+index].value;
3145 25 Feb 15 nicklas 916         info.coloured = frm['coloured.'+index].checked;
3145 25 Feb 15 nicklas 917         info.nofPieces = frm['nofPieces.'+index].value;
3145 25 Feb 15 nicklas 918       }
2740 06 Oct 14 nicklas 919       info.spWeight = frm['spWeight.'+index].value;
2740 06 Oct 14 nicklas 920       info.hisWeight = frm['hisWeight.'+index].value;
2740 06 Oct 14 nicklas 921       info.apWeight = frm['apWeight.'+index].value;
2740 06 Oct 14 nicklas 922       info.multPieces = frm['multPieces.'+index].checked;
2740 06 Oct 14 nicklas 923       App.setLocal('reggie.specimen.' + specimen.id + '.partitionInfo', JSON.stringify(info));
2740 06 Oct 14 nicklas 924       if (debug)
2740 06 Oct 14 nicklas 925       {
2740 06 Oct 14 nicklas 926         App.debug(index + ': ' + App.getLocal('reggie.specimen.' + specimen.id + '.partitionInfo'));
2740 06 Oct 14 nicklas 927       }
2740 06 Oct 14 nicklas 928     }
2740 06 Oct 14 nicklas 929   }
2740 06 Oct 14 nicklas 930
2740 06 Oct 14 nicklas 931   partition.removeFromLocalStorage = function(specimenId)
2740 06 Oct 14 nicklas 932   {
2740 06 Oct 14 nicklas 933     App.removeLocal('reggie.specimen.' + specimenId + '.partitionInfo');
2740 06 Oct 14 nicklas 934   }
2740 06 Oct 14 nicklas 935   
2740 06 Oct 14 nicklas 936   partition.getStoredInfo = function(specimenId)
2740 06 Oct 14 nicklas 937   {
2740 06 Oct 14 nicklas 938     try
2740 06 Oct 14 nicklas 939     {
2740 06 Oct 14 nicklas 940       var stored = App.getLocal('reggie.specimen.' + specimenId + '.partitionInfo');
2740 06 Oct 14 nicklas 941       if (debug) App.debug(stored);
2740 06 Oct 14 nicklas 942       return stored ? JSON.parse(stored) : null;
2740 06 Oct 14 nicklas 943     }
2740 06 Oct 14 nicklas 944     catch (e)
2740 06 Oct 14 nicklas 945     {
2740 06 Oct 14 nicklas 946       App.debug('Could not load stored information for tube ' + specimenId + ': ' + e);
2740 06 Oct 14 nicklas 947     }
2740 06 Oct 14 nicklas 948   }
2740 06 Oct 14 nicklas 949
2740 06 Oct 14 nicklas 950   
2740 06 Oct 14 nicklas 951   return partition;
2740 06 Oct 14 nicklas 952 }();
2740 06 Oct 14 nicklas 953
2740 06 Oct 14 nicklas 954 Doc.onLoad(Partition.initPage);
2740 06 Oct 14 nicklas 955