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

Last change on this file since 1765 was 1765, checked in by olle, 10 years ago

Fixes #438. First version of overview report added.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 70.7 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;
36  var numPatientsNoSamples = 0;
37 
38  var month=new Array(12);
39    month[0]="Jan";
40    month[1]="Feb";
41    month[2]="Mar";
42    month[3]="Apr";
43    month[4]="May";
44    month[5]="Jun";
45    month[6]="Jul";
46    month[7]="Aug";
47    month[8]="Sep";
48    month[9]="Oct";
49    month[10]="Nov";
50    month[11]="Dec";
51 
52  var intervalIsValid = true;
53 
54  function goNext()
55  {
56    if (currentStep == 1)
57    {
58      gotoStep2();
59    }
60  }
61 
62  function gotoStep2()
63  {
64    var frm = document.forms['reggie'];
65    frm.reporttype.disabled = true;
66    // Hide report period input fields
67    document.getElementById("reportPeriodSubSection02").style.display = 'none';
68    // Hide sample type pop-up menu
69    document.getElementById("sampleTypeSubSection01").style.display = 'none';
70    document.getElementById("sampleTypeSubSection02").style.display = 'none';
71    document.getElementById("sampleTypeSubSection04").style.display = 'none';
72    if (frm.reporttype[frm.reporttype.selectedIndex].value == 'samplecount')
73    {
74      // Show report period input fields
75      document.getElementById("reportPeriodSubSection01Header").innerHTML="Report period";
76      document.getElementById("reportPeriodSubSection02").style.display = 'block';
77      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Define which period the report should cover. Empty fields will include all tubes.";
78      // Set item name for report time step text
79      document.getElementById("items02").innerHTML="samples";
80      document.getElementById("items03").innerHTML="samples";
81      document.getElementById("items04").innerHTML="samples";
82      document.getElementById("items05").innerHTML="samples";
83      // Show view type pop-up menu
84      document.getElementById("viewTypeSubSection01").style.display = 'block';
85      document.getElementById("viewTypeSubSection02").style.display = 'block';
86      document.getElementById("viewTypeSubSection04").style.display = 'block';
87      // Show sample type pop-up menu
88      document.getElementById("sampleTypeSubSection01").style.display = 'block';
89      document.getElementById("sampleTypeSubSection02").style.display = 'block';
90      document.getElementById("sampleTypeSubSection04").style.display = 'block';
91    }
92    else if (frm.reporttype[frm.reporttype.selectedIndex].value == 'consentcount')
93    {
94      // Show report period input fields
95      document.getElementById("reportPeriodSubSection01Header").innerHTML="Report period";
96      document.getElementById("reportPeriodSubSection02").style.display = 'block';
97      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Define which period the report should cover. Empty fields will include all consents.";
98      // Hide view type pop-up menu
99      document.getElementById("viewTypeSubSection01").style.display = 'none';
100      document.getElementById("viewTypeSubSection02").style.display = 'none';
101      document.getElementById("viewTypeSubSection04").style.display = 'none';
102    }
103    else if (frm.reporttype[frm.reporttype.selectedIndex].value == 'patientcount')
104    {
105      // Show report period input fields
106      document.getElementById("reportPeriodSubSection01Header").innerHTML="Report period";
107      document.getElementById("reportPeriodSubSection02").style.display = 'block';
108      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Define which period the report should cover. Empty fields will include all patients.";
109      // Set item name for report time step text
110      document.getElementById("items02").innerHTML="patients";
111      document.getElementById("items03").innerHTML="patients";
112      document.getElementById("items04").innerHTML="patients";
113      document.getElementById("items05").innerHTML="patients";
114      // Show view type pop-up menu
115      document.getElementById("viewTypeSubSection01").style.display = 'block';
116      document.getElementById("viewTypeSubSection02").style.display = 'block';
117      document.getElementById("viewTypeSubSection04").style.display = 'block';
118    }
119    else if (frm.reporttype[frm.reporttype.selectedIndex].value == 'overviewreport')
120    {
121      // Set parameters (report period) help text
122      document.getElementById("reportPeriodSubSection01Header").innerHTML="No report parameters";
123      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Overview report will be generated irrespective of date for items.";
124      // Hide view type pop-up menu
125      document.getElementById("viewTypeSubSection01").style.display = 'none';
126      document.getElementById("viewTypeSubSection02").style.display = 'none';
127      document.getElementById("viewTypeSubSection04").style.display = 'none';
128    }
129    Main.show('itemCountSection');
130       
131    Main.show('gocreate');   
132    Main.hide('gonext');
133    frm.fromdate.focus();
134    currentStep = 2;
135  }
136 
137  function dateOnChange()
138  {
139    var frm = document.forms['reggie'];   
140    var fdate;
141    var tdate;
142   
143    intervalIsValid = false;
144    setInputStatus('displayInterval','','valid');
145    if (frm.fromdate.value != null && frm.fromdate.value != '')
146    {
147      frm.fromdate.value = autoFillDate(frm.fromdate.value);     
148      if (!Dates.isDate(frm.fromdate.value, 'yyyyMMdd'))
149      {
150        setInputStatus('displayInterval','Not a valid from-date', 'invalid');
151        return;
152      }
153      else
154      {
155        fdate = frm.fromdate.value;
156        fdate = new Date(fdate.substr(0,4), parseInt(fdate.substr(4,2), 10)-1, fdate.substr(6,2));
157      }
158    }
159   
160    if (frm.todate.value != null && frm.todate.value != '')
161    {
162      frm.todate.value = autoFillDate(frm.todate.value);
163      if (!Dates.isDate(frm.todate.value, 'yyyyMMdd'))
164      {
165        setInputStatus('displayInterval', 'Not a valid to-date', 'invalid');
166        return;
167      }
168      else
169      {
170        tdate = frm.todate.value;
171        tdate = new Date(tdate.substr(0,4), parseInt(tdate.substr(4,2), 10)-1, tdate.substr(6,2));
172      }
173    }
174   
175    if (tdate != null && fdate != null)
176    {
177      if (fdate > tdate)
178      {
179        setInputStatus('displayInterval', 'Invalid period', 'invalid')
180        return;
181      }     
182    }
183    intervalIsValid = true;
184  }
185 
186  function goCreate()
187  {
188    if (!intervalIsValid) return;
189    var cellElement = document.getElementById('reportcell');
190    var frm = document.forms['reggie'];   
191    var reportType = frm.reporttype[frm.reporttype.selectedIndex].value;   
192    frm.fromdate.disabled = true;
193    frm.todate.disabled = true;
194    var sampleType = frm.sampletype[frm.sampletype.selectedIndex].value;   
195    if (reportType == 'samplecount')
196    {
197      frm.viewtype.disabled = true;
198      frm.sampletype.disabled = true;
199    }
200    if (reportType == 'patientcount')
201    {
202      frm.viewtype.disabled = true;
203    }
204    Main.hide('gocreate');
205    Main.show('reportSection');
206    var url = 'SampleReport.servlet?ID=<%=ID%>&cmd='+reportType;   
207   
208    if (frm.fromdate.value != null) url += '&fdate='+frm.fromdate.value;
209    if (frm.todate.value != null) url += '&tdate='+frm.todate.value;
210    if (reportType == 'samplecount')
211    {     
212      if (frm.viewtype.value != null) url += '&vtype='+frm.viewtype.value;
213      if (frm.sampletype.value != null) url += '&stype='+frm.sampletype.value;
214    }
215    if (reportType == 'patientcount')
216    {     
217      if (frm.viewtype.value != null) url += '&vtype='+frm.viewtype.value;
218    }
219   
220    var request = Ajax.getXmlHttpRequest();
221    request.open("GET", url, false);
222    request.send(null);
223   
224    if (debug) Main.debug(request.responseText);   
225    var response = JSON.parse(request.responseText); 
226    if (response.status != 'ok')
227    {
228      setFatalError(response.message);
229      return false;
230    }
231    var report = response.report;
232    var reportTable;
233   
234    if (report != null)
235    {
236      if ('samplecount' == reportType)
237      {     
238        reportTable = createItemCountReport(report, reportType);
239      }
240      else if ('consentcount' == reportType)
241      {     
242        reportTable = createConsentCountReport(report);
243      }
244      else if ('patientcount' == reportType)
245      {     
246        reportTable = createItemCountReport(report, reportType);
247      }
248      else if ('overviewreport' == reportType)
249      {     
250        reportTable = createOverviewReport(report);
251      }
252    }
253    else
254    {
255      var messageCell = getTableCellElement('No values could be found during given period', 'reportheader');
256      var messageRow = document.createElement('tr');
257      messageRow.appendChild(messageCell);     
258      var messageTable = getReportTable();
259      messageTable.appendChild(messageRow);
260      reportTable = messageTable;     
261    }
262    setInnerHTML('reportcell', '');
263    cellElement.appendChild(reportTable);
264    // Optional extra tables
265    if ('consentcount' == reportType)
266    {
267      var spacer = document.createElement('text');
268      spacer.innerHTML = "<BR>";
269      cellElement.appendChild(spacer);
270      var unknownDateTable = createConsentCountUnknownDateTable(report);
271      cellElement.appendChild(unknownDateTable);
272    }
273    else if ('overviewreport' == reportType)
274    {
275      var spacer = document.createElement('text');
276      spacer.innerHTML = "<BR>";
277      cellElement.appendChild(spacer);
278      var patientDetailedTable = createOverviewPatientDetailedTable(report);
279      cellElement.appendChild(patientDetailedTable);
280    }
281    // Summary list
282    var summaryList = document.createElement('ul');
283    if (unknownSite == null) unknownSite = 0;
284    if (unknownCreation == null) unknownCreation = 0;
285    if ('samplecount' == reportType)
286    {
287      var samples = 'specimens';
288      if ('blood' == sampleType)
289      {
290        samples = 'blood samples';
291      }
292      summaryList.appendChild(getListElement(unknownSite + ' ' + samples + ' registered to unknown sites.'));
293      summaryList.appendChild(getListElement(unknownCreation + ' ' + samples + ' without creation date. These are included in the \'Total\' column.'));
294    }
295    else if ('consentcount' == reportType)
296    {
297      var numDuplicates = 0;
298      if (report != null)
299      {
300        var statistics = report.statistics;
301        numDuplicates = statistics.duplicateKey;
302      }
303      if (numDuplicates == null)
304      {
305        numDuplicates = 0;
306      }
307      summaryList.appendChild(getListElement(unknownSite + ' consents registered to unknown sites.'));
308      summaryList.appendChild(getListElement(unknownCreation + ' consents without known date. These are included in the \'Total\' column.'));
309      summaryList.appendChild(getListElement(numDuplicates + ' duplicates ignored.'));
310
311      var patientsWithMultipleDates = statistics.patientsWithMultipleDatesKey;
312      var counter = 0;
313      for (var key in patientsWithMultipleDates)
314      {
315        counter++;
316      }
317      var patientsWithMultipleDatesText = counter + ' patients with multiple dates.';
318      summaryList.appendChild(getListElement(patientsWithMultipleDatesText));
319    }
320    else if ('patientcount' == reportType)
321    {
322      summaryList.appendChild(getListElement(unknownSite + ' patients registered to unknown sites.'));
323      summaryList.appendChild(getListElement(unknownCreation + ' patients without creation date. These are included in the \'Total\' column.'));
324    }
325    else if ('overviewreport' == reportType)
326    {
327      summaryList.appendChild(getListElement(unknownSite + ' patients registered to unknown sites.'));
328      summaryList.appendChild(getListElement(numPatientsNoSamples + ' patients with no samples.'));
329      summaryList.appendChild(getListElement('Note: Consents of type "Yes" include consents without patient id (PAT#) or date.'));
330    }
331    cellElement.appendChild(summaryList);
332    if ('consentcount' == reportType)
333    {
334      // Add table with patients with consents with multiple dates
335      var multipleDatesTable = createConsentTablePatientsWithMultipleDates(report);
336      cellElement.appendChild(multipleDatesTable);
337    }
338    Main.show('gorestart');   
339  }
340 
341  function createItemCountReport(report, reportType)
342  {
343    var reportTable = getReportTable();
344    var sdString = report.beginDate;
345    var edString = report.endDate;
346    var psdString = report.periodBeginDate;
347    var ldString = report.latestDate;
348    var startDate = new Date();
349    startDate.setYear(sdString.substr(0,4));
350    startDate.setMonth(sdString.substr(4,2)-1);
351    startDate.setDate(sdString.substr(6));
352    var endDate = new Date();
353    endDate.setYear(edString.substr(0,4));
354    endDate.setMonth(edString.substr(4,2)-1);
355    endDate.setDate(edString.substr(6));
356    var periodStartDate = new Date();
357    periodStartDate.setYear(psdString.substr(0,4));
358    periodStartDate.setMonth(psdString.substr(4,2)-1);
359    periodStartDate.setDate(psdString.substr(6));
360    var latestDate;
361    if (ldString != null)
362    {
363      latestDate = new Date();
364      latestDate.setYear(ldString.substr(0,4));
365      latestDate.setMonth(ldString.substr(4,2)-1);
366      latestDate.setDate(ldString.substr(6));
367    }   
368   
369    var viewType = report.viewType;   
370    var sampleType = report.sampleType;
371 
372    var headerRow = document.createElement('tr');   
373    var subHeaderRowYear = document.createElement('tr');
374    var columnHeaderRow = document.createElement('tr');
375   
376    var headerText = '# Items by ';
377    if ('samplecount' == reportType)
378    {
379      headerText = '# Specimens by ';
380      if ('blood' == sampleType)
381      {
382        headerText = '# Blood samples by ';
383      }
384    }
385    else if ('patientcount' == reportType)
386    {
387      headerText = '# Patients by ';
388    }
389    if (viewType == 'WEEK')
390    {
391      var startWeek = getISOWeekNumber(periodStartDate);
392      var endWeek = getISOWeekNumber(endDate);
393      var tempDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate()-periodStartDate.getDay()+1);
394      numCols = 0;
395      while (tempDate < endDate)
396      {
397        numCols++;
398        tempDate.setDate(tempDate.getDate()+7);
399      }
400      headerText += 'week';
401    }
402    else if (viewType == 'MONTH')
403    {
404      numCols = (endDate.getFullYear()-periodStartDate.getFullYear())*12 + endDate.getMonth()-periodStartDate.getMonth()+1;
405      headerText += 'month';
406    }
407    else if (viewType == 'QUARTER')
408    {
409      // First year (from start quarter to end of year)
410      numCols = 4 - Math.floor(periodStartDate.getMonth()/3);
411      // Last year (from start of year to end quarter) 
412      numCols += Math.floor(endDate.getMonth()/3)+1;
413      // If first and last year is the same, subtract 4 quarters
414      if (endDate.getFullYear() - periodStartDate.getFullYear() == 0)
415      {
416        numCols -= 4;
417      }
418      // Full years between start and end dates
419      if((endDate.getFullYear() - periodStartDate.getFullYear()) > 1)
420      {
421        numCols += 4 * (endDate.getFullYear() - periodStartDate.getFullYear()-1);
422      }
423      headerText += 'quarter';
424    }
425    else
426    {
427      numCols = endDate.getFullYear() - periodStartDate.getFullYear() + 1;
428      headerText += 'year';
429    }
430     
431    // Set table header
432    headerText += ' (between ' + startDate.getFullYear()+'-';
433    if ((startDate.getMonth()+1) < 10)
434    {
435      headerText += '0' + (startDate.getMonth()+1);
436    }
437    else
438    {
439      headerText += (startDate.getMonth()+1);
440    }
441    headerText += '-';
442    if (startDate.getDate() < 10)
443    {
444      headerText += '0' + startDate.getDate();
445    }
446    else
447    {
448      headerText += startDate.getDate();
449    }
450    headerText += ' and ';
451    headerText += endDate.getFullYear()+'-';
452    if ((endDate.getMonth()+1) < 10)
453    {
454      headerText += '0' + (endDate.getMonth()+1);
455    }
456    else
457    {
458      headerText += (endDate.getMonth()+1);
459    }
460    headerText += '-';
461    if (endDate.getDate() < 10)
462    {
463      headerText += '0' + endDate.getDate();
464    }
465    else
466    {
467      headerText += endDate.getDate();
468    }
469    headerText += ')';
470    if (latestDate != null)
471    {
472      headerText += '\nLast registration ' + latestDate.getFullYear();
473      headerText += '-';
474      if ((latestDate.getMonth()+1) < 10)
475      {
476        headerText += '0';
477      }
478      headerText += (latestDate.getMonth()+1);
479      headerText += '-';
480      if (latestDate.getDate()<10)
481      {
482        headerText += '0';
483      }
484      headerText += latestDate.getDate();
485    }   
486    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+5)));
487   
488    // Sub headers
489    // Only if each datacol is less then a year
490    if (viewType != 'YEAR')
491    {
492      subHeaderRowYear.appendChild(getTableCellElement('', 'reportsubheader', 3));
493      addYearSubHeaders(periodStartDate, endDate, subHeaderRowYear, viewType);     
494      subHeaderRowYear.appendChild(getTableCellElement('', 'reportsubheader', 2));
495    }   
496         
497    // Columnsheader   
498    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
499    var startDateHeader = getTableCellElement('Start date','reportsubheader');
500    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
501    columnHeaderRow.appendChild(siteHeader);
502    columnHeaderRow.appendChild(startDateHeader); 
503    columnHeaderRow.appendChild(latestDateHeader); 
504   
505    if (viewType == 'MONTH') addMonthColumnHeaders(columnHeaderRow, periodStartDate);
506    else if (viewType == 'WEEK') addWeekColumnHeaders(columnHeaderRow, periodStartDate);
507    else if (viewType == 'QUARTER') addQuarterColumnHeaders(columnHeaderRow, periodStartDate);
508    else if (viewType == 'YEAR') addYearSubHeaders(periodStartDate, endDate, columnHeaderRow, viewType);
509   
510   
511    columnHeaderRow.appendChild(getTableCellElement('Sum', 'reportsubheader'));
512    columnHeaderRow.appendChild(getTableCellElement('Total', 'reportsubheader'));
513
514    // Build table     
515    reportTable.appendChild(headerRow);
516    reportTable.appendChild(subHeaderRowYear);
517    reportTable.appendChild(columnHeaderRow);
518         
519    // Data rows     
520    addDataRowsToTable(report, reportTable);
521     
522    // Add a row with the combined numbers for all sites for each period
523    var sitesCombinedRow = document.createElement('tr');
524    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
525    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
526    // Get combined numbers for all sites for each period
527    var statistics = report.statistics;
528    var sitesCombined = statistics.sitesCombinedKey;   
529    var sortedKeyArray = createSortedPeriodArray(report, numCols);
530    var key;
531    for (arrayIndex in sortedKeyArray)
532    {
533      key = sortedKeyArray[arrayIndex];
534      var data = getJSONData(sitesCombined, key, 0);
535      // Add entry with sample sum for site for selected time period
536      sitesCombinedRow.appendChild(getTableCellElement(data,'colsummary'));
537    }
538    // Get total number of samples for site for the selected time period
539    var sum = getJSONData(statistics, 'sumKey', 0);
540    // Add entry with total number of samples for site for the selected time period
541    sitesCombinedRow.appendChild(getTableCellElement(sum, 'colsummary'));
542    // Get total number of samples for all sites, regardless of creation date
543    var total = getJSONData(statistics, 'totalKey', 0);
544    // Add entry with total number of samples for all sites, regardless of creation date
545    sitesCombinedRow.appendChild(getTableCellElement(total, 'colsummary'));
546    reportTable.appendChild(sitesCombinedRow); 
547
548    return reportTable;
549  }
550 
551  function createConsentCountReport(report)
552  {
553    var reportTable = getReportTable();
554    var sdString = report.beginDate;
555    var edString = report.endDate;
556/*
557    var psdString = report.periodBeginDate;
558*/
559    var ldString = report.latestDate;
560    var startDate = new Date();
561    startDate.setYear(sdString.substr(0,4));
562    startDate.setMonth(sdString.substr(4,2)-1);
563    startDate.setDate(sdString.substr(6));
564    var endDate = new Date();
565    endDate.setYear(edString.substr(0,4));
566    endDate.setMonth(edString.substr(4,2)-1);
567    endDate.setDate(edString.substr(6));
568/*
569    var periodStartDate = new Date();
570    periodStartDate.setYear(psdString.substr(0,4));
571    periodStartDate.setMonth(psdString.substr(4,2)-1);
572    periodStartDate.setDate(psdString.substr(6));
573*/
574    var latestDate;
575    if (ldString != null)
576    {
577      latestDate = new Date();
578      latestDate.setYear(ldString.substr(0,4));
579      latestDate.setMonth(ldString.substr(4,2)-1);
580      latestDate.setDate(ldString.substr(6));
581    }   
582
583/*   
584    var viewType = report.viewType; 
585*/ 
586 
587    var headerRow = document.createElement('tr');   
588    var subHeaderRow = document.createElement('tr');
589    var columnHeaderRow = document.createElement('tr');
590   
591    var numCols = 5;
592    var numDecimals = 0;
593    var headerText = '# Consent forms of different types for cases and blood samples';
594    var startDateStr = addHyphensToDateString(sdString);
595    var endDateStr = addHyphensToDateString(edString);
596    var latestDateStr = addHyphensToDateString(ldString);
597    headerText += ' (betweeen ' + startDateStr + ' and ' + endDateStr + ')';
598    if (latestDate != null)
599    {
600        headerText += '\nLast registration ' + latestDateStr;
601    }
602    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+5)));
603   
604    // Subheader   
605    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 3));
606   
607    subHeaderRow.appendChild(getTableCellElement('Yes', 'reportsubheader'));
608    subHeaderRow.appendChild(getTableCellElement('Yes', 'reportsubheader'));
609    subHeaderRow.appendChild(getTableCellElement('No', 'reportsubheader'));
610    subHeaderRow.appendChild(getTableCellElement('Not asked', 'reportsubheader'));
611    subHeaderRow.appendChild(getTableCellElement('Unknown date', 'reportsubheader'));
612    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 2));
613
614    // Columnsheader   
615    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
616    var startDateHeader = getTableCellElement('Start date','reportsubheader');
617    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
618    columnHeaderRow.appendChild(siteHeader);
619    columnHeaderRow.appendChild(startDateHeader); 
620    columnHeaderRow.appendChild(latestDateHeader); 
621   
622    columnHeaderRow.appendChild(getTableCellElement('(has PAT#)', 'reportsubheader'));
623    columnHeaderRow.appendChild(getTableCellElement('(no PAT#)', 'reportsubheader'));
624    columnHeaderRow.appendChild(getTableCellElement('(has date)', 'reportsubheader'));
625    columnHeaderRow.appendChild(getTableCellElement('(has date)', 'reportsubheader'));
626    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
627    columnHeaderRow.appendChild(getTableCellElement('Sum', 'reportsubheader'));
628    columnHeaderRow.appendChild(getTableCellElement('Total', 'reportsubheader'));
629
630    // Build table     
631    reportTable.appendChild(headerRow);
632    reportTable.appendChild(subHeaderRow);
633    reportTable.appendChild(columnHeaderRow);
634         
635    // Data rows     
636    addDataRowsToConsentTable(report, reportTable);
637     
638    // Add a row with the combined numbers for all sites for each period
639    var sitesCombinedRow = document.createElement('tr');
640    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
641    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
642    // Get combined numbers for all sites for each period
643    var noDateKey = 'noDate';
644    var sumKey = 'sumKey';
645    var statistics = report.statistics;
646    var sitesCombined = statistics.sitesCombinedKey;
647    if (sitesCombined != null)
648    {
649      data = getJSONDataWithPercent(sitesCombined, 'yesPatient', sumKey, numDecimals);
650      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
651      data = getJSONDataWithPercent(sitesCombined, 'yesNoPatient', sumKey, numDecimals);
652      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
653      data = getJSONDataWithPercent(sitesCombined, 'no', sumKey, numDecimals);
654      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
655      data = getJSONDataWithPercent(sitesCombined, 'notAsked', sumKey, numDecimals);
656      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
657      data = getJSONDataWithPercent(sitesCombined, noDateKey, sumKey, numDecimals);
658      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
659    }
660    // Add entry with total number of consents with chosen restrictions
661    data = getJSONData(sitesCombined, sumKey, 0);
662    sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
663    // Add entry with total number of consents, regardless of restrictions
664    var totalKey = 'totalKey';
665    data = getJSONData(sitesCombined, totalKey, 0);
666    sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
667    reportTable.appendChild(sitesCombinedRow); 
668
669    return reportTable;
670  }
671 
672  function createConsentCountUnknownDateTable(report)
673  {
674    var reportTable = getReportTable();
675    var headerRow = document.createElement('tr');   
676    var subHeaderRow = document.createElement('tr');
677    var columnHeaderRow = document.createElement('tr');
678   
679    var numCols = 4;
680    var numDecimals = 0;
681    var headerText = '# Consent forms of different types for cases and blood samples, unknown consent date';
682    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+5)));
683   
684    // Subheader   
685    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 3));
686   
687    subHeaderRow.appendChild(getTableCellElement('Yes', 'reportsubheader'));
688    subHeaderRow.appendChild(getTableCellElement('No', 'reportsubheader'));
689    subHeaderRow.appendChild(getTableCellElement('Not asked', 'reportsubheader'));
690    subHeaderRow.appendChild(getTableCellElement('Missing', 'reportsubheader'));
691    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 2));
692
693    // Columnsheader   
694    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
695    var startDateHeader = getTableCellElement('Start date','reportsubheader');
696    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
697    columnHeaderRow.appendChild(siteHeader);
698    columnHeaderRow.appendChild(startDateHeader); 
699    columnHeaderRow.appendChild(latestDateHeader); 
700   
701    columnHeaderRow.appendChild(getTableCellElement('(no date)', 'reportsubheader'));
702    columnHeaderRow.appendChild(getTableCellElement('(no date)', 'reportsubheader'));
703    columnHeaderRow.appendChild(getTableCellElement('(no date)', 'reportsubheader'));
704    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
705    columnHeaderRow.appendChild(getTableCellElement('Sum', 'reportsubheader'));
706    columnHeaderRow.appendChild(getTableCellElement('Total', 'reportsubheader'));
707
708    // Build table     
709    reportTable.appendChild(headerRow);
710    reportTable.appendChild(subHeaderRow);
711    reportTable.appendChild(columnHeaderRow);
712         
713    // Data rows     
714    addDataRowsToConsentTableUnknownDate(report, reportTable);
715     
716    // Add a row with the combined numbers for all sites
717    var sitesCombinedRow = document.createElement('tr');
718    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
719    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
720    // Get combined numbers for all sites
721    var sumKey = 'sumKey';
722    var statistics = report.statistics;
723    var sitesCombined = statistics.sitesCombinedKey;
724    if (sitesCombined != null)
725    {
726      data = getJSONDataWithPercent(sitesCombined, 'yesNoDate', sumKey, numDecimals);
727      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
728      data = getJSONDataWithPercent(sitesCombined, 'noNoDate', sumKey, numDecimals);
729      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
730      data = getJSONDataWithPercent(sitesCombined, 'notAskedNoDate', sumKey, numDecimals);
731      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
732      data = getJSONDataWithPercent(sitesCombined, 'missing', sumKey, numDecimals);
733      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
734    }
735    // Add entry with total number of consents with chosen restrictions
736    var noDateKey = 'noDate';
737    data = getJSONData(sitesCombined, noDateKey, 0);
738    sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
739    // Add entry with total number of consents, regardless of restrictions
740    var totalKey = 'totalKey';
741    data = getJSONData(sitesCombined, totalKey, 0);
742    sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
743    reportTable.appendChild(sitesCombinedRow); 
744
745    return reportTable;
746  }
747 
748  function createOverviewReport(report)
749  {
750    var reportTable = getReportTable();
751    var sdString = report.beginDate;
752    var edString = report.endDate;
753    var ldString = report.latestDate;
754    var startDate = new Date();
755    startDate.setYear(sdString.substr(0,4));
756    startDate.setMonth(sdString.substr(4,2)-1);
757    startDate.setDate(sdString.substr(6));
758    var endDate = new Date();
759    endDate.setYear(edString.substr(0,4));
760    endDate.setMonth(edString.substr(4,2)-1);
761    endDate.setDate(edString.substr(6));
762    var latestDate;
763    if (ldString != null)
764    {
765      latestDate = new Date();
766      latestDate.setYear(ldString.substr(0,4));
767      latestDate.setMonth(ldString.substr(4,2)-1);
768      latestDate.setDate(ldString.substr(6));
769    }   
770 
771    var headerRow = document.createElement('tr');   
772    var subHeaderRow = document.createElement('tr');
773    var subHeader2Row = document.createElement('tr');
774    var columnHeaderRow = document.createElement('tr');
775   
776    var numCols = 6;
777    var numDecimals = 0;
778    var headerText = 'Number of items of different kinds';
779    var startDateStr = addHyphensToDateString(sdString);
780    var endDateStr = addHyphensToDateString(edString);
781    var latestDateStr = addHyphensToDateString(ldString);
782    headerText += ' (betweeen ' + startDateStr + ' and ' + endDateStr + ')';
783    if (latestDate != null)
784    {
785        headerText += '\nLast registration ' + latestDateStr;
786    }
787    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+3)));
788   
789    // Subheader
790    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 3));
791   
792    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
793    subHeaderRow.appendChild(getTableCellElement('Blood', 'reportsubheader'));
794    subHeaderRow.appendChild(getTableCellElement('Specimens', 'reportsubheader'));
795    subHeaderRow.appendChild(getTableCellElement('No specimens', 'reportsubheader'));
796    subHeaderRow.appendChild(getTableCellElement('Consents', 'reportsubheader'));
797    subHeaderRow.appendChild(getTableCellElement('Consents', 'reportsubheader'));
798
799    // Columnsheader   
800    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
801    var startDateHeader = getTableCellElement('Start date','reportsubheader');
802    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
803    columnHeaderRow.appendChild(siteHeader);
804    columnHeaderRow.appendChild(startDateHeader); 
805    columnHeaderRow.appendChild(latestDateHeader); 
806   
807    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
808    columnHeaderRow.appendChild(getTableCellElement('samples', 'reportsubheader'));
809    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
810    columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
811    columnHeaderRow.appendChild(getTableCellElement('(Yes)', 'reportsubheader'));
812    columnHeaderRow.appendChild(getTableCellElement('missing', 'reportsubheader'));
813
814    // Build table     
815    reportTable.appendChild(headerRow);
816    reportTable.appendChild(subHeaderRow);
817    reportTable.appendChild(subHeader2Row);
818    reportTable.appendChild(columnHeaderRow);
819         
820    // Data rows     
821    addDataRowsToOverviewTable(report, reportTable);
822     
823    // Add a row with the combined numbers for all sites for each period
824    var sitesCombinedRow = document.createElement('tr');
825    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
826    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
827    // Get combined numbers for all sites for each period
828    var noDateKey = 'noDate';
829    var sumKey = 'sumKey';
830    var statistics = report.statistics;
831    // Get values for use in summary section
832    numPatientsNoSamples = statistics.patientNoSamples;
833    var sitesCombined = statistics.sitesCombinedKey;
834    if (sitesCombined != null)
835    {
836      data = getJSONData(sitesCombined, 'patient');
837      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
838      data = getJSONData(sitesCombined, 'bloodSample');
839      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
840      data = getJSONData(sitesCombined, 'specimen');
841      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
842      data = getJSONData(sitesCombined, 'noSpecimen');
843      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
844      data = getJSONData(sitesCombined, 'consentYes');
845      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
846      data = getJSONData(sitesCombined, 'consentMissing');
847      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
848    }
849    reportTable.appendChild(sitesCombinedRow); 
850
851    return reportTable;
852  }
853 
854  function createOverviewPatientDetailedTable(report)
855  {
856    var reportTable = getReportTable();
857    var sdString = report.beginDate;
858    var edString = report.endDate;
859    var ldString = report.latestDate;
860    var startDate = new Date();
861    startDate.setYear(sdString.substr(0,4));
862    startDate.setMonth(sdString.substr(4,2)-1);
863    startDate.setDate(sdString.substr(6));
864/*
865    var endDate = new Date();
866    endDate.setYear(edString.substr(0,4));
867    endDate.setMonth(edString.substr(4,2)-1);
868    endDate.setDate(edString.substr(6));
869*/
870    var latestDate;
871    if (ldString != null)
872    {
873      latestDate = new Date();
874      latestDate.setYear(ldString.substr(0,4));
875      latestDate.setMonth(ldString.substr(4,2)-1);
876      latestDate.setDate(ldString.substr(6));
877    }   
878 
879    var headerRow = document.createElement('tr');   
880    var subHeaderRow = document.createElement('tr');
881    var subHeader2Row = document.createElement('tr');
882    var columnHeaderRow = document.createElement('tr');
883   
884    var numCols = 8;
885    var numDecimals = 0;
886    var headerText = 'Patient records of different kinds';
887    var startDateStr = addHyphensToDateString(sdString);
888    var endDateStr = addHyphensToDateString(edString);
889    var latestDateStr = addHyphensToDateString(ldString);
890    headerText += ' (betweeen ' + startDateStr + ' and ' + endDateStr + ')';
891/*
892    if (latestDate != null)
893    {
894        headerText += '\nLast registration ' + latestDateStr;
895    }
896*/
897    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+2)));
898   
899    // Subheader
900    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 2));
901   
902    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
903    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
904    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
905    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
906    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
907    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
908    subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
909    //subHeaderRow.appendChild(getTableCellElement('Patients', 'reportsubheader'));
910    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
911
912    // Subheader 2
913    subHeader2Row.appendChild(getTableCellElement('', 'reportsubheader', 2));
914   
915    subHeader2Row.appendChild(getTableCellElement('(blood', 'reportsubheader'));
916    subHeader2Row.appendChild(getTableCellElement('(spec.', 'reportsubheader'));
917    subHeader2Row.appendChild(getTableCellElement('(no spec.', 'reportsubheader'));
918    subHeader2Row.appendChild(getTableCellElement('(blood and', 'reportsubheader'));
919    subHeader2Row.appendChild(getTableCellElement('(blood and', 'reportsubheader'));
920    subHeader2Row.appendChild(getTableCellElement('(spec. and', 'reportsubheader'));
921    subHeader2Row.appendChild(getTableCellElement('(blood, spec.,', 'reportsubheader'));
922    //subHeader2Row.appendChild(getTableCellElement('(no samples)', 'reportsubheader'));
923    subHeader2Row.appendChild(getTableCellElement('', 'reportsubheader'));
924
925    // Columnsheader   
926    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
927    var startDateHeader = getTableCellElement('Start date','reportsubheader');
928    //var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
929    columnHeaderRow.appendChild(siteHeader);
930    columnHeaderRow.appendChild(startDateHeader); 
931    //columnHeaderRow.appendChild(latestDateHeader); 
932   
933    columnHeaderRow.appendChild(getTableCellElement('only)', 'reportsubheader'));
934    columnHeaderRow.appendChild(getTableCellElement('only)', 'reportsubheader'));
935    columnHeaderRow.appendChild(getTableCellElement('only)', 'reportsubheader'));
936    columnHeaderRow.appendChild(getTableCellElement('specimens)', 'reportsubheader'));
937    columnHeaderRow.appendChild(getTableCellElement('no spec.)', 'reportsubheader'));
938    columnHeaderRow.appendChild(getTableCellElement('no spec.)', 'reportsubheader'));
939    columnHeaderRow.appendChild(getTableCellElement('and no spec.)', 'reportsubheader'));
940    //columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
941
942    columnHeaderRow.appendChild(getTableCellElement('Sum', 'reportsubheader'));
943
944    // Build table     
945    reportTable.appendChild(headerRow);
946    reportTable.appendChild(subHeaderRow);
947    reportTable.appendChild(subHeader2Row);
948    reportTable.appendChild(columnHeaderRow);
949         
950    // Data rows     
951    addDataRowsToOverviewPatientDetailedTable(report, reportTable);
952     
953    // Add a row with the combined numbers for all sites
954    var sitesCombinedRow = document.createElement('tr');
955    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
956    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary'));
957    // Get combined numbers for all sites
958    var noDateKey = 'noDate';
959    var sumKey = 'sumKey';
960    var statistics = report.statistics;
961    // Get values for use in summary section
962    numPatientsNoSamples = statistics.patientNoSamples;
963    var sitesCombined = statistics.sitesCombinedKey;
964    if (sitesCombined != null)
965    {
966      data = getJSONData(sitesCombined, 'patientBloodSampleOnly');
967      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
968      data = getJSONData(sitesCombined, 'patientSpecimenOnly');
969      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
970      data = getJSONData(sitesCombined, 'patientNoSpecimenOnly');
971      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
972      data = getJSONData(sitesCombined, 'patientBloodSampleAndSpecimen');
973      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
974      data = getJSONData(sitesCombined, 'patientBloodSampleAndNoSpecimen');
975      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
976      data = getJSONData(sitesCombined, 'patientSpecimenAndNoSpecimen');
977      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
978      data = getJSONData(sitesCombined, 'patientBloodSampleAndSpecimenAndNoSpecimen');
979      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
980      //data = getJSONData(sitesCombined, 'patientNoSamples');
981      //sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
982      data = getJSONData(sitesCombined, 'sumKey');
983      sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
984    }
985    reportTable.appendChild(sitesCombinedRow); 
986
987    return reportTable;
988  }
989 
990  function addHyphensToDateString(yyyymmddStr)
991  {
992    var dateWithHyphensStr = '????-??-??';
993    if (yyyymmddStr != null)
994    {
995      var yyyyStr = yyyymmddStr.substr(0,4);
996      var mmStr   = yyyymmddStr.substr(4,2);
997      var ddStr = yyyymmddStr.substr(6);
998      dateWithHyphensStr = yyyyStr + '-' + mmStr + '-' + ddStr;
999    }
1000    return dateWithHyphensStr;
1001  }
1002
1003  function createConsentTablePatientsWithMultipleDates(report)
1004  {
1005    var multipleDatesTable = getReportTable();
1006    var headerRow = document.createElement('tr');   
1007    var columnHeaderRow = document.createElement('tr');
1008   
1009    // Table header
1010    var numCols = 3;
1011    var headerText = 'Consent forms with multiple dates for same patient';
1012    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', numCols));
1013   
1014    // Columnsheader
1015    columnHeaderRow.appendChild(getTableCellElement('Patient ID', 'reportsubheader'));
1016    columnHeaderRow.appendChild(getTableCellElement('Date 1', 'reportsubheader'));
1017    columnHeaderRow.appendChild(getTableCellElement('Date 2', 'reportsubheader'));
1018
1019    // Build table     
1020    multipleDatesTable.appendChild(headerRow);
1021    multipleDatesTable.appendChild(columnHeaderRow);
1022         
1023    // Data rows
1024    if (report != null)
1025    {
1026      var statistics = report.statistics;
1027      var sessionId = statistics.sessionIdKey;
1028      var patientsWithMultipleDates = statistics.patientsWithMultipleDatesKey;
1029      var patientnamePatientid = statistics.patientnamePatientidKey;
1030      for (var patientName in patientsWithMultipleDates)
1031      {
1032        var tableRow = document.createElement('tr');
1033        // Add patient name to table
1034        var patientIdStr = patientnamePatientid[patientName];
1035        var columnCell = document.createElement('td');
1036        var patientLinkStr = createLinkStr(patientName, patientIdStr, 'BIOSOURCE', 'View this sample', sessionId);
1037        var tableCol = createTableCellElementHtml(patientLinkStr, 'reportdata');
1038        tableRow.appendChild(tableCol);
1039        // Add dates to table in chronological order
1040        var dateSet = patientsWithMultipleDates[patientName];
1041        var dateStr1 = '';
1042        var dateStr2 = '';
1043        for (var key in dateSet)
1044        {
1045          var dateStr = dateSet[key];
1046          if (dateStr1 == '')
1047          {
1048            dateStr1 = dateStr;
1049          }
1050          else if (dateStr > dateStr1)
1051          {
1052            dateStr2 = dateStr;
1053          }
1054          else
1055          {
1056            dateStr2 = dateStr1;
1057            dateStr1 = dateStr;
1058          }
1059        }
1060        var dateCol = '';
1061        dateCol = getTableCellElement(dateStr1, 'reportdata');
1062        tableRow.appendChild(dateCol);
1063        dateCol = getTableCellElement(dateStr2, 'reportdata');
1064        tableRow.appendChild(dateCol);
1065        multipleDatesTable.appendChild(tableRow);
1066      }
1067    }
1068
1069    return multipleDatesTable;
1070  }
1071 
1072  function addDataRowsToConsentTable(report, reportTable, numDecimals)
1073  {
1074    var sites = report.sites;   
1075    var statistics = report.statistics;
1076    unknownCreation = statistics.noDate;
1077    unknownSite = statistics.unknownSite;
1078    var siteOrderList = report.siteOrderListKey;
1079    for (var siteOrderIndex in siteOrderList)
1080    {
1081      var namePrefix = siteOrderList[siteOrderIndex];   
1082      if (!sites.hasOwnProperty(namePrefix)) continue;       
1083      var site = sites[namePrefix];
1084      var siteName = site.name;       
1085      var year = site.startDate.substr(0,4);
1086      var month = site.startDate.substr(5,2);
1087      var date = site.startDate.substr(8,2);     
1088      var siteStartDate = new Date(year, month-1, date);
1089     
1090      var siteData = statistics[namePrefix];     
1091      var siteLatestDate = siteData['latestDateKey'];
1092      var siteLatestDateYear = siteLatestDate.substr(0,4);
1093      var siteLatestDateMonth = siteLatestDate.substr(4,2);
1094      var siteLatestDateDate = siteLatestDate.substr(6,2);
1095      var siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
1096      var tableRow = document.createElement('tr');
1097      var tableCol = getTableCellElement(siteName, 'rowtitle');
1098      tableRow.appendChild(tableCol);
1099      tableRow.appendChild(getTableCellElement(year+'-'+(month)+'-'+date, 'reportdata'));
1100      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1101      //var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
1102      var noDateKey = 'noDate';
1103      var sumKey = 'sumKey';
1104      var totalKey = 'totalKey';
1105      if (siteData != null)
1106      {
1107        data = getJSONDataWithPercent(siteData, 'yesPatient', sumKey, numDecimals);
1108        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1109        data = getJSONDataWithPercent(siteData, 'yesNoPatient', sumKey, numDecimals);
1110        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1111        data = getJSONDataWithPercent(siteData, 'no', sumKey, numDecimals);
1112        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1113        data = getJSONDataWithPercent(siteData, 'notAsked', sumKey, numDecimals);
1114        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1115        data = getJSONDataWithPercent(siteData, noDateKey, sumKey, numDecimals);
1116        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1117        // Add column with summed values for site
1118        var siteSum = getJSONData(siteData, sumKey, 0);
1119        tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
1120      }
1121      // Add column with total number of samples for site, regardless of creation date
1122      var siteTotal = getJSONData(siteData, totalKey, 0);
1123      tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
1124      reportTable.appendChild(tableRow);
1125    }
1126  }
1127
1128  function addDataRowsToConsentTableUnknownDate(report, reportTable, numDecimals)
1129  {
1130    var sites = report.sites;   
1131    var statistics = report.statistics;
1132    unknownCreation = statistics.noDate;
1133    unknownSite = statistics.unknownSite;
1134    var siteOrderList = report.siteOrderListKey;
1135    for (var siteOrderIndex in siteOrderList)
1136    {
1137      var namePrefix = siteOrderList[siteOrderIndex];   
1138      if (!sites.hasOwnProperty(namePrefix)) continue;       
1139      var site = sites[namePrefix];
1140      var siteName = site.name;
1141      var year = site.startDate.substr(0,4);
1142      var month = site.startDate.substr(5,2);
1143      var date = site.startDate.substr(8,2);     
1144      var siteStartDate = new Date(year, month-1, date);
1145     
1146      var siteData = statistics[namePrefix];     
1147      var siteLatestDate = siteData['latestDateKey'];
1148      var siteLatestDateYear = siteLatestDate.substr(0,4);
1149      var siteLatestDateMonth = siteLatestDate.substr(4,2);
1150      var siteLatestDateDate = siteLatestDate.substr(6,2);
1151      var siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
1152      var tableRow = document.createElement('tr');
1153      var tableCol = getTableCellElement(siteName, 'rowtitle');
1154      tableRow.appendChild(tableCol);
1155      tableRow.appendChild(getTableCellElement(year+'-'+(month)+'-'+date, 'reportdata'));
1156      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1157      //var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
1158      var noDateKey = 'noDate';
1159      var sumKey = 'sumKey';
1160      var totalKey = 'totalKey';
1161      if (siteData != null)
1162      {
1163        data = getJSONDataWithPercent(siteData, 'yesNoDate', sumKey, numDecimals);
1164        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1165        data = getJSONDataWithPercent(siteData, 'noNoDate', sumKey, numDecimals);
1166        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1167        data = getJSONDataWithPercent(siteData, 'notAskedNoDate', sumKey, numDecimals);
1168        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1169        data = getJSONDataWithPercent(siteData, 'missing', sumKey, numDecimals);
1170        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1171        // Add column with summed values for site
1172        var siteSum = getJSONData(siteData, noDateKey, 0);
1173        tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
1174      }
1175      // Add column with total number of samples for site, regardless of creation date
1176      var siteTotal = getJSONData(siteData, totalKey, 0);
1177      tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
1178      reportTable.appendChild(tableRow);
1179    }
1180  }
1181
1182  function addDataRowsToOverviewTable(report, reportTable)
1183  {
1184    var sites = report.sites;   
1185    var statistics = report.statistics;
1186    unknownCreation = statistics.noDate;
1187    unknownSite = statistics.unknownSite;
1188    var siteOrderList = report.siteOrderListKey;
1189    for (var siteOrderIndex in siteOrderList)
1190    {
1191      var namePrefix = siteOrderList[siteOrderIndex];   
1192      if (!sites.hasOwnProperty(namePrefix)) continue;       
1193      var site = sites[namePrefix];
1194      var siteName = site.name;       
1195      var year = site.startDate.substr(0,4);
1196      var month = site.startDate.substr(5,2);
1197      var date = site.startDate.substr(8,2);     
1198      var siteStartDate = new Date(year, month-1, date);
1199     
1200      var siteData = statistics[namePrefix];     
1201      var siteLatestDate = siteData['latestDateKey'];
1202      var siteLatestDateYear = siteLatestDate.substr(0,4);
1203      var siteLatestDateMonth = siteLatestDate.substr(4,2);
1204      var siteLatestDateDate = siteLatestDate.substr(6,2);
1205      var siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
1206      var tableRow = document.createElement('tr');
1207      var tableCol = getTableCellElement(siteName, 'rowtitle');
1208      tableRow.appendChild(tableCol);
1209      tableRow.appendChild(getTableCellElement(year+'-'+(month)+'-'+date, 'reportdata'));
1210      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1211      //var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
1212      var noDateKey = 'noDate';
1213      var sumKey = 'sumKey';
1214      var totalKey = 'totalKey';
1215      if (siteData != null)
1216      {
1217        data = getJSONData(siteData, 'patient');
1218        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1219        data = getJSONData(siteData, 'bloodSample');
1220        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1221        data = getJSONData(siteData, 'specimen');
1222        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1223        data = getJSONData(siteData, 'noSpecimen');
1224        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1225        data = getJSONData(siteData, 'consentYes');
1226        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1227        data = getJSONData(siteData, 'consentMissing');
1228        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1229      }
1230      reportTable.appendChild(tableRow);
1231    }
1232  }
1233
1234  function addDataRowsToOverviewPatientDetailedTable(report, reportTable)
1235  {
1236    var sites = report.sites;   
1237    var statistics = report.statistics;
1238    unknownCreation = statistics.noDate;
1239    unknownSite = statistics.unknownSite;
1240    var siteOrderList = report.siteOrderListKey;
1241    for (var siteOrderIndex in siteOrderList)
1242    {
1243      var namePrefix = siteOrderList[siteOrderIndex];   
1244      if (!sites.hasOwnProperty(namePrefix)) continue;       
1245      var site = sites[namePrefix];
1246      var siteName = site.name;       
1247      var year = site.startDate.substr(0,4);
1248      var month = site.startDate.substr(5,2);
1249      var date = site.startDate.substr(8,2);     
1250      var siteStartDate = new Date(year, month-1, date);
1251     
1252      var siteData = statistics[namePrefix];
1253/*   
1254      var siteLatestDate = siteData['latestDateKey'];
1255      var siteLatestDateYear = siteLatestDate.substr(0,4);
1256      var siteLatestDateMonth = siteLatestDate.substr(4,2);
1257      var siteLatestDateDate = siteLatestDate.substr(6,2);
1258      var siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
1259*/
1260      var tableRow = document.createElement('tr');
1261      var tableCol = getTableCellElement(siteName, 'rowtitle');
1262      tableRow.appendChild(tableCol);
1263      tableRow.appendChild(getTableCellElement(year+'-'+(month)+'-'+date, 'reportdata'));
1264/*
1265      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1266*/
1267      //var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
1268      var noDateKey = 'noDate';
1269      var sumKey = 'sumKey';
1270      var totalKey = 'totalKey';
1271      if (siteData != null)
1272      {
1273        data = getJSONData(siteData, 'patientBloodSampleOnly');
1274        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1275        data = getJSONData(siteData, 'patientSpecimenOnly');
1276        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1277        data = getJSONData(siteData, 'patientNoSpecimenOnly');
1278        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1279        data = getJSONData(siteData, 'patientBloodSampleAndSpecimen');
1280        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1281        data = getJSONData(siteData, 'patientBloodSampleAndNoSpecimen');
1282        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1283        data = getJSONData(siteData, 'patientSpecimenAndNoSpecimen');
1284        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1285        data = getJSONData(siteData, 'patientBloodSampleAndSpecimenAndNoSpecimen');
1286        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1287        //data = getJSONData(siteData, 'patientNoSamples');
1288        //tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1289        data = getJSONData(siteData, 'sumKey');
1290        tableRow.appendChild(getTableCellElement(data, 'rowsummary'));
1291      }
1292      reportTable.appendChild(tableRow);
1293    }
1294  }
1295
1296  function createLinkStr(linkName, idStr, itemTypeStr, titleStr, sessionId)
1297  {
1298    var linkStr = '<span class="link" onclick="Main.itemOnClick(event, \'' + sessionId + '\', \'' + itemTypeStr + '\', ' + idStr + ', false)" title="' + titleStr + '">' + linkName + '</span>';
1299    return linkStr;
1300  }
1301
1302  function createTableCellElementHtml(html, clazz, colspan, rowspan)
1303  {
1304    var htmlStr = new String(html);
1305    var cellElement = document.createElement('td');
1306    cellElement.innerHTML = htmlStr;
1307    cellElement.setAttribute('class', clazz);
1308    if (colspan != null) cellElement.setAttribute('colspan', colspan);
1309    if (rowspan != null) cellElement.setAttribute('rowspan', rowspan);
1310   
1311    return cellElement;
1312  }
1313 
1314  function getJSONDataWithPercent(jsonObject, key, sumKey, numDecimals)
1315  {
1316    var dataNum = getJSONData(jsonObject, key);
1317    var dataSum = getJSONData(jsonObject, sumKey);
1318    var dataPct = '0';
1319    if (dataSum != null || dataSum != 0)
1320    {
1321      dataPct = 100*dataNum/dataSum;
1322      dataPct = dataPct.toFixed(numDecimals);
1323    }
1324    var data = dataNum + ' (' + dataPct + '%)';
1325    return data;
1326  }
1327
1328  function getJSONData(jsonObject, key)
1329  {
1330    var data = getJSONData(jsonObject, key, '');
1331    return data;
1332  }
1333
1334  function getJSONData(jsonObject, key, defaultChoice)
1335  {
1336    var data = defaultChoice;
1337    if (jsonObject != null)
1338    {
1339      if (jsonObject[key] != null)
1340      {
1341        data = jsonObject[key];
1342      }
1343    }
1344    /*
1345    else
1346    {
1347      data = 'jsonObject==null';
1348    }
1349    */
1350    return data;
1351  }
1352
1353  function addQuarterColumnHeaders(columnHeaderRow, startDate)
1354  {
1355    var currentDate = startDate;
1356    for (var i=0;i<numCols;i++)
1357    {
1358      var quarter = Math.floor(currentDate.getMonth()/3)+1;
1359      var columnText = 'Q'+quarter;
1360      var quarterHeader = getTableCellElement(columnText, 'reportsubheader');
1361      columnHeaderRow.appendChild(quarterHeader); 
1362      currentDate.setMonth(currentDate.getMonth()+3);     
1363    }
1364  }
1365 
1366  function addWeekColumnHeaders(columnHeaderRow, startDate)
1367  {
1368    var currentDate = startDate;
1369    var day = currentDate.getDay()-1;
1370    day = day>=0 ? day: day + 7;
1371    currentDate.setDate(currentDate.getDate()-day);
1372    for (var i=0;i<numCols;i++)
1373    {     
1374      var weekNum = getISOWeekNumber(currentDate);
1375      var columnText = weekNum;
1376      if (weekNum < 10) columnText = '0'+columnText;     
1377      columnHeaderRow.appendChild(getTableCellElement(columnText, 'reportsubheader'));
1378      currentDate.setDate(currentDate.getDate()+7);     
1379    }
1380  }
1381 
1382  function addMonthColumnHeaders(columnHeaderRow, startDate)
1383  {   
1384    var currentDate = new Date(startDate.getFullYear(), startDate.getMonth());
1385    for (var i=0;i<numCols;i++)
1386    {             
1387      var monthHeader = getTableCellElement(month[currentDate.getMonth()], 'reportsubheader');
1388      columnHeaderRow.appendChild(monthHeader);       
1389      currentDate.setMonth(currentDate.getMonth() +1);
1390    }   
1391  }
1392 
1393  function addYearSubHeaders(startDate, endDate, subHeaderRowYear, vt)
1394  {   
1395    var currentYear = startDate.getFullYear(); 
1396   
1397    var columnCounter = 0;   
1398    do
1399    {
1400      var colspan;
1401      var headerText = currentYear;
1402      if (vt == "MONTH")
1403      {
1404        if (currentYear == startDate.getFullYear())
1405        {
1406          colspan =  11-startDate.getMonth()+1;
1407          if (endDate.getFullYear() == currentYear)
1408          {
1409            colspan = colspan - (11-endDate.getMonth());
1410          }
1411        }
1412        else if (currentYear == endDate.getFullYear()) 
1413          colspan = endDate.getMonth()+1;
1414        else
1415          colspan = 12;
1416      }
1417      else if (vt == "WEEK")
1418      { 
1419        if (startDate.getFullYear() == endDate.getFullYear())
1420        {
1421          colspan = numCols;
1422        }
1423        else if (currentYear == startDate.getFullYear())
1424        {
1425          var startWeek = getISOWeekNumber(startDate);
1426          var lastDay = new Date(startDate.getFullYear(), 11, 31);
1427          var endWeek = getISOWeekNumber(lastDay);
1428          if (endWeek == 1)
1429          {
1430            lastDay.setDate(lastDay.getDate()-7);
1431            endWeek = getISOWeekNumber(lastDay);
1432          }
1433          colspan = endWeek - startWeek +1;
1434        }
1435        else if (currentYear == endDate.getFullYear())
1436        {
1437          var endWeek = getISOWeekNumber(endDate);
1438          colspan = endWeek;
1439        }
1440        else
1441        {
1442          var dateInLastWeek = new Date(currentYear, 11, 31);
1443          var endWeek = getISOWeekNumber(dateInLastWeek);
1444          if (endWeek == 1)
1445          {
1446            dateInLastWeek.setDate(dateInLastWeek.getDate()-7);
1447            endWeek = getISOWeekNumber(dateInLastWeek);
1448          }
1449          colspan = endWeek;
1450        }               
1451      }
1452      else if (vt == "QUARTER")
1453      {
1454        if (currentYear == startDate.getFullYear())
1455        {
1456          if (startDate.getFullYear() == endDate.getFullYear())
1457          {
1458            colspan = Math.floor((endDate.getMonth()-startDate.getMonth())/3)+1;
1459          }
1460          else
1461          {
1462            colspan = Math.floor((11-startDate.getMonth())/3) +1;
1463          }
1464        }
1465        else if(currentYear == endDate.getFullYear())
1466        {
1467          colspan = Math.floor(endDate.getMonth()/3)+1;
1468        }
1469        else 
1470        {
1471          colspan = 4;
1472        }
1473      }
1474      else if (vt == "YEAR")
1475      {
1476        colspan = 1;       
1477      }
1478      columnCounter += colspan;           
1479      subHeaderRowYear.appendChild(getTableCellElement(headerText, 'reportsubheader', colspan));
1480    }while(!(++currentYear>endDate.getFullYear()));
1481  }
1482 
1483  function addDataRowsToTable(report, reportTable)
1484  {
1485    var fdString = report.beginDate;
1486    var ldString = report.endDate;
1487    var psdString = report.periodBeginDate;
1488    var startDate = new Date();
1489    startDate.setYear(fdString.substr(0,4));
1490    startDate.setMonth(fdString.substr(4,2)-1);
1491    startDate.setDate(fdString.substr(6));
1492    var endDate = new Date();
1493    endDate.setYear(ldString.substr(0,4));
1494    endDate.setMonth(ldString.substr(4,2)-1);
1495    endDate.setDate(ldString.substr(6));
1496    var periodStartDate = new Date();
1497    periodStartDate.setYear(psdString.substr(0,4));
1498    periodStartDate.setMonth(psdString.substr(4,2)-1);
1499    periodStartDate.setDate(psdString.substr(6));
1500    var viewType = report.viewType;   
1501    var sites = report.sites;   
1502    var statistics = report.statistics;
1503    unknownCreation = statistics.noDate;
1504    unknownSite = statistics.unknownSite;
1505    var siteOrderList = report.siteOrderListKey;
1506    for (var siteOrderIndex in siteOrderList)
1507    {
1508      var namePrefix = siteOrderList[siteOrderIndex];   
1509      if (!sites.hasOwnProperty(namePrefix)) continue;
1510      var site = sites[namePrefix];
1511      var siteName = site.name;   
1512      var year = site.startDate.substr(0,4);
1513      var month = site.startDate.substr(5,2);
1514      var date = site.startDate.substr(8,2);     
1515      var siteStartDate = new Date(year, month-1, date);
1516     
1517      var siteData = statistics[namePrefix];
1518      var siteLatestDate = siteData['latestDateKey'];
1519      var siteLatestDateStr = '????-??-??';
1520      if (siteLatestDate != null)
1521      {
1522        var siteLatestDateYear = siteLatestDate.substr(0,4);
1523        var siteLatestDateMonth = siteLatestDate.substr(4,2);
1524        var siteLatestDateDate = siteLatestDate.substr(6,2);
1525        siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
1526      }
1527/*
1528      var siteLatestDateYear = siteLatestDate.substr(0,4);
1529      var siteLatestDateMonth = siteLatestDate.substr(4,2);
1530      var siteLatestDateDate = siteLatestDate.substr(6,2);
1531      var siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
1532*/
1533      var tableRow = document.createElement('tr');
1534      var tableCol = getTableCellElement(siteName, 'rowtitle');
1535      tableRow.appendChild(tableCol);
1536      tableRow.appendChild(getTableCellElement(year+'-'+(month)+'-'+date, 'reportdata'));
1537      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
1538      var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
1539      var columnCounter = 0;
1540      do
1541      {
1542        var data = 0;
1543        var keyIndex;
1544        var yearIndex = currentDate.getFullYear();
1545       
1546        if (viewType == 'YEAR')
1547        {
1548          keyIndex = yearIndex;
1549          if (siteData != null)
1550          {
1551            if (siteData[keyIndex] != null) data = siteData[keyIndex];
1552          }
1553          if ( (currentDate.getFullYear() < siteStartDate.getFullYear()))
1554          {
1555            data = '';
1556          }
1557          currentDate.setFullYear(currentDate.getFullYear()+1);
1558        }
1559        else if (viewType == 'QUARTER')
1560        {
1561          var qIndex = Math.floor(currentDate.getMonth()/3) + 1;
1562          var startQuarter = Math.floor(siteStartDate.getMonth()/3)+1;
1563          keyIndex = yearIndex + '' + qIndex;
1564          if (siteData != null)
1565          {
1566            if (siteData[keyIndex] != null) data = siteData[keyIndex];           
1567          }         
1568          if ( (currentDate.getFullYear() <= siteStartDate.getFullYear()) && qIndex<startQuarter)
1569          {
1570            data = '';
1571          }
1572          currentDate.setMonth(currentDate.getMonth()+3);         
1573        }
1574        else if (viewType == 'MONTH')
1575        {
1576          var monthIndex = currentDate.getMonth()+1;
1577          var rowFill = monthIndex < 10 ? '0' : '';
1578          keyIndex = yearIndex + rowFill + monthIndex;
1579          if (siteData != null)
1580          {
1581            if (siteData[keyIndex] != null) data = siteData[keyIndex];
1582          }
1583          if (currentDate.getFullYear() <= siteStartDate.getFullYear() && (monthIndex-1) < siteStartDate.getMonth())
1584          {
1585            data = '';
1586          }
1587         
1588         
1589          currentDate.setMonth(currentDate.getMonth()+1);
1590        }
1591        else if (viewType == 'WEEK')
1592        {
1593          var weekIndex = getISOWeekNumber(currentDate);
1594          keyIndex = yearIndex + '' + weekIndex;
1595          if (siteData != null)
1596          {
1597            if (siteData[keyIndex] != null) data = siteData[keyIndex];
1598          }
1599          if (currentDate.getFullYear() <= siteStartDate.getFullYear() && getISOWeekNumber(currentDate) < getISOWeekNumber(siteStartDate))
1600          {
1601            data = '';
1602          }
1603          currentDate.setDate(currentDate.getDate()+7);
1604        }
1605       
1606        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
1607        columnCounter++;       
1608      } while (columnCounter < numCols)
1609      // Add column with sample sum for site for the selected time period
1610      var siteSum = 0;
1611      if (siteData != null)
1612      {
1613        var sumSiteKey = 'sumSiteKey';
1614        if (siteData[sumSiteKey] != null)
1615        {
1616          siteSum = siteData[sumSiteKey];
1617        }
1618      }
1619      tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
1620      // Add column with total number of samples for site, regardless of creation date
1621      var siteTotal = 0;
1622      if (siteData != null)
1623      {
1624        var totalSiteKey = 'totalSiteKey';
1625        if (siteData[totalSiteKey] != null)
1626        {
1627          siteTotal = siteData[totalSiteKey];
1628        }
1629      }
1630      tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
1631      reportTable.appendChild(tableRow);
1632    }
1633  }
1634 
1635  function createSortedPeriodArray(report, numberOfColumns)
1636  {
1637    var psdString = report.periodBeginDate;
1638    var periodStartDate = new Date();
1639    periodStartDate.setYear(psdString.substr(0,4));
1640    periodStartDate.setMonth(psdString.substr(4,2)-1);
1641    periodStartDate.setDate(psdString.substr(6));
1642    var viewType = report.viewType;   
1643    var sortedPeriodArray = Array(numberOfColumns);
1644    var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
1645    var columnCounter = 0;
1646    do
1647    { 
1648      var keyIndex;
1649      var yearIndex = currentDate.getFullYear();
1650       
1651      if (viewType == 'YEAR')
1652      {
1653        keyIndex = yearIndex;
1654        currentDate.setFullYear(currentDate.getFullYear()+1);
1655      }
1656      else if (viewType == 'QUARTER')
1657      {
1658        var qIndex = Math.floor(currentDate.getMonth()/3) + 1;
1659        keyIndex = yearIndex + '' + qIndex;
1660        currentDate.setMonth(currentDate.getMonth()+3);         
1661      }
1662      else if (viewType == 'MONTH')
1663      {
1664        var monthIndex = currentDate.getMonth()+1;
1665        var rowFill = monthIndex < 10 ? '0' : '';
1666        keyIndex = yearIndex + rowFill + monthIndex;
1667        currentDate.setMonth(currentDate.getMonth()+1);
1668      }
1669      else if (viewType == 'WEEK')
1670      {
1671        var weekIndex = getISOWeekNumber(currentDate);
1672        keyIndex = yearIndex + '' + weekIndex;
1673        currentDate.setDate(currentDate.getDate()+7);
1674      }
1675      sortedPeriodArray[columnCounter] = keyIndex;
1676      columnCounter++;       
1677    } while (columnCounter < numberOfColumns)
1678    return sortedPeriodArray;
1679  }
1680 
1681  function getReportTable()
1682  {
1683      var reportTable = document.createElement('table');
1684      reportTable.setAttribute('class','reporttable');
1685      reportTable.setAttribute('border','1');     
1686      return reportTable;
1687  }
1688 
1689  function getTableCellElement(text, clazz, colspan, rowspan)
1690  {
1691    var cellElement = document.createElement('td');
1692    text = new String(text);   
1693    var textArray = text.split("\n");   
1694    if (textArray.length > 1)
1695    {
1696      for (var i=0;i<textArray.length;i++)
1697      {       
1698        if (i>0)cellElement.appendChild(document.createElement('br'));
1699        cellElement.appendChild(document.createTextNode(textArray[i]));
1700      }     
1701    }
1702    else
1703    {
1704      cellElement.appendChild(document.createTextNode(text));
1705    }
1706    cellElement.setAttribute('class', clazz);
1707    if (colspan != null) cellElement.setAttribute('colspan', colspan);
1708    if (rowspan != null) cellElement.setAttribute('rowspan', rowspan);
1709   
1710    return cellElement;
1711  }
1712 
1713  function getListElement(itemText)
1714  {
1715    var listElement = document.createElement('li');
1716    var textNode = document.createTextNode(itemText);
1717    listElement.appendChild(textNode);
1718    return listElement;
1719  }
1720
1721  /*
1722   * Get the ISO week number for a given date
1723   *
1724   * Based on code at http://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php
1725   */
1726  function getISOWeekNumber(date)
1727  {
1728    tmpDate = new Date(date);
1729    tmpDate.setHours(0,0,0);
1730    // Set to nearest Thursday: current date + 4 - current day number
1731    // Make Sunday day number 7
1732    tmpDate.setDate(tmpDate.getDate() + 4 - (tmpDate.getDay() || 7));
1733    // Get first day of year
1734    var yearStart = new Date(tmpDate.getFullYear(), 0, 1);
1735    // Calculate full weeks to nearast Thursday (86400000 = 24*60*60*1000 number of ms in a day)
1736    var weekNo = Math.ceil(( ( (tmpDate - yearStart) / 86400000) + 1)/7);
1737    return weekNo;
1738  }
1739
1740  </script>
1741 
1742 
1743  </base:head>
1744  <base:body onload="init()">
1745    <p:path><p:pathelement 
1746      title="Reggie" href="<%="index.jsp?ID="+ID%>" 
1747      /><p:pathelement title="Report generator" 
1748      /></p:path>
1749    <div class="content">
1750    <%
1751    if (sc.getActiveProjectId() == 0)
1752    {
1753      %>
1754      <div class="messagecontainer note" style="width: 950px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
1755        No project has been selected. You may proceed with the report generation but
1756        only your own items will be included in the report.
1757      </div>
1758      <%
1759    }
1760    %>
1761 
1762    <form name="reggie" onsubmit="return false;">
1763      <!-- 1. Report type-->
1764      <table border="0" cellspacing="0" cellpadding="0" class="stepform">
1765      <tr>
1766        <td rowspan="3" class="stepno">1</td>
1767        <td class="steptitle">Report type</td>
1768      </tr>
1769      <tr>
1770        <td class="stepfields">
1771          <table border="0" cellspacing="0" cellpadding="0" width="100%">
1772          <tr valign="top">
1773            <td class="prompt">Report</td>
1774            <td class="input">
1775              <select name="reporttype">
1776                <option value="samplecount" selected="yes">Sample count report</option>
1777                <option value="consentcount">Consent count report</option>
1778                <option value="patientcount">Patient count report</option>
1779                <option value="overviewreport">Overview report</option>
1780              </select>
1781            </td>
1782            <td class="status" id="report.status"></td>
1783            <td class="help">
1784              <span id="report.message" class="message" style="display: none;"></span>
1785              Select which report to generate.
1786            </td>
1787          </tr>
1788          </table>
1789        </td>
1790      </tr>
1791      </table>
1792     
1793      <div id="itemCountSection" style="display:none;">
1794        <p></p>
1795        <!-- 2. Report parameters-->
1796        <table border="0" cellspacing="0" cellpadding="0" class="stepform">
1797        <tr>
1798          <td rowspan="3" class="stepno">2</td>
1799          <td class="steptitle">Report parameters</td>
1800        </tr>
1801        <tr>
1802          <td class="stepfields">
1803            <table border="0" cellspacing="0" cellpadding="0" width="100%">           
1804            <tr>
1805              <td valign="top" class="prompt">
1806                <text id="reportPeriodSubSection01Header">Report period</text>
1807              </td>
1808              <td valign="top" class="input">
1809                <div id="reportPeriodSubSection02" style="display:none;">
1810                  From<input type="text" onChange="dateOnChange()" size=7 name="fromdate"/>&nbsp;
1811                  To<input type="text" onChange="dateOnChange()" size=7 name="todate" />
1812                </div>
1813              </td>
1814              <td valign="top" class="status" id="displayInterval.status"></td>
1815              <td class="help">
1816                <span id="displayInterval.message" class="message" style="display: none;"></span>
1817                <!--
1818                Define which period the report should cover. Empty fields will include all <text id="items01">items</text>.<br>
1819                -->
1820                <text id="reportPeriodSubSection04HelpText">Parameter help text</text><br>
1821              </td>
1822            </tr> 
1823            <tr>
1824              <td valign="top" class="prompt">
1825                <div id="viewTypeSubSection01" style="display:none;">
1826                  View type
1827                </div>
1828              </td>
1829              <td valign="top" class="input">
1830                <div id="viewTypeSubSection02" style="display:none;">
1831                  <select name="viewtype">
1832                    <option value="AUTO" selected="yes">Auto</option>
1833                    <option value="WEEK">Week</option>
1834                    <option value="MONTH">Month</option>
1835                    <option value="QUARTER">Quarter</option>
1836                    <option value="YEAR">Year</option>
1837                  </select>
1838                </div>
1839              </td>
1840              <td valign="top" class="status" id="displayViewType.status"></td>
1841              <td class="help">
1842                <div id="viewTypeSubSection04" style="display:none;">
1843                  <span id="displayViewType.message" class="message" style="display: none;"></span>
1844                  Auto will adjust the report depending on the size of the period.
1845                  <ul>
1846                    <li>Period shorter than 3 months - <text id="items02">items</text> per week</li>
1847                    <li>Period shorter than 13 months - <text id="items03">items</text> per month</li>
1848                    <li>Period shorter than 3 years - <text id="items04">items</text> per quarter</li>
1849                    <li>Period is 3 years or greater - <text id="items05">items</text> per year</li>
1850                  </ul>                 
1851                </div>
1852              </td>
1853            </tr>
1854            <tr>
1855              <td valign="top" class="prompt">
1856                <div id="sampleTypeSubSection01" style="display:none;">
1857                  Sample type
1858                </div>
1859              </td>
1860              <td valign="top" class="input">
1861                <div id="sampleTypeSubSection02" style="display:none;">
1862                  <select name="sampletype">
1863                    <option value="specimen" selected="yes">Specimen</option>
1864                    <option value="blood">Blood</option>
1865                  </select>
1866                </div>
1867              </td>
1868              <td valign="top" class="status" id="displaySampleType.status"></td>
1869              <td class="help">
1870                <div id="sampleTypeSubSection04" style="display:none;">
1871                  <span id="displaySampleType.message" class="message" style="display: none;"></span>
1872                  Select sample type for report.
1873                </div>
1874              </td>
1875            </tr>
1876            </table>
1877          </td>
1878        </tr>
1879        </table>
1880      </div>
1881     
1882      <div id="reportSection" style="display:none;">
1883        <p></p>
1884        <table border="0" cellspacing="0" cellpadding="0" class="stepform">
1885        <tr>
1886          <td rowspan="3" class="stepno">3</td>
1887          <td class="steptitle">Generated report</td>
1888        </tr>
1889        <tr>
1890          <td id="reportcell" class="stepfields">
1891            <i>Generating report...</i>
1892          </td>
1893        </tr>
1894        </table>
1895      </div> 
1896     
1897      <div class="messagecontainer error" id="errorMessage" style="display: none; width: 950px; margin-left: 20px; margin-bottom: 0px;"></div>   
1898       
1899      <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
1900        <tr>
1901          <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
1902          <td><base:button id="gonext" title="Next" image="<%=home+"/images/gonext.png"%>" onclick="goNext(true)" /></td>
1903          <td><base:button id="gocreate" title="Generate" image="<%=home+"/images/gonext.png"%>" onclick="goCreate()" style="display: none;"/></td>         
1904          <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
1905          <td id="gonext.message" class="message"></td>
1906        </tr>
1907      </table>     
1908    </form>
1909    </div>
1910   
1911  </base:body>
1912  </base:page>
1913  <%
1914}
1915finally
1916{
1917  if (dc != null) dc.close();
1918}
1919%>
Note: See TracBrowser for help on using the repository browser.