[FIX] project : keep one task as model for recurrence

Steps :
Create a recurrent task.
Delete it.
Run the cron "Create Recurring Tasks".

Issue :
IndexError: tuple index out of range.

Cause :
The cron calls a method which takes the last task of the recurrence
as a model. As there is no such task, an python error is thrown.

Fix :
Do not display the "Continue Recurrence" button when deleting the last
task of it.

opw-2743788

closes odoo/odoo#86309

X-original-commit: 9cfe0042dd6846cf8b52aebeb9dd6e7432b32322
Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
This commit is contained in:
Audric Onockx (auon)
2022-03-11 19:46:17 +00:00
parent 714854a9cb
commit 8bd94f422f
+56 -19
View File
@@ -39,14 +39,45 @@ const ProjectListController = ListController.extend({
return this._super(...arguments);
},
_stopRecurrence(recurringResIds, resIds, mode) {
_countRecordsPerReccurence(recurrenceIds, resIds) {
return this._rpc({
model: 'project.task',
method: 'read_group',
args: [
[['recurrence_id', 'in', recurrenceIds], ['id', 'not in', resIds]],
['recurrence_id'],
['recurrence_id'],
],
});
},
async _stopRecurrence(recurringResIds, resIds, mode) {
const recurrenceIdsSet = new Set();
for (const record of this.getSelectedRecords()) {
const recurrenceId = record.data.recurrence_id;
if (recurrenceId) {
recurrenceIdsSet.add(recurrenceId);
}
}
const recurrenceIds = Array.from(recurrenceIdsSet);
// list recurrences that have tasks left after deleting/archiving
let countsLeft = await this._countRecordsPerReccurence(recurrenceIds, recurringResIds);
countsLeft = countsLeft.map(rec => rec.recurrence_id[0]);
// so we check that no recurrence is absent, as it would mean no task is left
const allowContinue = recurrenceIds.every(rec => countsLeft.includes(rec));
let warning;
if (resIds.length > 1) {
warning = _t('It seems that some tasks are part of a recurrence.');
warning = allowContinue
? _t('It seems that some tasks are part of a recurrence.')
: _t('It seems that some tasks are part of a recurrence. At least one of them must be kept as a model to create the next occurences.');
} else {
warning = _t('It seems that this task is part of a recurrence.');
warning = allowContinue
? _t('It seems that this task is part of a recurrence.')
: _t('It seems that this task is part of a recurrence. You must keep it as a model to create the next occurences.');
}
return new Dialog(this, {
const dialog = new Dialog(this, {
buttons: [
{
classes: 'btn-primary',
@@ -66,6 +97,21 @@ const ProjectListController = ListController.extend({
close: true,
text: _t('Stop Recurrence'),
},
{
close: true,
text: _t('Discard'),
}
],
size: 'medium',
title: _t('Confirmation'),
$content: $('<main/>', {
role: 'alert',
text: warning,
}),
});
if (allowContinue) {
Dialog.buttons.splice(0, 1,
{
click: () => {
this._rpc({
@@ -79,22 +125,13 @@ const ProjectListController = ListController.extend({
this._deleteRecords(resIds);
}
});
},
close: true,
text: _t('Continue Recurrence'),
},
{
close: true,
text: _t('Discard'),
}
],
size: 'medium',
title: _t('Confirmation'),
$content: $('<main/>', {
role: 'alert',
text: warning,
}),
}).open();
close: true,
text: _t('Continue Recurrence'),
});
}
dialog.open();
}
});