Changeset 1772


Ignore:
Timestamp:
Dec 6, 2012, 4:54:45 PM (10 years ago)
Author:
olle
Message:

Fixes #439. First version of missing sample data report added.

Location:
extensions/net.sf.basedb.reggie/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • extensions/net.sf.basedb.reggie/trunk/resources/index.jsp

    r1765 r1772  
    273273            <li>Patient count report</li>
    274274            <li>Overview report</li>
     275            <li>Missing sample data report</li>
    275276            </ul>
    276277          </dd>
  • extensions/net.sf.basedb.reggie/trunk/resources/samplereportgenerator.jsp

    r1766 r1772  
    6565    frm.reporttype.disabled = true;
    6666    // Hide report period input fields
     67    document.getElementById("reportPeriodSubSection01").style.display = 'none';
    6768    document.getElementById("reportPeriodSubSection02").style.display = 'none';
     69    document.getElementById("reportPeriodSubSection04").style.display = 'none';
     70    // Hide view type pop-up menu
     71    document.getElementById("viewTypeSubSection01").style.display = 'none';
     72    document.getElementById("viewTypeSubSection02").style.display = 'none';
     73    document.getElementById("viewTypeSubSection04").style.display = 'none';
    6874    // Hide sample type pop-up menu
    6975    document.getElementById("sampleTypeSubSection01").style.display = 'none';
     
    7379    {
    7480      // Show report period input fields
     81      document.getElementById("reportPeriodSubSection01").style.display = 'block';
     82      document.getElementById("reportPeriodSubSection02").style.display = 'block';
     83      document.getElementById("reportPeriodSubSection04").style.display = 'block';
    7584      document.getElementById("reportPeriodSubSection01Header").innerHTML="Report period";
    76       document.getElementById("reportPeriodSubSection02").style.display = 'block';
    7785      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Define which period the report should cover. Empty fields will include all tubes.";
    7886      // Set item name for report time step text
     
    93101    {
    94102      // Show report period input fields
     103      document.getElementById("reportPeriodSubSection01").style.display = 'block';
     104      document.getElementById("reportPeriodSubSection02").style.display = 'block';
     105      document.getElementById("reportPeriodSubSection04").style.display = 'block';
    95106      document.getElementById("reportPeriodSubSection01Header").innerHTML="Report period";
     107      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Define which period the report should cover. Empty fields will include all consents.";
     108    }
     109    else if (frm.reporttype[frm.reporttype.selectedIndex].value == 'patientcount')
     110    {
     111      // Show report period input fields
     112      document.getElementById("reportPeriodSubSection01").style.display = 'block';
    96113      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
     114      document.getElementById("reportPeriodSubSection04").style.display = 'block';
    106115      document.getElementById("reportPeriodSubSection01Header").innerHTML="Report period";
    107       document.getElementById("reportPeriodSubSection02").style.display = 'block';
    108116      document.getElementById("reportPeriodSubSection04HelpText").innerHTML="Define which period the report should cover. Empty fields will include all patients.";
    109117      // Set item name for report time step text
     
    120128    {
    121129      // Set parameters (report period) help text
     130      document.getElementById("reportPeriodSubSection01").style.display = 'block';
     131      document.getElementById("reportPeriodSubSection04").style.display = 'block';
    122132      document.getElementById("reportPeriodSubSection01Header").innerHTML="No report parameters";
    123133      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';
     134    }
     135    else if (frm.reporttype[frm.reporttype.selectedIndex].value == 'missingsampledatareport')
     136    {
     137      // Show sample type pop-up menu
     138      document.getElementById("sampleTypeSubSection01").style.display = 'block';
     139      document.getElementById("sampleTypeSubSection02").style.display = 'block';
     140      document.getElementById("sampleTypeSubSection04").style.display = 'block';
    128141    }
    129142    Main.show('itemCountSection');
     
    198211      frm.sampletype.disabled = true;
    199212    }
    200     if (reportType == 'patientcount')
     213    else if (reportType == 'patientcount')
    201214    {
    202215      frm.viewtype.disabled = true;
     216    }
     217    else if (reportType == 'missingsampledatareport')
     218    {
     219      frm.sampletype.disabled = true;
    203220    }
    204221    Main.hide('gocreate');
     
    213230      if (frm.sampletype.value != null) url += '&stype='+frm.sampletype.value;
    214231    }
    215     if (reportType == 'patientcount')
     232    else if (reportType == 'patientcount')
    216233    {     
    217234      if (frm.viewtype.value != null) url += '&vtype='+frm.viewtype.value;
     235    }
     236    else if (reportType == 'missingsampledatareport')
     237    {     
     238      if (frm.sampletype.value != null) url += '&stype='+frm.sampletype.value;
    218239    }
    219240   
     
    230251    }
    231252    var report = response.report;
     253    var permissionDeniedForPatientName = report.permissionDeniedForPatientName;
    232254    var reportTable;
    233255   
     
    249271      {     
    250272        reportTable = createOverviewReport(report);
     273      }
     274      else if ('missingsampledatareport' == reportType)
     275      {     
     276        reportTable = createMissingSampleDataReport(report);
    251277      }
    252278    }
     
    333359      summaryList.appendChild(getListElement('Note: Consents of type "Yes" include consents without patient id (PAT#) or date.'));
    334360    }
     361    else if ('missingsampledatareport' == reportType)
     362    {
     363      summaryList.appendChild(getListElement('Note: Patient name is considered missing if either "all first names" or "family name" is missing.'));
     364      if ('true' == permissionDeniedForPatientName)
     365      {
     366        var patientNamePermissionWarningIconWithMessage = document.createElement('img');
     367        patientNamePermissionWarningIconWithMessage.innerHTML = '<img src="images/warning.png"> Sorry, logged-in user does not have permission to check patient names.</img>';
     368        var patientNamePermissionWarningListElement = document.createElement('li');
     369        patientNamePermissionWarningListElement.appendChild(patientNamePermissionWarningIconWithMessage);
     370        summaryList.appendChild(patientNamePermissionWarningListElement);
     371      }
     372    }
    335373    cellElement.appendChild(summaryList);
    336374    if ('consentcount' == reportType)
     
    350388    var psdString = report.periodBeginDate;
    351389    var ldString = report.latestDate;
    352     var startDate = new Date();
    353     startDate.setYear(sdString.substr(0,4));
    354     startDate.setMonth(sdString.substr(4,2)-1);
    355     startDate.setDate(sdString.substr(6));
    356     var endDate = new Date();
    357     endDate.setYear(edString.substr(0,4));
    358     endDate.setMonth(edString.substr(4,2)-1);
    359     endDate.setDate(edString.substr(6));
    360     var periodStartDate = new Date();
    361     periodStartDate.setYear(psdString.substr(0,4));
    362     periodStartDate.setMonth(psdString.substr(4,2)-1);
    363     periodStartDate.setDate(psdString.substr(6));
    364     var latestDate;
    365     if (ldString != null)
    366     {
    367       latestDate = new Date();
    368       latestDate.setYear(ldString.substr(0,4));
    369       latestDate.setMonth(ldString.substr(4,2)-1);
    370       latestDate.setDate(ldString.substr(6));
    371     }   
     390    var startDate = dateStrToDate(sdString);
     391    var endDate = dateStrToDate(edString);
     392    var periodStartDate = dateStrToDate(psdString);
     393    var latestDate = dateStrToDate(ldString);
    372394   
    373395    var viewType = report.viewType;   
     
    379401   
    380402    var headerText = '# Items by ';
     403    var startDateStr = addHyphensToDateString(sdString);
     404    var endDateStr = addHyphensToDateString(edString);
     405    var latestDateStr = addHyphensToDateString(ldString);
    381406    if ('samplecount' == reportType)
    382407    {
     
    438463     
    439464    // Set table header
    440     headerText += ' (between ' + startDate.getFullYear()+'-';
    441     if ((startDate.getMonth()+1) < 10)
    442     {
    443       headerText += '0' + (startDate.getMonth()+1);
    444     }
    445     else
    446     {
    447       headerText += (startDate.getMonth()+1);
    448     }
    449     headerText += '-';
    450     if (startDate.getDate() < 10)
    451     {
    452       headerText += '0' + startDate.getDate();
    453     }
    454     else
    455     {
    456       headerText += startDate.getDate();
    457     }
    458     headerText += ' and ';
    459     headerText += endDate.getFullYear()+'-';
    460     if ((endDate.getMonth()+1) < 10)
    461     {
    462       headerText += '0' + (endDate.getMonth()+1);
    463     }
    464     else
    465     {
    466       headerText += (endDate.getMonth()+1);
    467     }
    468     headerText += '-';
    469     if (endDate.getDate() < 10)
    470     {
    471       headerText += '0' + endDate.getDate();
    472     }
    473     else
    474     {
    475       headerText += endDate.getDate();
    476     }
    477     headerText += ')';
     465    headerText += ' (between ' + startDateStr + ' and ' + endDateStr + ')';
    478466    if (latestDate != null)
    479467    {
    480       headerText += '\nLast registration ' + latestDate.getFullYear();
    481       headerText += '-';
    482       if ((latestDate.getMonth()+1) < 10)
    483       {
    484         headerText += '0';
    485       }
    486       headerText += (latestDate.getMonth()+1);
    487       headerText += '-';
    488       if (latestDate.getDate()<10)
    489       {
    490         headerText += '0';
    491       }
    492       headerText += latestDate.getDate();
     468      headerText += '\nLast registration ' + latestDateStr;
    493469    }   
    494470    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+5)));
     
    562538    var sdString = report.beginDate;
    563539    var edString = report.endDate;
    564 /*
    565     var psdString = report.periodBeginDate;
    566 */
    567540    var ldString = report.latestDate;
    568     var startDate = new Date();
    569     startDate.setYear(sdString.substr(0,4));
    570     startDate.setMonth(sdString.substr(4,2)-1);
    571     startDate.setDate(sdString.substr(6));
    572     var endDate = new Date();
    573     endDate.setYear(edString.substr(0,4));
    574     endDate.setMonth(edString.substr(4,2)-1);
    575     endDate.setDate(edString.substr(6));
    576 /*
    577     var periodStartDate = new Date();
    578     periodStartDate.setYear(psdString.substr(0,4));
    579     periodStartDate.setMonth(psdString.substr(4,2)-1);
    580     periodStartDate.setDate(psdString.substr(6));
    581 */
    582     var latestDate;
    583     if (ldString != null)
    584     {
    585       latestDate = new Date();
    586       latestDate.setYear(ldString.substr(0,4));
    587       latestDate.setMonth(ldString.substr(4,2)-1);
    588       latestDate.setDate(ldString.substr(6));
    589     }   
    590 
    591 /*   
    592     var viewType = report.viewType;
    593 */ 
    594  
     541    var startDate = dateStrToDate(sdString);
     542    var endDate = dateStrToDate(edString);
     543    var latestDate = dateStrToDate(ldString);
     544
    595545    var headerRow = document.createElement('tr');   
    596546    var subHeaderRow = document.createElement('tr');
     
    760710    var edString = report.endDate;
    761711    var ldString = report.latestDate;
    762     var startDate = new Date();
    763     startDate.setYear(sdString.substr(0,4));
    764     startDate.setMonth(sdString.substr(4,2)-1);
    765     startDate.setDate(sdString.substr(6));
    766     var endDate = new Date();
    767     endDate.setYear(edString.substr(0,4));
    768     endDate.setMonth(edString.substr(4,2)-1);
    769     endDate.setDate(edString.substr(6));
    770     var latestDate;
    771     if (ldString != null)
    772     {
    773       latestDate = new Date();
    774       latestDate.setYear(ldString.substr(0,4));
    775       latestDate.setMonth(ldString.substr(4,2)-1);
    776       latestDate.setDate(ldString.substr(6));
    777     }   
     712    var startDate = dateStrToDate(sdString);
     713    var endDate = dateStrToDate(edString);
     714    var latestDate = dateStrToDate(ldString);
    778715 
    779716    var headerRow = document.createElement('tr');   
     
    866803    var edString = report.endDate;
    867804    var ldString = report.latestDate;
    868     var startDate = new Date();
    869     startDate.setYear(sdString.substr(0,4));
    870     startDate.setMonth(sdString.substr(4,2)-1);
    871     startDate.setDate(sdString.substr(6));
    872 /*
    873     var endDate = new Date();
    874     endDate.setYear(edString.substr(0,4));
    875     endDate.setMonth(edString.substr(4,2)-1);
    876     endDate.setDate(edString.substr(6));
    877 */
    878     var latestDate;
    879     if (ldString != null)
    880     {
    881       latestDate = new Date();
    882       latestDate.setYear(ldString.substr(0,4));
    883       latestDate.setMonth(ldString.substr(4,2)-1);
    884       latestDate.setDate(ldString.substr(6));
    885     }   
     805    var startDate = dateStrToDate(sdString);
     806    var endDate = dateStrToDate(edString);
    886807 
    887808    var headerRow = document.createElement('tr');   
     
    996917  }
    997918 
    998   function addHyphensToDateString(yyyymmddStr)
    999   {
    1000     var dateWithHyphensStr = '????-??-??';
    1001     if (yyyymmddStr != null)
    1002     {
    1003       var yyyyStr = yyyymmddStr.substr(0,4);
    1004       var mmStr   = yyyymmddStr.substr(4,2);
    1005       var ddStr = yyyymmddStr.substr(6);
    1006       dateWithHyphensStr = yyyyStr + '-' + mmStr + '-' + ddStr;
    1007     }
    1008     return dateWithHyphensStr;
    1009   }
    1010 
     919  function createMissingSampleDataReport(report)
     920  {
     921    var reportTable = getReportTable();
     922    var sdString = report.beginDate;
     923    var edString = report.endDate;
     924    var ldString = report.latestDate;
     925    var startDate = dateStrToDate(sdString);
     926    var endDate = dateStrToDate(edString);
     927    var latestDate = dateStrToDate(ldString);
     928
     929    var sampleType = report.sampleType;
     930    var permissionDeniedForPatientName = report.permissionDeniedForPatientName;
     931
     932    var headerRow = document.createElement('tr');   
     933    var subHeaderRow = document.createElement('tr');
     934    var subHeader2Row = document.createElement('tr');
     935    var columnHeaderRow = document.createElement('tr');
     936   
     937    var numCols = 5;
     938    if (sampleType == 'specimen')
     939    {
     940      numCols = 5;
     941    }
     942    else if (sampleType == 'nospecimen')
     943    {
     944      numCols = 2;
     945    }
     946    else if (sampleType == 'blood')
     947    {
     948      numCols = 3;
     949    }
     950    var numDecimals = 0;
     951    var headerText = 'Number of missing specimen items of different kinds';
     952    if ('nospecimen' == sampleType)
     953    {
     954      headerText = 'Number of missing "no specimen" items of different kinds';
     955    }
     956    else if ('blood' == sampleType)
     957    {
     958      headerText = 'Number of missing blood sample items of different kinds';
     959    }
     960    var startDateStr = addHyphensToDateString(sdString);
     961    var endDateStr = addHyphensToDateString(edString);
     962    var latestDateStr = addHyphensToDateString(ldString);
     963    headerText += ' (betweeen ' + startDateStr + ' and ' + endDateStr + ')';
     964    if (latestDate != null)
     965    {
     966        headerText += '\nLast registration ' + latestDateStr;
     967    }
     968    headerRow.appendChild(getTableCellElement(headerText, 'reportheader', (numCols+3)));
     969   
     970    // Subheader
     971    subHeaderRow.appendChild(getTableCellElement('', 'reportsubheader', 3));
     972   
     973    subHeaderRow.appendChild(getTableCellElement('Patient', 'reportsubheader'));
     974    if (sampleType == 'specimen')
     975    {
     976      subHeaderRow.appendChild(getTableCellElement('PAD', 'reportsubheader'));
     977      subHeaderRow.appendChild(getTableCellElement('Laterality', 'reportsubheader'));
     978      subHeaderRow.appendChild(getTableCellElement('Sampling', 'reportsubheader'));
     979      subHeaderRow.appendChild(getTableCellElement('RNALater', 'reportsubheader'));
     980    }
     981    else if (sampleType == 'nospecimen')
     982    {
     983      subHeaderRow.appendChild(getTableCellElement('Sampling', 'reportsubheader'));
     984    }
     985    else if (sampleType == 'blood')
     986    {
     987      subHeaderRow.appendChild(getTableCellElement('Blood sampling', 'reportsubheader'));
     988      subHeaderRow.appendChild(getTableCellElement('Blood freezer', 'reportsubheader'));
     989    }
     990
     991    // Columnsheader   
     992    var siteHeader = getTableCellElement('Site', 'reportsubheader');     
     993    var startDateHeader = getTableCellElement('Start date','reportsubheader');
     994    var latestDateHeader = getTableCellElement('Latest date','reportsubheader');
     995    columnHeaderRow.appendChild(siteHeader);
     996    columnHeaderRow.appendChild(startDateHeader);
     997    columnHeaderRow.appendChild(latestDateHeader); 
     998   
     999    columnHeaderRow.appendChild(getTableCellElement('name', 'reportsubheader'));
     1000    if (sampleType == 'specimen')
     1001    {
     1002      columnHeaderRow.appendChild(getTableCellElement('reference', 'reportsubheader'));
     1003      columnHeaderRow.appendChild(getTableCellElement('', 'reportsubheader'));
     1004      columnHeaderRow.appendChild(getTableCellElement('date', 'reportsubheader'));
     1005      columnHeaderRow.appendChild(getTableCellElement('date', 'reportsubheader'));
     1006    }
     1007    else if (sampleType == 'nospecimen')
     1008    {
     1009      columnHeaderRow.appendChild(getTableCellElement('date', 'reportsubheader'));
     1010    }
     1011    else if (sampleType == 'blood')
     1012    {
     1013      columnHeaderRow.appendChild(getTableCellElement('date', 'reportsubheader'));
     1014      columnHeaderRow.appendChild(getTableCellElement('date', 'reportsubheader'));
     1015    }
     1016
     1017    // Build table     
     1018    reportTable.appendChild(headerRow);
     1019    reportTable.appendChild(subHeaderRow);
     1020    reportTable.appendChild(columnHeaderRow);
     1021         
     1022    // Data rows     
     1023    addDataRowsToMissingSampleDataTable(report, reportTable);
     1024     
     1025    // Add a row with the combined numbers for all sites for each period
     1026    var sitesCombinedRow = document.createElement('tr');
     1027    sitesCombinedRow.appendChild(getTableCellElement('Sites combined', 'colsummary'));
     1028    sitesCombinedRow.appendChild(getTableCellElement('', 'colsummary', 2));
     1029    // Get combined numbers for all sites for each period
     1030    var noDateKey = 'noDate';
     1031    var sumKey = 'sumKey';
     1032    var statistics = report.statistics;
     1033    var sitesCombined = statistics.sitesCombinedKey;
     1034    if (sitesCombined != null)
     1035    {
     1036      if ('false' == permissionDeniedForPatientName)
     1037      {
     1038        data = getJSONData(sitesCombined, 'missingPatientName');
     1039        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
     1040      }
     1041      else
     1042      {
     1043        data = '-';
     1044        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
     1045      }
     1046      if (sampleType == 'specimen')
     1047      {
     1048        data = getJSONData(sitesCombined, 'missingPadReference');
     1049        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
     1050        data = getJSONData(sitesCombined, 'missingLaterality');
     1051        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
     1052        data = getJSONData(sitesCombined, 'missingSamplingDateTime');
     1053        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
     1054        data = getJSONData(sitesCombined, 'missingRnaLaterDateTime');
     1055        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
     1056      }
     1057      else if (sampleType == 'nospecimen')
     1058      {
     1059        data = getJSONData(sitesCombined, 'missingSamplingDateTime');
     1060        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
     1061      }
     1062      else if (sampleType == 'blood')
     1063      {
     1064        data = getJSONData(sitesCombined, 'missingBloodSamplingDateTime');
     1065        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
     1066        data = getJSONData(sitesCombined, 'missingBloodFreezerDateTime');
     1067        sitesCombinedRow.appendChild(getTableCellElement(data, 'colsummary'));
     1068      }
     1069    }
     1070    reportTable.appendChild(sitesCombinedRow); 
     1071
     1072    return reportTable;
     1073  }
     1074 
    10111075  function createConsentTablePatientsWithMultipleDates(report)
    10121076  {
     
    10901154      if (!sites.hasOwnProperty(namePrefix)) continue;       
    10911155      var site = sites[namePrefix];
    1092       var siteName = site.name;       
    1093       var year = site.startDate.substr(0,4);
    1094       var month = site.startDate.substr(5,2);
    1095       var date = site.startDate.substr(8,2);     
    1096       var siteStartDate = new Date(year, month-1, date);
     1156      var siteName = site.name;
     1157      var siteStartDate = dateStrToDate(site.startDate);
     1158      var siteStartDateStr = addHyphensToDateString(site.startDate);
    10971159     
    10981160      var siteData = statistics[namePrefix];     
    10991161      var siteLatestDate = siteData['latestDateKey'];
    1100       var siteLatestDateYear = siteLatestDate.substr(0,4);
    1101       var siteLatestDateMonth = siteLatestDate.substr(4,2);
    1102       var siteLatestDateDate = siteLatestDate.substr(6,2);
    1103       var siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
     1162      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
    11041163      var tableRow = document.createElement('tr');
    11051164      var tableCol = getTableCellElement(siteName, 'rowtitle');
    11061165      tableRow.appendChild(tableCol);
    1107       tableRow.appendChild(getTableCellElement(year+'-'+(month)+'-'+date, 'reportdata'));
     1166      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
     1167      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
     1168      var noDateKey = 'noDate';
     1169      var sumKey = 'sumKey';
     1170      var totalKey = 'totalKey';
     1171      if (siteData != null)
     1172      {
     1173        data = getJSONDataWithPercent(siteData, 'yesPatient', sumKey, numDecimals);
     1174        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1175        data = getJSONDataWithPercent(siteData, 'yesNoPatient', sumKey, numDecimals);
     1176        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1177        data = getJSONDataWithPercent(siteData, 'no', sumKey, numDecimals);
     1178        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1179        data = getJSONDataWithPercent(siteData, 'notAsked', sumKey, numDecimals);
     1180        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1181        data = getJSONDataWithPercent(siteData, noDateKey, sumKey, numDecimals);
     1182        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1183        // Add column with summed values for site
     1184        var siteSum = getJSONData(siteData, sumKey, 0);
     1185        tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
     1186      }
     1187      // Add column with total number of samples for site, regardless of creation date
     1188      var siteTotal = getJSONData(siteData, totalKey, 0);
     1189      tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
     1190      reportTable.appendChild(tableRow);
     1191    }
     1192  }
     1193
     1194  function addDataRowsToConsentTableUnknownDate(report, reportTable, numDecimals)
     1195  {
     1196    var sites = report.sites;   
     1197    var statistics = report.statistics;
     1198    unknownCreation = statistics.noDate;
     1199    unknownSite = statistics.unknownSite;
     1200    var siteOrderList = report.siteOrderListKey;
     1201    for (var siteOrderIndex in siteOrderList)
     1202    {
     1203      var namePrefix = siteOrderList[siteOrderIndex];   
     1204      if (!sites.hasOwnProperty(namePrefix)) continue;       
     1205      var site = sites[namePrefix];
     1206      var siteName = site.name;
     1207      var siteStartDate = dateStrToDate(site.startDate);
     1208      var siteStartDateStr = addHyphensToDateString(site.startDate);
     1209     
     1210      var siteData = statistics[namePrefix];     
     1211      var siteLatestDate = siteData['latestDateKey'];
     1212      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
     1213      var tableRow = document.createElement('tr');
     1214      var tableCol = getTableCellElement(siteName, 'rowtitle');
     1215      tableRow.appendChild(tableCol);
     1216      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
     1217      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
     1218      var noDateKey = 'noDate';
     1219      var sumKey = 'sumKey';
     1220      var totalKey = 'totalKey';
     1221      if (siteData != null)
     1222      {
     1223        data = getJSONDataWithPercent(siteData, 'yesNoDate', sumKey, numDecimals);
     1224        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1225        data = getJSONDataWithPercent(siteData, 'noNoDate', sumKey, numDecimals);
     1226        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1227        data = getJSONDataWithPercent(siteData, 'notAskedNoDate', sumKey, numDecimals);
     1228        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1229        data = getJSONDataWithPercent(siteData, 'missing', sumKey, numDecimals);
     1230        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1231        // Add column with summed values for site
     1232        var siteSum = getJSONData(siteData, noDateKey, 0);
     1233        tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
     1234      }
     1235      // Add column with total number of samples for site, regardless of creation date
     1236      var siteTotal = getJSONData(siteData, totalKey, 0);
     1237      tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
     1238      reportTable.appendChild(tableRow);
     1239    }
     1240  }
     1241
     1242  function addDataRowsToOverviewTable(report, reportTable)
     1243  {
     1244    var sites = report.sites;   
     1245    var statistics = report.statistics;
     1246    unknownCreation = statistics.noDate;
     1247    unknownSite = statistics.unknownSite;
     1248    var siteOrderList = report.siteOrderListKey;
     1249    for (var siteOrderIndex in siteOrderList)
     1250    {
     1251      var namePrefix = siteOrderList[siteOrderIndex];   
     1252      if (!sites.hasOwnProperty(namePrefix)) continue;       
     1253      var site = sites[namePrefix];
     1254      var siteName = site.name;       
     1255      var siteStartDate = dateStrToDate(site.startDate);
     1256      var siteStartDateStr = addHyphensToDateString(site.startDate);
     1257     
     1258      var siteData = statistics[namePrefix];     
     1259      var siteLatestDate = siteData['latestDateKey'];
     1260      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
     1261      var tableRow = document.createElement('tr');
     1262      var tableCol = getTableCellElement(siteName, 'rowtitle');
     1263      tableRow.appendChild(tableCol);
     1264      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
     1265      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
     1266      var noDateKey = 'noDate';
     1267      var sumKey = 'sumKey';
     1268      var totalKey = 'totalKey';
     1269      if (siteData != null)
     1270      {
     1271        data = getJSONData(siteData, 'patient');
     1272        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1273        data = getJSONData(siteData, 'bloodSample');
     1274        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1275        data = getJSONData(siteData, 'specimen');
     1276        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1277        data = getJSONData(siteData, 'noSpecimen');
     1278        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1279        data = getJSONData(siteData, 'consentYes');
     1280        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1281        data = getJSONData(siteData, 'consentMissing');
     1282        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1283      }
     1284      reportTable.appendChild(tableRow);
     1285    }
     1286  }
     1287
     1288  function addDataRowsToOverviewPatientDetailedTable(report, reportTable)
     1289  {
     1290    var sites = report.sites;   
     1291    var statistics = report.statistics;
     1292    unknownCreation = statistics.noDate;
     1293    unknownSite = statistics.unknownSite;
     1294    var siteOrderList = report.siteOrderListKey;
     1295    for (var siteOrderIndex in siteOrderList)
     1296    {
     1297      var namePrefix = siteOrderList[siteOrderIndex];   
     1298      if (!sites.hasOwnProperty(namePrefix)) continue;       
     1299      var site = sites[namePrefix];
     1300      var siteName = site.name;       
     1301      var siteStartDate = dateStrToDate(site.startDate);
     1302      var siteStartDateStr = addHyphensToDateString(site.startDate);
     1303     
     1304      var siteData = statistics[namePrefix];
     1305/*   
     1306      var siteLatestDate = siteData['latestDateKey'];
     1307      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
     1308*/
     1309      var tableRow = document.createElement('tr');
     1310      var tableCol = getTableCellElement(siteName, 'rowtitle');
     1311      tableRow.appendChild(tableCol);
     1312      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
     1313/*
     1314      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
     1315*/
     1316      var noDateKey = 'noDate';
     1317      var sumKey = 'sumKey';
     1318      var totalKey = 'totalKey';
     1319      if (siteData != null)
     1320      {
     1321        data = getJSONData(siteData, 'patientBloodSampleOnly');
     1322        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1323        data = getJSONData(siteData, 'patientSpecimenOnly');
     1324        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1325        data = getJSONData(siteData, 'patientNoSpecimenOnly');
     1326        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1327        data = getJSONData(siteData, 'patientBloodSampleAndSpecimen');
     1328        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1329        data = getJSONData(siteData, 'patientBloodSampleAndNoSpecimen');
     1330        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1331        data = getJSONData(siteData, 'patientSpecimenAndNoSpecimen');
     1332        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1333        data = getJSONData(siteData, 'patientBloodSampleAndSpecimenAndNoSpecimen');
     1334        tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1335        //data = getJSONData(siteData, 'patientNoSamples');
     1336        //tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1337        data = getJSONData(siteData, 'sumKey');
     1338        tableRow.appendChild(getTableCellElement(data, 'rowsummary'));
     1339      }
     1340      reportTable.appendChild(tableRow);
     1341    }
     1342  }
     1343
     1344  function addDataRowsToMissingSampleDataTable(report, reportTable)
     1345  {
     1346    var sites = report.sites;   
     1347    var statistics = report.statistics;
     1348    var sampleType = report.sampleType;
     1349    var permissionDeniedForPatientName = report.permissionDeniedForPatientName;
     1350    var unknownCreation = statistics.noDate;
     1351    var unknownSite = statistics.unknownSite;
     1352    var siteOrderList = report.siteOrderListKey;
     1353    for (var siteOrderIndex in siteOrderList)
     1354    {
     1355      var namePrefix = siteOrderList[siteOrderIndex];   
     1356      if (!sites.hasOwnProperty(namePrefix)) continue;       
     1357      var site = sites[namePrefix];
     1358      var siteName = site.name;
     1359      var siteStartDate = dateStrToDate(site.startDate);
     1360      var siteStartDateStr = addHyphensToDateString(site.startDate);
     1361     
     1362      var siteData = statistics[namePrefix];     
     1363      var siteLatestDate = siteData['latestDateKey'];
     1364      var siteLatestDateStr = addHyphensToDateString(siteLatestDate);
     1365      var tableRow = document.createElement('tr');
     1366      var tableCol = getTableCellElement(siteName, 'rowtitle');
     1367      tableRow.appendChild(tableCol);
     1368      tableRow.appendChild(getTableCellElement(siteStartDateStr, 'reportdata'));
    11081369      tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
    11091370      //var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
     
    11131374      if (siteData != null)
    11141375      {
    1115         data = getJSONDataWithPercent(siteData, 'yesPatient', sumKey, numDecimals);
    1116         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1117         data = getJSONDataWithPercent(siteData, 'yesNoPatient', sumKey, numDecimals);
    1118         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1119         data = getJSONDataWithPercent(siteData, 'no', sumKey, numDecimals);
    1120         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1121         data = getJSONDataWithPercent(siteData, 'notAsked', sumKey, numDecimals);
    1122         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1123         data = getJSONDataWithPercent(siteData, noDateKey, sumKey, numDecimals);
    1124         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1125         // Add column with summed values for site
    1126         var siteSum = getJSONData(siteData, sumKey, 0);
    1127         tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
    1128       }
    1129       // Add column with total number of samples for site, regardless of creation date
    1130       var siteTotal = getJSONData(siteData, totalKey, 0);
    1131       tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
    1132       reportTable.appendChild(tableRow);
    1133     }
    1134   }
    1135 
    1136   function addDataRowsToConsentTableUnknownDate(report, reportTable, numDecimals)
    1137   {
    1138     var sites = report.sites;   
    1139     var statistics = report.statistics;
    1140     unknownCreation = statistics.noDate;
    1141     unknownSite = statistics.unknownSite;
    1142     var siteOrderList = report.siteOrderListKey;
    1143     for (var siteOrderIndex in siteOrderList)
    1144     {
    1145       var namePrefix = siteOrderList[siteOrderIndex];   
    1146       if (!sites.hasOwnProperty(namePrefix)) continue;       
    1147       var site = sites[namePrefix];
    1148       var siteName = site.name;
    1149       var year = site.startDate.substr(0,4);
    1150       var month = site.startDate.substr(5,2);
    1151       var date = site.startDate.substr(8,2);     
    1152       var siteStartDate = new Date(year, month-1, date);
    1153      
    1154       var siteData = statistics[namePrefix];     
    1155       var siteLatestDate = siteData['latestDateKey'];
    1156       var siteLatestDateYear = siteLatestDate.substr(0,4);
    1157       var siteLatestDateMonth = siteLatestDate.substr(4,2);
    1158       var siteLatestDateDate = siteLatestDate.substr(6,2);
    1159       var siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
    1160       var tableRow = document.createElement('tr');
    1161       var tableCol = getTableCellElement(siteName, 'rowtitle');
    1162       tableRow.appendChild(tableCol);
    1163       tableRow.appendChild(getTableCellElement(year+'-'+(month)+'-'+date, 'reportdata'));
    1164       tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
    1165       //var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
    1166       var noDateKey = 'noDate';
    1167       var sumKey = 'sumKey';
    1168       var totalKey = 'totalKey';
    1169       if (siteData != null)
    1170       {
    1171         data = getJSONDataWithPercent(siteData, 'yesNoDate', sumKey, numDecimals);
    1172         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1173         data = getJSONDataWithPercent(siteData, 'noNoDate', sumKey, numDecimals);
    1174         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1175         data = getJSONDataWithPercent(siteData, 'notAskedNoDate', sumKey, numDecimals);
    1176         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1177         data = getJSONDataWithPercent(siteData, 'missing', sumKey, numDecimals);
    1178         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1179         // Add column with summed values for site
    1180         var siteSum = getJSONData(siteData, noDateKey, 0);
    1181         tableRow.appendChild(getTableCellElement(siteSum, 'rowsummary'));
    1182       }
    1183       // Add column with total number of samples for site, regardless of creation date
    1184       var siteTotal = getJSONData(siteData, totalKey, 0);
    1185       tableRow.appendChild(getTableCellElement(siteTotal, 'rowsummary'));
    1186       reportTable.appendChild(tableRow);
    1187     }
    1188   }
    1189 
    1190   function addDataRowsToOverviewTable(report, reportTable)
    1191   {
    1192     var sites = report.sites;   
    1193     var statistics = report.statistics;
    1194     unknownCreation = statistics.noDate;
    1195     unknownSite = statistics.unknownSite;
    1196     var siteOrderList = report.siteOrderListKey;
    1197     for (var siteOrderIndex in siteOrderList)
    1198     {
    1199       var namePrefix = siteOrderList[siteOrderIndex];   
    1200       if (!sites.hasOwnProperty(namePrefix)) continue;       
    1201       var site = sites[namePrefix];
    1202       var siteName = site.name;       
    1203       var year = site.startDate.substr(0,4);
    1204       var month = site.startDate.substr(5,2);
    1205       var date = site.startDate.substr(8,2);     
    1206       var siteStartDate = new Date(year, month-1, date);
    1207      
    1208       var siteData = statistics[namePrefix];     
    1209       var siteLatestDate = siteData['latestDateKey'];
    1210       var siteLatestDateYear = siteLatestDate.substr(0,4);
    1211       var siteLatestDateMonth = siteLatestDate.substr(4,2);
    1212       var siteLatestDateDate = siteLatestDate.substr(6,2);
    1213       var siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
    1214       var tableRow = document.createElement('tr');
    1215       var tableCol = getTableCellElement(siteName, 'rowtitle');
    1216       tableRow.appendChild(tableCol);
    1217       tableRow.appendChild(getTableCellElement(year+'-'+(month)+'-'+date, 'reportdata'));
    1218       tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
    1219       //var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
    1220       var noDateKey = 'noDate';
    1221       var sumKey = 'sumKey';
    1222       var totalKey = 'totalKey';
    1223       if (siteData != null)
    1224       {
    1225         data = getJSONData(siteData, 'patient');
    1226         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1227         data = getJSONData(siteData, 'bloodSample');
    1228         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1229         data = getJSONData(siteData, 'specimen');
    1230         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1231         data = getJSONData(siteData, 'noSpecimen');
    1232         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1233         data = getJSONData(siteData, 'consentYes');
    1234         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1235         data = getJSONData(siteData, 'consentMissing');
    1236         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1237       }
    1238       reportTable.appendChild(tableRow);
    1239     }
    1240   }
    1241 
    1242   function addDataRowsToOverviewPatientDetailedTable(report, reportTable)
    1243   {
    1244     var sites = report.sites;   
    1245     var statistics = report.statistics;
    1246     unknownCreation = statistics.noDate;
    1247     unknownSite = statistics.unknownSite;
    1248     var siteOrderList = report.siteOrderListKey;
    1249     for (var siteOrderIndex in siteOrderList)
    1250     {
    1251       var namePrefix = siteOrderList[siteOrderIndex];   
    1252       if (!sites.hasOwnProperty(namePrefix)) continue;       
    1253       var site = sites[namePrefix];
    1254       var siteName = site.name;       
    1255       var year = site.startDate.substr(0,4);
    1256       var month = site.startDate.substr(5,2);
    1257       var date = site.startDate.substr(8,2);     
    1258       var siteStartDate = new Date(year, month-1, date);
    1259      
    1260       var siteData = statistics[namePrefix];
    1261 /*   
    1262       var siteLatestDate = siteData['latestDateKey'];
    1263       var siteLatestDateYear = siteLatestDate.substr(0,4);
    1264       var siteLatestDateMonth = siteLatestDate.substr(4,2);
    1265       var siteLatestDateDate = siteLatestDate.substr(6,2);
    1266       var siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
    1267 */
    1268       var tableRow = document.createElement('tr');
    1269       var tableCol = getTableCellElement(siteName, 'rowtitle');
    1270       tableRow.appendChild(tableCol);
    1271       tableRow.appendChild(getTableCellElement(year+'-'+(month)+'-'+date, 'reportdata'));
    1272 /*
    1273       tableRow.appendChild(getTableCellElement(siteLatestDateStr, 'reportdata'));
    1274 */
    1275       //var currentDate = new Date(periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate());     
    1276       var noDateKey = 'noDate';
    1277       var sumKey = 'sumKey';
    1278       var totalKey = 'totalKey';
    1279       if (siteData != null)
    1280       {
    1281         data = getJSONData(siteData, 'patientBloodSampleOnly');
    1282         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1283         data = getJSONData(siteData, 'patientSpecimenOnly');
    1284         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1285         data = getJSONData(siteData, 'patientNoSpecimenOnly');
    1286         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1287         data = getJSONData(siteData, 'patientBloodSampleAndSpecimen');
    1288         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1289         data = getJSONData(siteData, 'patientBloodSampleAndNoSpecimen');
    1290         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1291         data = getJSONData(siteData, 'patientSpecimenAndNoSpecimen');
    1292         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1293         data = getJSONData(siteData, 'patientBloodSampleAndSpecimenAndNoSpecimen');
    1294         tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1295         //data = getJSONData(siteData, 'patientNoSamples');
    1296         //tableRow.appendChild(getTableCellElement(data, 'reportdata'));
    1297         data = getJSONData(siteData, 'sumKey');
    1298         tableRow.appendChild(getTableCellElement(data, 'rowsummary'));
     1376        if ('false' == permissionDeniedForPatientName)
     1377        {
     1378          data = getJSONData(siteData, 'missingPatientName');
     1379          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1380        }
     1381        else
     1382        {
     1383          data = '-';
     1384          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1385        }
     1386        if (sampleType == 'specimen')
     1387        {
     1388          data = getJSONData(siteData, 'missingPadReference');
     1389          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1390          data = getJSONData(siteData, 'missingLaterality');
     1391          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1392          data = getJSONData(siteData, 'missingSamplingDateTime');
     1393          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1394          data = getJSONData(siteData, 'missingRnaLaterDateTime');
     1395          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1396        }
     1397        else if (sampleType == 'nospecimen')
     1398        {
     1399          data = getJSONData(siteData, 'missingSamplingDateTime');
     1400          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1401        }
     1402        else if (sampleType == 'blood')
     1403        {
     1404          data = getJSONData(siteData, 'missingBloodSamplingDateTime');
     1405          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1406          data = getJSONData(siteData, 'missingBloodFreezerDateTime');
     1407          tableRow.appendChild(getTableCellElement(data, 'reportdata'));
     1408        }
    12991409      }
    13001410      reportTable.appendChild(tableRow);
     
    15331643        siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
    15341644      }
    1535 /*
    1536       var siteLatestDateYear = siteLatestDate.substr(0,4);
    1537       var siteLatestDateMonth = siteLatestDate.substr(4,2);
    1538       var siteLatestDateDate = siteLatestDate.substr(6,2);
    1539       var siteLatestDateStr = siteLatestDateYear + '-' + siteLatestDateMonth + '-' + siteLatestDateDate;
    1540 */
    15411645      var tableRow = document.createElement('tr');
    15421646      var tableCol = getTableCellElement(siteName, 'rowtitle');
     
    17271831  }
    17281832
     1833  /**
     1834   *  addHyphensToDateStr()
     1835   *
     1836   *  Adds hyphens to date string in yyyymmdd format to
     1837   *  get yyyy-mm-dd format. If input string already contains
     1838   *  hyphen(s), the input string is returned unchanged.
     1839   *  If input string is null or empty, '????-??-??' is returned.
     1840   *
     1841   *  @param dateStr String Input date string in yyyy-mm-dd or yyyymmdd format.
     1842   *  @return String Date string in yyyy-mm-dd format.
     1843   */
     1844  function addHyphensToDateString(dateStr)
     1845  {
     1846    var dateWithHyphensStr = '????-??-??';
     1847    if (dateStr != null && dateStr != '')
     1848    {
     1849      // Check if input string already contains hyphen
     1850      if (dateStr.indexOf("-") >= 0)
     1851      {
     1852        // Date already has hyphen(s)
     1853        dateWithHyphensStr = dateStr;
     1854      }
     1855      else
     1856      {
     1857        // Date in yyyymmdd format
     1858        var yearStr = dateStr.substr(0,4);
     1859        var monthStr = dateStr.substr(4,2);
     1860        var dayStr = dateStr.substr(6,2);     
     1861        dateWithHyphensStr = yearStr + '-' + monthStr + '-' + dayStr;
     1862      }
     1863    }
     1864    return dateWithHyphensStr;
     1865  }
     1866
     1867  /**
     1868   *  dateStrToDate()
     1869   *
     1870   *  Takes an input date string in yyyy-mm-dd or yyyymmdd format
     1871   *  and returns a date corresponding to the date string.
     1872   *  If input string is null or empty, null is returned.
     1873   *
     1874   *  @param dateStr String Input date string in yyyy-mm-dd or yyyymmdd format.
     1875   *  @return Date Date corresponding to input date string.
     1876   */
     1877  function dateStrToDate(dateStr)
     1878  {
     1879    var date = null;
     1880    if (dateStr != null && dateStr != '')
     1881    {
     1882      // Check if input string already contains hyphen
     1883      if (dateStr.indexOf("-") >= 0)
     1884      {
     1885        // Date in yyyy-mm-dd format
     1886        var yearStr = dateStr.substr(0,4);
     1887        var monthStr = dateStr.substr(5,2);
     1888        var dayStr = dateStr.substr(8,2);     
     1889        var date = new Date(parseInt(yearStr, 10), parseInt(monthStr, 10)-1, parseInt(dayStr, 10));
     1890      }
     1891      else
     1892      {
     1893        // Date in yyyymmdd format
     1894        var yearStr = dateStr.substr(0,4);
     1895        var monthStr = dateStr.substr(4,2);
     1896        var dayStr = dateStr.substr(6,2);     
     1897        var date = new Date(parseInt(yearStr, 10), parseInt(monthStr, 10)-1, parseInt(dayStr, 10));
     1898      }
     1899    }
     1900    return date;
     1901  }
     1902
    17291903  /*
    1730    * Get the ISO week number for a given date
     1904   *  Get the ISO week number for a given date
    17311905   *
    1732    * Based on code at http://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php
     1906   *  Based on code at http://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php
     1907   *
     1908   *  @param date String Input date to get ISO week number for.
     1909   *  @return int ISO week number for input date.
    17331910   */
    17341911  function getISOWeekNumber(date)
     
    17861963                <option value="patientcount">Patient count report</option>
    17871964                <option value="overviewreport">Overview report</option>
     1965                <option value="missingsampledatareport">Missing sample data report</option>
    17881966              </select>
    17891967            </td>
     
    18121990            <tr>
    18131991              <td valign="top" class="prompt">
    1814                 <text id="reportPeriodSubSection01Header">Report period</text>
     1992                <div id="reportPeriodSubSection01" style="display:none;">
     1993                  <text id="reportPeriodSubSection01Header">Report period</text>
     1994                </div>
    18151995              </td>
    18161996              <td valign="top" class="input">
     
    18222002              <td valign="top" class="status" id="displayInterval.status"></td>
    18232003              <td class="help">
    1824                 <span id="displayInterval.message" class="message" style="display: none;"></span>
    1825                 <!--
    1826                 Define which period the report should cover. Empty fields will include all <text id="items01">items</text>.<br>
    1827                 -->
    1828                 <text id="reportPeriodSubSection04HelpText">Parameter help text</text><br>
     2004                <div id="reportPeriodSubSection04" style="display:none;">
     2005                  <span id="displayInterval.message" class="message" style="display: none;"></span>
     2006                  <!--
     2007                  Define which period the report should cover. Empty fields will include all <text id="items01">items</text>.<br>
     2008                  -->
     2009                  <text id="reportPeriodSubSection04HelpText">Parameter help text</text><br>
     2010                </div>
    18292011              </td>
    18302012            </tr>
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/SampleReportServlet.java

    r1766 r1772  
    2727import net.sf.basedb.core.ItemSubtype;
    2828import net.sf.basedb.core.MeasuredBioMaterial;
     29import net.sf.basedb.core.PermissionDeniedException;
    2930import net.sf.basedb.core.Sample;
    3031import net.sf.basedb.core.SessionControl;
     
    223224
    224225        json = createOverviewReport(dc, json, startDate, endDate);
     226      }
     227      else if ("missingsampledatareport".equals(cmd))
     228      {
     229        String startDateParameter = Values.getString(req.getParameter("fdate"), null);
     230        String endDateParameter = Values.getString(req.getParameter("tdate"), null);
     231
     232        Date startDate = Reggie.CONVERTER_STRING_TO_DATE.convert(startDateParameter);
     233        Date endDate = Reggie.CONVERTER_STRING_TO_DATE.convert(endDateParameter);
     234       
     235        if (startDate == null)
     236        {
     237          // Get the when the first site started
     238          for (Site s : Site.getAllSites())
     239          {
     240            Date siteDate = Reggie.CONVERTER_STRING_TO_DATE.convert(s.getStartDate().replaceAll("-", ""));
     241            if (siteDate != null && (startDate == null || startDate.after(siteDate)))
     242            {
     243              startDate = siteDate;           
     244            }
     245          }
     246        }
     247        if (endDate == null)
     248        {
     249          // Get the date for today
     250          endDate = new Date();
     251        }
     252
     253        String sampleType = "specimen";
     254        String sampleTypeParameter = Values.getString(req.getParameter("stype"), null);
     255        if (sampleTypeParameter != null)
     256        {
     257          sampleType = sampleTypeParameter;
     258        }
     259
     260        json = createMissingSampleDataReport(dc, json, startDate, endDate, sampleType);
    225261      }
    226262    }
     
    10921128  }
    10931129
     1130  @SuppressWarnings({ "unchecked", "rawtypes" })
     1131  private JSONObject createMissingSampleDataReport(DbControl dc, JSONObject json, Date startDate, Date endDate, String sampleType)
     1132      throws ServletException, IOException
     1133  {
     1134    JSONObject jsonReport = new JSONObject();
     1135    jsonReport.put("sites", getJSONSites());
     1136   
     1137    ItemQuery<Sample> sampleQuery = Sample.getQuery();
     1138    sampleQuery.joinPermanent(Hql.innerJoin(null, "creationEvent", "ce", true));
     1139    // Select what sample subtype to include in database search
     1140    if (sampleType.equals("nospecimen"))
     1141    {
     1142      Subtype.NO_SPECIMEN.addFilter(dc, sampleQuery);
     1143    }
     1144    else if (sampleType.equals("blood"))
     1145    {
     1146      Subtype.BLOOD.addFilter(dc, sampleQuery);
     1147    }
     1148    else
     1149    {
     1150      Subtype.SPECIMEN.addFilter(dc, sampleQuery);
     1151    }
     1152    sampleQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
     1153    sampleQuery.order(Orders.asc(Hql.property("name")));
     1154    sampleQuery.order(Orders.asc(Hql.property("ce", "eventDate")));
     1155    sampleQuery.setCacheResult(true);
     1156    ItemResultIterator<Sample> sampleIterator = sampleQuery.iterate(dc);       
     1157    // Use stored annotation snapshots for performance reasons
     1158    SnapshotManager manager = new SnapshotManager();       
     1159
     1160    JSONObject jsonStatistics = new JSONObject();
     1161    JSONObject jsonSitesCombined = new JSONObject();
     1162    String missingPatientNameKey = "missingPatientName";
     1163    String missingPadReferenceKey = "missingPadReference";
     1164    String missingLateralityKey = "missingLaterality";
     1165    String missingSamplingDateTimeKey = "missingSamplingDateTime";
     1166    String missingRnaLaterDateTimeKey = "missingRnaLaterDateTime";
     1167    String missingBloodSamplingDateTimeKey = "missingBloodSamplingDateTime";
     1168    String missingBloodFreezerDateTimeKey = "missingBloodFreezerDateTime";
     1169    String permissionDeniedForPatientNameKey = "permissionDeniedForPatientName";
     1170    String sitesCombinedKey = "sitesCombinedKey";
     1171    String sumKey = "sumKey";
     1172    String latestDateKey = "latestDateKey";
     1173    String duplicateKey = "duplicateKey";
     1174    jsonStatistics.put(sitesCombinedKey, jsonSitesCombined);
     1175    // Initialize site data to 0 for the different keys
     1176    jsonStatistics = initializeJSONSiteData(jsonStatistics, missingPatientNameKey);
     1177    jsonStatistics = initializeJSONSiteData(jsonStatistics, missingPadReferenceKey);
     1178    jsonStatistics = initializeJSONSiteData(jsonStatistics, missingLateralityKey);
     1179    jsonStatistics = initializeJSONSiteData(jsonStatistics, missingSamplingDateTimeKey);
     1180    jsonStatistics = initializeJSONSiteData(jsonStatistics, missingRnaLaterDateTimeKey);
     1181    jsonStatistics = initializeJSONSiteData(jsonStatistics, missingBloodSamplingDateTimeKey);
     1182    jsonStatistics = initializeJSONSiteData(jsonStatistics, missingBloodFreezerDateTimeKey);
     1183    // Initialize combined data to 0 for the different keys
     1184    jsonSitesCombined.put(missingPatientNameKey, 0);
     1185    jsonSitesCombined.put(missingPadReferenceKey, 0);
     1186    jsonSitesCombined.put(missingLateralityKey, 0);
     1187    jsonSitesCombined.put(missingSamplingDateTimeKey, 0);
     1188    jsonSitesCombined.put(missingRnaLaterDateTimeKey, 0);
     1189    jsonSitesCombined.put(missingBloodSamplingDateTimeKey, 0);
     1190    jsonSitesCombined.put(missingBloodFreezerDateTimeKey, 0);
     1191    // Initialize other data to 0 for different keys
     1192    jsonStatistics.put(duplicateKey, 0);
     1193    Date latestDate = null;
     1194    // Create HashMap to keep track of latest item date for each site
     1195    HashMap<String, Date> sitePrefixDateHashMap = new HashMap<String, Date>();
     1196    // Get item subtype constants for later use
     1197    ItemSubtype subtypeSpecimen = Subtype.SPECIMEN.load(dc);
     1198    ItemSubtype subtypeNoSpecimen = Subtype.NO_SPECIMEN.load(dc);
     1199    ItemSubtype subtypeBlood = Subtype.BLOOD.load(dc);
     1200    Boolean permissionDeniedForPatientName = false;
     1201    //
     1202    while (sampleIterator != null && sampleIterator.hasNext())
     1203    {
     1204      Sample s = sampleIterator.next();
     1205      BioMaterialEvent creationEvent = s.getCreationEvent();
     1206      Date creationDate = creationEvent.getEventDate();
     1207
     1208      // Find patient id
     1209      BioMaterial patient = null;
     1210      if (s.getItemSubtype().equals(subtypeBlood))
     1211      {
     1212        // The parent is the 'Patient' for blood samples and cases
     1213        patient = s.getParent();
     1214      }
     1215      else if (s.getItemSubtype().equals(subtypeSpecimen) || s.getItemSubtype().equals(subtypeNoSpecimen))
     1216      {
     1217        // The grandparent is the 'Patient' for specimens and no specimens
     1218        MeasuredBioMaterial parent = (MeasuredBioMaterial) s.getParent();
     1219        if (parent != null)
     1220        {
     1221          patient = parent.getParent();
     1222        }
     1223      }
     1224
     1225      // Initialize sample data
     1226      String allFirstNames = null;
     1227      String familyName = null;
     1228      String pad = null;
     1229      String laterality = null;
     1230      Date samplingDate = null;
     1231      Date rnaLaterDate = null;
     1232      Date bloodSamplingDate = null;
     1233      Date bloodFreezerDate = null;
     1234
     1235      if (patient != null)
     1236      {
     1237        try
     1238        {
     1239          // Get patient all first names
     1240          allFirstNames = (String) Annotationtype.ALL_FIRST_NAMES.getAnnotationValue(dc, manager, patient);
     1241          // Get patient family name
     1242          familyName = (String) Annotationtype.FAMILY_NAME.getAnnotationValue(dc, manager, patient);
     1243        }
     1244        catch (PermissionDeniedException e)
     1245        {
     1246          permissionDeniedForPatientName = true;
     1247        }
     1248      }
     1249      if (sampleType.equals("specimen"))
     1250      {
     1251        // Get PAD reference
     1252        pad = (String) Annotationtype.PAD.getAnnotationValue(dc, manager, s);
     1253        // Get laterality
     1254        laterality = (String) Annotationtype.LATERALITY.getAnnotationValue(dc, manager, s);
     1255        // Get sampling date
     1256        samplingDate = (Date) Annotationtype.SAMPLING_DATETIME.getAnnotationValue(dc, manager, s);
     1257        // Get RNALater date
     1258        rnaLaterDate = (Date) Annotationtype.RNALATER_DATETIME.getAnnotationValue(dc, manager, s);
     1259      }
     1260      else if (sampleType.equals("nospecimen"))
     1261      {
     1262        // Get sampling date
     1263        samplingDate = (Date) Annotationtype.SAMPLING_DATETIME.getAnnotationValue(dc, manager, s);
     1264      }
     1265      else if (sampleType.equals("blood"))
     1266      {
     1267        // Get blood sampling date
     1268        bloodSamplingDate = (Date) Annotationtype.BLOOD_SAMPLING_DATETIME.getAnnotationValue(dc, manager, s);
     1269        // Get blood freezer date
     1270        bloodFreezerDate = (Date) Annotationtype.BLOOD_FREEZER_DATETIME.getAnnotationValue(dc, manager, s);
     1271      }
     1272      // Update statistics for sample type
     1273      Site site = Site.findByCaseName(s.getName());
     1274      if (site == Site.UNKNOWN)
     1275      {
     1276        String key = "unknownSite";
     1277        jsonStatistics = updateJSONObjectCounter(jsonStatistics, key);
     1278      }
     1279      else
     1280      {
     1281        // Get site info           
     1282        JSONObject jsonSite = (JSONObject)jsonStatistics.get(site.getPrefix());
     1283        if (jsonSite == null)
     1284        {
     1285          jsonSite = new JSONObject();
     1286          jsonStatistics.put(site.getPrefix(), jsonSite);
     1287        }
     1288
     1289        if (patient != null)
     1290        {
     1291          // Update missing first names data and family name data
     1292          if (allFirstNames == null || allFirstNames.equals("")
     1293              || familyName == null || familyName.equals(""))
     1294          {
     1295            // Update missing patient name data, provided the user has permission to check it
     1296            if (!permissionDeniedForPatientName)
     1297            {
     1298              jsonSite = updateJSONObjectCounter(jsonSite, missingPatientNameKey);
     1299              jsonSitesCombined = updateJSONObjectCounter(jsonSitesCombined, missingPatientNameKey);
     1300            }
     1301          }
     1302        }
     1303        if (sampleType.equals("specimen"))
     1304        {
     1305          // Update missing PAD reference data
     1306          if (pad == null || pad.equals(""))
     1307          {
     1308            jsonSite = updateJSONObjectCounter(jsonSite, missingPadReferenceKey);
     1309            jsonSitesCombined = updateJSONObjectCounter(jsonSitesCombined, missingPadReferenceKey);
     1310          }
     1311          // Update missing laterality data
     1312          if (laterality == null || laterality.equals(""))
     1313          {
     1314            jsonSite = updateJSONObjectCounter(jsonSite, missingLateralityKey);
     1315            jsonSitesCombined = updateJSONObjectCounter(jsonSitesCombined, missingLateralityKey);
     1316          }
     1317          // Update missing sampling date data
     1318          if (samplingDate == null)
     1319          {
     1320            jsonSite = updateJSONObjectCounter(jsonSite, missingSamplingDateTimeKey);
     1321            jsonSitesCombined = updateJSONObjectCounter(jsonSitesCombined, missingSamplingDateTimeKey);
     1322          }
     1323          // Update missing RNALater date data
     1324          if (rnaLaterDate == null)
     1325          {
     1326            jsonSite = updateJSONObjectCounter(jsonSite, missingRnaLaterDateTimeKey);
     1327            jsonSitesCombined = updateJSONObjectCounter(jsonSitesCombined, missingRnaLaterDateTimeKey);
     1328          }
     1329        }
     1330        else if (sampleType.equals("nospecimen"))
     1331        {
     1332          // Update missing sampling date data
     1333          if (samplingDate == null)
     1334          {
     1335            jsonSite = updateJSONObjectCounter(jsonSite, missingSamplingDateTimeKey);
     1336            jsonSitesCombined = updateJSONObjectCounter(jsonSitesCombined, missingSamplingDateTimeKey);
     1337          }
     1338        }
     1339        else if (sampleType.equals("blood"))
     1340        {
     1341          // Update missing blood sampling date data
     1342          if (bloodSamplingDate == null)
     1343          {
     1344            jsonSite = updateJSONObjectCounter(jsonSite, missingBloodSamplingDateTimeKey);
     1345            jsonSitesCombined = updateJSONObjectCounter(jsonSitesCombined, missingBloodSamplingDateTimeKey);
     1346          }
     1347          // Update missing blood freezer date data
     1348          if (bloodFreezerDate == null)
     1349          {
     1350            jsonSite = updateJSONObjectCounter(jsonSite, missingBloodFreezerDateTimeKey);
     1351            jsonSitesCombined = updateJSONObjectCounter(jsonSitesCombined, missingBloodFreezerDateTimeKey);
     1352          }
     1353        }
     1354
     1355        // Keep track of latest item date for site
     1356        if (creationDate != null)
     1357        {
     1358          Date siteLatestDate = sitePrefixDateHashMap.get(site.getPrefix());
     1359          if (siteLatestDate == null || siteLatestDate.before(creationDate))
     1360          {
     1361            sitePrefixDateHashMap.put(site.getPrefix(), creationDate);
     1362          }
     1363          // Keep track of latest item date so far
     1364          if (latestDate == null || latestDate.before(creationDate))
     1365          {
     1366            latestDate = creationDate;
     1367          }
     1368        }
     1369      }
     1370    }
     1371    // Add latest item date for site to site JSON object
     1372    DateToStringConverter date2StringConverter = Reggie.CONVERTER_DATE_TO_STRING;
     1373    for (Site s: Site.getAllSites())
     1374    {
     1375      JSONObject jsonSite = (JSONObject) jsonStatistics.get(s.getPrefix());
     1376      if (jsonSite == null)
     1377      {
     1378        jsonSite = new JSONObject();
     1379        jsonStatistics.put(s.getPrefix(), jsonSite);
     1380      }
     1381      Date siteLatestDate = sitePrefixDateHashMap.get(s.getPrefix());
     1382      jsonSite.put(latestDateKey, date2StringConverter.convert(siteLatestDate));
     1383    }
     1384    // Add latest date for further transfer to other JSON object
     1385    jsonStatistics.put(latestDateKey, date2StringConverter.convert(latestDate));
     1386    //
     1387    jsonReport.put("statistics", jsonStatistics);       
     1388    jsonReport.put("sampleType", sampleType);
     1389    jsonReport.put("beginDate", date2StringConverter.convert(startDate));
     1390    jsonReport.put("endDate", date2StringConverter.convert(endDate));
     1391    // Transfer latest date from jsonStatistics to jsonReport
     1392    String latestDateStr = (String) jsonStatistics.get("latestDateKey");
     1393    jsonReport.put("latestDate", latestDateStr);
     1394    jsonReport.put(permissionDeniedForPatientNameKey, permissionDeniedForPatientName.toString());
     1395    String siteOrder = alphabeticalOrder;
     1396    JSONObject jsonSiteOrderList = createJSONSiteOrderList(siteOrder);
     1397    jsonReport.put("siteOrderListKey", jsonSiteOrderList);
     1398    json.put("report", jsonReport);
     1399    return json;
     1400  }
     1401
    10941402  private Boolean inStringDateSetHashMap(HashMap<String, Set<Date>> stringDateSetHashMap, String string, Date date)
    10951403  {
Note: See TracChangeset for help on using the changeset viewer.