source: extensions/net.sf.basedb.reggie/trunk/resources/reports/samplereportgenerator.jsp @ 2000

Last change on this file since 2000 was 2000, checked in by olle, 9 years ago

Fixes #496. Sample source reports updated to initialize table data from new sites correctly:

  1. JSP file samplereportgenerator.jsp in reggie/resources/reports/ updated in JavaScript function addDataRowsToTable(report, reportTable) to initialize cells in columns for time periods before the start date of the site to an empty string.
  2. JSP file samplereportgenerator.jsp in reggie/resources/reports/ updated in JavaScript function getJSONDataWithPercent(jsonObject, key, sumKey, numDecimals) by fix of bug (condition "dataSum != null || dataSum != 0" corrected to "dataSum != null && dataSum != 0").
  3. Servlet SampleReportServlet in reggie/src/net/sf/basedb/reggie/servlet/ updated in private method JSONObject createOverviewReport(DbControl dc, JSONObject json, Date startDate, Date endDate) to initialize data for JSON key "sumKey".
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 89.1 KB
Line 
1<%@ page
2  pageEncoding="UTF-8"
3  session="false"
4  import="net.sf.basedb.core.User"
5  import="net.sf.basedb.core.DbControl"
6  import="net.sf.basedb.core.SessionControl"
7  import="net.sf.basedb.core.Application"
8  import="net.sf.basedb.clients.web.Base" 
9  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
10%>
11<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
12<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
13<%
14final SessionControl sc = Base.getExistingSessionControl(request, true);
15final String ID = sc.getId();
16final float scale = Base.getScale(sc);
17final String home = ExtensionsControl.getHomeUrl("net.sf.basedb.reggie");
18DbControl dc = null;
19try
20{
21  dc = sc.newDbControl();
22  final User user = User.getById(dc, sc.getLoggedInUserId());
23  %>
24<base:page type="default" >
25<base:head scripts="ajax.js" styles="path.css">
26  <link rel="stylesheet" type="text/css" href="../css/reggie.css">
27  <script language="JavaScript" src="../reggie.js" type="text/javascript" charset="UTF-8"></script>
28   
29   
30  <script language="JavaScript">
31  var currentStep = 1;
32  var debug = false;
33  var numCols;
34  var unknownSite = 0;
35  var unknownCreation = 0;
36  var numMissing = 0;
37  var numPatientsNoSamples = 0;
38 
39  var month=new Array(12);
40    month[0]="Jan";
41    month[1]="Feb";
42    month[2]="Mar";
43    month[3]="Apr";
44    month[4]="May";
45    month[5]="Jun";
46    month[6]="Jul";
47    month[7]="Aug";
48    month[8]="Sep";
49    month[9]="Oct";
50    month[10]="Nov";
51    month[11]="Dec";
52 
53  var intervalIsValid = true;
54 
55  function goNext()
56  {
57    if (currentStep == 1)
58    {
59      gotoStep2();
60    }
61  }
62 
63  function gotoStep2()
64  {
65    var frm = document.forms['reggie'];
66    frm.reporttype.disabled = true;
67    // Hide report period input fields
68    document.getElementById("reportPeriodSubSection01").style.display = 'none';
69    document.getElementById("reportPeriodSubSection02").style.display = 'none';
70    document.getElementById("reportPeriodSubSection04").style.display = 'none';
71    // Hide view type pop-up menu
72    document.getElementById("viewTypeSubSection01").style.display = 'none';
73    document.getElementById("viewTypeSubSection02").style.display = 'none';
74    document.getElementById("viewTypeSubSection04").style.display = 'none';
75    // Hide sample type pop-up menu
76    document.getElementById("sampleTypeSubSection01").style.display = 'none';
77    document.getElementById("sampleTypeSubSection02").style.display = 'none';
78    document.getElementById("sampleTypeSubSection04").style.display = 'none';
79    if (frm.reporttype[frm.reporttype.selectedIndex].value == 'samplecount')
80    {
81      // Show report period input fields
82      document.getElementById("reportPeriodSubSection01").style.display = 'block';
83      document.getElementById("reportPeriodSubSection02").style.display = 'block';
84      document.getElementById("reportPeriodSubSection04").style.display = 'block';
85      document.getElementById("reportPeriodSubSection01Header").innerHTML="Report period";
86      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Define which period the report should cover. Empty fields will include all tubes.";
87      // Set item name for report time step text
88      document.getElementById("items02").innerHTML="samples";
89      document.getElementById("items03").innerHTML="samples";
90      document.getElementById("items04").innerHTML="samples";
91      document.getElementById("items05").innerHTML="samples";
92      // Show view type pop-up menu
93      document.getElementById("viewTypeSubSection01").style.display = 'block';
94      document.getElementById("viewTypeSubSection02").style.display = 'block';
95      document.getElementById("viewTypeSubSection04").style.display = 'block';
96      // Show sample type pop-up menu
97      document.getElementById("sampleTypeSubSection01").style.display = 'block';
98      document.getElementById("sampleTypeSubSection02").style.display = 'block';
99      document.getElementById("sampleTypeSubSection04").style.display = 'block';
100    }
101    else if (frm.reporttype[frm.reporttype.selectedIndex].value == 'consentcount')
102    {
103      // Show report period input fields
104      document.getElementById("reportPeriodSubSection01").style.display = 'block';
105      document.getElementById("reportPeriodSubSection02").style.display = 'block';
106      document.getElementById("reportPeriodSubSection04").style.display = 'block';
107      document.getElementById("reportPeriodSubSection01Header").innerHTML="Report period";
108      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Define which period the report should cover. Empty fields will include all consents.";
109    }
110    else if (frm.reporttype[frm.reporttype.selectedIndex].value == 'patientcount')
111    {
112      // Show report period input fields
113      document.getElementById("reportPeriodSubSection01").style.display = 'block';
114      document.getElementById("reportPeriodSubSection02").style.display = 'block';
115      document.getElementById("reportPeriodSubSection04").style.display = 'block';
116      document.getElementById("reportPeriodSubSection01Header").innerHTML="Report period";
117      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Define which period the report should cover. Empty fields will include all patients.";
118      // Set item name for report time step text
119      document.getElementById("items02").innerHTML="patients";
120      document.getElementById("items03").innerHTML="patients";
121      document.getElementById("items04").innerHTML="patients";
122      document.getElementById("items05").innerHTML="patients";
123      // Show view type pop-up menu
124      document.getElementById("viewTypeSubSection01").style.display = 'block';
125      document.getElementById("viewTypeSubSection02").style.display = 'block';
126      document.getElementById("viewTypeSubSection04").style.display = 'block';
127    }
128    else if (frm.reporttype[frm.reporttype.selectedIndex].value == 'overviewreport')
129    {
130      // Set parameters (report period) help text
131      document.getElementById("reportPeriodSubSection01").style.display = 'block';
132      document.getElementById("reportPeriodSubSection04").style.display = 'block';
133      document.getElementById("reportPeriodSubSection01Header").innerHTML="No report parameters";
134      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Overview report will be generated irrespective of date for items.";
135    }
136    else if (frm.reporttype[frm.reporttype.selectedIndex].value == 'missingsampledatareport')
137    {
138      // Show sample type pop-up menu
139      document.getElementById("sampleTypeSubSection01").style.display = 'block';
140      document.getElementById("sampleTypeSubSection02").style.display = 'block';
141      document.getElementById("sampleTypeSubSection04").style.display = 'block';
142    }
143    Main.show('itemCountSection');
144       
145    Main.show('gocreate');   
146    Main.hide('gonext');
147    frm.fromdate.focus();
148    currentStep = 2;
149  }
150 
151  function dateOnChange()
152  {
153    var frm = document.forms['reggie'];   
154    var fdate;
155    var tdate;
156   
157    intervalIsValid = false;
158    setInputStatus('displayInterval','','valid');
159    if (frm.fromdate.value != null && frm.fromdate.value != '')
160    {
161      frm.fromdate.value = autoFillDate(frm.fromdate.value);     
162      if (!Dates.isDate(frm.fromdate.value, 'yyyyMMdd'))
163      {
164        setInputStatus('displayInterval','Not a valid from-date', 'invalid');
165        return;
166      }
167      else
168      {
169        fdate = frm.fromdate.value;
170        fdate = new Date(fdate.substr(0,4), parseInt(fdate.substr(4,2), 10)-1, fdate.substr(6,2));
171      }
172    }
173   
174    if (frm.todate.value != null && frm.todate.value != '')
175    {
176      frm.todate.value = autoFillDate(frm.todate.value);
177      if (!Dates.isDate(frm.todate.value, 'yyyyMMdd'))
178      {
179        setInputStatus('displayInterval', 'Not a valid to-date', 'invalid');
180        return;
181      }
182      else
183      {
184        tdate = frm.todate.value;
185        tdate = new Date(tdate.substr(0,4), parseInt(tdate.substr(4,2), 10)-1, tdate.substr(6,2));
186      }
187    }
188   
189    if (tdate != null && fdate != null)
190    {
191      if (fdate > tdate)
192      {
193        setInputStatus('displayInterval', 'Invalid period', 'invalid')
194        return;
195      }     
196    }
197    intervalIsValid = true;
198  }
199 
200  function goCreate()
201  {
202    if (!intervalIsValid) return;
203    var cellElement = document.getElementById('reportcell');
204    var frm = document.forms['reggie'];   
205    var reportType = frm.reporttype[frm.reporttype.selectedIndex].value;   
206    frm.fromdate.disabled = true;
207    frm.todate.disabled = true;
208    var sampleType = frm.sampletype[frm.sampletype.selectedIndex].value;   
209    if (reportType == 'samplecount')
210    {
211      frm.viewtype.disabled = true;
212      frm.sampletype.disabled = true;
213    }
214    else if (reportType == 'patientcount')
215    {
216      frm.viewtype.disabled = true;
217    }
218    else if (reportType == 'missingsampledatareport')
219    {
220      frm.sampletype.disabled = true;
221    }
222    Main.hide('gocreate');
223    Main.show('reportSection');
224    var url = '../SampleReport.servlet?ID=<%=ID%>&cmd='+reportType;   
225   
226    if (frm.fromdate.value != null) url += '&fdate='+frm.fromdate.value;
227    if (frm.todate.value != null) url += '&tdate='+frm.todate.value;
228    if (reportType == 'samplecount')
229    {     
230      if (frm.viewtype.value != null) url += '&vtype='+frm.viewtype.value;
231      if (frm.sampletype.value != null) url += '&stype='+frm.sampletype.value;
232    }
233    else if (reportType == 'patientcount')
234    {     
235      if (frm.viewtype.value != null) url += '&vtype='+frm.viewtype.value;
236    }
237    else if (reportType == 'missingsampledatareport')
238    {     
239      if (frm.sampletype.value != null) url += '&stype='+frm.sampletype.value;
240    }
241   
242    var request = Ajax.getXmlHttpRequest();
243    request.open("GET", url, false);
244    request.send(null);
245   
246    if (debug) Main.debug(request.responseText);   
247    var response = JSON.parse(request.responseText); 
248    if (response.status != 'ok')
249    {
250      setFatalError(response.message);
251      return false;
252    }
253    var report = response.report;
254    var permissionDeniedForPatientName = report.permissionDeniedForPatientName;
255    var reportTable;
256   
257    if (report != null)
258    {
259      if ('samplecount' == reportType)
260      {     
261        reportTable = createItemCountReport(report, reportType);
262      }
263      else if ('consentcount' == reportType)
264      {     
265        reportTable = createConsentCountReport(report);
266      }
267      else if ('patientcount' == reportType)
268      {     
269        reportTable = createItemCountReport(report, reportType);
270      }
271      else if ('overviewreport' == reportType)
272      {     
273        reportTable = createOverviewReport(report);
274      }
275      else if ('missingsampledatareport' == reportType)
276      {     
277        reportTable = createMissingSampleDataReport(report);
278      }
279    }
280    else
281    {
282      var messageCell = getTableCellElement('No values could be found during given period', 'reportheader');
283      var messageRow = document.createElement('tr');
284      messageRow.appendChild(messageCell);     
285      var messageTable = getReportTable();
286      messageTable.appendChild(messageRow);
287      reportTable = messageTable;     
288    }
289    setInnerHTML('reportcell', '');
290    cellElement.appendChild(reportTable);
291    // Optional extra tables
292    if ('consentcount' == reportType)
293    {
294      var spacer0 = document.createElement('text');
295      spacer0.innerHTML = "<BR>";
296      cellElement.appendChild(spacer0);
297      var spacer = document.createElement('text');
298      spacer.innerHTML = "<BR>";
299      cellElement.appendChild(spacer);
300      // Table with consents in different categories with date, as well as consents with unknown date
301      cellElement.appendChild(spacer);
302      var hasDateTable = createConsentCountHasDateTable(report);
303      cellElement.appendChild(hasDateTable);
304      // Table with consents in different categories with unknown date, as well as missing consents
305      cellElement.appendChild(spacer);
306      var unknownDateTable = createConsentCountUnknownDateTable(report);
307      cellElement.appendChild(unknownDateTable);
308    }
309    else if ('overviewreport' == reportType)
310    {
311      var spacer = document.createElement('text');
312      spacer.innerHTML = "<BR>";
313      cellElement.appendChild(spacer);
314      var patientDetailedTable = createOverviewPatientDetailedTable(report);
315      cellElement.appendChild(patientDetailedTable);
316    }
317    // Summary list
318    var summaryList = document.createElement('ul');
319    if (unknownSite == null) unknownSite = 0;
320    if (unknownCreation == null) unknownCreation = 0;
321    if ('samplecount' == reportType)
322    {
323      var samples = 'specimens';
324      if ('nospecimen' == sampleType)
325      {
326        samples = '"no specimens"';
327      }
328      else if ('blood' == sampleType)
329      {
330        samples = 'blood samples';
331      }
332      summaryList.appendChild(getListElement(unknownSite + ' ' + samples + ' registered to unknown sites.'));
333      summaryList.appendChild(getListElement(unknownCreation + ' ' + samples + ' without creation date. These are included in the \'Total\' column.'));
334    }
335    else if ('consentcount' == reportType)
336    {
337      var numDuplicates = 0;
338      if (report != null)
339      {
340        var statistics = report.statistics;
341        numDuplicates = statistics.duplicateKey;
342      }
343      if (numDuplicates == null)
344      {
345        numDuplicates = 0;
346      }
347      summaryList.appendChild(getListElement(unknownSite + ' consents registered to unknown sites.'));
348      summaryList.appendChild(getListElement(unknownCreation + ' consents without known date. These are included in the \'Total\' column.'));
349      summaryList.appendChild(getListElement(numMissing + ' missing consents for cases and blood samples. These are NOT included in the \'Total\' column.'));
350      summaryList.appendChild(getListElement(numDuplicates + ' duplicates ignored.'));
351
352      var patientsWithMultipleDates = statistics.patientsWithMultipleDatesKey;
353      var counter = 0;
354      for (var key in patientsWithMultipleDates)
355      {
356        counter++;
357      }
358      var patientsWithMultipleDatesText = counter + ' patients with multiple dates.';
359      summaryList.appendChild(getListElement(patientsWithMultipleDatesText));
360    }
361    else if ('patientcount' == reportType)
362    {
363      summaryList.appendChild(getListElement(unknownSite + ' patients registered to unknown sites.'));
364      summaryList.appendChild(getListElement(unknownCreation + ' patients without creation date. These are included in the \'Total\' column.'));
365    }
366    else if ('overviewreport' == reportType)
367    {
368      summaryList.appendChild(getListElement(unknownSite + ' patients registered to unknown sites.'));
369      summaryList.appendChild(getListElement(numPatientsNoSamples + ' patients with no samples.'));
370      summaryList.appendChild(getListElement('Note: Consents of type "Yes" include consents without patient id (PAT#) or date.'));
371    }
372    else if ('missingsampledatareport' == reportType)
373    {
374      summaryList.appendChild(getListElement('Note: Patient name is considered missing if either "all first names" or "family name" is missing.'));
375      if ('true' == permissionDeniedForPatientName)
376      {
377        var patientNamePermissionWarningIconWithMessage = document.createElement('img');
378        patientNamePermissionWarningIconWithMessage.innerHTML = '<img src="images/warning.png"> Sorry, logged-in user does not have permission to check patient names.</img>';
379        var patientNamePermissionWarningListElement = document.createElement('li');
380        patientNamePermissionWarningListElement.appendChild(patientNamePermissionWarningIconWithMessage);
381        summaryList.appendChild(patientNamePermissionWarningListElement);
382      }
383    }
384    cellElement.appendChild(summaryList);
385    if ('consentcount' == reportType)
386    {
387      // Add table with patients with consents with multiple dates
388      var multipleDatesTable = createConsentTablePatientsWithMultipleDates(report);
389      cellElement.appendChild(multipleDatesTable);
390    }
391    Main.show('printButton');
392    Main.show('gorestart');
393  }
394 
395  function createItemCountReport(report, reportType)
396  {
397    var reportTable = getReportTable();
398    var sdString = report.beginDate;
399    var edString = report.endDate;
400    var psdString = report.periodBeginDate;
401    var ldString = report.latestDate;
402    var startDate = dateStrToDate(sdString);
403    var endDate = dateStrToDate(edString);
404    var periodStartDate = dateStrToDate(psdString);
405    var latestDate = dateStrToDate(ldString);
406   
407    var viewType = report.viewType;   
408    var sampleType = report.sampleType;
409 
410    var headerRow = document.createElement('tr');   
411    var subHeaderRowYear = document.createElement('tr');
412    var columnHeaderRow = document.createElement('tr');
413   
414    var headerText = '# Items by ';
415    var startDateStr = addHyphensToDateString(sdString);
416    var endDateStr = addHyphensToDateString(edString);
417    var latestDateStr = addHyphensToDateString(ldString);
418    if ('samplecount' == reportType)
419    {
420      headerText = '# Specimens by ';
421      if ('nospecimen' == sampleType)
422      {
423        headerText = '# "No specimens" by ';
424      }
425      else if ('blood' == sampleType)
426      {
427        headerText = '# Blood samples by ';
428      }
429    }
430    else if ('patientcount' == reportType)
431    {
432      headerText = '# Patients by ';
433    }
434    if (viewType == 'WEEK')
435    {
436      var startWeek = getISOWeekNumber(periodStartDate);
437      var endWeek = getISOWeekNumber(endDate);
438      var tempDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate()-periodStartDate.getDay()+1);
439      numCols = 0;
440      while (tempDate < endDate)
441      {
442        numCols++;
443        tempDate.setDate(tempDate.getDate()+7);
444      }
445      headerText += 'week';
446    }
447    else if (viewType == 'MONTH')
448    {
449      numCols = (endDate.getFullYear()-periodStartDate.getFullYear())*12 + endDate.getMonth()-periodStartDate.getMonth()+1;
450      headerText += 'month';
451    }
452    else if (viewType == 'QUARTER')
453    {
454      // First year (from start quarter to end of year)
455      numCols = 4 - Math.floor(periodStartDate.getMonth()/3);
456      // Last year (from start of year to end quarter) 
457      numCols += Math.floor(endDate.getMonth()/3)+1;
458      // If first and last year is the same, subtract 4 quarters
459      if (endDate.getFullYear() - periodStartDate.getFullYear() == 0)
460      {
461        numCols -= 4;
462      }
463      // Full years between start and end dates
464      if((endDate.getFullYear() - periodStartDate.getFullYear()) > 1)
465      {
466        numCols += 4 * (endDate.getFullYear() - periodStartDate.getFullYear()-1);
467      }
468      headerText += 'quarter';
469    }
470    else
471    {
472      numCols = endDate.getFullYear() - periodStartDate.getFullYear() + 1;
473      headerText += 'year';
474    }
475     
476    // Set table header
477    headerText += ' (between ' + startDateStr + ' and ' + endDateStr + ')';
478    if (latestDate != null)
479    {
480      headerText += '\nLast registration ' + latestDateStr;
481    }   
482    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+5)));
483   
484    // Sub headers
485    // Only if each datacol is less then a year
486    if (viewType != 'YEAR')
487    {
488      subHeaderRowYear.appendChild(getTableCellElement('', 'reportsubheader', 3));
489      addYearSubHeaders(periodStartDate, endDate, subHeaderRowYear, viewType);     
490      subHeaderRowYear.appendChild(getTableCellElement('', 'reportsubheader', 2));
491    }   
492         
493    // Columnsheader   
494    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
495    var startDateHeader = getTableCellElement('Start date','reportsubheader');
496    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
497    columnHeaderRow.appendChild(siteHeader);
498    columnHeaderRow.appendChild(startDateHeader);
499    columnHeaderRow.appendChild(latestDateHeader); 
500   
501    if (viewType == 'MONTH') addMonthColumnHeaders(columnHeaderRow, periodStartDate);
502    else if (viewType == 'WEEK') addWeekColumnHeaders(columnHeaderRow, periodStartDate);
503    else if (viewType == 'QUARTER') addQuarterColumnHeaders(columnHeaderRow, periodStartDate);
504    else if (viewType == 'YEAR') addYearSubHeaders(periodStartDate, endDate, columnHeaderRow, viewType);
505   
506   
507    columnHeaderRow.appendChild(getTableCellElement('Sum', 'reportsubheader'));
508    columnHeaderRow.appendChild(getTableCellElement('Total', 'reportsubheader'));
509
510    // Build table     
511    reportTable.appendChild(headerRow);
512    reportTable.appendChild(subHeaderRowYear);
513    reportTable.appendChild(columnHeaderRow);
514         
515    // Data rows     
516    addDataRowsToTable(report, reportTable);
517     
518    // Add a row with the combined numbers for all sites for each period
519    var sitesCombinedRow = document.createElement('tr');
520    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
521    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
522    // Get combined numbers for all sites for each period
523    var statistics = report.statistics;
524    var sitesCombined = statistics.sitesCombinedKey;   
525    var sortedKeyArray = createSortedPeriodArray(report, numCols);
526    var key;
527    for (arrayIndex in sortedKeyArray)
528    {
529      key = sortedKeyArray[arrayIndex];
530      var data = getJSONData(sitesCombined, key, 0);
531      // Add entry with sample sum for site for selected time period
532      sitesCombinedRow.appendChild(getTableCellElement(data,'colsummary'));
533    }
534    // Get total number of samples for site for the selected time period
535    var sum = getJSONData(statistics, 'sumKey', 0);
536    // Add entry with total number of samples for site for the selected time period
537    sitesCombinedRow.appendChild(getTableCellElement(sum, 'colsummary'));
538    // Get total number of samples for all sites, regardless of creation date
539    var total = getJSONData(statistics, 'totalKey', 0);
540    // Add entry with total number of samples for all sites, regardless of creation date
541    sitesCombinedRow.appendChild(getTableCellElement(total, 'colsummary'));
542    reportTable.appendChild(sitesCombinedRow); 
543
544    return reportTable;
545  }
546 
547  function createConsentCountReport(report)
548  {
549    var reportTable = getReportTable();
550    var sdString = report.beginDate;
551    var edString = report.endDate;
552    var ldString = report.latestDate;
553    var startDate = dateStrToDate(sdString);
554    var endDate = dateStrToDate(edString);
555    var latestDate = dateStrToDate(ldString);
556
557    var headerRow = document.createElement('tr');   
558    var subHeaderRow = document.createElement('tr');
559    var columnHeaderRow = document.createElement('tr');
560   
561    var numCols = 5;
562    var numDecimals = 0;
563    var headerText = '# Consent forms of different types for cases and blood samples';
564    var startDateStr = addHyphensToDateString(sdString);
565    var endDateStr = addHyphensToDateString(edString);
566    var latestDateStr = addHyphensToDateString(ldString);
567    headerText += ' (betweeen ' + startDateStr + ' and ' + endDateStr + ')';
568    if (latestDate != null)
569    {
570        headerText += '\nLast registration ' + latestDateStr;
571    }
572    headerText += '\nConsents without date treated as if belonging to selected time period';
573    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+3)));
574   
575    // Subheader   
576    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 3));
577   
578    subHeaderRow.appendChild(getTableCellElement('Yes', 'reportsubheader'));
579    subHeaderRow.appendChild(getTableCellElement('No', 'reportsubheader'));
580    subHeaderRow.appendChild(getTableCellElement('Not asked', 'reportsubheader'));
581    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 2));
582
583    // Columnsheader   
584    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
585    var startDateHeader = getTableCellElement('Start date','reportsubheader');
586    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
587    columnHeaderRow.appendChild(siteHeader);
588    columnHeaderRow.appendChild(startDateHeader);
589    columnHeaderRow.appendChild(latestDateHeader); 
590   
591    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
592    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
593    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
594    columnHeaderRow.appendChild(getTableCellElement('Sum', 'reportsubheader'));
595    columnHeaderRow.appendChild(getTableCellElement('Total', 'reportsubheader'));
596
597    // Build table     
598    reportTable.appendChild(headerRow);
599    reportTable.appendChild(subHeaderRow);
600    reportTable.appendChild(columnHeaderRow);
601         
602    // Data rows     
603    addDataRowsToConsentTable(report, reportTable);
604     
605    // Add a row with the combined numbers for all sites for each period
606    var sitesCombinedRow = document.createElement('tr');
607    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
608    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
609    // Get combined numbers for all sites for each period
610    var noDateKey = 'noDate';
611    var sumDateIgnoredKey = 'sumDateIgnoredKey';
612    var statistics = report.statistics;
613    var sitesCombined = statistics.sitesCombinedKey;
614    if (sitesCombined != null)
615    {
616      data = getJSONDataWithPercent(sitesCombined, 'yes', sumDateIgnoredKey, numDecimals);
617      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
618      data = getJSONDataWithPercent(sitesCombined, 'no', sumDateIgnoredKey, numDecimals);
619      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
620      data = getJSONDataWithPercent(sitesCombined, 'notAsked', sumDateIgnoredKey, numDecimals);
621      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
622    }
623    // Add entry with total number of consents with chosen restrictions
624    data = getJSONData(sitesCombined, sumDateIgnoredKey, 0);
625    sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
626    // Add entry with total number of consents, regardless of restrictions
627    var totalKey = 'totalKey';
628    data = getJSONData(sitesCombined, totalKey, 0);
629    sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
630    reportTable.appendChild(sitesCombinedRow); 
631
632    return reportTable;
633  }
634 
635  function createConsentCountHasDateTable(report)
636  {
637    var reportTable = getReportTable();
638    var sdString = report.beginDate;
639    var edString = report.endDate;
640    var ldString = report.latestDate;
641    var startDate = dateStrToDate(sdString);
642    var endDate = dateStrToDate(edString);
643    var latestDate = dateStrToDate(ldString);
644
645    var headerRow = document.createElement('tr');   
646    var subHeaderRow = document.createElement('tr');
647    var columnHeaderRow = document.createElement('tr');
648   
649    var numCols = 5;
650    var numDecimals = 0;
651    var headerText = '# Consent forms of different types for cases and blood samples';
652    var startDateStr = addHyphensToDateString(sdString);
653    var endDateStr = addHyphensToDateString(edString);
654    var latestDateStr = addHyphensToDateString(ldString);
655    headerText += ' (betweeen ' + startDateStr + ' and ' + endDateStr + ')';
656    if (latestDate != null)
657    {
658        headerText += '\nLast registration ' + latestDateStr;
659    }
660    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+5)));
661   
662    // Subheader   
663    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 3));
664   
665    subHeaderRow.appendChild(getTableCellElement('Yes', 'reportsubheader'));
666    subHeaderRow.appendChild(getTableCellElement('Yes', 'reportsubheader'));
667    subHeaderRow.appendChild(getTableCellElement('No', 'reportsubheader'));
668    subHeaderRow.appendChild(getTableCellElement('Not asked', 'reportsubheader'));
669    subHeaderRow.appendChild(getTableCellElement('Unknown date', 'reportsubheader'));
670    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 2));
671
672    // Columnsheader   
673    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
674    var startDateHeader = getTableCellElement('Start date','reportsubheader');
675    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
676    columnHeaderRow.appendChild(siteHeader);
677    columnHeaderRow.appendChild(startDateHeader);
678    columnHeaderRow.appendChild(latestDateHeader); 
679   
680    columnHeaderRow.appendChild(getTableCellElement('(has PAT#)', 'reportsubheader'));
681    columnHeaderRow.appendChild(getTableCellElement('(no PAT#)', 'reportsubheader'));
682    columnHeaderRow.appendChild(getTableCellElement('(has date)', 'reportsubheader'));
683    columnHeaderRow.appendChild(getTableCellElement('(has date)', 'reportsubheader'));
684    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
685    columnHeaderRow.appendChild(getTableCellElement('Sum', 'reportsubheader'));
686    columnHeaderRow.appendChild(getTableCellElement('Total', 'reportsubheader'));
687
688    // Build table     
689    reportTable.appendChild(headerRow);
690    reportTable.appendChild(subHeaderRow);
691    reportTable.appendChild(columnHeaderRow);
692         
693    // Data rows     
694    addDataRowsToConsentTableHasDate(report, reportTable);
695     
696    // Add a row with the combined numbers for all sites for each period
697    var sitesCombinedRow = document.createElement('tr');
698    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
699    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
700    // Get combined numbers for all sites for each period
701    var noDateKey = 'noDate';
702    var sumKey = 'sumKey';
703    var statistics = report.statistics;
704    var sitesCombined = statistics.sitesCombinedKey;
705    if (sitesCombined != null)
706    {
707      data = getJSONDataWithPercent(sitesCombined, 'yesPatientExistsDateExists', sumKey, numDecimals);
708      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
709      data = getJSONDataWithPercent(sitesCombined, 'yesPatientUnknownDateExists', sumKey, numDecimals);
710      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
711      data = getJSONDataWithPercent(sitesCombined, 'noDateExists', sumKey, numDecimals);
712      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
713      data = getJSONDataWithPercent(sitesCombined, 'notAskedDateExists', sumKey, numDecimals);
714      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
715      data = getJSONDataWithPercent(sitesCombined, noDateKey, sumKey, numDecimals);
716      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
717    }
718    // Add entry with total number of consents with chosen restrictions
719    data = getJSONData(sitesCombined, sumKey, 0);
720    sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
721    // Add entry with total number of consents, regardless of restrictions
722    var totalKey = 'totalKey';
723    data = getJSONData(sitesCombined, totalKey, 0);
724    sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
725    reportTable.appendChild(sitesCombinedRow); 
726
727    return reportTable;
728  }
729 
730  function createConsentCountUnknownDateTable(report)
731  {
732    var reportTable = getReportTable();
733    var headerRow = document.createElement('tr');   
734    var subHeaderRow = document.createElement('tr');
735    var columnHeaderRow = document.createElement('tr');
736   
737    var numCols = 4;
738    var numDecimals = 0;
739    var headerText = '# Consent forms of different types for cases and blood samples with unknown consent date, as well as items with missing consents';
740    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+5)));
741   
742    // Subheader   
743    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 3));
744   
745    subHeaderRow.appendChild(getTableCellElement('Yes', 'reportsubheader'));
746    subHeaderRow.appendChild(getTableCellElement('No', 'reportsubheader'));
747    subHeaderRow.appendChild(getTableCellElement('Not asked', 'reportsubheader'));
748    subHeaderRow.appendChild(getTableCellElement('Missing', 'reportsubheader'));
749    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 2));
750
751    // Columnsheader   
752    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
753    var startDateHeader = getTableCellElement('Start date','reportsubheader');
754    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
755    columnHeaderRow.appendChild(siteHeader);
756    columnHeaderRow.appendChild(startDateHeader);
757    columnHeaderRow.appendChild(latestDateHeader); 
758   
759    columnHeaderRow.appendChild(getTableCellElement('(no date)', 'reportsubheader'));
760    columnHeaderRow.appendChild(getTableCellElement('(no date)', 'reportsubheader'));
761    columnHeaderRow.appendChild(getTableCellElement('(no date)', 'reportsubheader'));
762    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
763    columnHeaderRow.appendChild(getTableCellElement('Sum', 'reportsubheader'));
764    columnHeaderRow.appendChild(getTableCellElement('Total', 'reportsubheader'));
765
766    // Build table     
767    reportTable.appendChild(headerRow);
768    reportTable.appendChild(subHeaderRow);
769    reportTable.appendChild(columnHeaderRow);
770         
771    // Data rows     
772    addDataRowsToConsentTableUnknownDate(report, reportTable);
773     
774    // Add a row with the combined numbers for all sites
775    var sitesCombinedRow = document.createElement('tr');
776    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
777    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
778    // Get combined numbers for all sites
779    var noDateOrMissingKey = 'noDateOrMissing';
780    var sumKey = 'sumKey';
781    var statistics = report.statistics;
782    var sitesCombined = statistics.sitesCombinedKey;
783    if (sitesCombined != null)
784    {
785      data = getJSONDataWithPercent(sitesCombined, 'yesDateUnknown', noDateOrMissingKey, numDecimals);
786      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
787      data = getJSONDataWithPercent(sitesCombined, 'noDateUnknown', noDateOrMissingKey, numDecimals);
788      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
789      data = getJSONDataWithPercent(sitesCombined, 'notAskedDateUnknown', noDateOrMissingKey, numDecimals);
790      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
791      data = getJSONDataWithPercent(sitesCombined, 'missing', noDateOrMissingKey, numDecimals);
792      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
793      // Add entry with total number of consents with chosen restrictions
794      var noDateOrMissingKey = 'noDateOrMissing';
795      data = getJSONData(sitesCombined, noDateOrMissingKey, 0);
796      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
797      // Add entry with total number of consents, regardless of restrictions
798      var totalKey = 'totalKey';
799      data = getJSONData(sitesCombined, totalKey, 0);
800      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
801    }
802    reportTable.appendChild(sitesCombinedRow); 
803
804    return reportTable;
805  }
806 
807  function createOverviewReport(report)
808  {
809    var reportTable = getReportTable();
810    var sdString = report.beginDate;
811    var edString = report.endDate;
812    var ldString = report.latestDate;
813    var startDate = dateStrToDate(sdString);
814    var endDate = dateStrToDate(edString);
815    var latestDate = dateStrToDate(ldString);
816 
817    var headerRow = document.createElement('tr');   
818    var subHeaderRow = document.createElement('tr');
819    var subHeader2Row = document.createElement('tr');
820    var columnHeaderRow = document.createElement('tr');
821   
822    var numCols = 6;
823    var numDecimals = 0;
824    var headerText = 'Number of items of different kinds';
825    var startDateStr = addHyphensToDateString(sdString);
826    var endDateStr = addHyphensToDateString(edString);
827    var latestDateStr = addHyphensToDateString(ldString);
828    headerText += ' (betweeen ' + startDateStr + ' and ' + endDateStr + ')';
829    if (latestDate != null)
830    {
831        headerText += '\nLast registration ' + latestDateStr;
832    }
833    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+3)));
834   
835    // Subheader
836    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 3));
837   
838    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
839    subHeaderRow.appendChild(getTableCellElement('Blood', 'reportsubheader'));
840    subHeaderRow.appendChild(getTableCellElement('Specimens', 'reportsubheader'));
841    subHeaderRow.appendChild(getTableCellElement('No specimens', 'reportsubheader'));
842    subHeaderRow.appendChild(getTableCellElement('Consents', 'reportsubheader'));
843    subHeaderRow.appendChild(getTableCellElement('Consents', 'reportsubheader'));
844
845    // Columnsheader   
846    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
847    var startDateHeader = getTableCellElement('Start date','reportsubheader');
848    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
849    columnHeaderRow.appendChild(siteHeader);
850    columnHeaderRow.appendChild(startDateHeader);
851    columnHeaderRow.appendChild(latestDateHeader); 
852   
853    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
854    columnHeaderRow.appendChild(getTableCellElement('samples', 'reportsubheader'));
855    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
856    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
857    columnHeaderRow.appendChild(getTableCellElement('(Yes)', 'reportsubheader'));
858    columnHeaderRow.appendChild(getTableCellElement('missing', 'reportsubheader'));
859
860    // Build table     
861    reportTable.appendChild(headerRow);
862    reportTable.appendChild(subHeaderRow);
863    reportTable.appendChild(subHeader2Row);
864    reportTable.appendChild(columnHeaderRow);
865         
866    // Data rows     
867    addDataRowsToOverviewTable(report, reportTable);
868     
869    // Add a row with the combined numbers for all sites for each period
870    var sitesCombinedRow = document.createElement('tr');
871    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
872    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
873    // Get combined numbers for all sites for each period
874    var noDateKey = 'noDate';
875    var sumKey = 'sumKey';
876    var statistics = report.statistics;
877    // Get values for use in summary section
878    numPatientsNoSamples = statistics.patientNoSamples;
879    var sitesCombined = statistics.sitesCombinedKey;
880    if (sitesCombined != null)
881    {
882      data = getJSONData(sitesCombined, 'patient');
883      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
884      data = getJSONData(sitesCombined, 'bloodSample');
885      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
886      data = getJSONData(sitesCombined, 'specimen');
887      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
888      data = getJSONData(sitesCombined, 'noSpecimen');
889      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
890      data = getJSONData(sitesCombined, 'consentYes');
891      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
892      data = getJSONData(sitesCombined, 'consentMissing');
893      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
894    }
895    reportTable.appendChild(sitesCombinedRow); 
896
897    return reportTable;
898  }
899 
900  function createOverviewPatientDetailedTable(report)
901  {
902    var reportTable = getReportTable();
903    var sdString = report.beginDate;
904    var edString = report.endDate;
905    var ldString = report.latestDate;
906    var startDate = dateStrToDate(sdString);
907    var endDate = dateStrToDate(edString);
908 
909    var headerRow = document.createElement('tr');   
910    var subHeaderRow = document.createElement('tr');
911    var subHeader2Row = document.createElement('tr');
912    var columnHeaderRow = document.createElement('tr');
913   
914    var numCols = 8;
915    var numDecimals = 0;
916    var headerText = 'Patient records of different kinds';
917    var startDateStr = addHyphensToDateString(sdString);
918    var endDateStr = addHyphensToDateString(edString);
919    var latestDateStr = addHyphensToDateString(ldString);
920    headerText += ' (betweeen ' + startDateStr + ' and ' + endDateStr + ')';
921/*
922    if (latestDate != null)
923    {
924        headerText += '\nLast registration ' + latestDateStr;
925    }
926*/
927    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+2)));
928   
929    // Subheader
930    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 2));
931   
932    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
933    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
934    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
935    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
936    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
937    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
938    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
939    //subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
940    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
941
942    // Subheader 2
943    subHeader2Row.appendChild(getTableCellElement('', 'reportsubheader', 2));
944   
945    subHeader2Row.appendChild(getTableCellElement('(blood', 'reportsubheader'));
946    subHeader2Row.appendChild(getTableCellElement('(spec.', 'reportsubheader'));
947    subHeader2Row.appendChild(getTableCellElement('(no spec.', 'reportsubheader'));
948    subHeader2Row.appendChild(getTableCellElement('(blood and', 'reportsubheader'));
949    subHeader2Row.appendChild(getTableCellElement('(blood and', 'reportsubheader'));
950    subHeader2Row.appendChild(getTableCellElement('(spec. and', 'reportsubheader'));
951    subHeader2Row.appendChild(getTableCellElement('(blood, spec.,', 'reportsubheader'));
952    //subHeader2Row.appendChild(getTableCellElement('(no samples)', 'reportsubheader'));
953    subHeader2Row.appendChild(getTableCellElement('', 'reportsubheader'));
954
955    // Columnsheader   
956    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
957    var startDateHeader = getTableCellElement('Start date','reportsubheader');
958    //var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
959    columnHeaderRow.appendChild(siteHeader);
960    columnHeaderRow.appendChild(startDateHeader);
961    //columnHeaderRow.appendChild(latestDateHeader); 
962   
963    columnHeaderRow.appendChild(getTableCellElement('only)', 'reportsubheader'));
964    columnHeaderRow.appendChild(getTableCellElement('only)', 'reportsubheader'));
965    columnHeaderRow.appendChild(getTableCellElement('only)', 'reportsubheader'));
966    columnHeaderRow.appendChild(getTableCellElement('specimens)', 'reportsubheader'));
967    columnHeaderRow.appendChild(getTableCellElement('no spec.)', 'reportsubheader'));
968    columnHeaderRow.appendChild(getTableCellElement('no spec.)', 'reportsubheader'));
969    columnHeaderRow.appendChild(getTableCellElement('and no spec.)', 'reportsubheader'));
970    //columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
971
972    columnHeaderRow.appendChild(getTableCellElement('Sum', 'reportsubheader'));
973
974    // Build table     
975    reportTable.appendChild(headerRow);
976    reportTable.appendChild(subHeaderRow);
977    reportTable.appendChild(subHeader2Row);
978    reportTable.appendChild(columnHeaderRow);
979         
980    // Data rows     
981    addDataRowsToOverviewPatientDetailedTable(report, reportTable);
982     
983    // Add a row with the combined numbers for all sites
984    var sitesCombinedRow = document.createElement('tr');
985    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
986    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary'));
987    // Get combined numbers for all sites
988    var noDateKey = 'noDate';
989    var sumKey = 'sumKey';
990    var statistics = report.statistics;
991    // Get values for use in summary section
992    numPatientsNoSamples = statistics.patientNoSamples;
993    var sitesCombined = statistics.sitesCombinedKey;
994    if (sitesCombined != null)
995    {
996      data = getJSONData(sitesCombined, 'patientBloodSampleOnly');
997      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
998      data = getJSONData(sitesCombined, 'patientSpecimenOnly');
999      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1000      data = getJSONData(sitesCombined, 'patientNoSpecimenOnly');
1001      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1002      data = getJSONData(sitesCombined, 'patientBloodSampleAndSpecimen');
1003      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1004      data = getJSONData(sitesCombined, 'patientBloodSampleAndNoSpecimen');
1005      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1006      data = getJSONData(sitesCombined, 'patientSpecimenAndNoSpecimen');
1007      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1008      data = getJSONData(sitesCombined, 'patientBloodSampleAndSpecimenAndNoSpecimen');
1009      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1010      //data = getJSONData(sitesCombined, 'patientNoSamples');
1011      //sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1012      data = getJSONData(sitesCombined, 'sumKey');
1013      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1014    }
1015    reportTable.appendChild(sitesCombinedRow); 
1016
1017    return reportTable;
1018  }
1019 
1020  function createMissingSampleDataReport(report)
1021  {
1022    var reportTable = getReportTable();
1023    var sdString = report.beginDate;
1024    var edString = report.endDate;
1025    var ldString = report.latestDate;
1026    var startDate = dateStrToDate(sdString);
1027    var endDate = dateStrToDate(edString);
1028    var latestDate = dateStrToDate(ldString);
1029
1030    var sampleType = report.sampleType;
1031    var permissionDeniedForPatientName = report.permissionDeniedForPatientName;
1032
1033    var headerRow = document.createElement('tr');   
1034    var subHeaderRow = document.createElement('tr');
1035    var subHeader2Row = document.createElement('tr');
1036    var columnHeaderRow = document.createElement('tr');
1037   
1038    var numCols = 5;
1039    if (sampleType == 'specimen')
1040    {
1041      numCols = 5;
1042    }
1043    else if (sampleType == 'nospecimen')
1044    {
1045      numCols = 4;
1046    }
1047    else if (sampleType == 'blood')
1048    {
1049      numCols = 3;
1050    }
1051    var numDecimals = 0;
1052    var headerText = 'Number of missing specimen items of different kinds';
1053    if ('nospecimen' == sampleType)
1054    {
1055      headerText = 'Number of missing "no specimen" items of different kinds';
1056    }
1057    else if ('blood' == sampleType)
1058    {
1059      headerText = 'Number of missing blood sample items of different kinds';
1060    }
1061    var startDateStr = addHyphensToDateString(sdString);
1062    var endDateStr = addHyphensToDateString(edString);
1063    var latestDateStr = addHyphensToDateString(ldString);
1064    headerText += ' (betweeen ' + startDateStr + ' and ' + endDateStr + ')';
1065    if (latestDate != null)
1066    {
1067        headerText += '\nLast registration ' + latestDateStr;
1068    }
1069    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+3)));
1070   
1071    // Subheader
1072    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 3));
1073   
1074    subHeaderRow.appendChild(getTableCellElement('Patient', 'reportsubheader'));
1075    if (sampleType == 'specimen')
1076    {
1077      subHeaderRow.appendChild(getTableCellElement('PAD', 'reportsubheader'));
1078      subHeaderRow.appendChild(getTableCellElement('Laterality', 'reportsubheader'));
1079      subHeaderRow.appendChild(getTableCellElement('Sampling', 'reportsubheader'));
1080      subHeaderRow.appendChild(getTableCellElement('RNALater', 'reportsubheader'));
1081    }
1082    else if (sampleType == 'nospecimen')
1083    {
1084      subHeaderRow.appendChild(getTableCellElement('PAD', 'reportsubheader'));
1085      subHeaderRow.appendChild(getTableCellElement('Laterality', 'reportsubheader'));
1086      subHeaderRow.appendChild(getTableCellElement('Sampling', 'reportsubheader'));
1087    }
1088    else if (sampleType == 'blood')
1089    {
1090      subHeaderRow.appendChild(getTableCellElement('Blood sampling', 'reportsubheader'));
1091      subHeaderRow.appendChild(getTableCellElement('Blood freezer', 'reportsubheader'));
1092    }
1093
1094    // Columnsheader   
1095    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
1096    var startDateHeader = getTableCellElement('Start date','reportsubheader');
1097    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
1098    columnHeaderRow.appendChild(siteHeader);
1099    columnHeaderRow.appendChild(startDateHeader);
1100    columnHeaderRow.appendChild(latestDateHeader); 
1101   
1102    columnHeaderRow.appendChild(getTableCellElement('name', 'reportsubheader'));
1103    if (sampleType == 'specimen')
1104    {
1105      columnHeaderRow.appendChild(getTableCellElement('reference', 'reportsubheader'));
1106      columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
1107      columnHeaderRow.appendChild(getTableCellElement('date', 'reportsubheader'));
1108      columnHeaderRow.appendChild(getTableCellElement('date', 'reportsubheader'));
1109    }
1110    else if (sampleType == 'nospecimen')
1111    {
1112      columnHeaderRow.appendChild(getTableCellElement('reference', 'reportsubheader'));
1113      columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
1114      columnHeaderRow.appendChild(getTableCellElement('date', 'reportsubheader'));
1115    }
1116    else if (sampleType == 'blood')
1117    {
1118      columnHeaderRow.appendChild(getTableCellElement('date', 'reportsubheader'));
1119      columnHeaderRow.appendChild(getTableCellElement('date', 'reportsubheader'));
1120    }
1121
1122    // Build table     
1123    reportTable.appendChild(headerRow);
1124    reportTable.appendChild(subHeaderRow);
1125    reportTable.appendChild(columnHeaderRow);
1126         
1127    // Data rows     
1128    addDataRowsToMissingSampleDataTable(report, reportTable);
1129     
1130    // Add a row with the combined numbers for all sites for each period
1131    var sitesCombinedRow = document.createElement('tr');
1132    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
1133    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
1134    // Get combined numbers for all sites for each period
1135    var noDateKey = 'noDate';
1136    var sumKey = 'sumKey';
1137    var statistics = report.statistics;
1138    var sitesCombined = statistics.sitesCombinedKey;
1139    if (sitesCombined != null)
1140    {
1141      if ('false' == permissionDeniedForPatientName)
1142      {
1143        data = getJSONData(sitesCombined, 'missingPatientName');
1144        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1145      }
1146      else
1147      {
1148        data = '-';
1149        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1150      }
1151      if (sampleType == 'specimen')
1152      {
1153        data = getJSONData(sitesCombined, 'missingPadReference');
1154        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1155        data = getJSONData(sitesCombined, 'missingLaterality');
1156        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1157        data = getJSONData(sitesCombined, 'missingSamplingDateTime');
1158        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1159        data = getJSONData(sitesCombined, 'missingRnaLaterDateTime');
1160        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1161      }
1162      else if (sampleType == 'nospecimen')
1163      {
1164        data = getJSONData(sitesCombined, 'missingPadReference');
1165        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1166        data = getJSONData(sitesCombined, 'missingLaterality');
1167        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1168        data = getJSONData(sitesCombined, 'missingSamplingDateTime');
1169        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1170      }
1171      else if (sampleType == 'blood')
1172      {
1173        data = getJSONData(sitesCombined, 'missingBloodSamplingDateTime');
1174        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1175        data = getJSONData(sitesCombined, 'missingBloodFreezerDateTime');
1176        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
1177      }
1178    }
1179    reportTable.appendChild(sitesCombinedRow); 
1180
1181    return reportTable;
1182  }
1183 
1184  function createConsentTablePatientsWithMultipleDates(report)
1185  {
1186    var multipleDatesTable = getReportTable();
1187    var headerRow = document.createElement('tr');   
1188    var columnHeaderRow = document.createElement('tr');
1189   
1190    // Table header
1191    var numCols = 3;
1192    var headerText = 'Consent forms with multiple dates for same patient';
1193    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', numCols));
1194   
1195    // Columnsheader
1196    columnHeaderRow.appendChild(getTableCellElement('Patient ID', 'reportsubheader'));
1197    columnHeaderRow.appendChild(getTableCellElement('Date 1', 'reportsubheader'));
1198    columnHeaderRow.appendChild(getTableCellElement('Date 2', 'reportsubheader'));
1199
1200    // Build table     
1201    multipleDatesTable.appendChild(headerRow);
1202    multipleDatesTable.appendChild(columnHeaderRow);
1203         
1204    // Data rows
1205    if (report != null)
1206    {
1207      var statistics = report.statistics;
1208      var sessionId = statistics.sessionIdKey;
1209      var patientsWithMultipleDates = statistics.patientsWithMultipleDatesKey;
1210      var patientnamePatientid = statistics.patientnamePatientidKey;
1211      for (var patientName in patientsWithMultipleDates)
1212      {
1213        var tableRow = document.createElement('tr');
1214        // Add patient name to table
1215        var patientIdStr = patientnamePatientid[patientName];
1216        var columnCell = document.createElement('td');
1217        var patientLinkStr = createLinkStr(patientName, patientIdStr, 'BIOSOURCE', 'View this sample', sessionId);
1218        var tableCol = createTableCellElementHtml(patientLinkStr, 'reportdata');
1219        tableRow.appendChild(tableCol);
1220        // Add dates to table in chronological order
1221        var dateSet = patientsWithMultipleDates[patientName];
1222        var dateStr1 = '';
1223        var dateStr2 = '';
1224        for (var key in dateSet)
1225        {
1226          var dateStr = dateSet[key];
1227          if (dateStr1 == '')
1228          {
1229            dateStr1 = dateStr;
1230          }
1231          else if (dateStr > dateStr1)
1232          {
1233            dateStr2 = dateStr;
1234          }
1235          else
1236          {
1237            dateStr2 = dateStr1;
1238            dateStr1 = dateStr;
1239          }
1240        }
1241        var dateCol = '';
1242        dateCol = getTableCellElement(dateStr1, 'reportdata');
1243        tableRow.appendChild(dateCol);
1244        dateCol = getTableCellElement(dateStr2, 'reportdata');
1245        tableRow.appendChild(dateCol);
1246        multipleDatesTable.appendChild(tableRow);
1247      }
1248    }
1249
1250    return multipleDatesTable;
1251  }
1252 
1253  function addDataRowsToConsentTable(report, reportTable, numDecimals)
1254  {
1255    var sites = report.sites;   
1256    var statistics = report.statistics;
1257    unknownCreation = statistics.noDate;
1258    unknownSite = statistics.unknownSite;
1259    var siteOrderList = report.siteOrderListKey;
1260    for (var siteOrderIndex in siteOrderList)
1261    {
1262      var namePrefix = siteOrderList[siteOrderIndex];   
1263      if (!sites.hasOwnProperty(namePrefix)) continue;       
1264      var site = sites[namePrefix];
1265      var siteName = site.name;
1266      var siteStartDate = dateStrToDate(site.startDate);
1267      var siteStartDateStr = addHyphensToDateString(site.startDate);
1268     
1269      var siteData = statistics[namePrefix];     
1270      var siteLatestDate = siteData['latestDateKey'];
1271      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
1272      var tableRow = document.createElement('tr');
1273      var tableCol = getTableCellElement(siteName, 'rowtitle');
1274      tableRow.appendChild(tableCol);
1275      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
1276      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1277      var noDateKey = 'noDate';
1278      var sumDateIgnoredKey = 'sumDateIgnoredKey';
1279      var totalKey = 'totalKey';
1280      if (siteData != null)
1281      {
1282        data = getJSONDataWithPercent(siteData, 'yes', sumDateIgnoredKey, numDecimals);
1283        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1284        data = getJSONDataWithPercent(siteData, 'no', sumDateIgnoredKey, numDecimals);
1285        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1286        data = getJSONDataWithPercent(siteData, 'notAsked', sumDateIgnoredKey, numDecimals);
1287        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1288        // Add column with summed values for site
1289        var siteSum = getJSONData(siteData, sumDateIgnoredKey, 0);
1290        tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
1291      }
1292      // Add column with total number of samples for site, regardless of creation date
1293      var siteTotal = getJSONData(siteData, totalKey, 0);
1294      tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
1295      reportTable.appendChild(tableRow);
1296    }
1297  }
1298
1299  function addDataRowsToConsentTableHasDate(report, reportTable, numDecimals)
1300  {
1301    var sites = report.sites;   
1302    var statistics = report.statistics;
1303    unknownCreation = statistics.noDate;
1304    unknownSite = statistics.unknownSite;
1305    var siteOrderList = report.siteOrderListKey;
1306    for (var siteOrderIndex in siteOrderList)
1307    {
1308      var namePrefix = siteOrderList[siteOrderIndex];   
1309      if (!sites.hasOwnProperty(namePrefix)) continue;       
1310      var site = sites[namePrefix];
1311      var siteName = site.name;
1312      var siteStartDate = dateStrToDate(site.startDate);
1313      var siteStartDateStr = addHyphensToDateString(site.startDate);
1314     
1315      var siteData = statistics[namePrefix];     
1316      var siteLatestDate = siteData['latestDateKey'];
1317      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
1318      var tableRow = document.createElement('tr');
1319      var tableCol = getTableCellElement(siteName, 'rowtitle');
1320      tableRow.appendChild(tableCol);
1321      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
1322      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1323      var noDateKey = 'noDate';
1324      var sumKey = 'sumKey';
1325      var totalKey = 'totalKey';
1326      if (siteData != null)
1327      {
1328        data = getJSONDataWithPercent(siteData, 'yesPatientExistsDateExists', sumKey, numDecimals);
1329        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1330        data = getJSONDataWithPercent(siteData, 'yesPatientUnknownDateExists', sumKey, numDecimals);
1331        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1332        data = getJSONDataWithPercent(siteData, 'noDateExists', sumKey, numDecimals);
1333        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1334        data = getJSONDataWithPercent(siteData, 'notAskedDateExists', sumKey, numDecimals);
1335        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1336        data = getJSONDataWithPercent(siteData, noDateKey, sumKey, numDecimals);
1337        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1338        // Add column with summed values for site
1339        var siteSum = getJSONData(siteData, sumKey, 0);
1340        tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
1341      }
1342      // Add column with total number of samples for site, regardless of creation date
1343      var siteTotal = getJSONData(siteData, totalKey, 0);
1344      tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
1345      reportTable.appendChild(tableRow);
1346    }
1347  }
1348
1349  function addDataRowsToConsentTableUnknownDate(report, reportTable, numDecimals)
1350  {
1351    var sites = report.sites;   
1352    var statistics = report.statistics;
1353    unknownCreation = statistics.noDate;
1354    unknownSite = statistics.unknownSite;
1355    numMissing = statistics.missing;
1356    var siteOrderList = report.siteOrderListKey;
1357    for (var siteOrderIndex in siteOrderList)
1358    {
1359      var namePrefix = siteOrderList[siteOrderIndex];   
1360      if (!sites.hasOwnProperty(namePrefix)) continue;       
1361      var site = sites[namePrefix];
1362      var siteName = site.name;
1363      var siteStartDate = dateStrToDate(site.startDate);
1364      var siteStartDateStr = addHyphensToDateString(site.startDate);
1365     
1366      var siteData = statistics[namePrefix];     
1367      var siteLatestDate = siteData['latestDateKey'];
1368      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
1369      var tableRow = document.createElement('tr');
1370      var tableCol = getTableCellElement(siteName, 'rowtitle');
1371      tableRow.appendChild(tableCol);
1372      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
1373      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1374      var noDateOrMissingKey = 'noDateOrMissing';
1375      var sumKey = 'sumKey';
1376      var totalKey = 'totalKey';
1377      if (siteData != null)
1378      {
1379        data = getJSONDataWithPercent(siteData, 'yesDateUnknown', noDateOrMissingKey, numDecimals);
1380        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1381        data = getJSONDataWithPercent(siteData, 'noDateUnknown', noDateOrMissingKey, numDecimals);
1382        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1383        data = getJSONDataWithPercent(siteData, 'notAskedDateUnknown', noDateOrMissingKey, numDecimals);
1384        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1385        data = getJSONDataWithPercent(siteData, 'missing', noDateOrMissingKey, numDecimals);
1386        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1387        // Add column with summed values for site
1388        var siteSum = getJSONData(siteData, noDateOrMissingKey, 0);
1389        tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
1390      }
1391      // Add column with total number of samples for site, regardless of creation date
1392      var siteTotal = getJSONData(siteData, totalKey, 0);
1393      tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
1394      reportTable.appendChild(tableRow);
1395    }
1396  }
1397
1398  function addDataRowsToOverviewTable(report, reportTable)
1399  {
1400    var sites = report.sites;   
1401    var statistics = report.statistics;
1402    unknownCreation = statistics.noDate;
1403    unknownSite = statistics.unknownSite;
1404    var siteOrderList = report.siteOrderListKey;
1405    for (var siteOrderIndex in siteOrderList)
1406    {
1407      var namePrefix = siteOrderList[siteOrderIndex];   
1408      if (!sites.hasOwnProperty(namePrefix)) continue;       
1409      var site = sites[namePrefix];
1410      var siteName = site.name;       
1411      var siteStartDate = dateStrToDate(site.startDate);
1412      var siteStartDateStr = addHyphensToDateString(site.startDate);
1413     
1414      var siteData = statistics[namePrefix];     
1415      var siteLatestDate = siteData['latestDateKey'];
1416      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
1417      var tableRow = document.createElement('tr');
1418      var tableCol = getTableCellElement(siteName, 'rowtitle');
1419      tableRow.appendChild(tableCol);
1420      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
1421      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1422      var noDateKey = 'noDate';
1423      var sumKey = 'sumKey';
1424      var totalKey = 'totalKey';
1425      if (siteData != null)
1426      {
1427        data = getJSONData(siteData, 'patient');
1428        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1429        data = getJSONData(siteData, 'bloodSample');
1430        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1431        data = getJSONData(siteData, 'specimen');
1432        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1433        data = getJSONData(siteData, 'noSpecimen');
1434        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1435        data = getJSONData(siteData, 'consentYes');
1436        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1437        data = getJSONData(siteData, 'consentMissing');
1438        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1439      }
1440      reportTable.appendChild(tableRow);
1441    }
1442  }
1443
1444  function addDataRowsToOverviewPatientDetailedTable(report, reportTable)
1445  {
1446    var sites = report.sites;   
1447    var statistics = report.statistics;
1448    unknownCreation = statistics.noDate;
1449    unknownSite = statistics.unknownSite;
1450    var siteOrderList = report.siteOrderListKey;
1451    for (var siteOrderIndex in siteOrderList)
1452    {
1453      var namePrefix = siteOrderList[siteOrderIndex];   
1454      if (!sites.hasOwnProperty(namePrefix)) continue;       
1455      var site = sites[namePrefix];
1456      var siteName = site.name;       
1457      var siteStartDate = dateStrToDate(site.startDate);
1458      var siteStartDateStr = addHyphensToDateString(site.startDate);
1459     
1460      var siteData = statistics[namePrefix];
1461/*   
1462      var siteLatestDate = siteData['latestDateKey'];
1463      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
1464*/
1465      var tableRow = document.createElement('tr');
1466      var tableCol = getTableCellElement(siteName, 'rowtitle');
1467      tableRow.appendChild(tableCol);
1468      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
1469/*
1470      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1471*/
1472      var noDateKey = 'noDate';
1473      var sumKey = 'sumKey';
1474      var totalKey = 'totalKey';
1475      if (siteData != null)
1476      {
1477        data = getJSONData(siteData, 'patientBloodSampleOnly');
1478        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1479        data = getJSONData(siteData, 'patientSpecimenOnly');
1480        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1481        data = getJSONData(siteData, 'patientNoSpecimenOnly');
1482        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1483        data = getJSONData(siteData, 'patientBloodSampleAndSpecimen');
1484        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1485        data = getJSONData(siteData, 'patientBloodSampleAndNoSpecimen');
1486        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1487        data = getJSONData(siteData, 'patientSpecimenAndNoSpecimen');
1488        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1489        data = getJSONData(siteData, 'patientBloodSampleAndSpecimenAndNoSpecimen');
1490        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1491        //data = getJSONData(siteData, 'patientNoSamples');
1492        //tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1493        data = getJSONData(siteData, 'sumKey');
1494        tableRow.appendChild(getTableCellElement(data, 'rowsummary'));
1495      }
1496      reportTable.appendChild(tableRow);
1497    }
1498  }
1499
1500  function addDataRowsToMissingSampleDataTable(report, reportTable)
1501  {
1502    var sites = report.sites;   
1503    var statistics = report.statistics;
1504    var sampleType = report.sampleType;
1505    var permissionDeniedForPatientName = report.permissionDeniedForPatientName;
1506    var unknownCreation = statistics.noDate;
1507    var unknownSite = statistics.unknownSite;
1508    var siteOrderList = report.siteOrderListKey;
1509    for (var siteOrderIndex in siteOrderList)
1510    {
1511      var namePrefix = siteOrderList[siteOrderIndex];   
1512      if (!sites.hasOwnProperty(namePrefix)) continue;       
1513      var site = sites[namePrefix];
1514      var siteName = site.name;
1515      var siteStartDate = dateStrToDate(site.startDate);
1516      var siteStartDateStr = addHyphensToDateString(site.startDate);
1517     
1518      var siteData = statistics[namePrefix];     
1519      var siteLatestDate = siteData['latestDateKey'];
1520      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
1521      var tableRow = document.createElement('tr');
1522      var tableCol = getTableCellElement(siteName, 'rowtitle');
1523      tableRow.appendChild(tableCol);
1524      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
1525      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1526      //var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
1527      var noDateKey = 'noDate';
1528      var sumKey = 'sumKey';
1529      var totalKey = 'totalKey';
1530      if (siteData != null)
1531      {
1532        if ('false' == permissionDeniedForPatientName)
1533        {
1534          data = getJSONData(siteData, 'missingPatientName');
1535          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1536        }
1537        else
1538        {
1539          data = '-';
1540          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1541        }
1542        if (sampleType == 'specimen')
1543        {
1544          data = getJSONData(siteData, 'missingPadReference');
1545          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1546          data = getJSONData(siteData, 'missingLaterality');
1547          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1548          data = getJSONData(siteData, 'missingSamplingDateTime');
1549          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1550          data = getJSONData(siteData, 'missingRnaLaterDateTime');
1551          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1552        }
1553        else if (sampleType == 'nospecimen')
1554        {
1555          data = getJSONData(siteData, 'missingPadReference');
1556          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1557          data = getJSONData(siteData, 'missingLaterality');
1558          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1559          data = getJSONData(siteData, 'missingSamplingDateTime');
1560          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1561        }
1562        else if (sampleType == 'blood')
1563        {
1564          data = getJSONData(siteData, 'missingBloodSamplingDateTime');
1565          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1566          data = getJSONData(siteData, 'missingBloodFreezerDateTime');
1567          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1568        }
1569      }
1570      reportTable.appendChild(tableRow);
1571    }
1572  }
1573
1574  function createLinkStr(linkName, idStr, itemTypeStr, titleStr, sessionId)
1575  {
1576    var linkStr = '<span class="link" onclick="Main.itemOnClick(event, \'' + sessionId + '\', \'' + itemTypeStr + '\', ' + idStr + ', false)" title="' + titleStr + '">' + linkName + '</span>';
1577    return linkStr;
1578  }
1579
1580  function createTableCellElementHtml(html, clazz, colspan, rowspan)
1581  {
1582    var htmlStr = new String(html);
1583    var cellElement = document.createElement('td');
1584    cellElement.innerHTML = htmlStr;
1585    cellElement.setAttribute('class', clazz);
1586    if (colspan != null) cellElement.setAttribute('colspan', colspan);
1587    if (rowspan != null) cellElement.setAttribute('rowspan', rowspan);
1588   
1589    return cellElement;
1590  }
1591 
1592  function getJSONDataWithPercent(jsonObject, key, sumKey, numDecimals)
1593  {
1594    var dataNum = getJSONData(jsonObject, key);
1595    var dataSum = getJSONData(jsonObject, sumKey);
1596    var dataPct = '0';
1597    if (dataSum != null && dataSum != 0)
1598    {
1599      dataPct = 100*dataNum/dataSum;
1600      dataPct = dataPct.toFixed(numDecimals);
1601    }
1602    var data = dataNum + ' (' + dataPct + '%)';
1603    return data;
1604  }
1605
1606  function getJSONData(jsonObject, key)
1607  {
1608    var data = getJSONData(jsonObject, key, '');
1609    return data;
1610  }
1611
1612  function getJSONData(jsonObject, key, defaultChoice)
1613  {
1614    var data = defaultChoice;
1615    if (jsonObject != null)
1616    {
1617      if (jsonObject[key] != null)
1618      {
1619        data = jsonObject[key];
1620      }
1621    }
1622    /*
1623    else
1624    {
1625      data = 'jsonObject==null';
1626    }
1627    */
1628    return data;
1629  }
1630
1631  function addQuarterColumnHeaders(columnHeaderRow, startDate)
1632  {
1633    var currentDate = startDate;
1634    for (var i=0;i<numCols;i++)
1635    {
1636      var quarter = Math.floor(currentDate.getMonth()/3)+1;
1637      var columnText = 'Q'+quarter;
1638      var quarterHeader = getTableCellElement(columnText, 'reportsubheader');
1639      columnHeaderRow.appendChild(quarterHeader); 
1640      currentDate.setMonth(currentDate.getMonth()+3);     
1641    }
1642  }
1643 
1644  function addWeekColumnHeaders(columnHeaderRow, startDate)
1645  {
1646    var currentDate = startDate;
1647    var day = currentDate.getDay()-1;
1648    day = day>=0 ? day: day + 7;
1649    currentDate.setDate(currentDate.getDate()-day);
1650    for (var i=0;i<numCols;i++)
1651    {     
1652      var weekNum = getISOWeekNumber(currentDate);
1653      var columnText = weekNum;
1654      if (weekNum < 10) columnText = '0'+columnText;     
1655      columnHeaderRow.appendChild(getTableCellElement(columnText, 'reportsubheader'));
1656      currentDate.setDate(currentDate.getDate()+7);     
1657    }
1658  }
1659 
1660  function addMonthColumnHeaders(columnHeaderRow, startDate)
1661  {   
1662    var currentDate = new Date(startDate.getFullYear(), startDate.getMonth());
1663    for (var i=0;i<numCols;i++)
1664    {             
1665      var monthHeader = getTableCellElement(month[currentDate.getMonth()], 'reportsubheader');
1666      columnHeaderRow.appendChild(monthHeader);       
1667      currentDate.setMonth(currentDate.getMonth() +1);
1668    }   
1669  }
1670 
1671  function addYearSubHeaders(startDate, endDate, subHeaderRowYear, vt)
1672  {   
1673    var currentYear = startDate.getFullYear(); 
1674   
1675    var columnCounter = 0;   
1676    do
1677    {
1678      var colspan;
1679      var headerText = currentYear;
1680      if (vt == "MONTH")
1681      {
1682        if (currentYear == startDate.getFullYear())
1683        {
1684          colspan =  11-startDate.getMonth()+1;
1685          if (endDate.getFullYear() == currentYear)
1686          {
1687            colspan = colspan - (11-endDate.getMonth());
1688          }
1689        }
1690        else if (currentYear == endDate.getFullYear()) 
1691          colspan = endDate.getMonth()+1;
1692        else
1693          colspan = 12;
1694      }
1695      else if (vt == "WEEK")
1696      { 
1697        if (startDate.getFullYear() == endDate.getFullYear())
1698        {
1699          colspan = numCols;
1700        }
1701        else if (currentYear == startDate.getFullYear())
1702        {
1703          var startWeek = getISOWeekNumber(startDate);
1704          var lastDay = new Date(startDate.getFullYear(), 11, 31);
1705          var endWeek = getISOWeekNumber(lastDay);
1706          if (endWeek == 1)
1707          {
1708            lastDay.setDate(lastDay.getDate()-7);
1709            endWeek = getISOWeekNumber(lastDay);
1710          }
1711          colspan = endWeek - startWeek +1;
1712        }
1713        else if (currentYear == endDate.getFullYear())
1714        {
1715          var endWeek = getISOWeekNumber(endDate);
1716          colspan = endWeek;
1717        }
1718        else
1719        {
1720          var dateInLastWeek = new Date(currentYear, 11, 31);
1721          var endWeek = getISOWeekNumber(dateInLastWeek);
1722          if (endWeek == 1)
1723          {
1724            dateInLastWeek.setDate(dateInLastWeek.getDate()-7);
1725            endWeek = getISOWeekNumber(dateInLastWeek);
1726          }
1727          colspan = endWeek;
1728        }               
1729      }
1730      else if (vt == "QUARTER")
1731      {
1732        if (currentYear == startDate.getFullYear())
1733        {
1734          if (startDate.getFullYear() == endDate.getFullYear())
1735          {
1736            colspan = Math.floor((endDate.getMonth()-startDate.getMonth())/3)+1;
1737          }
1738          else
1739          {
1740            colspan = Math.floor((11-startDate.getMonth())/3) +1;
1741          }
1742        }
1743        else if(currentYear == endDate.getFullYear())
1744        {
1745          colspan = Math.floor(endDate.getMonth()/3)+1;
1746        }
1747        else 
1748        {
1749          colspan = 4;
1750        }
1751      }
1752      else if (vt == "YEAR")
1753      {
1754        colspan = 1;       
1755      }
1756      columnCounter += colspan;           
1757      subHeaderRowYear.appendChild(getTableCellElement(headerText, 'reportsubheader', colspan));
1758    }while(!(++currentYear>endDate.getFullYear()));
1759  }
1760 
1761  function addDataRowsToTable(report, reportTable)
1762  {
1763    var fdString = report.beginDate;
1764    var ldString = report.endDate;
1765    var psdString = report.periodBeginDate;
1766    var startDate = new Date();
1767    startDate.setYear(fdString.substr(0,4));
1768    startDate.setMonth(fdString.substr(4,2)-1);
1769    startDate.setDate(fdString.substr(6));
1770    var endDate = new Date();
1771    endDate.setYear(ldString.substr(0,4));
1772    endDate.setMonth(ldString.substr(4,2)-1);
1773    endDate.setDate(ldString.substr(6));
1774    var periodStartDate = new Date();
1775    periodStartDate.setYear(psdString.substr(0,4));
1776    periodStartDate.setMonth(psdString.substr(4,2)-1);
1777    periodStartDate.setDate(psdString.substr(6));
1778    var viewType = report.viewType;   
1779    var sites = report.sites;   
1780    var statistics = report.statistics;
1781    unknownCreation = statistics.noDate;
1782    unknownSite = statistics.unknownSite;
1783    var siteOrderList = report.siteOrderListKey;
1784    for (var siteOrderIndex in siteOrderList)
1785    {
1786      var namePrefix = siteOrderList[siteOrderIndex];   
1787      if (!sites.hasOwnProperty(namePrefix)) continue;
1788      var site = sites[namePrefix];
1789      var siteName = site.name;   
1790      var year = site.startDate.substr(0,4);
1791      var month = site.startDate.substr(5,2);
1792      var date = site.startDate.substr(8,2);     
1793      var siteStartDate = new Date(year, month-1, date);
1794     
1795      var siteData = statistics[namePrefix];
1796      var siteLatestDate = siteData['latestDateKey'];
1797      var siteLatestDateStr = '????-??-??';
1798      if (siteLatestDate != null)
1799      {
1800        var siteLatestDateYear = siteLatestDate.substr(0,4);
1801        var siteLatestDateMonth = siteLatestDate.substr(4,2);
1802        var siteLatestDateDate = siteLatestDate.substr(6,2);
1803        siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
1804      }
1805      var tableRow = document.createElement('tr');
1806      var tableCol = getTableCellElement(siteName, 'rowtitle');
1807      tableRow.appendChild(tableCol);
1808      tableRow.appendChild(getTableCellElement(year+'-'+(month)+'-'+date, 'reportdata'));
1809      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1810      var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
1811      var columnCounter = 0;
1812      do
1813      {
1814        var data = 0;
1815        var keyIndex;
1816        var yearIndex = currentDate.getFullYear();
1817       
1818        if (viewType == 'YEAR')
1819        {
1820          keyIndex = yearIndex;
1821          if (siteData != null)
1822          {
1823            if (siteData[keyIndex] != null) data = siteData[keyIndex];
1824          }
1825          // Initialize data columns before site start date to empty string
1826          if ( (currentDate.getFullYear() < siteStartDate.getFullYear()))
1827          {
1828            data = '';
1829          }
1830          currentDate.setFullYear(currentDate.getFullYear()+1);
1831        }
1832        else if (viewType == 'QUARTER')
1833        {
1834          var qIndex = Math.floor(currentDate.getMonth()/3) + 1;
1835          var startQuarter = Math.floor(siteStartDate.getMonth()/3)+1;
1836          keyIndex = yearIndex + '' + qIndex;
1837          if (siteData != null)
1838          {
1839            if (siteData[keyIndex] != null) data = siteData[keyIndex];           
1840          }         
1841          // Initialize data columns before site start date to empty string
1842          if ( (currentDate.getFullYear() < siteStartDate.getFullYear()) ||
1843               (currentDate.getFullYear() == siteStartDate.getFullYear() && qIndex < startQuarter))
1844          {
1845            data = '';
1846          }
1847          currentDate.setMonth(currentDate.getMonth()+3);         
1848        }
1849        else if (viewType == 'MONTH')
1850        {
1851          var monthIndex = currentDate.getMonth()+1;
1852          var rowFill = monthIndex < 10 ? '0' : '';
1853          keyIndex = yearIndex + rowFill + monthIndex;
1854          if (siteData != null)
1855          {
1856            if (siteData[keyIndex] != null) data = siteData[keyIndex];
1857          }
1858          // Initialize data columns before site start date to empty string
1859          if ( (currentDate.getFullYear() < siteStartDate.getFullYear()) ||
1860               (currentDate.getFullYear() == siteStartDate.getFullYear() && (monthIndex-1) < siteStartDate.getMonth()))
1861          {
1862            data = '';
1863          }
1864          currentDate.setMonth(currentDate.getMonth()+1);
1865        }
1866        else if (viewType == 'WEEK')
1867        {
1868          var weekIndex = getISOWeekNumber(currentDate);
1869          // Week number in year stored as yyyyww with leading 0 if needed
1870          if (weekIndex < 10)
1871          {
1872            keyIndex = yearIndex + '0' + weekIndex;
1873          }
1874          else
1875          {
1876            keyIndex = yearIndex + '' + weekIndex;
1877          }
1878          if (siteData != null)
1879          {
1880            if (siteData[keyIndex] != null) data = siteData[keyIndex];
1881          }
1882          // Initialize data columns before site start date to empty string
1883          //
1884          // Note: ISO week numbers are tricky in their short form (without being coupled to a year),
1885          // since days in different years may lie in the same week, and days at the start of
1886          // a year may have week number 52 or 53 of the previous year and days at the end of
1887          // a year may have week number 01 of the next year.
1888          // Example: Monday 2012-01-02 has week number 2012-01, Monday 2012-12-31 has week number 2013-01
1889          // If current date is before site start date - 6 days, it is in a previous week
1890          // If current date is within site start date +/- 6 days and not in the same week, check dates
1891          // (just checking week numbers in the last case leads to e.g. 2012-12-30 (w52) > 2012-12-31 (w01))
1892          //
1893          if (currentDate.getTime() < siteStartDate.getTime() - 6*24*3600*1000 ||
1894              currentDate.getTime() < siteStartDate.getTime() + 6*24*3600*1000 &&
1895                 getISOWeekNumber(currentDate) != getISOWeekNumber(siteStartDate) &&
1896                 currentDate < siteStartDate)
1897          {
1898            data = '';
1899          }
1900          currentDate.setDate(currentDate.getDate()+7);
1901        }
1902       
1903        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1904        columnCounter++;       
1905      } while (columnCounter < numCols)
1906      // Add column with sample sum for site for the selected time period
1907      var siteSum = 0;
1908      if (siteData != null)
1909      {
1910        var sumSiteKey = 'sumSiteKey';
1911        if (siteData[sumSiteKey] != null)
1912        {
1913          siteSum = siteData[sumSiteKey];
1914        }
1915      }
1916      tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
1917      // Add column with total number of samples for site, regardless of creation date
1918      var siteTotal = 0;
1919      if (siteData != null)
1920      {
1921        var totalSiteKey = 'totalSiteKey';
1922        if (siteData[totalSiteKey] != null)
1923        {
1924          siteTotal = siteData[totalSiteKey];
1925        }
1926      }
1927      tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
1928      reportTable.appendChild(tableRow);
1929    }
1930  }
1931 
1932  function createSortedPeriodArray(report, numberOfColumns)
1933  {
1934    var psdString = report.periodBeginDate;
1935    var periodStartDate = new Date();
1936    periodStartDate.setYear(psdString.substr(0,4));
1937    periodStartDate.setMonth(psdString.substr(4,2)-1);
1938    periodStartDate.setDate(psdString.substr(6));
1939    var viewType = report.viewType;   
1940    var sortedPeriodArray = Array(numberOfColumns);
1941    var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
1942    var columnCounter = 0;
1943    do
1944    { 
1945      var keyIndex;
1946      var yearIndex = currentDate.getFullYear();
1947       
1948      if (viewType == 'YEAR')
1949      {
1950        keyIndex = yearIndex;
1951        currentDate.setFullYear(currentDate.getFullYear()+1);
1952      }
1953      else if (viewType == 'QUARTER')
1954      {
1955        var qIndex = Math.floor(currentDate.getMonth()/3) + 1;
1956        keyIndex = yearIndex + '' + qIndex;
1957        currentDate.setMonth(currentDate.getMonth()+3);         
1958      }
1959      else if (viewType == 'MONTH')
1960      {
1961        var monthIndex = currentDate.getMonth()+1;
1962        var rowFill = monthIndex < 10 ? '0' : '';
1963        keyIndex = yearIndex + rowFill + monthIndex;
1964        currentDate.setMonth(currentDate.getMonth()+1);
1965      }
1966      else if (viewType == 'WEEK')
1967      {
1968        var weekIndex = getISOWeekNumber(currentDate);
1969        // Week number in year stored as yyyyww with leading 0 if needed
1970        if (weekIndex < 10)
1971        {
1972          keyIndex = yearIndex + '0' + weekIndex;
1973        }
1974        else
1975        {
1976          keyIndex = yearIndex + '' + weekIndex;
1977        }
1978        currentDate.setDate(currentDate.getDate()+7);
1979      }
1980      sortedPeriodArray[columnCounter] = keyIndex;
1981      columnCounter++;       
1982    } while (columnCounter < numberOfColumns)
1983    return sortedPeriodArray;
1984  }
1985 
1986  function getReportTable()
1987  {
1988      var reportTable = document.createElement('table');
1989      reportTable.setAttribute('class','reporttable');
1990      reportTable.setAttribute('border','1');     
1991      return reportTable;
1992  }
1993 
1994  function getTableCellElement(text, clazz, colspan, rowspan)
1995  {
1996    var cellElement = document.createElement('td');
1997    text = new String(text);   
1998    var textArray = text.split("\n");   
1999    if (textArray.length > 1)
2000    {
2001      for (var i=0;i<textArray.length;i++)
2002      {       
2003        if (i>0)cellElement.appendChild(document.createElement('br'));
2004        cellElement.appendChild(document.createTextNode(textArray[i]));
2005      }     
2006    }
2007    else
2008    {
2009      cellElement.appendChild(document.createTextNode(text));
2010    }
2011    cellElement.setAttribute('class', clazz);
2012    if (colspan != null) cellElement.setAttribute('colspan', colspan);
2013    if (rowspan != null) cellElement.setAttribute('rowspan', rowspan);
2014   
2015    return cellElement;
2016  }
2017 
2018  function getListElement(itemText)
2019  {
2020    var listElement = document.createElement('li');
2021    var textNode = document.createTextNode(itemText);
2022    listElement.appendChild(textNode);
2023    return listElement;
2024  }
2025
2026  /**
2027   *  addHyphensToDateStr()
2028   *
2029   *  Adds hyphens to date string in yyyymmdd format to
2030   *  get yyyy-mm-dd format. If input string already contains
2031   *  hyphen(s), the input string is returned unchanged.
2032   *  If input string is null or empty, '????-??-??' is returned.
2033   *
2034   *  @param dateStr String Input date string in yyyy-mm-dd or yyyymmdd format.
2035   *  @return String Date string in yyyy-mm-dd format.
2036   */
2037  function addHyphensToDateString(dateStr)
2038  {
2039    var dateWithHyphensStr = '????-??-??';
2040    if (dateStr != null && dateStr != '')
2041    {
2042      // Check if input string already contains hyphen
2043      if (dateStr.indexOf("-") >= 0)
2044      {
2045        // Date already has hyphen(s)
2046        dateWithHyphensStr = dateStr;
2047      }
2048      else
2049      {
2050        // Date in yyyymmdd format
2051        var yearStr = dateStr.substr(0,4);
2052        var monthStr = dateStr.substr(4,2);
2053        var dayStr = dateStr.substr(6,2);     
2054        dateWithHyphensStr = yearStr + '-' + monthStr + '-' + dayStr;
2055      }
2056    }
2057    return dateWithHyphensStr;
2058  }
2059
2060  /**
2061   *  dateStrToDate()
2062   *
2063   *  Takes an input date string in yyyy-mm-dd or yyyymmdd format
2064   *  and returns a date corresponding to the date string.
2065   *  If input string is null or empty, null is returned.
2066   *
2067   *  @param dateStr String Input date string in yyyy-mm-dd or yyyymmdd format.
2068   *  @return Date Date corresponding to input date string.
2069   */
2070  function dateStrToDate(dateStr)
2071  {
2072    var date = null;
2073    if (dateStr != null && dateStr != '')
2074    {
2075      // Check if input string already contains hyphen
2076      if (dateStr.indexOf("-") >= 0)
2077      {
2078        // Date in yyyy-mm-dd format
2079        var yearStr = dateStr.substr(0,4);
2080        var monthStr = dateStr.substr(5,2);
2081        var dayStr = dateStr.substr(8,2);     
2082        var date = new Date(parseInt(yearStr, 10), parseInt(monthStr, 10)-1, parseInt(dayStr, 10));
2083      }
2084      else
2085      {
2086        // Date in yyyymmdd format
2087        var yearStr = dateStr.substr(0,4);
2088        var monthStr = dateStr.substr(4,2);
2089        var dayStr = dateStr.substr(6,2);     
2090        var date = new Date(parseInt(yearStr, 10), parseInt(monthStr, 10)-1, parseInt(dayStr, 10));
2091      }
2092    }
2093    return date;
2094  }
2095
2096  /*
2097   *  Get the ISO week number for a given date
2098   *
2099   *  Based on code at http://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php
2100   *
2101   *  @param date String Input date to get ISO week number for.
2102   *  @return int ISO week number for input date.
2103   */
2104  function getISOWeekNumber(date)
2105  {
2106    tmpDate = new Date(date);
2107    tmpDate.setHours(0,0,0);
2108    // Set to nearest Thursday: current date + 4 - current day number
2109    // Make Sunday day number 7
2110    tmpDate.setDate(tmpDate.getDate() + 4 - (tmpDate.getDay() || 7));
2111    // Get first day of year
2112    var yearStart = new Date(tmpDate.getFullYear(), 0, 1);
2113    // Calculate full weeks to nearast Thursday (86400000 = 24*60*60*1000 number of ms in a day)
2114    var weekNo = Math.ceil(( ( (tmpDate - yearStart) / 86400000) + 1)/7);
2115    return weekNo;
2116  }
2117 
2118  function goPrint()
2119  {
2120    var frm = document.forms['reggie'];
2121    var reportName = frm.reporttype[frm.reporttype.selectedIndex].text;
2122    var printNote = '<b>Note!</b> For better printing set page orientation to <i>landscape</i>.';
2123    openPrintWindow('<%=ID%>', 'reportcell', reportName, 'landscape', printNote, '../');
2124  }
2125
2126  </script>
2127 
2128 
2129  </base:head>
2130  <base:body onload="init()">
2131    <p:path><p:pathelement 
2132      title="Reggie" href="<%="../index.jsp?ID="+ID%>" 
2133      /><p:pathelement title="Sample source report" 
2134      /></p:path>
2135    <div class="content">
2136    <%
2137    if (sc.getActiveProjectId() == 0)
2138    {
2139      %>
2140      <div class="messagecontainer note" style="width: 950px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
2141        No project has been selected. You may proceed with the report generation but
2142        only your own items will be included in the report.
2143      </div>
2144      <%
2145    }
2146    %>
2147 
2148    <form name="reggie" onsubmit="return false;">
2149      <!-- 1. Report type-->
2150      <table border="0" cellspacing="0" cellpadding="0" class="stepform">
2151      <tr>
2152        <td rowspan="3" class="stepno">1</td>
2153        <td class="steptitle">Report type</td>
2154      </tr>
2155      <tr>
2156        <td class="stepfields">
2157          <table border="0" cellspacing="0" cellpadding="0" width="100%">
2158          <tr valign="top">
2159            <td class="prompt">Report</td>
2160            <td class="input">
2161              <select name="reporttype">
2162                <option value="samplecount" selected="yes">Sample count report</option>
2163                <option value="consentcount">Consent count report</option>
2164                <option value="patientcount">Patient count report</option>
2165                <option value="overviewreport">Overview report</option>
2166                <option value="missingsampledatareport">Missing sample data report</option>
2167              </select>
2168            </td>
2169            <td class="status" id="report.status"></td>
2170            <td class="help">
2171              <span id="report.message" class="message" style="display: none;"></span>
2172              Select which report to generate.
2173            </td>
2174          </tr>
2175          </table>
2176        </td>
2177      </tr>
2178      </table>
2179     
2180      <div id="itemCountSection" style="display:none;">
2181        <p></p>
2182        <!-- 2. Report parameters-->
2183        <table border="0" cellspacing="0" cellpadding="0" class="stepform">
2184        <tr>
2185          <td rowspan="3" class="stepno">2</td>
2186          <td class="steptitle">Report parameters</td>
2187        </tr>
2188        <tr>
2189          <td class="stepfields">
2190            <table border="0" cellspacing="0" cellpadding="0" width="100%">           
2191            <tr>
2192              <td valign="top" class="prompt">
2193                <div id="reportPeriodSubSection01" style="display:none;">
2194                  <text id="reportPeriodSubSection01Header">Report period</text>
2195                </div>
2196              </td>
2197              <td valign="top" class="input">
2198                <div id="reportPeriodSubSection02" style="display:none;">
2199                  From<input type="text" onChange="dateOnChange()" size=7 name="fromdate"/>&nbsp;
2200                  To<input type="text" onChange="dateOnChange()" size=7 name="todate" />
2201                </div>
2202              </td>
2203              <td valign="top" class="status" id="displayInterval.status"></td>
2204              <td class="help">
2205                <div id="reportPeriodSubSection04" style="display:none;">
2206                  <span id="displayInterval.message" class="message" style="display: none;"></span>
2207                  <!--
2208                  Define which period the report should cover. Empty fields will include all <text id="items01">items</text>.<br>
2209                  -->
2210                  <text id="reportPeriodSubSection04HelpText">Parameter help text</text><br>
2211                </div>
2212              </td>
2213            </tr> 
2214            <tr>
2215              <td valign="top" class="prompt">
2216                <div id="viewTypeSubSection01" style="display:none;">
2217                  View type
2218                </div>
2219              </td>
2220              <td valign="top" class="input">
2221                <div id="viewTypeSubSection02" style="display:none;">
2222                  <select name="viewtype">
2223                    <option value="AUTO" selected="yes">Auto</option>
2224                    <option value="WEEK">Week</option>
2225                    <option value="MONTH">Month</option>
2226                    <option value="QUARTER">Quarter</option>
2227                    <option value="YEAR">Year</option>
2228                  </select>
2229                </div>
2230              </td>
2231              <td valign="top" class="status" id="displayViewType.status"></td>
2232              <td class="help">
2233                <div id="viewTypeSubSection04" style="display:none;">
2234                  <span id="displayViewType.message" class="message" style="display: none;"></span>
2235                  Auto will adjust the report depending on the size of the period.
2236                  <ul>
2237                    <li>Period shorter than 3 months - <text id="items02">items</text> per week</li>
2238                    <li>Period shorter than 13 months - <text id="items03">items</text> per month</li>
2239                    <li>Period shorter than 3 years - <text id="items04">items</text> per quarter</li>
2240                    <li>Period is 3 years or greater - <text id="items05">items</text> per year</li>
2241                  </ul>                 
2242                </div>
2243              </td>
2244            </tr>
2245            <tr>
2246              <td valign="top" class="prompt">
2247                <div id="sampleTypeSubSection01" style="display:none;">
2248                  Sample type
2249                </div>
2250              </td>
2251              <td valign="top" class="input">
2252                <div id="sampleTypeSubSection02" style="display:none;">
2253                  <select name="sampletype">
2254                    <option value="specimen" selected="yes">Specimen</option>
2255                    <option value="nospecimen">No specimen</option>
2256                    <option value="blood">Blood</option>
2257                  </select>
2258                </div>
2259              </td>
2260              <td valign="top" class="status" id="displaySampleType.status"></td>
2261              <td class="help">
2262                <div id="sampleTypeSubSection04" style="display:none;">
2263                  <span id="displaySampleType.message" class="message" style="display: none;"></span>
2264                  Select sample type for report.
2265                </div>
2266              </td>
2267            </tr>
2268            </table>
2269          </td>
2270        </tr>
2271        </table>
2272      </div>
2273     
2274      <div id="reportSection" style="display:none;">
2275        <p></p>
2276        <table border="0" cellspacing="0" cellpadding="0" class="stepform">
2277        <tr>
2278          <td rowspan="3" class="stepno">3</td>
2279          <td class="steptitle">Generated report
2280            <span id="printButton" class="link" style="float:right; display: none;" onclick="goPrint()"><img src="../images/print.png" style="padding-right: 0.5em;">Print version&hellip;</span>
2281          </td>
2282        </tr>
2283        <tr>
2284          <td id="reportcell" class="stepfields">
2285            <div class="loading" id="loading">
2286              <table>
2287              <tr>
2288                <td><img src="../images/loading.gif"></td>
2289                <td id="loading.msg">Generating report...</td>
2290              </tr>
2291              </table>
2292            </div>
2293          </td>
2294        </tr>
2295        </table>
2296      </div> 
2297     
2298      <div class="messagecontainer error" id="errorMessage" style="display: none; width: 950px; margin-left: 20px; margin-bottom: 0px;"></div>   
2299       
2300      <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
2301        <tr>
2302          <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
2303          <td><base:button id="gonext" title="Next" image="<%=home+"/images/gonext.png"%>" onclick="goNext(true)" /></td>
2304          <td><base:button id="gocreate" title="Generate" image="<%=home+"/images/gonext.png"%>" onclick="goCreate()" style="display: none;"/></td>         
2305          <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
2306          <td id="gonext.message" class="message"></td>
2307        </tr>
2308      </table>     
2309    </form>
2310    </div>
2311   
2312  </base:body>
2313  </base:page>
2314  <%
2315}
2316finally
2317{
2318  if (dc != null) dc.close();
2319}
2320%>
Note: See TracBrowser for help on using the repository browser.