MDL-52432 tool_lp: Add ability to unlink a plan from its template

This commit is contained in:
Serge Gauthier
2016-04-18 10:58:48 +08:00
committed by Frederic Massart
parent 7a9f14c396
commit a8902ee2d7
11 changed files with 156 additions and 8 deletions
File diff suppressed because one or more lines are too long
+59
View File
@@ -305,6 +305,63 @@ define(['jquery',
var data = this._findPlanData($(e.target));
this.completePlan(data);
};
/**
* Unlink plan and reload the region.
*
* @param {Object} planData Plan data from plan node.
*/
PlanActions.prototype._doUnlinkPlan = function(planData) {
var self = this,
calls = [{
methodname: 'tool_lp_unlink_plan_from_template',
args: { planid: planData.id}
}];
self._callAndRefresh(calls, planData);
};
/**
* Unlink a plan process.
*
* @param {Object} planData Plan data from plan node.
*/
PlanActions.prototype.unlinkPlan = function(planData) {
var self = this,
requests = ajax.call([{
methodname: 'tool_lp_read_plan',
args: { id: planData.id }
}]);
requests[0].done(function(plan) {
str.get_strings([
{ key: 'confirm', component: 'moodle' },
{ key: 'unlinkplantemplateconfirm', component: 'tool_lp', param: plan.name },
{ key: 'unlinkplantemplate', component: 'tool_lp' },
{ key: 'cancel', component: 'moodle' }
]).done(function (strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Unlink plan X?
strings[2], // Unlink.
strings[3], // Cancel.
function() {
self._doUnlinkPlan(planData);
}.bind(self)
);
}).fail(notification.exception);
}).fail(notification.exception);
};
/**
* Unlink plan handler.
*
* @param {Event} e The event.
*/
PlanActions.prototype._unlinkPlanHandler = function(e) {
e.preventDefault();
var data = this._findPlanData($(e.target));
this.unlinkPlan(data);
};
/**
* Find the plan data from the plan node.
@@ -339,6 +396,7 @@ define(['jquery',
'[data-action="plan-delete"]': self._deletePlanHandler.bind(self),
'[data-action="plan-complete"]': self._completePlanHandler.bind(self),
'[data-action="plan-reopen"]': self._reopenPlanHandler.bind(self),
'[data-action="plan-unlink"]': self._unlinkPlanHandler.bind(self),
});
};
@@ -355,6 +413,7 @@ define(['jquery',
wrapper.find('[data-action="plan-delete"]').click(self._deletePlanHandler.bind(self));
wrapper.find('[data-action="plan-complete"]').click(self._completePlanHandler.bind(self));
wrapper.find('[data-action="plan-reopen"]').click(self._reopenPlanHandler.bind(self));
wrapper.find('[data-action="plan-unlink"]').click(self._unlinkPlanHandler.bind(self));
};
return PlanActions;
+5
View File
@@ -1741,6 +1741,11 @@ class api {
throw new required_capability_exception($plan->get_context(), 'tool/lp:planmanage', 'nopermissions', '');
}
// Only plan with status DRAFT or ACTIVE can be unliked..
if ($plan->get_status() == plan::STATUS_COMPLETE) {
throw new coding_exception('Only draft or active plan can be unliked from a template');
}
// Early exit, it's already done...
if (!$plan->is_based_on_template()) {
return true;
+45
View File
@@ -4422,4 +4422,49 @@ class external extends external_api {
return evidence_exporter::get_read_structure();
}
/**
* Returns description of unlink_plan_from_template_() parameters.
*
* @return \external_function_parameters
*/
public static function unlink_plan_from_template_parameters() {
$planid = new external_value(
PARAM_INT,
'Data base record id for the plan',
VALUE_REQUIRED
);
$params = array(
'planid' => $planid,
);
return new external_function_parameters($params);
}
/**
* Unlink the plan from the template.
*
* @param int $planid The plan id
* @return bool
*/
public static function unlink_plan_from_template($planid) {
$params = self::validate_parameters(self::unlink_plan_from_template_parameters(),
array(
'planid' => $planid,
));
$plan = new plan($params['planid']);
self::validate_context($plan->get_context());
return api::unlink_plan_from_template($plan);
}
/**
* Returns description of unlink_plan_from_template_() result value.
*
* @return \external_value
*/
public static function unlink_plan_from_template_returns() {
return new external_value(PARAM_BOOL, 'True if the unlink was successful');
}
}
+6
View File
@@ -53,6 +53,9 @@ class plan_exporter extends persistent_exporter {
$this->persistent->get_status() == $classname::STATUS_COMPLETE,
'usercancomplete' => $this->persistent->can_manage() &&
$this->persistent->get_status() == $classname::STATUS_ACTIVE,
'usercanunlink' => $this->persistent->can_manage() &&
$this->persistent->get_status() != $classname::STATUS_COMPLETE &&
$this->persistent->is_based_on_template(),
'iscompleted' => $this->persistent->get_status() == $classname::STATUS_COMPLETE,
'duedateformatted' => userdate($this->persistent->get_duedate())
);
@@ -85,6 +88,9 @@ class plan_exporter extends persistent_exporter {
'usercancomplete' => array(
'type' => PARAM_BOOL,
),
'usercanunlink' => array(
'type' => PARAM_BOOL,
),
'iscompleted' => array(
'type' => PARAM_BOOL
),
+9 -1
View File
@@ -662,7 +662,6 @@ $functions = array(
'capabilities' => 'tool/lp:userevidencemanageown',
'ajax' => true,
),
'tool_lp_grade_competency_in_plan' => array(
'classname' => 'tool_lp\external',
'methodname' => 'grade_competency_in_plan',
@@ -699,5 +698,14 @@ $functions = array(
'capabilities' => 'tool/lp:coursecompetencyread',
'ajax' => true,
),
'tool_lp_unlink_plan_from_template' => array(
'classname' => 'tool_lp\external',
'methodname' => 'unlink_plan_from_template',
'classpath' => '',
'description' => 'Unlink a plan form it template.',
'type' => 'write',
'capabilities' => 'tool/lp:planmanage',
'ajax' => true,
),
);
+2
View File
@@ -279,6 +279,8 @@ $string['templatename'] = 'Name';
$string['templates'] = 'Learning plan templates';
$string['templateupdated'] = 'Learning plan template updated';
$string['totalrequiredtocomplete'] = 'Total required to complete';
$string['unlinkplantemplate'] = 'Unlink from template';
$string['unlinkplantemplateconfirm'] = 'Unlink the plan \'{$a}\' from its template? Any change made to the template will no longer be applied to the plan. This action can not be undone.';
$string['uponcoursecompletion'] = 'Upon course completion:';
$string['usercompetencystatus_idle'] = 'Idle';
$string['usercompetencystatus_inreview'] = 'In review';
+4 -4
View File
@@ -44,10 +44,10 @@
{{#canread}}
<a href="{{pluginbaseurl}}/templatecompetencies.php?templateid={{id}}&amp;pagecontextid={{contextid}}">
{{/canread}}
{{plan.template.shortname}}
{{#canread}}
</a>
{{/canread}}
{{plan.template.shortname}}{{#canread}}</a>{{/canread}}
{{#plan.usercanunlink}}
(<a data-action="plan-unlink" href="#">{{#str}}unlinkplantemplate, tool_lp{{/str}}</a>)
{{/plan.usercanunlink}}
</dd>
{{/plan.template}}
{{#description}}
@@ -93,6 +93,13 @@
</a>
</li>
{{/usercancomplete}}
{{#usercanunlink}}
<li>
<a data-action="plan-unlink" href="#">
{{#pix}}t/edit{{/pix}} {{#str}}unlinkplantemplate, tool_lp{{/str}}
</a>
</li>
{{/usercanunlink}}
<li>
<a data-action="plan-delete" href="#">
{{#pix}}t/delete{{/pix}} {{#str}}deletethisplan, tool_lp{{/str}}
+17 -1
View File
@@ -29,6 +29,7 @@ use tool_lp\api;
use tool_lp\competency;
use tool_lp\evidence;
use tool_lp\user_competency;
use tool_lp\plan;
/**
* API tests.
@@ -519,8 +520,9 @@ class tool_lp_api_testcase extends advanced_testcase {
'sortorder' => 8));
$tplc2a = $lpg->create_template_competency(array('templateid' => $tpl2->get_id(), 'competencyid' => $c2a->get_id()));
$plan1 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id()));
$plan1 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id(), 'status' => plan::STATUS_ACTIVE));
$plan2 = $lpg->create_plan(array('userid' => $u2->id, 'templateid' => $tpl2->get_id()));
$plan3 = $lpg->create_plan(array('userid' => $u1->id, 'templateid' => $tpl1->get_id(), 'status' => plan::STATUS_COMPLETE));
// Check that we have what we expect at this stage.
$this->assertEquals(2, \tool_lp\template_competency::count_records(array('templateid' => $tpl1->get_id())));
@@ -549,6 +551,20 @@ class tool_lp_api_testcase extends advanced_testcase {
$this->assertTrue($plan2->is_based_on_template());
$this->assertEquals(null, $plan2->get_origtemplateid());
// Check we can unlink draft plan.
try {
api::unlink_plan_from_template($plan2);
} catch (coding_exception $e) {
$this->fail('Fail to unlink draft plan.');
}
// Check we can not unlink completed plan.
try {
api::unlink_plan_from_template($plan3);
$this->fail('We can not unlink completed plan.');
} catch (coding_exception $e) {
}
// Even the order remains.
$plan1comps = \tool_lp\plan_competency::list_competencies($plan1->get_id());
$before = reset($tpl1comps);
+1 -1
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2015111034; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2015111035; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2014110400; // Requires this Moodle version.
$plugin->component = 'tool_lp'; // Full name of the plugin (used for diagnostics).