[Ils-source] r1438 - in trunk: db/mssql src/com/resolutions/ils/data webapp

scribe at crosswire.org scribe at crosswire.org
Thu Apr 7 22:40:59 MST 2016


Author: scribe
Date: 2016-04-07 22:40:59 -0700 (Thu, 07 Apr 2016)
New Revision: 1438

Modified:
   trunk/db/mssql/ilsdb.sql
   trunk/src/com/resolutions/ils/data/Course.java
   trunk/src/com/resolutions/ils/data/CourseAttempt.java
   trunk/webapp/admin_curricnew.jsp
   trunk/webapp/report_employeecourseatt.jsp
Log:
Working Curriculum grouped reports


Modified: trunk/db/mssql/ilsdb.sql
===================================================================
--- trunk/db/mssql/ilsdb.sql	2016-04-08 03:38:26 UTC (rev 1437)
+++ trunk/db/mssql/ilsdb.sql	2016-04-08 05:40:59 UTC (rev 1438)
@@ -1,5 +1,5 @@
 CREATE TABLE ILSGROUP (COMPANYID INTEGER NOT NULL, ILSGROUPID INTEGER IDENTITY(1,1) NOT NULL, GROUPNAME VARCHAR(75) NOT NULL, GROUPDESC VARCHAR(255), GROUPTYPEID INTEGER, USERDATA VARCHAR(80), CONSTRAINT ILSGROUPPK1 PRIMARY KEY (COMPANYID, ILSGROUPID))
-CREATE TABLE COURSE (COMPANYID INTEGER NOT NULL, COURSID INTEGER IDENTITY(1,1) NOT NULL, COURSNUM VARCHAR(20) NOT NULL, COURSNAME VARCHAR(100), COURSDESC VARCHAR(500), COURSTYPEID INTEGER, COURSPASS INTEGER, COURSPASSEXPDAYS INTEGER, COURSREASBEFDAYS INTEGER, COURSURL VARCHAR(255), COURSCKLISTURL VARCHAR(255), COURSCOST FLOAT, COURSSEATMINS INTEGER, COURSISCURRICULUM CHAR(1), COURSISQUICKVIEW CHAR(1), COURSPOSTDATE DATETIME, COURSISACTIVE CHAR(1), COURSISIPRESTRICTED char(1), COURSREQMGRAPPRVL CHAR(1), USERDATA VARCHAR(80), COURSISCURRICCERT char(1) DEFAULT 'F', COURSCERTGEN VARCHAR(60) DEFAULT null, CONSTRAINT COURSEPK1 PRIMARY KEY (COMPANYID, COURSID))
+CREATE TABLE COURSE (COMPANYID INTEGER NOT NULL, COURSID INTEGER IDENTITY(1,1) NOT NULL, COURSNUM VARCHAR(20) NOT NULL, COURSNAME VARCHAR(100), COURSDESC VARCHAR(500), COURSTYPEID INTEGER, COURSPASS INTEGER, COURSPASSEXPDAYS INTEGER, COURSREASBEFDAYS INTEGER, COURSURL VARCHAR(255), COURSCKLISTURL VARCHAR(255), COURSCOST FLOAT, COURSSEATMINS INTEGER, COURSISCURRICULUM CHAR(1), COURSISQUICKVIEW CHAR(1), COURSPOSTDATE DATETIME, COURSISACTIVE CHAR(1), COURSISIPRESTRICTED char(1), COURSREQMGRAPPRVL CHAR(1), USERDATA VARCHAR(80), COURSISCURRICCERT char(1) DEFAULT 'F', COURSISALLOWCERTPARTRETAKE char(1) DEFAULT 'F', COURSCERTGEN VARCHAR(60) DEFAULT null, CONSTRAINT COURSEPK1 PRIMARY KEY (COMPANYID, COURSID))
 
 CREATE TABLE USERPROFILE (COMPANYID INTEGER NOT NULL, USERPRID INTEGER IDENTITY(1,1) NOT NULL, USERPRNUM VARCHAR(50) NOT NULL, USERPRPASSWD VARCHAR(20), USERPRMNAME VARCHAR(40), USERPRSNAME VARCHAR(40), USERPRFNAME VARCHAR(40), USERPRLNAME VARCHAR(40), USERPRSTATUSID INTEGER, USERPRADDR1 VARCHAR(60),USERPRADDR2 VARCHAR(60),USERPRCITY VARCHAR(30),USERPRSTATE VARCHAR(2),USERPRZIP VARCHAR(12),USERPRCOUNTRY VARCHAR(50),USERPREMAIL VARCHAR(50), USERPRPHONE VARCHAR(50), USERPREMPTITLEID INTEGER, USERPRLASTLOGIN TIMESTAMP, USERPRACCESSLEVEL INTEGER, USERPRACCESSMOD INTEGER, USERPRINACTDATE DATETIME, USERPRHIREDATE DATETIME, USERPRTERMDATE DATETIME, USERPRIPRESTRICTOVERRIDE char(1), USERDATA VARCHAR(80), USERPRSECONDLOGINOVERRIDE char(1) DEFAULT 'F', USERPMGRRECUREMAILSOVERRIDE char(1) DEFAULT 'F', CONSTRAINT USERPROFILEPK1 PRIMARY KEY (COMPANYID, USERPRID))
 CREATE TABLE ANNOUNCEMENT (COMPANYID INTEGER NOT NULL, ANNOUNCID INTEGER IDENTITY(1,1) NOT NULL, ANNOUNCTITLE VARCHAR(100), ANNOUNCMESSAGE VARCHAR(255), ANNOUNCEXP DATETIME, ANNOUNCURL VARCHAR(255), ANNOUNCPOSTDATE DATETIME, USERDATA VARCHAR(80), CONSTRAINT ANNOUNCEMENTPK1 PRIMARY KEY (COMPANYID, ANNOUNCID))

Modified: trunk/src/com/resolutions/ils/data/Course.java
===================================================================
--- trunk/src/com/resolutions/ils/data/Course.java	2016-04-08 03:38:26 UTC (rev 1437)
+++ trunk/src/com/resolutions/ils/data/Course.java	2016-04-08 05:40:59 UTC (rev 1438)
@@ -223,7 +223,7 @@
         return query.getDataSet(LOOKUPUSERQUICKVIEWS);
     }
 
-    static public Vector getCurriculumCourses(ILSSession session,
+    static public Vector<Course> getCurriculumCourses(ILSSession session,
                                               int curriculumID) {
         Course query = new Course();
         query.setCompanyID(session.getCompanyID());
@@ -231,13 +231,25 @@
         return query.getDataSet(LOOKUPCURRICULUMCOURSES);
     }
 
-    public Vector<Course> getCurriculumCourses() {
-        Course query = new Course();
-        query.setCompanyID(getCompanyID());
-        query.setCourseID(getCourseID());
-        return query.getDataSet(LOOKUPCURRICULUMCOURSES);
-    }
+	private Vector<Course> curCourses = null;
 
+	public Vector<Course> getCurriculumCourses() {
+		if (curCourses == null) {
+			Course query = new Course();
+			query.setCompanyID(getCompanyID());
+			query.setCourseID(getCourseID());
+			curCourses = query.getDataSet(LOOKUPCURRICULUMCOURSES);
+		}
+		return curCourses;
+	}
+
+	boolean isCurriculumCourse(int courseID) {
+		for (Course c : getCurriculumCourses()) {
+			if (c.getCourseID() == courseID) return true;
+		}
+		return false;
+	}
+
     static public int deleteCurriculumCourses(ILSSession session, int courseID) {
         Course query = new Course();
         query.setCompanyID(session.getCompanyID());
@@ -340,6 +352,10 @@
         return ("T".equals(getValue("COURSISCURRICCERT")));
     }
 
+    public boolean isCourseAllowCurriculumPartRetake() {
+        return ("T".equals(getValue("COURSISALLOWCURRPARTRETAKE")));
+    }
+
     public boolean isCourseQuickView() {
         return ("T".equals(getValue("COURSISQUICKVIEW")));
     }
@@ -413,6 +429,10 @@
         setValue("COURSISCURRICCERT", (val) ? "T" : "F");
     }
 
+    public void setCourseAllowCurriculumPartRetake(boolean val) {
+        setValue("COURSISALLOWCURRPARTRETAKE", (val) ? "T" : "F");
+    }
+
     public void setCourseQuickView(boolean isQuickView) {
         setValue("COURSISQUICKVIEW", (isQuickView) ? "T" : "F");
     }
@@ -502,26 +522,20 @@
 //                logger.error(ex, ex);
             }
             if (inputSource == null) {
-				try {
-					File f = new File(context.getRealPath(url));
-					inputSource = new org.xml.sax.InputSource(new java.io.
-							FileInputStream(f));
-				} catch (Exception ex) {
-//					logger.error(ex, ex);
-				}
+		try {
+			File f = new File(context.getRealPath(url));
+			inputSource = new org.xml.sax.InputSource(new java.io.FileInputStream(f));
+		} catch (Exception ex) {
+		//					logger.error(ex, ex);
+		}
             }
             if (inputSource != null) {
                 try {
-					javax.xml.xpath.XPath xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
-                    com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList nodes = (
-                            com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList)
-                            xpath.evaluate(expression, inputSource,
-                                           javax.xml.xpath.XPathConstants.
-                                           NODESET);
+			javax.xml.xpath.XPath xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
+			com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList nodes = (com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList) xpath.evaluate(expression, inputSource, javax.xml.xpath.XPathConstants.NODESET);
                     if (nodes.getLength() > 0) {
                         org.w3c.dom.Node n = nodes.item(0);
-                        org.w3c.dom.Node name = n.getAttributes().getNamedItem(
-                                "frameFeatures");
+                        org.w3c.dom.Node name = n.getAttributes().getNamedItem("frameFeatures");
                         if (name != null) {
 	                        retVal = (String) name.getNodeValue();
                         }

Modified: trunk/src/com/resolutions/ils/data/CourseAttempt.java
===================================================================
--- trunk/src/com/resolutions/ils/data/CourseAttempt.java	2016-04-08 03:38:26 UTC (rev 1437)
+++ trunk/src/com/resolutions/ils/data/CourseAttempt.java	2016-04-08 05:40:59 UTC (rev 1438)
@@ -134,6 +134,10 @@
         return query.executeSQL(DELETE);
     }
 
+			
+
+
+
     /********************************
      * 
      * @param session
@@ -337,6 +341,9 @@
 	}
 
 	public void passAllAssociatedCurriculum(ILSSession session, HttpServletRequest request) {
+		passAllAssociatedCurriculum(session, request, null);
+	}
+	public void passAllAssociatedCurriculum(ILSSession session, HttpServletRequest request, String forcePassReason) {
 		Collection<Course> curs = Course.getUserCurricula(session, getCourseAttemptUserProfileID());
 		if (curs != null) {
 			for (Course cur : curs) {
@@ -394,6 +401,7 @@
 
 						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());
@@ -849,11 +857,15 @@
 		else {
 			xml.append(">");
 
-			xml.append(user.toXML(DETAIL_HEADERONLY));
-			xml.append(course.toXML(DETAIL_BRIEF));
+			if (user != null) xml.append(user.toXML(DETAIL_HEADERONLY));
+			if (course != null) xml.append(course.toXML(DETAIL_BRIEF));
 
-			xml.append("<startDate>").append(HTTPUtils.canonize(df.format(getCourseAttemptStartDate()))+"</startDate>");
-			xml.append("<completeDate>").append(HTTPUtils.canonize(df.format(getCourseAttemptCompleteDate()))+"</completeDate>");
+			if (getCourseAttemptStartDate() != null) {
+				xml.append("<startDate>").append(HTTPUtils.canonize(df.format(getCourseAttemptStartDate()))+"</startDate>");
+			}
+			if (getCourseAttemptCompleteDate() != null) {
+				xml.append("<completeDate>").append(HTTPUtils.canonize(df.format(getCourseAttemptCompleteDate()))+"</completeDate>");
+			}
 			xml.append("<score>").append(getCourseAttemptScore()+"</score>");
 			xml.append("<status statusID=\"").append(getCourseAttemptStatusID()+"\">"+passedFailed+"</status>");
 			xml.append("<aiccStage>").append(HTTPUtils.canonize(getCourseAttemptStage())+"</aiccStage>");
@@ -897,15 +909,89 @@
         return count;
     }
 
+
+
+
+
+
+	public static void forcePass(int courseID, int userProfileID, String reason, ILSSession ilsSession, HttpServletRequest httpRequest) {
+		CourseAttempt.forcePass(courseID, userProfileID, reason, ilsSession, httpRequest, false, -1);
+	}
+	public static void forcePass(int courseID, int userProfileID, String reason, ILSSession ilsSession, HttpServletRequest httpRequest, boolean allCurriculumCourses, int courseAttemptID) {
+		CourseAttempt ca = null;
+		Course course = null;
+		if (courseAttemptID > -1) {
+			CourseAttempt caOrig = CourseAttempt.getCourseAttempt(ilsSession, courseAttemptID);
+			if (caOrig != null) {
+				course = Course.getCourse(ilsSession, caOrig.getCourseAttemptCourseID());
+				
+				if (!allCurriculumCourses || !course.isCourseCurriculum()) {
+					ca = (CourseAttempt)caOrig.clone();
+					ca.setCourseAttemptForcePass(reason);
+					ca.save(caOrig);
+				}
+			}
+		}
+		else {
+			course = Course.getCourse(ilsSession, courseID);
+
+			if (!allCurriculumCourses || !course.isCourseCurriculum()) {
+				ca = new CourseAttempt();
+				ca.defaultAll();
+				ca.setCourseAttemptCourseID(courseID);
+				ca.setCourseAttemptUserProfileID(userProfileID);
+				ca.setCourseAttemptForcePass(reason);
+				ca = ca.saveNew(ilsSession);
+			}
+		}
+		if (ca != null) {
+
+			ca.sendStatusUpdateEvent(httpRequest.getSession().getServletContext());
+
+			String certgen = course.getCourseCertificateGenerator();
+			if (certgen != null && certgen.trim().length() > 0) {
+				try {
+					ca.saveCertificate(ca.generateCertificate(ilsSession, httpRequest));
+				}
+				catch (Exception e) {
+					logger.error(e, e);
+				}
+			}
+
+			ca.passAllAssociatedCurriculum(ilsSession, httpRequest, reason);
+		}
+
+		if (allCurriculumCourses && course.isCourseCurriculum()) {
+			for (Course curCourse : course.getCurriculumCourses()) {
+				Vector<CourseAttempt> cas = CourseAttempt.getUserCourseAttempts(ilsSession, userProfileID, curCourse.getCourseID(), false);
+				boolean skipCourse = false;
+				if (cas != null) {
+					for (CourseAttempt ca2 : cas) {
+						if (ca2.getCourseAttemptStatusID() == STATUS_PASSED && !ca2.isCourseAttemptExpired()) {
+							skipCourse = true;
+						}
+					}
+				}
+				if (!skipCourse) {
+					CourseAttempt.forcePass(curCourse.getCourseID(), userProfileID, reason, ilsSession, httpRequest, allCurriculumCourses, -1);
+				}
+			}
+		}
+	}
+
+
 	public void assignRetake(String reason, ILSSession ilsSession, HttpSession httpSession) {
+		assignRetake(reason, ilsSession, httpSession, false);
+	}
+	public void assignRetake(String reason, ILSSession ilsSession, HttpSession httpSession, boolean allCurriculumCourses) {
 		CourseAttempt ca = (CourseAttempt)this.clone();
 		setCourseAttemptExpired(reason);
 		save(ca);
+		Course course = Course.getCourse(ilsSession, ca.getCourseAttemptCourseID());
 		Properties sysConfig = Utils.getSysConfig(httpSession.getServletContext(), getCompanyID());
 		boolean emailNotice = "on".equals(sysConfig.getProperty("EmailEnableAssignedRetakes", "off"));
 		if (emailNotice) {
 			try {
-				Course course = Course.getCourse(ilsSession, ca.getCourseAttemptCourseID());
 				UserProfile up = UserProfile.getUserProfile(ilsSession, ca.getCourseAttemptUserProfileID());
 				String subject = "Assigned Retake Notice";
 				String body =  "You have been reassigned to take " + course.getCourseName() + " training.  ";
@@ -919,6 +1005,18 @@
 				e.printStackTrace();
 			}
 		}
+		if (allCurriculumCourses && course.isCourseCurriculum()) {
+			for (Course curCourse : course.getCurriculumCourses()) {
+				Vector<CourseAttempt> cas = CourseAttempt.getUserCourseAttempts(ilsSession, getCourseAttemptUserProfileID(), curCourse.getCourseID(), false);
+				if (cas != null) {
+					for (CourseAttempt ca2 : cas) {
+						if (ca2.getCourseAttemptStatusID() == STATUS_PASSED && !ca2.isCourseAttemptExpired()) {
+							ca2.assignRetake(reason, ilsSession, httpSession, allCurriculumCourses);
+						}
+					}
+				}
+			}
+		}
 	}
 
 	public byte[] generateCertificate(ILSSession ilsSession, HttpServletRequest request) throws Exception {
@@ -943,10 +1041,11 @@
 		Dimension windowSize = new Dimension(850, 1100);
 
 		String baseURL = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
+		String certGen = c.getCourseCertificateGenerator();
 		String urlString = baseURL;
-		String certGen = c.getCourseCertificateGenerator();
 		if (certGen != null && certGen.length() > 0 && !"default".equals(certGen)) {
-			urlString += "/" + certGen;
+			if (certGen.indexOf("://") > -1) urlString = certGen;
+			else urlString += "/" + certGen;
 		}
 		else {
 			urlString += (c.isCourseCurriculum() ? "/certificate_curriculum.jsp" : "/certificate.jsp");

Modified: trunk/webapp/admin_curricnew.jsp
===================================================================
--- trunk/webapp/admin_curricnew.jsp	2016-04-08 03:38:26 UTC (rev 1437)
+++ trunk/webapp/admin_curricnew.jsp	2016-04-08 05:40:59 UTC (rev 1438)
@@ -63,6 +63,8 @@
         if (val != null) current.setCourseName(val);
         val = request.getParameter("desc");
         if (val != null) current.setCourseDesc(val);
+        val = request.getParameter("certgen");
+  	if (val != null) current.setCourseCertificateGenerator(val);
 try {
         val = request.getParameter("statusID");
         if (val != null) current.setCourseActive(Integer.parseInt(val)>0);
@@ -74,6 +76,9 @@
 try {
         current.setCourseCurriculumCertificate("true".equals(request.getParameter("curricCert")));
 } catch (Exception e) { logger.error(e); }
+try {
+        current.setCourseAllowCurriculumPartRetake("true".equals(request.getParameter("curricPartRetake")));
+} catch (Exception e) { logger.error(e); }
 
         if ((current.getCourseNum() == null) || (current.getCourseNum().length() < 1))
             validError = "You must supply a Curriculum Number";
@@ -191,7 +196,15 @@
                               <td class="formHeadings">Enable Curriculum Certificate :</td>
                               <td><input type="checkbox" <%=(current.isCourseCurriculumCertificate())?"checked=\"checked\"":""%> name="curricCert" value="true" /></td>
                             </tr>
+			      <tr>
+				<td class="formHeadings">Course Certificate Generator </td>
+				<td><input name="certgen" style="width:100%" type="text" placeholder="default or certificate.jsp or curriculum_certificate.jsp" value="<%=current.getCourseCertificateGenerator()%>" size="40"/></td>
+			      </tr>
                             <tr>
+                              <td class="formHeadings">Enable Curriculum Part Retake :</td>
+                              <td><input type="checkbox" <%=(current.isCourseAllowCurriculumPartRetake())?"checked=\"checked\"":""%> name="curricPartRetake" value="true" /></td>
+                            </tr>
+                            <tr>
                               <td>&nbsp;</td>
                               <td>&nbsp;</td>
                             </tr>

Modified: trunk/webapp/report_employeecourseatt.jsp
===================================================================
--- trunk/webapp/report_employeecourseatt.jsp	2016-04-08 03:38:26 UTC (rev 1437)
+++ trunk/webapp/report_employeecourseatt.jsp	2016-04-08 05:40:59 UTC (rev 1438)
@@ -5,7 +5,12 @@
 <%@ page import="com.resolutions.ils.*" %>
 <%@ page import="com.resolutions.ils.data.*" %>
 <%@ page import="java.util.Vector" %>
+<%@ page import="java.util.Set" %>
+<%@ page import="java.util.Map" %>
+<%@ page import="java.util.HashSet" %>
+<%@ page import="java.util.HashMap" %>
 <%@ page import="java.util.Comparator" %>
+<%@ page import="java.util.Collection" %>
 <%@ page import="java.util.Date" %>
 <%@ page import="java.io.File" %>
 <%@ page import="java.io.StringWriter" %>
@@ -62,129 +67,111 @@
     	if (cid > -1) {
     		CourseAttempt caOrig = CourseAttempt.getCourseAttempt(ilsSession, cid);
     		if (caOrig != null) {
-			caOrig.assignRetake(reason, ilsSession, session);
+			caOrig.assignRetake(reason, ilsSession, session, true);
     		}
     	}
     }
-System.out.println("*************************************** managing: "+managing);
-    if (managing && "passCourse".equals(action) && (user.getUserProfileAccessLevel() > UserProfile.ACCESS_MANAGER || user.hasAccess(UserProfile.ACCESS_MODE_STUDENTREC_PASS_OVERRIDE))) {
-    	String cidString = request.getParameter("passCID");
-    	String courseIDString = request.getParameter("passCourseID");
-    	String reason    = request.getParameter("passReason");
-	if (reason != null) reason = new String(reason.getBytes("iso8859-1"), "UTF-8");
-System.out.println("passCourse: passCID-"+ cidString + "; passCourseID-"+courseIDString+"; passReason-"+reason);
-    	int cid = -1;
-    	try { cid = Integer.parseInt(cidString); } catch (Exception e) {}
-    	if (reason == null) reason = "";
-	CourseAttempt ca = null;
-    	if (cid > -1) {
-    		CourseAttempt caOrig = CourseAttempt.getCourseAttempt(ilsSession, cid);
-    		if (caOrig != null) {
-    			ca = (CourseAttempt)caOrig.clone();
-    			ca.setCourseAttemptForcePass(reason);
-    			ca.save(caOrig);
-    		}
-    	}
-	else {
-		ca = new CourseAttempt();
-		ca.defaultAll();
-		ca.setCourseAttemptCourseID(Integer.parseInt(courseIDString));
-		ca.setCourseAttemptUserProfileID(profileID);
-		ca.setCourseAttemptForcePass(reason);
-		ca = ca.saveNew(ilsSession);
+	if (managing && "passCourse".equals(action) && (user.getUserProfileAccessLevel() > UserProfile.ACCESS_MANAGER || user.hasAccess(UserProfile.ACCESS_MODE_STUDENTREC_PASS_OVERRIDE))) {
+		String cidString = request.getParameter("passCID");
+		String courseIDString = request.getParameter("passCourseID");
+		String reason    = request.getParameter("passReason");
+		if (reason != null) reason = new String(reason.getBytes("iso8859-1"), "UTF-8");
+		int cid = -1;
+		try { cid = Integer.parseInt(cidString); } catch (Exception e) {}
+		if (reason == null) reason = "";
+		int courseID = -1; try { courseID = Integer.parseInt(courseIDString); } catch (Exception e) {}
+		CourseAttempt.forcePass(courseID, profileID, reason, ilsSession, request, true, cid);
 	}
-	if (ca != null) {
+    
 
-		ca.sendStatusUpdateEvent(session.getServletContext());
+	Vector<Course> courses       = Course.getAllUserCourses(ilsSession, current.getUserProfileID());
+	int wordNum = 0;
 
-		Course course = Course.getCourse(ilsSession, ca.getCourseAttemptCourseID());
-		String certgen = course.getCourseCertificateGenerator();
-		if (certgen != null && certgen.trim().length() > 0) {
-			try {
-				ca.saveCertificate(ca.generateCertificate(ilsSession, request));
+	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>();
+	for (Course cur : curricula) {
+		for (Course c : Course.getCurriculumCourses(ilsSession, cur.getCourseID())) {
+			courseCurriculum.put(c.getCourseID(), cur.getCourseID());
+			courseSupressRetake.put(c.getCourseID(), !cur.isCourseAllowCurriculumPartRetake());
+		}
+	}
+
+	courses.addAll(curricula);
+	Vector<CourseAttempt> courseAttempts = new Vector<CourseAttempt>();
+	for (int j = 0; j < courses.size(); j++) {
+		Course mainCourse = (Course)courses.get(j);
+		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);
+				}
 			}
-			catch (Exception e) {
-				logger.error(e, e);
+			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) || (ca.getCourseAttemptStatusID() == CourseAttempt.STATUS_PASSED)) {
+				courseAttempts.add(ca);
+			}
 		}
-
-		ca.passAllAssociatedCurriculum(ilsSession);
 	}
-    }
-    
-    
-    Vector courses       = Course.getAllUserCourses(ilsSession, current.getUserProfileID());
-    int wordNum = 0;
 
-    Vector<CourseAttempt> courseAttempts = new Vector<CourseAttempt>();
-    for (int j = 0; j < courses.size(); j++) {
-        Course mainCourse = (Course)courses.get(j);
-        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);
-			}
-        	}
-        	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) || (ca.getCourseAttemptStatusID() == CourseAttempt.STATUS_PASSED)) {
-	        	courseAttempts.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.getCourseAttemptStartDate();
-                Date d2 = o2.getCourseAttemptStartDate();
+                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;
@@ -201,10 +188,14 @@
 <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">
+<style>
+	.curriculumHeader {
+		background: lightgrey;
+	}
+</style>
 <script type="text/javascript" src="crosswire.js"></script>
 <script type="text/javascript" src="js/jquery/jquery.min.js"></script>
 <script type="text/javascript">
-<!--
 var rcid=0;
 function retake(inCID) {
 	rcid=inCID;
@@ -245,13 +236,27 @@
 		$('.subCourseID_'+courseID).show();
 	}
 }
+function toggleCurriculumDetails(courseID) {
+	if ($('.subCurriculumID_'+courseID+':first').is(":visible")) {
+		$('#curriculumHeader_'+courseID).html('▶');
+		$('.subCurriculumID_'+courseID).hide();
+		$('.subCourseDetail').hide();
+		$('.courseHeader').html('▶');
+	}
+	else {
+		$('#curriculumHeader_'+courseID).html('▼');
+		$('.subCurriculumID_'+courseID).show();
+		$('.subCourseDetail').hide();
+		$('.courseHeader').html('▶');
+	}
+}
 
 $(document).ready(function() {
 	$('.subCourseDetail').hide();
+	$('.subCurriculumDetail').hide();
 });
 
 
--->
 </script>
 </head>
 <body>
@@ -288,6 +293,7 @@
                         <td><table class="tableDataList">
                             <tr>
                               <th>&nbsp;</th>
+                              <th>&nbsp;</th>
 <% if (managing) { %>                            
                               <th>Comments</th>
 <% } %>                              
@@ -301,30 +307,35 @@
                               <th>Cert</th>
                             </tr>
 <%
+// 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.
 	while (courseAttempts.size() > 0) {
+
+		// first see if we're a course in a Curriculum
 		CourseAttempt ca = courseAttempts.get(0);
-
-		String html = getCourseAttemptHTML(ca, managing, user, ++wordNum);
-		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=\"subCourseDetail subCourseID_"+ca2.getCourseAttemptCourseID()+"\"><td></td>"+getCourseAttemptHTML(ca2, managing, user, ++wordNum)+"</tr>";
-				courseAttempts.remove(ca2);
-				--j;
+		Integer curriculum = courseCurriculum.get(ca.getCourseAttemptCourseID());
+		String html = "";
+		int startSize = courseAttempts.size();
+		// process curriculum first
+		if (curriculum != null) {
+			// find the first course attempt for the curriculum 
+			for (CourseAttempt caCur : courseAttempts) {
+				if (caCur.getCourseAttemptCourseID() == curriculum) {
+					// set this course attempt be the next processed course attempt
+					ca = caCur;
+					break;
+				}
 			}
+			html = getCurriculumHTML(courseSupressRetake, courseCurriculum, courseAttempts, ca, managing, user, wordNum);
 		}
+		else {
+			html = getCourseHTML(courseAttempts, ca, managing, user, wordNum, null, null, false);
+		}
 
-		out.print("<tr>");
-		out.print("<td>");
-		if (moreHTML.length() > 0) {
-			out.write("<span id=\"courseHeader_"+ca.getCourseAttemptCourseID()+"\" onclick=\"toggleCourseDetails('"+ca.getCourseAttemptCourseID()+"');return false;\"> ▶ </span>");
-		}
-		out.write("</td>");
+		int processedSize = courseAttempts.size() - startSize;
+		wordNum += processedSize;
+
 		out.write(html);
-		out.write("</tr>");
-		out.write(moreHTML);
 	}
 %>
                         </table></td>
@@ -353,51 +364,117 @@
 </html>
 
 <%!
-	public static String getCourseAttemptHTML(CourseAttempt ca, boolean managing, UserProfile user, int wordNum) {
 
-		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()) {
-					out.write("<a href=\"#\" onClick=\"retake("+ca.getCourseAttemptID()+");return false;\" class=\"Assign\">Assign Retake</a>");
-				}
-			}
-			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>");
-	        
-			}
+public static String getCourseHTML(Vector<CourseAttempt> courseAttempts, CourseAttempt ca, boolean managing, UserProfile user, int wordNum, String headerAddition, String subClassAddition, boolean supressRetake) {
 
-			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>");
+	if (subClassAddition == null) subClassAddition = "";
+	else subClassAddition += " ";
+
+	StringWriter out = new StringWriter();
+	String html = getCourseAttemptHTML(ca, managing, user, wordNum, supressRetake);
+	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+"subCourseDetail subCourseID_"+ca2.getCourseAttemptCourseID()+"\"><td></td><td></td>"+getCourseAttemptHTML(ca2, managing, user, ++wordNum, supressRetake)+"</tr>";
+			courseAttempts.remove(ca2);
+			--j;
 		}
+	}
 
-		out.write("<td>"+status+"</td>");
-		out.write("<td>"+ca.getStringValue("coursenum")+"</td>");
-		out.write("<td><a href=\"#\" onclick=\"p('course','"+ca.getCourseAttemptCourseID()+"','"+wordNum+"');\"><strong>"+ca.getStringValue("coursename")+"</strong></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("<tr class=\""+subClassAddition+"\">");
+	out.write("<td>");
+	if (headerAddition != null) out.write(headerAddition);
+	out.write("</td><td>");
+	if (moreHTML.length() > 0) {
+		out.write("<span class=\"courseHeader\" 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) {
+
+	Logger logger = Logger.getLogger("getCurriculumHTML");
+
+	StringWriter out = new StringWriter();
+	String headerAddition = ("<span id=\"curriculumHeader_"+caCur.getCourseAttemptCourseID()+"\" onclick=\"toggleCurriculumDetails('"+caCur.getCourseAttemptCourseID()+"');return false;\"> ▶ </span>");
+	String html = getCourseHTML(courseAttempts, caCur, managing, user, wordNum, headerAddition, "curriculumHeader", false);
+	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 curriculum = courseCurriculum.get(ca2.getCourseAttemptCourseID());
+		if (curriculum != null && caCur.getCourseAttemptCourseID() == curriculum.intValue()) {
+logger.info("cours is in cur.");
+			String subClassAddition = "subCurriculumDetail subCurriculumID_"+caCur.getCourseAttemptCourseID();
+			Boolean supressRetake = courseSupressRetake.get(ca2.getCourseAttemptCourseID());
+			moreHTML += getCourseHTML(courseAttempts, ca2, managing, user, ++wordNum, null, subClassAddition, supressRetake != null && supressRetake.booleanValue());
+			--j;
+		}
+		else {
+logger.info("cours NOT is in cur. CourseID:"+ca2.getCourseAttemptCourseID()+"; curParent: " + curriculum);
+		}
+	}
+
+	out.write(html);
+	out.write(moreHTML);
+
+	return out.toString();
+}
+
+
+public static String getCourseAttemptHTML(CourseAttempt ca, boolean managing, UserProfile user, int wordNum, boolean supressRetake) {
+
+	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>");
+			}
+		}
+		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>");
+	
+		}
 
-		if (ca.getSavedCertificate() != null) {
-			out.write("<a target=\"_blank\" href=\"api/courseattempt/cert/get?courseAttemptID="+ca.getCourseAttemptID()+"\"><img src=\"images/certificate_saved.png\"/></a>");
+		String val = "";
+		if (ca.isCourseAttemptExpired()) {
+			val += ca.getCourseAttemptExpiredReason() + "<br/>" + df.format(ca.getCourseAttemptExpiredDate());
 		}
-		out.write("</td>");
+		if (ca.isCourseAttemptForcePass()) {
+			if (val.length() > 0) val += "<br/>";
+			val += ca.getCourseAttemptForcePassReason() + "<br/>" + df.format(ca.getCourseAttemptForcePassDate());
+		}
+		out.write(val+"</td>");
+	}
 
-		return out.toString();
+	out.write("<td>"+status+"</td>");
+	out.write("<td>"+ca.getStringValue("coursenum")+"</td>");
+	out.write("<td><a href=\"#\" onclick=\"p('course','"+ca.getCourseAttemptCourseID()+"','"+wordNum+"');\"><strong>"+ca.getStringValue("coursename")+"</strong></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>");
 	}
+	out.write("</td>");
+
+	return out.toString();
+}
 %>




More information about the Ils-source mailing list