diff --git a/bulkresetcompletion.php b/bulkresetcompletion.php
new file mode 100644
index 0000000..445c93e
--- /dev/null
+++ b/bulkresetcompletion.php
@@ -0,0 +1,112 @@
+.
+
+/**
+ * Manually reset completion date for a course for a selected amount of users.
+ *
+ * @package local_recompletion
+ * @copyright 2023 Catalyst IT
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once(__DIR__ . '/../../config.php');
+require_once($CFG->dirroot . '/user/lib.php');
+require_once($CFG->libdir . '/formslib.php');
+
+$courseid = required_param('id', PARAM_INT);
+$userid = optional_param('user', 0, PARAM_INT);
+$users = optional_param_array('users', [], PARAM_INT);
+
+$course = $DB->get_record('course', ['id' => $courseid], '*', MUST_EXIST);
+require_login($course);
+
+$context = context_course::instance($course->id);
+require_capability('local/recompletion:manage', $context);
+
+$PAGE->set_url('/local/recompletion/editcompletion.php', ['id' => $course->id]);
+
+if (empty($users) && empty($userid)) {
+ // The first time list hack.
+ if ($post = data_submitted()) {
+ foreach ($post as $k => $v) {
+ if (preg_match('/^user(\d+)$/', $k, $m)) {
+ $users[] = (int) $m[1];
+ }
+ }
+ }
+
+ if (empty($users)) {
+ redirect($CFG->wwwroot . '/local/recompletion/participants.php?id=' . $course->id,
+ get_string('nousersselected', 'local_recompletion'));
+ }
+}
+
+if (empty($users)) {
+ $users = [$userid];
+ // Get this users current completion date and use that in the form.
+ $params = ['userid' => $userid, 'course' => $courseid];
+ $ccompletion = new \completion_completion($params);
+ if ($ccompletion->is_complete()) {
+ $date = $ccompletion->timecompleted;
+ }
+}
+
+if (empty($date)) {
+ // Use current time as default.
+ $date = time();
+}
+
+$form = new local_recompletion_coursecompletion_form('editcompletion.php',
+ ['course' => $courseid, 'users' => $users, 'date' => $date]);
+
+if ($form->is_cancelled()) {
+ redirect($CFG->wwwroot . '/local/recompletion/participants.php?id=' . $course->id);
+} else if ($data = $form->get_data()) {
+ if (!empty($data->newcompletion)) {
+ // Update course completion.
+ foreach ($users as $user) {
+ $params = ['userid' => $user, 'course' => $courseid];
+ $ccompletion = new \completion_completion($params);
+ if ($ccompletion->is_complete()) {
+ // If we already have a completion date, clear it first so that mark_complete works.
+ $ccompletion->timecompleted = null;
+ }
+ $ccompletion->mark_complete($data->newcompletion);
+ }
+ redirect($CFG->wwwroot . '/local/recompletion/participants.php?id=' . $course->id,
+ get_string('completionupdated', 'local_recompletion'));
+ }
+}
+
+$userlist = user_get_users_by_id($users);
+
+echo $OUTPUT->header();
+echo $OUTPUT->heading(get_string('editcompletion', 'local_recompletion'));
+echo $OUTPUT->box(get_string('editcompletion_desc', 'local_recompletion'));
+
+echo html_writer::start_div('userlist');
+foreach ($userlist as $user) {
+ echo html_writer::div(fullname($user));
+}
+echo html_writer::end_div();
+
+echo html_writer::start_div('userform');
+$form->display();
+echo html_writer::end_div();
+
+echo $OUTPUT->footer();
diff --git a/editcompletion.php b/editcompletion.php
index 1c42826..d7dcbf0 100644
--- a/editcompletion.php
+++ b/editcompletion.php
@@ -25,6 +25,12 @@
require_once('../../config.php');
require_once($CFG->dirroot.'/user/lib.php');
require_once($CFG->libdir.'/formslib.php');
+require_once($CFG->dirroot.'/local/recompletion/locallib.php');
+require_once($CFG->dirroot.'/course/lib.php');
+require_once($CFG->libdir.'/completionlib.php');
+require_once($CFG->libdir.'/gradelib.php');
+require_once($CFG->dirroot . '/mod/assign/locallib.php');
+require_once($CFG->dirroot . '/mod/quiz/lib.php');
$courseid = required_param('id', PARAM_INT);
$userid = optional_param('user', 0, PARAM_INT);
@@ -70,6 +76,24 @@
$date = time();
}
+// Function to reset completion for $users.
+$resetcompletion = optional_param('reset_completion', 0, PARAM_BOOL);
+if ($resetcompletion && confirm_sesskey()) {
+ $config = $DB->get_records_menu('local_recompletion_config', array('course' => $course->id), '', 'name, value');
+ $config = (object) $config;
+
+ foreach ($users as $user) {
+ $userid = $user;
+ $reset = new local_recompletion\task\check_recompletion();
+ $errors = $reset->reset_user($userid, $course, $config);
+ }
+
+ redirect($CFG->wwwroot.'/local/recompletion/participants.php?id='.$course->id,
+ get_string('completionreset', 'local_recompletion'));
+}
+
+
+
$form = new local_recompletion_coursecompletion_form('editcompletion.php',
array('course' => $courseid, 'users' => $users, 'date' => $date));
diff --git a/lang/en/local_recompletion.php b/lang/en/local_recompletion.php
index a60f7d9..66db622 100644
--- a/lang/en/local_recompletion.php
+++ b/lang/en/local_recompletion.php
@@ -140,8 +140,10 @@
$string['bulkchangedate'] = 'Change completion date for selected users';
$string['nousersselected'] = 'No users were selected';
$string['resetallcompletion'] = 'Reset all completion';
+$string['bulkresetallcompletion'] = 'Reset all completion for selected users';
$string['resetcompletionfor'] = 'Reset completion for {$a}';
$string['completionresetuser'] = 'Completion for {$a} in this course has been reset.';
+$string['completionreset'] = 'Completion for the selected students in this course has been reset.';
$string['modifycompletiondates'] = 'Modify course completion dates';
$string['assignevent'] = 'Update course completion on grade change';
$string['defaultsettings'] = 'Recompletion default settings';
diff --git a/participants.php b/participants.php
index 244781e..da50ad1 100644
--- a/participants.php
+++ b/participants.php
@@ -199,12 +199,12 @@
if ($bulkoperations) {
echo '