[IMP] project: stop recurrence on delete/archive task
closes odoo/odoo#57226 Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
committed by
Yannick Tivisse
parent
642bce457c
commit
32c7b1442e
@@ -1379,6 +1379,10 @@ class Task(models.Model):
|
||||
|
||||
return action
|
||||
|
||||
# ------------
|
||||
# Actions
|
||||
# ------------
|
||||
|
||||
def action_recurring_tasks(self):
|
||||
return {
|
||||
'name': 'Tasks in Recurrence',
|
||||
@@ -1388,6 +1392,15 @@ class Task(models.Model):
|
||||
'domain': [('recurrence_id', 'in', self.recurrence_id.ids)],
|
||||
}
|
||||
|
||||
def action_stop_recurrence(self):
|
||||
tasks = self.env['project.task'].with_context(active_test=False).search([('recurrence_id', 'in', self.recurrence_id.ids)])
|
||||
tasks.write({'recurring_task': False})
|
||||
self.recurrence_id.unlink()
|
||||
|
||||
def action_continue_recurrence(self):
|
||||
self.recurrence_id = False
|
||||
self.recurring_task = False
|
||||
|
||||
# ---------------------------------------------------
|
||||
# Rating business
|
||||
# ---------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
odoo.define('project.ProjectFormView', function (require) {
|
||||
"use strict";
|
||||
|
||||
const Dialog = require('web.Dialog');
|
||||
const FormView = require('web.FormView');
|
||||
const FormController = require('web.FormController');
|
||||
const core = require('web.core');
|
||||
const view_registry = require('web.view_registry');
|
||||
|
||||
const _t = core._t;
|
||||
|
||||
const ProjectFormController = FormController.extend({
|
||||
_getActionMenuItems(state) {
|
||||
if (!this.archiveEnabled || !state.data['recurrence_id']) {
|
||||
return this._super(...arguments);
|
||||
}
|
||||
|
||||
this.archiveEnabled = false;
|
||||
let actions = this._super(...arguments);
|
||||
this.archiveEnabled = true;
|
||||
|
||||
if (actions) {
|
||||
const activeField = this.model.getActiveField(state);
|
||||
actions.items.other.unshift({
|
||||
description: state.data[activeField] ? _t('Archive') : _t('Unarchive'),
|
||||
callback: () => this._stopRecurrence(state.data['id'], state.data[activeField]?'archive':'unarchive'),
|
||||
});
|
||||
}
|
||||
|
||||
return actions;
|
||||
},
|
||||
|
||||
_onDeleteRecord() {
|
||||
const record = this.model.get(this.handle);
|
||||
|
||||
if(!record.data.recurrence_id) {
|
||||
return this._super(...arguments);
|
||||
}
|
||||
this._stopRecurrence(record.res_id, 'delete');
|
||||
},
|
||||
|
||||
_stopRecurrence(res_id, mode) {
|
||||
new Dialog(this, {
|
||||
buttons: [
|
||||
{
|
||||
classes: 'btn-primary',
|
||||
click: () => {
|
||||
this._rpc({
|
||||
model: 'project.task',
|
||||
method: 'action_stop_recurrence',
|
||||
args: [res_id],
|
||||
}).then(() => {
|
||||
if (mode === 'archive') {
|
||||
this._toggleArchiveState(true);
|
||||
} else if (mode === 'unarchive') {
|
||||
this._toggleArchiveState(false);
|
||||
} else if (mode === 'delete') {
|
||||
this._deleteRecords([this.handle]);
|
||||
}
|
||||
});
|
||||
},
|
||||
close: true,
|
||||
text: _t('Stop Recurrence'),
|
||||
},
|
||||
{
|
||||
click: () => {
|
||||
this._rpc({
|
||||
model: 'project.task',
|
||||
method: 'action_continue_recurrence',
|
||||
args: [res_id],
|
||||
}).then(() => {
|
||||
if (mode === 'archive') {
|
||||
this._toggleArchiveState(true);
|
||||
} else if (mode === 'unarchive') {
|
||||
this._toggleArchiveState(false);
|
||||
} else if (mode === 'delete') {
|
||||
this._deleteRecords([this.handle]);
|
||||
}
|
||||
});
|
||||
},
|
||||
close: true,
|
||||
text: _t('Continue Recurrence'),
|
||||
},
|
||||
{
|
||||
close: true,
|
||||
text: _t('Discard'),
|
||||
}
|
||||
],
|
||||
size: 'medium',
|
||||
title: _t('Confirmation'),
|
||||
$content: $('<main/>', {
|
||||
role: 'alert',
|
||||
text: _t('It seems that this task is part of a recurrence.'),
|
||||
}),
|
||||
}).open();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
const ProjectFormView = FormView.extend({
|
||||
config: _.extend({}, FormView.prototype.config, {
|
||||
Controller: ProjectFormController,
|
||||
}),
|
||||
});
|
||||
|
||||
view_registry.add('project_form', ProjectFormView);
|
||||
|
||||
return ProjectFormView;
|
||||
});
|
||||
@@ -0,0 +1,112 @@
|
||||
odoo.define('project.ProjectListView', function (require) {
|
||||
"use strict";
|
||||
|
||||
const Dialog = require('web.Dialog');
|
||||
const ListView = require('web.ListView');
|
||||
const ListController = require('web.ListController');
|
||||
const core = require('web.core');
|
||||
const view_registry = require('web.view_registry');
|
||||
|
||||
const _t = core._t;
|
||||
|
||||
const ProjectListController = ListController.extend({
|
||||
_getActionMenuItems(state) {
|
||||
if(!this.archiveEnabled) {
|
||||
return this._super(...arguments);
|
||||
}
|
||||
|
||||
const recurringRecords = this.getSelectedRecords().filter(rec => rec.data.recurrence_id).map(rec => rec.data.id);
|
||||
this.archiveEnabled = recurringRecords.length == 0;
|
||||
let actions = this._super(...arguments);
|
||||
this.archiveEnabled = true;
|
||||
|
||||
if(actions && recurringRecords.length > 0) {
|
||||
actions.items.other.unshift({
|
||||
description: _t('Archive'),
|
||||
callback: () => this._stopRecurrence(recurringRecords, this.selectedRecords, 'archive'),
|
||||
}, {
|
||||
description: _t('Unarchive'),
|
||||
callback: () => this._toggleArchiveState(false)
|
||||
});
|
||||
}
|
||||
return actions;
|
||||
},
|
||||
|
||||
_onDeleteSelectedRecords() {
|
||||
const recurringRecords = this.getSelectedRecords().filter(rec => rec.data.recurrence_id).map(rec => rec.data.id);
|
||||
if(recurringRecords.length > 0) {
|
||||
return this._stopRecurrence(recurringRecords, this.selectedRecords, 'delete');
|
||||
}
|
||||
|
||||
return this._super(...arguments);
|
||||
},
|
||||
|
||||
_stopRecurrence(recurring_res_ids, res_ids, mode) {
|
||||
let warning;
|
||||
if (res_ids.length > 1) {
|
||||
warning = _t('It seems that some tasks are part of a recurrence.');
|
||||
} else {
|
||||
warning = _t('It seems that this task is part of a recurrence.');
|
||||
}
|
||||
return new Dialog(this, {
|
||||
buttons: [
|
||||
{
|
||||
classes: 'btn-primary',
|
||||
click: () => {
|
||||
this._rpc({
|
||||
model: 'project.task',
|
||||
method: 'action_stop_recurrence',
|
||||
args: [recurring_res_ids],
|
||||
}).then(() => {
|
||||
if (mode === 'archive') {
|
||||
this._toggleArchiveState(true);
|
||||
} else if (mode === 'delete') {
|
||||
this._deleteRecords(res_ids);
|
||||
}
|
||||
});
|
||||
},
|
||||
close: true,
|
||||
text: _t('Stop Recurrence'),
|
||||
},
|
||||
{
|
||||
click: () => {
|
||||
this._rpc({
|
||||
model: 'project.task',
|
||||
method: 'action_continue_recurrence',
|
||||
args: [recurring_res_ids],
|
||||
}).then(() => {
|
||||
if (mode === 'archive') {
|
||||
this._toggleArchiveState(true);
|
||||
} else if (mode === 'delete') {
|
||||
this._deleteRecords(res_ids);
|
||||
}
|
||||
});
|
||||
},
|
||||
close: true,
|
||||
text: _t('Continue Recurrence'),
|
||||
},
|
||||
{
|
||||
close: true,
|
||||
text: _t('Discard'),
|
||||
}
|
||||
],
|
||||
size: 'medium',
|
||||
title: _t('Confirmation'),
|
||||
$content: $('<main/>', {
|
||||
role: 'alert',
|
||||
text: warning,
|
||||
}),
|
||||
}).open();
|
||||
}
|
||||
});
|
||||
|
||||
const ProjectListView = ListView.extend({
|
||||
config: _.extend({}, ListView.prototype.config, {
|
||||
Controller: ProjectListController,
|
||||
}),
|
||||
});
|
||||
|
||||
view_registry.add('project_list', ProjectListView);
|
||||
|
||||
return ProjectListView;
|
||||
});
|
||||
@@ -3,7 +3,9 @@
|
||||
<template id="assets_backend" name="project assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet" href="/project/static/src/css/project.css"/>
|
||||
<script type="text/javascript" src="/project/static/src/js/project_form.js"></script>
|
||||
<script type="text/javascript" src="/project/static/src/js/project_kanban.js"></script>
|
||||
<script type="text/javascript" src="/project/static/src/js/project_list.js"></script>
|
||||
<script type="text/javascript" src="/project/static/src/js/project_rating_reporting.js"></script>
|
||||
<script type="text/javascript" src="/project/static/src/js/project_task_kanban_examples.js"></script>
|
||||
<script type="text/javascript" src="/project/static/src/js/tours/project.js"></script>
|
||||
|
||||
@@ -614,7 +614,7 @@
|
||||
<field name="model">project.task</field>
|
||||
<field eval="2" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Task" class="o_form_project_tasks">
|
||||
<form string="Task" class="o_form_project_tasks" js_class="project_form">
|
||||
<field name="allow_subtasks" invisible="1" />
|
||||
<field name="is_closed" invisible="1" />
|
||||
<field name="allow_recurring_tasks" invisible="1" />
|
||||
@@ -909,7 +909,7 @@
|
||||
<field name="model">project.task</field>
|
||||
<field eval="2" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Tasks" multi_edit="1" sample="1">
|
||||
<tree string="Tasks" multi_edit="1" sample="1" js_class="project_list">
|
||||
<field name="message_needaction" invisible="1" readonly="1"/>
|
||||
<field name="is_closed" invisible="1" />
|
||||
<field name="sequence" invisible="1" readonly="1"/>
|
||||
@@ -923,6 +923,7 @@
|
||||
<field name="date_deadline" optional="hide" widget="remaining_days" attrs="{'invisible': [('is_closed', '=', True)]}"/>
|
||||
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}"/>
|
||||
<field name="stage_id" invisible="context.get('set_visible',False)" optional="show" readonly="1"/>
|
||||
<field name="recurrence_id" invisible="1" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
Reference in New Issue
Block a user