[Ils-source] r1529 - in trunk: src/com/resolutions/ils/data webapp

scribe at crosswire.org scribe at crosswire.org
Thu Mar 23 19:39:13 MST 2017


Author: scribe
Date: 2017-03-23 19:39:12 -0700 (Thu, 23 Mar 2017)
New Revision: 1529

Added:
   trunk/webapp/genbackcerts.jsp
Modified:
   trunk/src/com/resolutions/ils/data/CourseAttempt.java
   trunk/src/com/resolutions/ils/data/UserProfile.java
   trunk/webapp/report_employeecourseatt.jsp
Log:
Fixed report display bugs when user has no courses assigned
Added genbackcerts to ils


Modified: trunk/src/com/resolutions/ils/data/CourseAttempt.java
===================================================================
--- trunk/src/com/resolutions/ils/data/CourseAttempt.java	2017-02-15 01:16:28 UTC (rev 1528)
+++ trunk/src/com/resolutions/ils/data/CourseAttempt.java	2017-03-24 02:39:12 UTC (rev 1529)
@@ -360,13 +360,77 @@
 	public void passAllAssociatedCurriculum(ILSSession session, HttpServletRequest request) {
 		passAllAssociatedCurriculum(session, request, null);
 	}
+
+	public static CourseAttempt makeCurriculumCourseAttemptIfPassed(ILSSession session, int userProfileID, Course cur, Set<Integer> limitToCASIDs) {
+		boolean isPassed = false;
+		Vector<Course> courses = cur.getCurriculumCourses();
+		if (courses != null) {
+			// if so, then let's check if all courses are passed
+			int  timeframe   = 0;
+			long startDate   = 0;
+			long endDate     = 0;
+			int  score       = 0;
+			int  courseCount = 0;
+
+			for (Course c : courses) {
+				isPassed = false;
+
+				timeframe += c.getCourseSeatMinutes();
+				Vector<CourseAttempt> cas = CourseAttempt.getUserCourseAttempts(session, userProfileID, c.getCourseID(), limitToCASIDs != null);
+				if (cas != null) {
+					for (CourseAttempt ca : cas) {
+						if (limitToCASIDs != null && !limitToCASIDs.contains(ca.getCourseAttemptID())) continue;
+						Date d = ca.getCourseAttemptStartDate();
+						startDate = (d != null && (startDate == 0 || startDate > d.getTime())) ? d.getTime() : startDate;
+						d = ca.getCourseAttemptCompleteDate();
+						endDate = (d != null && (endDate == 0 || endDate < d.getTime())) ? d.getTime() : endDate;
+
+						boolean finished = !c.isCourseRequiresManagerApproval() || ca.isCourseAttemptManagerApproved();
+						if (finished && ca.getCourseAttemptStatusID() == STATUS_PASSED) {
+							int s = ca.getCourseAttemptScore();
+							if (s > -1) {
+								++courseCount;
+								score += s;
+							}
+							isPassed = true;
+logger.info("course is passed: " + c.getCourseName());
+							break;
+						}
+					}
+				}
+				if (!isPassed) {
+					break;
+				}
+			}
+			// if we have a curriculum of which our course is a member and all courses in this curriculum are passed,
+			// then create a passed course attempt for this curriculum
+			if (isPassed) {
+
+				if (courseCount != 0) score /= courseCount;
+
+				CourseAttempt ca = new CourseAttempt();
+				ca.defaultAll();
+				ca.setCourseAttemptStartDate(new Date(startDate));
+				ca.setCourseAttemptCompleteDate(new Date(endDate));
+				ca.setCourseAttemptCourseID(cur.getCourseID());
+				ca.setCourseAttemptUserProfileID(userProfileID);
+				ca.setCourseAttemptStatusID(ca.STATUS_PASSED);
+				ca.setCourseAttemptScore(score);
+
+				// TODO: timeframe?
+
+				return ca;
+			}
+		}
+		return null;
+	}
+
 	public void passAllAssociatedCurriculum(ILSSession session, HttpServletRequest request, String forcePassReason) {
 		Collection<Course> curs = Course.getUserCurricula(session, getCourseAttemptUserProfileID());
 		if (curs != null) {
 			// find all curricula our user is assigned and check each one
 			for (Course cur : curs) {
 
-				boolean isPassed = false;
 				Vector<Course> courses = cur.getCurriculumCourses();
 				if (courses != null) {
 					// is this course a member of the tested curriculum?
@@ -386,67 +450,25 @@
 					int  courseCount = 0;
 
 					if (isPertinent) {
-						for (Course c : courses) {
-							isPassed = false;
+						CourseAttempt ca = makeCurriculumCourseAttemptIfPassed(session, getCourseAttemptUserProfileID(), cur, null);
+						// if we have a curriculum of which our course is a member and all courses in this curriculum are passed,
+						// then create a passed course attempt for this curriculum
+						if (ca != null) {
+							if (forcePassReason != null) ca.setCourseAttemptForcePass(forcePassReason);
+							ca = ca.saveNew(session);
+logger.info("passing curriulum: " + cur.getCourseName());
 
-							timeframe += c.getCourseSeatMinutes();
-							Vector<CourseAttempt> cas = CourseAttempt.getUserCourseAttempts(session, getCourseAttemptUserProfileID(), c.getCourseID(), false);
-							if (cas != null) {
-								for (CourseAttempt ca : cas) {
-									Date d = ca.getCourseAttemptStartDate();
-									startDate = (d != null && (startDate == 0 || startDate > d.getTime())) ? d.getTime() : startDate;
-									d = ca.getCourseAttemptCompleteDate();
-									endDate = (d != null && (endDate == 0 || endDate < d.getTime())) ? d.getTime() : endDate;
-
-									boolean finished = !c.isCourseRequiresManagerApproval() || ca.isCourseAttemptManagerApproved();
-									if (finished && ca.getCourseAttemptStatusID() == STATUS_PASSED) {
-										int s = ca.getCourseAttemptScore();
-										if (s > -1) {
-											++courseCount;
-											score += s;
-										}
-										isPassed = true;
-logger.info("course is passed: " + c.getCourseName());
-										break;
-									}
+							// render certificate
+							if (cur.isCourseCertificateStore()) {
+								try {
+									ca.saveCertificate(ca.generateCertificate(session, request));
 								}
+								catch (Exception e) {
+									logger.error(e, e);
+								}
 							}
-							if (!isPassed) {
-								break;
-							}
 						}
 					}
-					// if we have a curriculum of which our course is a member and all courses in this curriculum are passed,
-					// then create a passed course attempt for this curriculum
-					if (isPertinent && isPassed) {
-
-						if (courseCount != 0) score /= courseCount;
-
-						CourseAttempt ca = new CourseAttempt();
-						ca.defaultAll();
-						if (forcePassReason != null) ca.setCourseAttemptForcePass(forcePassReason);
-						ca.setCourseAttemptStartDate(new Date(startDate));
-						ca.setCourseAttemptCompleteDate(new Date(endDate));
-						ca.setCourseAttemptCourseID(cur.getCourseID());
-						ca.setCourseAttemptUserProfileID(getCourseAttemptUserProfileID());
-						ca.setCourseAttemptStatusID(ca.STATUS_PASSED);
-						ca.setCourseAttemptScore(score);
-
-						// TODO: timeframe?
-
-						ca = ca.saveNew(session);
-logger.info("passing curriulum: " + cur.getCourseName());
-
-						// render certificate
-						if (cur.isCourseCertificateStore()) {
-							try {
-								ca.saveCertificate(ca.generateCertificate(session, request));
-							}
-							catch (Exception e) {
-								logger.error(e, e);
-							}
-						}
-					}
 				}
 			}
 		}
@@ -1070,6 +1092,9 @@
 	}
 
 	public byte[] generateCertificate(ILSSession ilsSession, HttpServletRequest request) throws Exception {
+		return generateCertificate(ilsSession, request, null);
+	}
+	public byte[] generateCertificate(ILSSession ilsSession, HttpServletRequest request, Set<Integer> limitToCAIDs) throws Exception {
 
 
 		Course c = Course.getCourse(ilsSession, getCourseAttemptCourseID());
@@ -1104,6 +1129,7 @@
 		urlString += "?ca=" + getCourseAttemptID();
 		urlString += "&c=" + c.getCourseID();
 		urlString += "&up=" + getCourseAttemptUserProfileID();
+		if (limitToCAIDs != null) urlString += "&caids="+CourseAttempt.join(",", limitToCAIDs);
 
 		if (!urlString.startsWith("http:") &&
 				!urlString.startsWith("ftp:") &&
@@ -1248,4 +1274,15 @@
 		return data;
 	}
 
+	public static String join(String delimeter, Collection items) {
+		if (items == null || items.size() == 0) return "";
+
+		StringBuilder sb = new StringBuilder();
+		for (Object o: items) {
+			if (sb.length() > 0) sb.append(delimeter);
+			sb.append(o.toString());
+		}
+		return sb.toString();
+	}
+
 }

Modified: trunk/src/com/resolutions/ils/data/UserProfile.java
===================================================================
--- trunk/src/com/resolutions/ils/data/UserProfile.java	2017-02-15 01:16:28 UTC (rev 1528)
+++ trunk/src/com/resolutions/ils/data/UserProfile.java	2017-03-24 02:39:12 UTC (rev 1529)
@@ -319,7 +319,7 @@
 	" (SELECT MAX(GROUPNAME) FROM USERGROUP UG JOIN ILSGROUP IG ON UG.ILSGROUPID=IG.ILSGROUPID AND UG.USERPRID=U.USERPRID AND GROUPTYPEID=2) WORKGROUP, " +
 	" (SELECT MAX(GROUPNAME) FROM USERGROUP UG JOIN ILSGROUP IG ON UG.ILSGROUPID=IG.ILSGROUPID AND UG.USERPRID=U.USERPRID AND GROUPTYPEID=1) ROLE, " +
 	" SUM(COALESCE(CA.CRS_COMPLETED, 0)) COURSESCOMPLETED, " +
-	" SUM(COALESCE(CA.CRS_OPEN, 1)) AS COURSESOPEN, " +
+	" CASE WHEN not exists (select 1 from USERCOURSEASSIGNMENTS T2 where T2.COMPANYID=U.COMPANYID AND T2.USERPRID=U.USERPRID) THEN 0 ELSE SUM(COALESCE(CA.CRS_OPEN, 1)) END AS COURSESOPEN, " +
 	" SUM(COALESCE(CA.CRS_FAILED, 0)) COURSESFAILED, " +
 	" MAX(CA.CACOMPLETEDATE) COURSESLASTATTEMPT " +
 	" FROM USERPROFILE  U" +

Added: trunk/webapp/genbackcerts.jsp
===================================================================
--- trunk/webapp/genbackcerts.jsp	                        (rev 0)
+++ trunk/webapp/genbackcerts.jsp	2017-03-24 02:39:12 UTC (rev 1529)
@@ -0,0 +1,768 @@
+<%@ page
+    language="java"
+    contentType="text/html;charset=utf-8"
+%>
+<%@ page import="com.resolutions.ils.*" %>
+<%@ page import="com.resolutions.ils.data.*" %>
+<%@ page import="java.io.File" %>
+<%@ page import="java.io.StringWriter" %>
+<%@ page import="java.net.URL" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+<%@ page import="org.apache.log4j.Logger" %>
+<%@ page import="java.util.*" %>
+
+<%!
+	class Pair<A, B> {
+		A a;
+		B b;
+		public Pair(A a, B b) {
+			this.a = a;
+			this.b = b;
+		}
+		public A getKey() { return a; }
+		public B getValue() { return b; }
+	}
+%>
+
+<%
+    ILSSession ilsSession = (ILSSession)session.getAttribute("ilsSession");
+    if (ilsSession == null) {
+        out.print("<html><head><META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;URL=login.jsp\"></head></html>");
+        return;
+    }
+    Vector<UserProfile> userProfiles = (Vector<UserProfile>)session.getAttribute("lastDataset");
+
+    UserProfile user    = ilsSession.getCurrentUserProfile();
+
+    boolean managing    = true;
+    String action	= request.getParameter("action");
+	if (managing && "removeCert".equals(action) && (user.getUserProfileAccessLevel() > UserProfile.ACCESS_MANAGER || user.hasAccess(UserProfile.ACCESS_MODE_STUDENTREC_PASS_OVERRIDE))) {
+		if (CourseAttempt.deleteCourseAttempt(ilsSession, Integer.parseInt(request.getParameter("caid"))) > 0) {
+			out.print("Deleted");
+		}
+		else	out.print("Failed to delete.");
+		return;
+	}
+	if (managing && "genBackCert".equals(action) && (user.getUserProfileAccessLevel() > UserProfile.ACCESS_MANAGER || user.hasAccess(UserProfile.ACCESS_MODE_STUDENTREC_PASS_OVERRIDE))) {
+		String userProfileIDString = request.getParameter("userProfileID");
+		String genCurID = request.getParameter("genCurID");
+		String genCAIDs = request.getParameter("genCAIDs");
+logger.info("genbackcert: " + userProfileIDString + ", " + genCurID + ", " + genCAIDs);
+		int curID = -1; try { curID = Integer.parseInt(genCurID); } catch (Exception e) {}
+		int userProfileID = -1; try { userProfileID = Integer.parseInt(userProfileIDString); } catch (Exception e) {}
+    		Course cur = Course.getCourse(ilsSession, curID);
+		Set<Integer> caids = new HashSet<Integer>();
+		for (String caid : genCAIDs.split(",")) {
+			try { caids.add(Integer.parseInt(caid)); } catch (Exception e) {}
+		}
+		CourseAttempt ca = CourseAttempt.makeCurriculumCourseAttemptIfPassed(ilsSession, userProfileID, cur, caids);
+		// if we have a curriculum of which our course is a member and all courses in this curriculum are passed,
+		// then create a passed course attempt for this curriculum
+		if (ca != null) {
+			ca = ca.saveNew(ilsSession);
+logger.info("passing curriulum: " + cur.getCourseName());
+
+			// render certificate
+			if (cur.isCourseCertificateStore()) {
+				try {
+					ca.saveCertificate(ca.generateCertificate(ilsSession, request, caids));
+				}
+				catch (Exception e) {
+					logger.error(e, e);
+				}
+			}
+//logger.info("cur.getCoursePassExpireDays(): " + cur.getCoursePassExpireDays());
+//logger.info("ca.getCourseAttemptCompleteDate(): " + ca.getCourseAttemptCompleteDate());
+			if (cur.getCoursePassExpireDays() > 0) {
+				Date expireOn = new Date(ca.getCourseAttemptCompleteDate().getTime() + (1000L * 60 * 60 * 24 * cur.getCoursePassExpireDays()));
+//logger.info("expireOn: " + expireOn);
+				if (expireOn.getTime() < new Date().getTime()) {
+					CourseAttempt ca2 = (CourseAttempt)ca.clone();
+					ca2.setCourseAttemptExpired("Recurrent Training Assigned");
+					ca2.setTSValue("CAEXPIREDON", expireOn);
+					ca2.save(ca);
+				}
+			}
+		}
+		out.print("Generated");
+		return;
+	}
+%>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><%= ilsSession.getCurrentCompany().getCompanyName() %> eLearning Portal</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link href="lms_style.css" rel="stylesheet" type="text/css">
+
+</head>
+<body>
+
+<%@ include file="header.jsp" %>
+
+<script type="text/javascript">
+var rcid=0;
+function retake(inCID) {
+	rcid=inCID;
+	inputBox('Please Type the Reason For Re-take', 3, 80, 3, 'retakeComplete');
+}
+
+function retakeComplete(resultObject) {
+	$.blockUI({ message: '<h3><img width=&quot;30&quot; height=&quot;30&quot; style=&quot;margin-right:10px;vertical-align:middle;&quot; src=&quot;images/loading.gif&quot;/> Generating Report...</h3>' });
+	reason = resultObject.value;
+	document.getElementById('revokeCID').value=rcid;
+	if (reason.length > 0) reason = reason + ' / ';
+	document.getElementById('revokeReason').value=reason + 'Retake Assigned';
+	document.revokeForm.submit();
+}
+
+var pcid=0;
+var pcourseid=0;
+function forcePass(inCID, inCourseID) {
+	pcid=inCID;
+	pcourseid=inCourseID;
+	inputBox('Please Type the Reason For Forcing Pass', 3, 80, 3, 'forcePassComplete');
+}
+
+function forcePassComplete(resultObject) {
+	$.blockUI({ message: '<h3><img width=&quot;30&quot; height=&quot;30&quot; style=&quot;margin-right:10px;vertical-align:middle;&quot; src=&quot;images/loading.gif&quot;/> Generating Report...</h3>' });
+	reason = resultObject.value;
+	document.getElementById('passCID').value=pcid;
+	document.getElementById('passCourseID').value=pcourseid;
+	if (reason.length > 0) reason = reason + ' / ';
+	document.getElementById('passReason').value=reason + 'Pass Forced';
+	document.forcePassForm.submit();
+}
+
+function genAllCerts(userProfileID) {
+	var i = 0;
+	while (true) {
+		++i;
+		if (!$('#cert_'+userProfileID+'_'+i).length) break;
+		$('#cert_'+userProfileID+'_'+i).children('a').trigger('click');
+	}
+}
+
+function removeCert(caid) {
+	var data = {
+		caid : caid,
+		action   : 'removeCert'
+	}
+	$('#ca_'+caid).html('<img height="18" src="images/loading.gif"/> Deleting...');
+	$.post('genbackcerts.jsp', data, function(result) {
+		$('#ca_'+caid).html('<b>'+result+'</b>');
+	}, 'text');
+}
+
+function genCert(userProfileID, curID, caids, count, needsForce) {
+	if (needsForce) return;
+	//$.blockUI({ message: '<h3><img width="30" height="30" style="margin-right:10px;vertical-align:middle;" src="images/loading.gif"/> Generating Back Cert...</h3>' });
+	var data = {
+		userProfileID : userProfileID,
+		genCurID : curID,
+		genCAIDs : caids,
+		action   : 'genBackCert'
+	}
+	$('#cert_'+userProfileID+'_'+count).html('<img height="18" src="images/loading.gif"/> Generating...');
+	$.post('genbackcerts.jsp', data, function(result) {
+		$('#cert_'+userProfileID+'_'+count).html('<b>'+result+'</b>');
+	}, 'text');
+}
+
+function toggleCourseDetails(courseID) {
+	if ($('.subCourseID_'+courseID+':first').is(":visible")) {
+		$('#courseHeader_'+courseID).html('+');
+		$('.subCourseID_'+courseID).hide();
+	}
+	else {
+		$('#courseHeader_'+courseID).html('&ndash;');
+		$('.subCourseID_'+courseID).show();
+	}
+}
+function toggleCurriculumDetails(courseID) {
+	if ($('.subCurriculumID_'+courseID+':first').is(":visible")) {
+		$('#curriculumHeader_'+courseID).html('˄<br>˅');
+		$('.subCurriculumID_'+courseID).hide();
+		$('.historyDetail').hide();
+		$('.courseHeader').html('+');
+	}
+	else {
+		$('#curriculumHeader_'+courseID).html('˅<br>˄');
+		$('.subCurriculumID_'+courseID).show();
+		$('.historyDetail').hide();
+		$('.courseHeader').html('+');
+	}
+}
+
+$(document).ready(function() {
+//	$('.historyDetail').hide();
+//	$('.subCourseHeaderRow').hide();
+});
+
+
+</script>
+
+  <div id="pageContainer">
+<%@ include file="menu.jsp" %>
+<div id="content">
+<div id="pageTitles">Reports </div>
+
+
+<%!
+	static SimpleDateFormat df  = new SimpleDateFormat("MM/dd/yyyy");
+	static Logger logger = Logger.getLogger("report/employee/course/attempt");
+%>
+<%
+	for (UserProfile current: userProfiles) {
+logger.info("**** " + current.getUserProfileLastName() + ", " + current.getUserProfileFirstName());
+
+    int profileID       = current.getUserProfileID();
+	int count = 0;
+    
+
+	Vector<Course> courses       = Course.getAllUserCourses(ilsSession, current.getUserProfileID());
+	int wordNum = 0;
+
+	Collection<Course> curricula = Course.getUserCurricula(ilsSession, current.getUserProfileID());
+
+	// map all courses to their parent curriculum
+	HashMap<Integer, Integer> courseCurriculum = new HashMap<Integer, Integer>();
+	HashMap<Integer, Boolean> courseSupressRetake = new HashMap<Integer, Boolean>();
+	HashMap<Integer, Course> curriculaList = new HashMap<Integer, Course>();
+	HashMap<Integer, HashSet<CourseAttempt>> courseCourseAttempts = new HashMap<Integer, HashSet<CourseAttempt>>();
+
+	Map<Course, List<List<Pair<Course, CourseAttempt>>>> curriculaEval = new HashMap<Course, List<List<Pair<Course, CourseAttempt>>>>();
+	for (Course cur : curricula) {
+		List<List<Pair<Course, CourseAttempt>>> associated = new ArrayList<List<Pair<Course, CourseAttempt>>>();
+		Set<Integer> usedCourses = new HashSet<Integer>();
+logger.info("CUR: (" + cur.getCourseNum() + " : " + cur.getCourseID() + ") " + cur.getCourseName());
+		curriculaList.put(cur.getCourseID(), cur);
+		boolean passed = true;
+		boolean missed = false;
+		while (passed) {
+			List<Pair<Course, CourseAttempt>> associatedCourseAttempts = new ArrayList<Pair<Course, CourseAttempt>>();
+			passed = false;
+			for (Course c : Course.getCurriculumCourses(ilsSession, cur.getCourseID())) {
+logger.debug(" - COURSE: (" + c.getCourseNum() + " : " + c.getCourseID() + ") " + c.getCourseName());
+				Vector<CourseAttempt> cas = CourseAttempt.getUserCourseAttempts(ilsSession, current.getUserProfileID(), c.getCourseID());
+
+    java.util.Collections.sort(cas, new Comparator<CourseAttempt>() {
+        public int compare(CourseAttempt o1, CourseAttempt o2) {
+                Date d1 = o1.getCourseAttemptCompleteDate();
+                if (d1 == null) d1 = o1.getCourseAttemptStartDate();
+                Date d2 = o2.getCourseAttemptCompleteDate();
+                if (d2 == null) d2 = o2.getCourseAttemptStartDate();
+                long i1 = (d1 == null) ? 0 : d1.getTime();
+                long i2 = (d2 == null) ? 0 : d2.getTime();
+                return (i1 < i2) ? -1 : (i1 == i2) ? 0 : 1;
+        }
+    });
+				passed = false;
+				for (CourseAttempt ca : cas) {
+					if (ca.getCourseAttemptStatusID() == 1 && !usedCourses.contains(ca.getCourseAttemptID())) {
+logger.debug("     .COURSEATTEMPT: " + ca.getCourseAttemptCompleteDate() + "; STATUS: " + ca.getCourseAttemptStatusID());
+						usedCourses.add(ca.getCourseAttemptID());
+						associatedCourseAttempts.add(new Pair(c,ca));
+						passed = true;
+						break;
+					}
+				}
+				if (!passed) {
+					associatedCourseAttempts.add(new Pair(c,null));
+logger.debug("    -- Missing: " + c.getCourseName());
+					missed = true;
+				}
+				courseCurriculum.put(c.getCourseID(), cur.getCourseID());
+				courseSupressRetake.put(c.getCourseID(), !cur.isCourseAllowCurriculumPartRetake());
+			}
+			if (!missed) {
+
+    java.util.Collections.sort(associatedCourseAttempts, new Comparator<Pair<Course, CourseAttempt>>() {
+        public int compare(Pair<Course, CourseAttempt> p1, Pair<Course, CourseAttempt> p2) {
+		CourseAttempt o1 = p1.getValue();
+		CourseAttempt o2 = p2.getValue();
+		if (o1 == null && o1 == null) return 0;
+		if (o1 == null) return -1;
+		if (o2 == null) return 1;
+                Date d1 = o1.getCourseAttemptCompleteDate();
+                if (d1 == null) d1 = o1.getCourseAttemptStartDate();
+                Date d2 = o2.getCourseAttemptCompleteDate();
+                if (d2 == null) d2 = o2.getCourseAttemptStartDate();
+                long i1 = (d1 == null) ? 0 : d1.getTime();
+                long i2 = (d2 == null) ? 0 : d2.getTime();
+                return (i1 < i2) ? -1 : (i1 == i2) ? 0 : 1;
+        }
+    });
+logger.info("------ CUR - PASSED; startDate: " + associatedCourseAttempts.get(0).getValue().getCourseAttemptStartDate() + "; completeDate: " + associatedCourseAttempts.get(associatedCourseAttempts.size() - 1).getValue().getCourseAttemptCompleteDate());
+			}
+			if (passed) associated.add(associatedCourseAttempts);
+		}
+		curriculaEval.put(cur, associated);
+	}
+
+	courses.addAll(curricula);
+	Vector<CourseAttempt> courseAttempts = new Vector<CourseAttempt>();
+	for (int j = 0; j < courses.size(); j++) {
+		Course mainCourse = (Course)courses.get(j);
+		HashSet<CourseAttempt> meCourseAttempts = new HashSet<CourseAttempt>();
+		courseCourseAttempts.put(mainCourse.getCourseID(), meCourseAttempts);
+logger.debug("processing course: " + mainCourse.getCourseName());
+		Vector cas = CourseAttempt.getUserCourseAttempts(ilsSession, current.getUserProfileID(), mainCourse.getCourseID());
+		boolean nonExpired = false;
+		for (int i = 0; i < cas.size() + 1; i++) {
+			CourseAttempt ca  = null;
+			if (i == cas.size()) {
+				// we've finished our course attempts and we already have a status, we're done
+				if (nonExpired) break;
+				else {
+					ca = new CourseAttempt();
+					ca.setCourseAttemptID(-1);
+					ca.setIntValue("COMPANYID", ilsSession.getCompanyID());
+				}
+			}
+			else {
+				ca = (CourseAttempt)cas.get(i);
+				// we've already populated our main course, let's add a dup
+				if (!ca.isCourseAttemptExpired()) {
+					nonExpired = true;
+				}
+			}
+			String score   = "";
+			String status   = "";
+			int statusSort = ca.getCourseAttemptStatusID();
+			boolean finished = false;
+			switch (ca.getCourseAttemptStatusID()) {
+			case CourseAttempt.STATUS_IN_PROGRESS:
+			    status   = "In Progress";
+			    statusSort = 1;
+			    break;
+			case CourseAttempt.STATUS_PASSED:
+			    finished = !((mainCourse.isCourseRequiresManagerApproval()) && (!ca.isCourseAttemptManagerApproved()));
+			    status   = (finished) ? "Passed" : "Awaiting <t:t>Manager</t:t> Approval";
+			    score = Integer.toString(ca.getCourseAttemptScore());
+			    if ("-1".equals(score)) score = "";
+			    statusSort = 4;
+			    break;
+			case CourseAttempt.STATUS_FAILED:
+			    status   = "Failed";
+			    score = Integer.toString(ca.getCourseAttemptScore());
+			    if ("-1".equals(score)) score = "";
+			    statusSort = 2;
+			    break;
+			case CourseAttempt.STATUS_NEW:
+			    status   = "New";
+			    statusSort = 3;
+			}
+			ca.setValue("status", status);
+			ca.setIntValue("statusSort", statusSort);
+			ca.setValue("score", score);
+			ca.setValue("coursenum", mainCourse.getCourseNum());
+			ca.setValue("coursename", mainCourse.getCourseName());
+			ca.setValue("seattimetext", mainCourse.getCourseSeatTimeText());
+			ca.setCourseAttemptCourseID(mainCourse.getCourseID());
+			if (mainCourse.isCourseActive() || (ca.getCourseAttemptStatusID() == CourseAttempt.STATUS_FAILED) || (finished && ca.getCourseAttemptStatusID() == CourseAttempt.STATUS_PASSED)) {
+				courseAttempts.add(ca);
+				meCourseAttempts.add(ca);
+			}
+		}
+	}
+
+
+    java.util.Collections.sort(courseAttempts, new Comparator<CourseAttempt>() {
+        public int compare(CourseAttempt o1, CourseAttempt o2) {
+            int a1 = o1.getIntValue("statusSort");
+            int a2 = o2.getIntValue("statusSort");
+            if ((a1 - a2) == 0) {
+                Date d1 = o1.getCourseAttemptCompleteDate();
+                if (d1 == null) d1 = o1.getCourseAttemptStartDate();
+                Date d2 = o2.getCourseAttemptCompleteDate();
+                if (d2 == null) d2 = o2.getCourseAttemptStartDate();
+                long i1 = (d1 == null) ? 0 : d1.getTime();
+                long i2 = (d2 == null) ? 0 : d2.getTime();
+                return (i1 > i2) ? -1 : (i1 == i2) ? 0 : 1;
+            }
+            return (a1 - a2);
+        }
+    });
+
+
+%>
+
+
+
+
+        <table cellpadding="0" cellspacing="0" class="tableMain">
+<tr>
+                        <td><table class="tableMain" style="margin-bottom:0px">
+                            <tr>
+                              <th><div style="float:left;"><%=current.getUserProfileFirstName()%> <%=current.getUserProfileLastName()%></div><div style="text-align:right; float:right; color:#7D7D7D; font-weight:bold; padding-right:5px"><%=df.format(new Date())%> </div></th>
+
+                            </tr>
+                        </table></td>
+          </tr>
+                      <tr>
+                        <td valign="top">
+                          <table class="tableBTN">
+                            <tr>
+                              <td ><table>
+                                  <tr>
+                                    <td><a href="javascript:void(window.print())" target="_top"><img border="0" src="images/print_btn.gif" width="24" height="24" alt=""/></a></td>
+                                    <td><a class="formButtons" href="#" onclick="genAllCerts(<%=current.getUserProfileID()%>);return false;" target="_top">Generate All</a></td>
+                                  </tr>
+                              </table></td>
+                            </tr>
+                          </table>
+                        </td>
+                      </tr>
+
+                      <tr>
+                        <td><table class="tableDataList tableDataListStudentRecords">
+				<thead>
+                            <tr>
+                              <th style="width: 16px !important;" title="Hide/Show Courses within Curriculum"></th>
+                              <th style="width: 22px !important;" title="Hide/Show All History for an Item"></th>
+<% if (managing) { %>                            
+                              <th style="width: 160px !important;">Comments</th>
+<% } %>                              
+                              <th style="width: 60px !important;">Status</th>
+                              <th style="width: 60px !important;">No.</th>
+                              <th style="width: 160px !important;">Course Name</th>
+                              <th style="width: 70px !important;">Timeframe</th>
+                              <th style="width: 70px !important;">Start Date </th>
+                              <th style="width: 70px !important;">End Date</th>
+                              <th style="width: 50px !important;">Score %</th>
+                              <th style="width: 35px !important;">Cert</th>
+                            </tr>
+				</thead>
+				<tbody>
+<%
+// TODO
+//	This is a little convoluted. We do this in the order of courseAttempt because they may sort things in some order and we'd like those results to have priority, pulling in their dependencies as we work through the queue.
+    for (Course cur : curriculaEval.keySet()) {
+    	%>
+<tr class="curriculumHeaderRow">
+	<td></td>
+	<td></td>
+	<td></td>
+	<td></td>
+	<td><%=cur.getCourseNum()%></td>
+	<td><%=cur.getCourseName()%></td>
+	<td></td>
+	<td></td>
+	<td></td>
+	<td></td>
+	<td></td>
+</tr>
+<%
+	// existing course attempts
+	for (CourseAttempt curriculaAttempt : (Vector<CourseAttempt>)CourseAttempt.getUserCourseAttempts(ilsSession, current.getUserProfileID(), cur.getCourseID())) {
+		String comments = "";
+		if (curriculaAttempt.isCourseAttemptExpired()) {
+			comments += curriculaAttempt.getCourseAttemptExpiredReason() + "<br/>" + df.format(curriculaAttempt.getCourseAttemptExpiredDate());
+		}
+		if (curriculaAttempt.isCourseAttemptForcePass()) {
+			if (comments.length() > 0) comments += "<br/>";
+			comments += curriculaAttempt.getCourseAttemptForcePassReason() + "<br/>" + df.format(curriculaAttempt.getCourseAttemptForcePassDate());
+		}
+%>
+<tr class="curriculumDetailRow historyDetail subCourseID_<%=curriculaAttempt.getCourseAttemptID()%>">
+	<td></td>
+	<td></td>
+	<td><%=comments%></td>
+	<td id="ca_<%=curriculaAttempt.getCourseAttemptID()%>">Passed (<a href="#" onclick="removeCert(<%=curriculaAttempt.getCourseAttemptID()%>); return false;">delete</a>)</td>
+	<td></td>
+	<td></td>
+	<td></td>
+	<td><%=df.format(curriculaAttempt.getCourseAttemptStartDate())%></td>
+	<td><%=df.format(curriculaAttempt.getCourseAttemptCompleteDate())%></td>
+	<td><%=curriculaAttempt.getCourseAttemptScore()%></td>
+	<td></td>
+</tr>
+<%
+	}
+
+	// possible course attempts
+	List<List<Pair<Course, CourseAttempt>>> curriculaAttempts = curriculaEval.get(cur);
+	for (List<Pair<Course, CourseAttempt>> curriculaAttempt : curriculaAttempts) {
+		++count;
+		List<Pair<Course, CourseAttempt>> finished = new ArrayList<Pair<Course, CourseAttempt>>();
+ 		for (Pair<Course, CourseAttempt> p : curriculaAttempt) { if (p.getValue() != null) finished.add(p); }
+		String startDate = finished.size() == 0 ? "" : df.format(finished.get(0).getValue().getCourseAttemptStartDate());
+		String completeDate = finished.size() == 0 ? "" : df.format(finished.get(finished.size() - 1).getValue().getCourseAttemptCompleteDate());
+		String cas = "";
+		if (curriculaAttempt.size() > 0) {
+			for (Pair<Course, CourseAttempt> x : curriculaAttempt) {
+				if (x.getValue() != null) {
+					cas += ((cas.length() > 0 ? "," : "") + x.getValue().getCourseAttemptID());
+				}
+			}
+		}
+%>
+
+<tr class="curriculumDetailRow historyDetail">
+	<td></td>
+	<td></td>
+	<td></td>
+	<td id="cert_<%=current.getUserProfileID()%>_<%=count%>"><a href="#" onclick="genCert(<%=current.getUserProfileID()%>, <%=cur.getCourseID()%>, '<%=cas%>', <%=count%>, <%=finished.size() != curriculaAttempt.size()%>); return false;">Generate<%=finished.size() != curriculaAttempt.size() ? " Anyway":""%></a></td>
+	<td><%=cur.getCourseNum()%></td>
+	<td><%=cur.getCourseName()%></td>
+	<td></td>
+	<td><%=startDate%></td>
+	<td><%=completeDate%></td>
+	<td></td>
+	<td></td>
+</tr>
+
+<%
+    for (Pair<Course, CourseAttempt> ca :  curriculaAttempt) {
+%>
+<tr class="subCurriculumID_<%=cur.getCourseID()%> subCourseHeaderRow">
+	<td></td>
+<td></td>
+<td></td>
+<td><%=ca.getValue() == null ? "MISSING" : "PASSED"%></td>
+<td><%=ca.getKey().getCourseNum()%></td>
+<td><%=ca.getKey().getCourseName()%></td>
+<td><%=ca.getKey().getCourseSeatTimeText()%></td>
+<td><%=ca.getValue() == null ? "" : df.format(ca.getValue().getCourseAttemptStartDate())%></td>
+<td><%=ca.getValue() == null ? "" : df.format(ca.getValue().getCourseAttemptCompleteDate())%></td>
+<td><%=ca.getValue() == null ? "" : Integer.toString(ca.getValue().getCourseAttemptScore())%></td>
+<td></td>
+</tr>
+<%
+    }
+	}
+	}
+%>
+			</tbody>
+                        </table></td>
+                      </tr>
+    </table>
+</div>
+
+<%
+logger.info("**** END " + current.getUserProfileLastName() + ", " + current.getUserProfileFirstName());
+}
+logger.info("**** footer");
+%>
+<%@ include file="footer.jsp" %>
+</div>
+
+</body>
+</html>
+
+<%!
+
+public static String getCourseHTML(Vector<CourseAttempt> courseAttempts, CourseAttempt ca, boolean managing, UserProfile user, int wordNum, String headerAddition, String subClassAddition, boolean supressRetake, HashMap<Integer, Integer> courseCurriculum, HashMap<Integer, Course> curriculaList, Vector<Course>courses, HashMap<Integer, HashSet<CourseAttempt>>courseCourseAttempts) {
+
+	if (subClassAddition == null) subClassAddition = "";
+	else subClassAddition += " ";
+
+	boolean isCurriculum = curriculaList.get(ca.getCourseAttemptCourseID()) != null;
+	StringWriter out = new StringWriter();
+	String html = getCourseAttemptHTML(ca, managing, user, wordNum, supressRetake, courseCurriculum, curriculaList, courses, courseCourseAttempts);
+	courseAttempts.remove(ca);
+	String moreHTML = "";
+	for (int j = 0; j < courseAttempts.size(); ++j) {
+		CourseAttempt ca2 = courseAttempts.get(j);
+		if (ca2.getCourseAttemptCourseID() == ca.getCourseAttemptCourseID()) {
+			moreHTML += "<tr class=\""+(subClassAddition.trim().length() > 0?"subC":"c")+(isCurriculum?"urriculum":"ourse")+"DetailRow historyDetail subCourseID_"+ca2.getCourseAttemptCourseID()+"\"><td></td><td></td>"+getCourseAttemptHTML(ca2, managing, user, ++wordNum, supressRetake, courseCurriculum, curriculaList, courses, courseCourseAttempts)+"</tr>";
+			courseAttempts.remove(ca2);
+			--j;
+		}
+	}
+
+	out.write("<tr class=\""+subClassAddition+(subClassAddition.trim().length() > 0?"subC":"c")+(isCurriculum?"urriculum":"ourse")+"HeaderRow\">");
+	out.write("<td>");
+	if (headerAddition != null) out.write(headerAddition);
+	out.write("</td><td>");
+	if (moreHTML.length() > 0) {
+		out.write("<span class=\"courseHeader\" title=\"Show / Hide history for this record.\" id=\"courseHeader_"+ca.getCourseAttemptCourseID()+"\" onclick=\"toggleCourseDetails('"+ca.getCourseAttemptCourseID()+"');return false;\">+</span>");
+	}
+	out.write("</td>");
+	out.write(html);
+	out.write("</tr>");
+	out.write(moreHTML);
+
+	return out.toString();
+}
+
+public static String getCurriculumHTML(HashMap<Integer, Boolean> courseSupressRetake, HashMap<Integer, Integer> courseCurriculum, Vector<CourseAttempt> courseAttempts, CourseAttempt caCur, boolean managing, UserProfile user, int wordNum, HashMap<Integer, Course> curriculaList, Vector<Course>courses, HashMap<Integer, HashSet<CourseAttempt>>courseCourseAttempts) {
+
+	Logger logger = Logger.getLogger("getCurriculumHTML");
+
+	StringWriter out = new StringWriter();
+	String headerAddition = ("<span class=\"curHeader\" id=\"curriculumHeader_"+caCur.getCourseAttemptCourseID()+"\" title=\"Show / Hide Courses within this Curriculum\" onclick=\"toggleCurriculumDetails('"+caCur.getCourseAttemptCourseID()+"');return false;\">˄<br>˅</span>");
+	String html = getCourseHTML(courseAttempts, caCur, managing, user, wordNum, headerAddition, null, false, courseCurriculum, curriculaList, courses, courseCourseAttempts);
+	String moreHTML = "";
+	for (int j = 0; j < courseAttempts.size(); ++j) {
+		CourseAttempt ca2 = courseAttempts.get(j);
+
+		// see if this course attempt is in our curriculum
+		Integer curriculumID = courseCurriculum.get(ca2.getCourseAttemptCourseID());
+		if (curriculumID != null && caCur.getCourseAttemptCourseID() == curriculumID.intValue()) {
+logger.info("cours is in cur.");
+			String subClassAddition = "subCurriculumID_"+caCur.getCourseAttemptCourseID();
+			Boolean supressRetake = courseSupressRetake.get(ca2.getCourseAttemptCourseID());
+			moreHTML += getCourseHTML(courseAttempts, ca2, managing, user, ++wordNum, null, subClassAddition, supressRetake != null && supressRetake.booleanValue(), courseCurriculum, curriculaList, courses, courseCourseAttempts);
+			--j;
+		}
+		else {
+logger.info("cours NOT is in cur. CourseID:"+ca2.getCourseAttemptCourseID()+"; curParent: " + curriculumID);
+		}
+	}
+
+	out.write(html);
+	out.write(moreHTML);
+
+	return out.toString();
+}
+
+
+public static String getCourseAttemptHTML(CourseAttempt ca, boolean managing, UserProfile user, int wordNum, boolean supressRetake, HashMap<Integer, Integer> courseCurriculum, HashMap<Integer, Course> curriculaList, Vector<Course>courses, HashMap<Integer, HashSet<CourseAttempt>>courseCourseAttempts) {
+
+	boolean supressCert = false;
+	// are we IN a curriculum?
+	Integer curriculumID = courseCurriculum.get(ca.getCourseAttemptCourseID());
+	if (curriculumID != null) {
+		Course curr = curriculaList.get(curriculumID);
+		supressCert = curr.isCourseCurriculumCertificate();
+	}
+
+	// are we a curriculum?
+	Course curr = curriculaList.get(ca.getCourseAttemptCourseID());
+	if (curr != null) {
+		supressCert = !curr.isCourseCurriculumCertificate();
+		HashMap<String, Object>values = new HashMap<String, Object>();
+		computeCurriculumStats(curr.getCourseID(), courses, courseCurriculum, courseCourseAttempts, values);
+		int  timeFrame         = (Integer)values.get("timeFrame");
+		long sDate         = (Long)values.get("startDate");
+		long eDate           = (Long)values.get("endDate");
+		int  score             = (Integer)values.get("score");
+		int  inProgressCourseCount = (Integer)values.get("inProgressCourseCount");
+		int  passedCourseCount = (Integer)values.get("passedCourseCount");
+		int  totalCourseCount  = (Integer)values.get("totalCourseCount");
+		ca.setValue("seattimetext", Course.getNiceTimeText(timeFrame));
+		boolean finished = !((curr.isCourseRequiresManagerApproval()) && (!ca.isCourseAttemptManagerApproved()));
+		// if we have a stored history of passed or failed, use it.  Otherwise, compute curriculum status based on course progress
+		if (
+			   (!finished || ca.getCourseAttemptStatusID() != CourseAttempt.STATUS_PASSED)
+			&& ca.getCourseAttemptStatusID() != CourseAttempt.STATUS_FAILED
+		) {
+			ca.setValue("status", passedCourseCount == totalCourseCount ? "Passed" : (inProgressCourseCount == 0 && passedCourseCount == 0) ? "New" : "In Progress");
+		}
+		if ("In Progress".equals(ca.getValue("status"))) ca.setCourseAttemptStartDate(new Date(sDate));
+	}
+
+	StringWriter out = new StringWriter();
+	Date tDate = ca.getCourseAttemptStartDate();
+	String startDate = (tDate != null) ? df.format(tDate) : "";
+	tDate = ca.getCourseAttemptCompleteDate();
+	String endDate = (tDate != null) ? df.format(tDate) : "";
+	String status = ca.getStringValue("status");
+	if (managing) {
+		out.write("<td>");
+		if ("Passed".equals(status)) {
+			if (!ca.isCourseAttemptExpired() && !supressRetake) {
+				out.write("<a href=\"#\" onClick=\"retake("+ca.getCourseAttemptID()+");return false;\" class=\"Assign\">Assign Retake</a><br>");
+			}
+		}
+		else if (!"Awaiting <t:t>Manager</t:t> Approval".equals(status) && user.getUserProfileAccessLevel() > UserProfile.ACCESS_MANAGER || user.hasAccess(UserProfile.ACCESS_MODE_STUDENTREC_PASS_OVERRIDE)) {
+			out.write("<a href=\"#\" onClick=\"forcePass("+ca.getCourseAttemptID()+", "+ca.getCourseAttemptCourseID()+");return false;\" class=\"Assign\">Force Pass</a>");
+	
+		}
+
+		String val = "";
+		if (ca.isCourseAttemptExpired()) {
+			val += ca.getCourseAttemptExpiredReason() + "<br/>" + df.format(ca.getCourseAttemptExpiredDate());
+		}
+		if (ca.isCourseAttemptForcePass()) {
+			if (val.length() > 0) val += "<br/>";
+			val += ca.getCourseAttemptForcePassReason() + "<br/>" + df.format(ca.getCourseAttemptForcePassDate());
+		}
+		out.write(val+"</td>");
+	}
+
+
+	out.write("<td>"+status+"</td>");
+	out.write("<td>"+ca.getStringValue("coursenum")+"</td>");
+	out.write("<td><a href=\"#\" onclick=\"p('course','"+ca.getCourseAttemptCourseID()+"','"+wordNum+"');\">"+ca.getStringValue("coursename")+"</a></td>");
+	out.write("<td>"+ca.getStringValue("seattimetext")+"</td>");
+	out.write("<td>"+startDate+"</td>");
+	out.write("<td>"+endDate+"</td>");
+	out.write("<td>"+ca.getStringValue("score")+"</td>");
+	out.write("<td>");
+
+	if (ca.getSavedCertificate() != null) {
+		out.write("<a target=\"_blank\" href=\"api/courseattempt/cert/get?courseAttemptID="+ca.getCourseAttemptID()+"\"><img src=\"images/certificate_saved.png\"/></a>");
+	}
+	else if ("Passed".equals(status) && !supressCert) {
+		Course c = Course.getCourse(ca.getCompanyID(), ca.getCourseAttemptCourseID());
+		String urlString = c.getCourseCertificateGenerator();
+		if (urlString == null || urlString.length() < 1) urlString = (c.isCourseCurriculum() ? "certificate_curriculum.jsp" : "certificate.jsp");
+		urlString += "?ca=" + ca.getCourseAttemptID();
+		urlString += "&c=" + c.getCourseID();
+		urlString += "&up=" + ca.getCourseAttemptUserProfileID();
+		out.write("<a target=\"_blank\" href=\""+urlString+"\"><img src=\"images/print_certficate.png\"/></a>");
+	}
+	out.write("</td>");
+
+	return out.toString();
+}
+public static void computeCurriculumStats(int curriculumID, Vector<Course> courses, HashMap<Integer, Integer> courseCurriculum, HashMap<Integer, HashSet<CourseAttempt>> courseCourseAttempts, HashMap<String, Object>values) {
+	int  timeFrame         = 0;
+	long startDate         = 0;
+	long endDate           = 0;
+	int  score             = 0;
+	int  inProgressCourseCount = 0;
+	int  passedCourseCount = 0;
+	int  totalCourseCount  = 0;
+	int  scoredCourseCount  = 0;
+
+	for (Course c : courses) {
+		// are we a course in our curriculum?
+		Integer thisCourseCurriculum = courseCurriculum.get(c.getCourseID());
+		if (thisCourseCurriculum != null && curriculumID == thisCourseCurriculum) {
+			++totalCourseCount;
+
+			timeFrame += c.getCourseSeatMinutes();
+			Set<CourseAttempt> cas = courseCourseAttempts.get(c.getCourseID());
+			if (cas != null) {
+				boolean inProgress = false;
+				for (CourseAttempt ca : cas) {
+					Date d = ca.getCourseAttemptStartDate();
+					startDate = (d != null && (startDate == 0 || startDate > d.getTime())) ? d.getTime() : startDate;
+					d = ca.getCourseAttemptCompleteDate();
+					endDate = (d != null && (endDate == 0 || endDate < d.getTime())) ? d.getTime() : endDate;
+
+					boolean finished = !((c.isCourseRequiresManagerApproval()) && (!ca.isCourseAttemptManagerApproved()));
+					if (finished && ca.getCourseAttemptStatusID() == CourseAttempt.STATUS_PASSED && !ca.isCourseAttemptExpired()) {
+						int s = ca.getCourseAttemptScore();
+						++passedCourseCount;
+						if (s > -1) {
+							++scoredCourseCount;
+							score += s;
+							inProgress = false;
+						}
+						break;
+					}
+					else if (ca.getCourseAttemptStatusID() == CourseAttempt.STATUS_IN_PROGRESS) inProgress = true;
+				}
+				if (inProgress) ++inProgressCourseCount;
+			}
+		}
+	}
+
+	if (scoredCourseCount != 0) score /= scoredCourseCount;
+	values.put("timeFrame", timeFrame);
+	values.put("startDate", startDate);
+	values.put("endDate", endDate);
+	values.put("score", score);
+	values.put("inProgressCourseCount", inProgressCourseCount);
+	values.put("passedCourseCount", passedCourseCount);
+	values.put("totalCourseCount", totalCourseCount);
+	values.put("timeFrame", timeFrame);
+
+logger.debug("curriculum: " + curriculumID + "; values: " + values);
+}
+%>

Modified: trunk/webapp/report_employeecourseatt.jsp
===================================================================
--- trunk/webapp/report_employeecourseatt.jsp	2017-02-15 01:16:28 UTC (rev 1528)
+++ trunk/webapp/report_employeecourseatt.jsp	2017-03-24 02:39:12 UTC (rev 1529)
@@ -275,7 +275,7 @@
 <tr>
                         <td><table class="tableMain" style="margin-bottom:0px">
                             <tr>
-                              <th><div style="float:left;"><%=current.getUserProfileFirstName()%> <%=current.getUserProfileLastName()%></div><div style="text-align:right; float:right; color:#7D7D7D; font-weight:bold; padding-right:5px"><%=df.format(new Date())%> </div></th>
+                              <th><div style="float:left;"><%=current.getUserProfileFirstName()%> <%=current.getUserProfileLastName()%> </div> <div style="text-align:right; float:right; color:#7D7D7D; font-weight:bold; padding-right:5px"><%=df.format(new Date())%> </div></th>
 
                             </tr>
                         </table></td>
@@ -322,7 +322,7 @@
 		// first see if we're a course in a Curriculum
 		CourseAttempt ca = courseAttempts.get(0);
 		boolean isCurriculum = curriculaList.get(ca.getCourseAttemptCourseID()) != null;
-		Integer curriculumID = isCurriculum ? ca.getCourseAttemptCourseID() : courseCurriculum.get(ca.getCourseAttemptCourseID());
+		Integer curriculumID = isCurriculum ? (Integer)ca.getCourseAttemptCourseID() : (Integer)courseCurriculum.get(ca.getCourseAttemptCourseID());
 		String html = "";
 		int startSize = courseAttempts.size();
 		// process curriculum first




More information about the Ils-source mailing list