New completion status

Re: New completion status

by Lee Mulvogue -
Number of replies: 2

Hi Stephan

Something to check is whether a "timecompleted" datestamp (in course_completions) exists; this gets stamped when a successful Completion is achieved (after the cron cycles and updates everything).  If you have a record of an attempt, but no timecompleted datestamp, then it's a failed/incomplete attempt (unless you have set up your Course Completion incorrectly)

A side thing to note is that this "timecompleted" is a one-off; it never updates with any subsequent completions.  If it's a course that the user will re-do in the future, you have to come up with clever jiggery to nullify this datestamp, clear the grades, wipe quiz attempts, etc., etc... because, you know, there's never ever any reason for someone to re-do the same course again in the Real World...

In reply to Lee Mulvogue

Re: New completion status

by Phil Everist -


HI Lee

I don't suppose you have some of that clever jiggery you can share that will allow someone to clear their completion settings (for annuals where staff want to just update their compliance)?

 

Phil

 

 

In reply to Phil Everist

Re: New completion status

by Lee Mulvogue -

Hi Phil

I've got jiggery, fudge, and hocus pocus! wink

NB: We're using 2.5, should also work in 2.6 but I don't know about anything past that.

Here's the essence of what I've done in a few places, which does a few different things;

  • NULLifies "timecompleted", allowing for a new date
  • Deletes any records of Completed course completion criteria; if you don't do this it will just re-trigger a Completion
  • Looks for any issued certificate for that person for that course, and deletes it
  • Deletes any Quiz attempts ONLY if the quiz is set to limited attempts

This all happens if the user has previously been enrolled but is now inactive; on end of enrolment we suspend the user rather than remove them, as that would remove all of their data for future tracking.  So if you re-enrol while still active this step just gets skipped, UNLESS it is a course with shortname starting with "R", in which case every re-enrolment clears the data no matter what (these courses have long enrolment periods and people re-attempt willy-nilly)

     $alreadyEnrolled = false;
     $previouslyEnrolled = false; //exists but not active, needs data clearing
     if (is_enrolled($coursecontext, $user->id, '', true)) {
      if (substr($shortname,0,1) == "R") { //already enrolled  and still active in a CAMS course, wipe
       $previouslyEnrolled = true;
       $mtracemsg = $user->username . ' still enrolled in course ' . $shortname . ', clear existing CAMS data';
       mtrace($mtracemsg);  $adminlog.=$mtracemsg."\r\n";
      }
      else{$alreadyEnrolled = true;} //already enrolled in other course, leave alone
     }
     else if (is_enrolled($coursecontext, $user->id, '', false)) { //enrolled but expired, wipe
      $previouslyEnrolled = true;
      $mtracemsg = $user->username . ' previously enrolled in course ' . $shortname . ', clear existing data';
      mtrace($mtracemsg);  $adminlog.=$mtracemsg."\r\n";
     }
     
     if($previouslyEnrolled){
      $enrollinstances = $DB->get_records('enrol', array('courseid' => $courseid));
      foreach ($enrollinstances as $enrollinstance) {
       $plugin = enrol_get_plugin($enrollinstance->enrol);
       $plugin->unenrol_user($enrollinstance, $user->id);
      }
      
      $DB->delete_records('course_completion_crit_compl', array('userid'=>$user->id,'course'=>$courseid));
      $DB->set_field('course_completions', 'timecompleted', NULL, array('userid'=>$user->id,'course'=>$courseid));
      $certid = $DB->get_field('certificate', 'id', array('course'=>$courseid));
      mtrace("certid: " . $certid);
      $DB->delete_records('certificate_issues', array('userid'=>$user->id,'certificateid'=>$certid));  
      
      $quizinstances = $DB->get_records('quiz', array('course' => $courseid));
      foreach ($quizinstances as $quizinstance) {
       mtrace("quiz id: " . $quizinstance->id . ", attempts limit: " . $quizinstance->attempts);
       if($quizinstance->attempts != "0")
       {
        $DB->delete_records('quiz_attempts', array('userid'=>$user->id,'quiz'=>$quizinstance->id));
        $mtracemsg = 'Quiz has limited attempts, deleting previous quiz attempts';
        mtrace($mtracemsg);  $adminlog.=$mtracemsg."\r\n";
       }
      }      
     }  
     mtrace("alreadyEnrolled: " . $alreadyEnrolled);

Depending on where you are putting this you may need to add various Required code... been a long time since I did it so don't know which is which.

[EDIT] Oh, looks like it must also have a "$coursecontext" already created before this step, you might need to do some digging around to figure that out if you haven't got one defined in your code already