diff --git a/addons/crm/views/crm_menu_views.xml b/addons/crm/views/crm_menu_views.xml index 3abc031a0b0..b883d166f25 100644 --- a/addons/crm/views/crm_menu_views.xml +++ b/addons/crm/views/crm_menu_views.xml @@ -129,7 +129,7 @@ sequence="10"/>
  • To-Do - Manager: Plan training
  • To-Do - Coach: Training
  • ' - '
  • To-Do - Employee: Send feedback to the manager
  • ') + '') self.assertFalse(form.has_error) wizard = form.save() wizard.action_schedule_plan() diff --git a/addons/hr/views/hr_employee_views.xml b/addons/hr/views/hr_employee_views.xml index 7edb9ba0c5f..712107edd57 100644 --- a/addons/hr/views/hr_employee_views.xml +++ b/addons/hr/views/hr_employee_views.xml @@ -57,7 +57,9 @@ -
    +
    +
    @@ -241,6 +243,9 @@ hr.employee +
    +
    diff --git a/addons/hr/views/mail_activity_plan_views.xml b/addons/hr/views/mail_activity_plan_views.xml index af578ab4252..6bb4ebe458a 100644 --- a/addons/hr/views/mail_activity_plan_views.xml +++ b/addons/hr/views/mail_activity_plan_views.xml @@ -21,11 +21,28 @@ mail.activity.plan + + + + - - res_model == 'hr.employee' + + + + + mail.activity.plan.view.form.hr.employee + primary + mail.activity.plan + 32 + + + + @@ -55,6 +72,21 @@ + + 1 + tree + + + + + + + 2 + form + + + + Launch Plan diff --git a/addons/hr_fleet/tests/test_mail_activity_plan.py b/addons/hr_fleet/tests/test_mail_activity_plan.py index 50d40785059..c12922686bc 100644 --- a/addons/hr_fleet/tests/test_mail_activity_plan.py +++ b/addons/hr_fleet/tests/test_mail_activity_plan.py @@ -44,7 +44,7 @@ class TestActivitySchedule(ActivityScheduleHRCase): form = self._instantiate_activity_schedule_wizard(employees) form.plan_id = self.plan_fleet self.assertEqual(form.plan_assignation_summary, - '
    • To-Do - Fleet Manager: Car return
    ') + '
    • To-Do: Car return
    ') self.assertFalse(form.has_error) wizard = form.save() wizard.action_schedule_plan() diff --git a/addons/mail/i18n/mail.pot b/addons/mail/i18n/mail.pot index f9a4d27c9c0..af5344b1b30 100644 --- a/addons/mail/i18n/mail.pot +++ b/addons/mail/i18n/mail.pot @@ -1199,6 +1199,11 @@ msgstr "" msgid "Are you sure you want to unblacklist this Email Address?" msgstr "" +#. module: mail +#: model:ir.model.fields.selection,name:mail.selection__mail_activity_plan_template__responsible_type__on_demand +msgid "Ask at launch" +msgstr "" + #. module: mail #. odoo-javascript #: code:addons/mail/static/src/views/web/fields/assign_user_command_hook.js:0 @@ -1213,22 +1218,16 @@ msgstr "" msgid "Assign to me" msgstr "" -#. module: mail -#: model:ir.model.fields,field_description:mail.field_mail_activity_plan__assignation_summary -#: model:ir.model.fields,field_description:mail.field_mail_activity_schedule__plan_assignation_summary -#: model_terms:ir.ui.view,arch_db:mail.mail_activity_schedule_view_form -msgid "Assignation summary" -msgstr "" - #. module: mail #: model:ir.model.fields,field_description:mail.field_mail_activity_schedule__plan_on_demand_user_id -msgid "Assigned To (On demand)" +msgid "Assigned To" msgstr "" #. module: mail #. odoo-javascript #: code:addons/mail/static/src/core/web/activity.xml:0 #: model:ir.model.fields,field_description:mail.field_mail_activity__user_id +#: model:ir.model.fields,field_description:mail.field_mail_activity_plan_template__responsible_id #: model:ir.model.fields,field_description:mail.field_mail_activity_schedule__activity_user_id #, python-format msgid "Assigned to" @@ -1244,6 +1243,11 @@ msgid "" "this activity." msgstr "" +#. module: mail +#: model:ir.model.fields,field_description:mail.field_mail_activity_plan_template__responsible_type +msgid "Assignment" +msgstr "" + #. module: mail #. odoo-python #: code:addons/mail/models/mail_thread.py:0 @@ -2611,6 +2615,11 @@ msgid "" "- email (using email_from or email field)" msgstr "" +#. module: mail +#: model:ir.model.fields.selection,name:mail.selection__mail_activity_plan_template__responsible_type__other +msgid "Default user" +msgstr "" + #. module: mail #: model:ir.model.fields,help:mail.field_fetchmail_server__priority msgid "Defines the order of processing, lower values mean higher priority" @@ -6408,10 +6417,6 @@ msgstr "" msgid "Old values" msgstr "" -#. module: mail -#: model:ir.model.fields.selection,name:mail.selection__mail_activity_plan_template__responsible_type__on_demand -msgid "On demand" -msgstr "" #. module: mail #. odoo-javascript @@ -6581,16 +6586,6 @@ msgstr "" msgid "Original message was deleted" msgstr "" -#. module: mail -#: model:ir.model.fields.selection,name:mail.selection__mail_activity_plan_template__responsible_type__other -msgid "Other" -msgstr "" - -#. module: mail -#: model:ir.model.fields,field_description:mail.field_mail_activity_plan_template__responsible_id -msgid "Other Responsible" -msgstr "" - #. module: mail #: model:ir.model.fields.selection,name:mail.selection__mail_mail__state__outgoing #: model_terms:ir.ui.view,arch_db:mail.view_mail_search @@ -6878,7 +6873,7 @@ msgstr "" #. module: mail #: model:ir.model.fields,field_description:mail.field_mail_activity_schedule__plan_date_deadline -msgid "Plan Due Date" +msgid "Plan Date" msgstr "" #. module: mail @@ -6886,6 +6881,17 @@ msgstr "" msgid "Plan Name" msgstr "" +#. module: mail +#: model:ir.model.fields,field_description:mail.field_mail_activity_plan__assignation_summary +#: model:ir.model.fields,field_description:mail.field_mail_activity_schedule__plan_assignation_summary +msgid "Plan Summary" +msgstr "" + +#. module: mail +#: model_terms:ir.ui.view,arch_db:mail.mail_activity_schedule_view_form +msgid "Plan summary" +msgstr "" + #. module: mail #. odoo-javascript #: code:addons/mail/static/src/core/web/activity_list_popover.xml:0 @@ -7598,7 +7604,6 @@ msgstr "" #. module: mail #: model:ir.model.fields,field_description:mail.field_ir_actions_server__activity_user_id #: model:ir.model.fields,field_description:mail.field_ir_cron__activity_user_id -#: model:ir.model.fields,field_description:mail.field_mail_activity_plan_template__responsible_type #: model:ir.model.fields,field_description:mail.field_mail_compose_message__res_domain_user_id msgid "Responsible" msgstr "" @@ -8344,10 +8349,6 @@ msgstr "" msgid "Specific User" msgstr "" -#. module: mail -#: model:ir.model.fields,help:mail.field_mail_activity_plan_template__responsible_id -msgid "Specific responsible of activity if not linked to the employee." -msgstr "" #. module: mail #: model:ir.model.fields,help:mail.field_mail_activity_plan__res_model @@ -10008,7 +10009,8 @@ msgstr "" #. odoo-python #: code:addons/mail/models/mail_activity_plan_template.py:0 #, python-format -msgid "When selecting responsible \"other\", you must specify a responsible." +msgid "" +"When selecting \"Default user\" assignment, you must specify a responsible." msgstr "" #. module: mail diff --git a/addons/mail/models/mail_activity.py b/addons/mail/models/mail_activity.py index c6b310f3c67..7ac69f4dc8f 100644 --- a/addons/mail/models/mail_activity.py +++ b/addons/mail/models/mail_activity.py @@ -185,12 +185,26 @@ class MailActivity(models.Model): self.note = self.activity_type_id.default_note @api.model - def _calculate_date_deadline(self, activity_type): - # Date.context_today is correct because date_deadline is a Date and is meant to be - # expressed in user TZ - base = fields.Date.context_today(self) - if activity_type.delay_from == 'previous_activity' and 'activity_previous_deadline' in self.env.context: + def _calculate_date_deadline(self, activity_type, force_base_date=None): + """ Compute the activity deadline given its type, the force_base_date and the context. + + The deadline is computed by adding the activity type delay to a base date defined as: + - the force_base_date + - or the activity_previous_deadline context value if the activity type delay_from is + previous_activity + - or the current date + + :param activity_type: activity type + :param date force_base_date: if set, this force the base date for computation + """ + if force_base_date: + # Date.context_today is correct because date_deadline is a Date and is meant to be + # expressed in user TZ + base = force_base_date + elif activity_type.delay_from == 'previous_activity' and 'activity_previous_deadline' in self.env.context: base = fields.Date.from_string(self.env.context.get('activity_previous_deadline')) + else: + base = fields.Date.context_today(self) return base + relativedelta(**{activity_type.delay_unit: activity_type.delay_count}) @api.onchange('recommended_activity_type_id') diff --git a/addons/mail/models/mail_activity_plan.py b/addons/mail/models/mail_activity_plan.py index 8c017223a63..87a45fa5680 100644 --- a/addons/mail/models/mail_activity_plan.py +++ b/addons/mail/models/mail_activity_plan.py @@ -33,7 +33,7 @@ class MailActivityPlan(models.Model): help='Specify a model if the activity should be specific to a model' ' and not available when managing activities for other models.') steps_count = fields.Integer(compute='_compute_steps_count') - assignation_summary = fields.Html('Assignation summary', compute='_compute_assignation') + assignation_summary = fields.Html('Plan Summary', compute='_compute_assignation_summary') has_user_on_demand = fields.Boolean('Has on demand responsible', compute='_compute_has_user_on_demand') @api.depends('res_model') @@ -51,13 +51,11 @@ class MailActivityPlan(models.Model): plan.steps_count = len(plan.template_ids) @api.depends('template_ids.summary') - def _compute_assignation(self): + def _compute_assignation_summary(self): self.assignation_summary = '' for plan in self.filtered('template_ids'): - resp_description = dict(self.env['mail.activity.plan.template']._fields['responsible_type']._description_selection(self.env)) summaries = [ - f"{template.activity_type_id.name} - {resp_description[template.responsible_type]}" + - (f": {template.summary}" if template.summary else '') + template.activity_type_id.name + (f": {template.summary}" if template.summary else '') for template in plan.template_ids ] if summaries: diff --git a/addons/mail/models/mail_activity_plan_template.py b/addons/mail/models/mail_activity_plan_template.py index 1200c224819..3faa636660d 100644 --- a/addons/mail/models/mail_activity_plan_template.py +++ b/addons/mail/models/mail_activity_plan_template.py @@ -25,14 +25,13 @@ class MailActivityPlanTemplate(models.Model): ) summary = fields.Char('Summary', compute="_compute_summary", store=True, readonly=False) responsible_type = fields.Selection([ - ('on_demand', 'On demand'), - ('other', 'Other'), - ], default='on_demand', string='Responsible', required=True) + ('on_demand', 'Ask at launch'), + ('other', 'Default user'), + ], default='on_demand', string='Assignment', required=True) responsible_id = fields.Many2one( 'res.users', - 'Other Responsible', - check_company=True, store=True, compute="_compute_responsible_id", readonly=False, - help='Specific responsible of activity if not linked to the employee.') + 'Assigned to', + check_company=True, store=True, compute="_compute_responsible_id", readonly=False) note = fields.Html('Note') @api.constrains('activity_type_id', 'plan_id') @@ -58,7 +57,7 @@ class MailActivityPlanTemplate(models.Model): """ Ensure that responsible_id is set when responsible is set to "other". """ for template in self: if template.responsible_type == 'other' and not template.responsible_id: - raise ValidationError(_('When selecting responsible "other", you must specify a responsible.')) + raise ValidationError(_('When selecting "Default user" assignment, you must specify a responsible.')) @api.depends('activity_type_id') def _compute_summary(self): diff --git a/addons/mail/tests/test_mail_activity.py b/addons/mail/tests/test_mail_activity.py index dfa21449607..61169d704fb 100644 --- a/addons/mail/tests/test_mail_activity.py +++ b/addons/mail/tests/test_mail_activity.py @@ -1,7 +1,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from contextlib import contextmanager -from datetime import timedelta +from dateutil.relativedelta import relativedelta from unittest.mock import patch from odoo import fields @@ -66,13 +66,13 @@ class ActivityScheduleCase(MailCommon): self.assertIn(activity_type.name, last_message.body) self.assertIn('done', last_message.body) - def assertActivitiesFromPlan(self, plan, record, force_date_deadline=None, force_responsible_id=None): + def assertActivitiesFromPlan(self, plan, record, force_base_date_deadline=None, force_responsible_id=None): """ Check that the last activities on the record correspond to the one that the plan must create (number of activities and activities content). :param plan: activity plan that has been applied on the record :param recordset record: record on which the plan has been applied - :param date force_date_deadline: deadline provided when scheduling the plan + :param date force_base_date_deadline: base plan date provided when scheduling the plan :param force_responsible_id: responsible provided when scheduling the plan """ expected_number_of_activity = len(plan.template_ids) @@ -83,10 +83,10 @@ class ActivityScheduleCase(MailCommon): for activity, template in zip(activities, plan.template_ids): self.assertEqual(activity.activity_type_id, template.activity_type_id) - if force_date_deadline: - self.assertEqual(activity.date_deadline, force_date_deadline) - else: - self.assertEqual(activity.date_deadline, fields.Date.today() + timedelta(days=template.activity_type_id.delay_count)) + self.assertEqual( + activity.date_deadline, + (force_base_date_deadline or fields.Date.today()) + relativedelta( + **{template.activity_type_id.delay_unit: template.activity_type_id.delay_count})) self.assertEqual(activity.note, template.note) self.assertEqual(activity.summary, template.summary) if force_responsible_id: @@ -94,23 +94,21 @@ class ActivityScheduleCase(MailCommon): else: self.assertEqual(activity.user_id, template.responsible_id or self.env.user) - def assertMessagesFromPlan(self, plan, record, force_date_deadline=None, force_responsible_id=None): + def assertMessagesFromPlan(self, plan, record, force_base_date_deadline=None, force_responsible_id=None): """ Check that the last posted message on the record correspond to the one that the plan must generate (number of activities and activities content). :param plan: activity plan that has been applied on the record :param recordset record: record on which the plan has been applied - :param date force_date_deadline: deadline provided when scheduling the plan + :param date force_base_date_deadline: deadline provided when scheduling the plan :param force_responsible_id: responsible provided when scheduling the plan """ message = record.message_ids[0] self.assertIn(f'The plan "{plan.name}" has been started', message.body) for template in plan.template_ids: - if force_date_deadline: - date_deadline = force_date_deadline - else: - date_deadline = fields.Date.today() + timedelta(days=template.activity_type_id.delay_count) + date_deadline = (force_base_date_deadline or fields.Date.today()) + relativedelta( + **{template.activity_type_id.delay_unit: template.activity_type_id.delay_count}) if force_responsible_id: responsible_id = force_responsible_id else: @@ -120,19 +118,19 @@ class ActivityScheduleCase(MailCommon): self.assertIn(f'{template.summary or template.activity_type_id.name}, ' f'assigned to {responsible_id.name}, due on the {date_deadline}', message.body) - def assertPlanExecution(self, plan, records, force_date_deadline=None, force_responsible_id=None): + def assertPlanExecution(self, plan, records, force_base_date_deadline=None, force_responsible_id=None): """ Check that the plan has created the right activities and send the right message on the records (see assertActivitiesFromPlan and assertMessagesFromPlan). """ for record in records: self.assertActivitiesFromPlan( plan, record, - force_date_deadline=force_date_deadline, + force_base_date_deadline=force_base_date_deadline, force_responsible_id=force_responsible_id, ) self.assertMessagesFromPlan( plan, record, - force_date_deadline=force_date_deadline, + force_base_date_deadline=force_base_date_deadline, force_responsible_id=force_responsible_id, ) diff --git a/addons/mail/views/mail_activity_plan_views.xml b/addons/mail/views/mail_activity_plan_views.xml index 1f5fd820435..8da2181ff8d 100644 --- a/addons/mail/views/mail_activity_plan_views.xml +++ b/addons/mail/views/mail_activity_plan_views.xml @@ -32,7 +32,6 @@
    - @@ -53,10 +52,13 @@ - + - + + + @@ -73,7 +75,12 @@ 10 - + + bottom + + + 1 + @@ -82,12 +89,6 @@ mail.activity.plan tree,form - -

    Add a new plan @@ -95,5 +96,20 @@ + + 1 + tree + + + + + + + 2 + form + + + + diff --git a/addons/mail/wizard/mail_activity_schedule.py b/addons/mail/wizard/mail_activity_schedule.py index 5c477ba0c2e..30792319a12 100644 --- a/addons/mail/wizard/mail_activity_schedule.py +++ b/addons/mail/wizard/mail_activity_schedule.py @@ -51,11 +51,11 @@ class MailActivitySchedule(models.TransientModel): plan_has_user_on_demand = fields.Boolean(related="plan_id.has_user_on_demand") plan_assignation_summary = fields.Html(related='plan_id.assignation_summary') plan_on_demand_user_id = fields.Many2one( - 'res.users', 'Assigned To (On demand)', + 'res.users', 'Assigned To', help='Choose assignation for activities with on demand assignation.', default=lambda self: self.env.user) plan_date_deadline = fields.Date( - 'Plan Due Date', compute='_compute_plan_date_deadline', + 'Plan Date', compute='_compute_plan_date_deadline', store=True, readonly=False) # activity-based activity_type_id = fields.Many2one( @@ -212,7 +212,7 @@ class MailActivitySchedule(models.TransientModel): else: responsible = template._determine_responsible(self.plan_on_demand_user_id, record)['responsible'] date_deadline = self.env['mail.activity']._calculate_date_deadline( - template.activity_type_id) if not self.plan_date_deadline else self.plan_date_deadline + template.activity_type_id, force_base_date=self.plan_date_deadline) record.activity_schedule( activity_type_id=template.activity_type_id.id, summary=template.summary, diff --git a/addons/mail/wizard/mail_activity_schedule_views.xml b/addons/mail/wizard/mail_activity_schedule_views.xml index 1f2f9c33e7a..bb0c8f74c00 100644 --- a/addons/mail/wizard/mail_activity_schedule_views.xml +++ b/addons/mail/wizard/mail_activity_schedule_views.xml @@ -27,7 +27,7 @@ diff --git a/addons/project/i18n/project.pot b/addons/project/i18n/project.pot index 6c4febdc28b..a0e11739b1e 100644 --- a/addons/project/i18n/project.pot +++ b/addons/project/i18n/project.pot @@ -559,8 +559,9 @@ msgid "Activity Exception Decoration" msgstr "" #. module: project -#: model:ir.ui.menu,name:project.mail_activity_plan_menu_config_task -msgid "Activity Plan" +#: model:ir.actions.act_window,name:project.mail_activity_plan_action_config_project_task_plan +#: model:ir.ui.menu,name:project.mail_activity_plan_menu_config_project +msgid "Activity Plans" msgstr "" #. module: project @@ -591,6 +592,7 @@ msgid "Add Milestone" msgstr "" #. module: project +#: model_terms:ir.actions.act_window,help:project.mail_activity_plan_action_config_project_task_plan #: model_terms:ir.actions.act_window,help:project.mail_activity_plan_action_config_task_plan msgid "Add a new plan" msgstr "" diff --git a/addons/project/security/project_security.xml b/addons/project/security/project_security.xml index 09e4854cdcf..1aed6dcbae9 100644 --- a/addons/project/security/project_security.xml +++ b/addons/project/security/project_security.xml @@ -315,18 +315,18 @@ - Manager can manage task plans + Manager can manage project/task plans - [('res_model', '=', 'project.task')] + [('res_model', 'in', ('project.project', 'project.task'))] - Manager can manage task plan templates + Manager can manage project/task plan templates - [('plan_id.res_model', '=', 'project.task')] + [('plan_id.res_model', 'in', ('project.project', 'project.task'))] diff --git a/addons/project/views/mail_activity_plan_views.xml b/addons/project/views/mail_activity_plan_views.xml index 0a38b02cd1e..a891662bc06 100644 --- a/addons/project/views/mail_activity_plan_views.xml +++ b/addons/project/views/mail_activity_plan_views.xml @@ -1,6 +1,52 @@ + + mail.activity.plan.view.form.project.and.task + mail.activity.plan + primary + 32 + + + + filterable_selection + {'whitelisted_values': ['project.project', 'project.task']} + + + bottom + + + + + + Activity Plans + mail.activity.plan + tree,form + + {'default_res_model': 'project.task'} + [('res_model', 'in', ('project.project', 'project.task'))] + +

    + Add a new plan +

    +
    + + + + 1 + tree + + + + + + + 2 + form + + + + Task Plans mail.activity.plan diff --git a/addons/project/views/project_menus.xml b/addons/project/views/project_menus.xml index 3deb6abce43..5c22d67abf0 100644 --- a/addons/project/views/project_menus.xml +++ b/addons/project/views/project_menus.xml @@ -109,9 +109,9 @@ action="mail_activity_type_action_config_project_types" /> diff --git a/addons/sale/__manifest__.py b/addons/sale/__manifest__.py index 7641996a510..5958231a843 100644 --- a/addons/sale/__manifest__.py +++ b/addons/sale/__manifest__.py @@ -47,6 +47,7 @@ This module contains all the common features of Sales Management and eCommerce. 'views/account_views.xml', 'views/crm_team_views.xml', 'views/mail_activity_views.xml', + 'views/mail_activity_plan_views.xml', 'views/payment_views.xml', 'views/product_document_views.xml', 'views/product_packaging_views.xml', diff --git a/addons/sale/i18n/sale.pot b/addons/sale/i18n/sale.pot index 3c419263985..c34d1a0f329 100644 --- a/addons/sale/i18n/sale.pot +++ b/addons/sale/i18n/sale.pot @@ -769,6 +769,11 @@ msgstr "" msgid "Activity Exception Decoration" msgstr "" +#. module: sale +#: model:ir.ui.menu,name:sale.sale_menu_config_activity_plan +msgid "Activity Plans" +msgstr "" + #. module: sale #: model:ir.model.fields,field_description:sale.field_sale_order__activity_state msgid "Activity State" @@ -785,6 +790,11 @@ msgstr "" msgid "Activity Types" msgstr "" +#. module: sale +#: model_terms:ir.actions.act_window,help:sale.mail_activity_plan_action_sale_order +msgid "Add a new plan" +msgstr "" + #. module: sale #: model_terms:ir.ui.view,arch_db:sale.view_order_form msgid "Add a note" @@ -3614,6 +3624,11 @@ msgstr "" msgid "Sale Order Count" msgstr "" +#. module: sale +#: model:ir.actions.act_window,name:sale.mail_activity_plan_action_sale_order +msgid "Sale Order Plans" +msgstr "" + #. module: sale #: model:ir.model.fields,field_description:sale.field_res_config_settings__group_warning_sale msgid "Sale Order Warnings" diff --git a/addons/sale/security/ir.model.access.csv b/addons/sale/security/ir.model.access.csv index 8ed860e1c66..58d8711886d 100644 --- a/addons/sale/security/ir.model.access.csv +++ b/addons/sale/security/ir.model.access.csv @@ -59,3 +59,5 @@ access_sale_advance_payment_inv,access.sale.advance.payment.inv,model_sale_advan access_sale_order_cancel,access.sale.order.cancel,model_sale_order_cancel,sales_team.group_sale_salesman,1,1,1,0 access_sale_mass_cancel_orders,access.sale.mass.cancel.orders,model_sale_mass_cancel_orders,sales_team.group_sale_salesman,1,1,1,0 access_sale_order_discount,access_sale_order_discount,model_sale_order_discount,sales_team.group_sale_salesman,1,1,1,0 +access_mail_activity_plan_sale_manager,mail.activity.plan.sale.manager,mail.model_mail_activity_plan,sales_team.group_sale_manager,1,1,1,1 +access_mail_activity_plan_template_sale_manager,mail.activity.plan.template.sale.manager,mail.model_mail_activity_plan_template,sales_team.group_sale_manager,1,1,1,1 diff --git a/addons/sale/security/ir_rules.xml b/addons/sale/security/ir_rules.xml index 51330e30738..c05491cd1fd 100644 --- a/addons/sale/security/ir_rules.xml +++ b/addons/sale/security/ir_rules.xml @@ -182,4 +182,20 @@ [('create_uid', '=', user.id)] + + Manager can manage sale order plans + + + [('res_model', '=', 'sale.order')] + + + + + Manager can manage sale order plan templates + + + [('plan_id.res_model', '=', 'sale.order')] + + + diff --git a/addons/sale/views/mail_activity_plan_views.xml b/addons/sale/views/mail_activity_plan_views.xml new file mode 100644 index 00000000000..6455b2ffa7d --- /dev/null +++ b/addons/sale/views/mail_activity_plan_views.xml @@ -0,0 +1,16 @@ + + + + Sale Order Plans + mail.activity.plan + tree,form + + {'default_res_model': 'sale.order'} + [('res_model', '=', 'sale.order')] + +

    + Add a new plan +

    +
    +
    +
    diff --git a/addons/sale/views/sale_menus.xml b/addons/sale/views/sale_menus.xml index 3b68bdd2bec..68e3a920b7a 100644 --- a/addons/sale/views/sale_menus.xml +++ b/addons/sale/views/sale_menus.xml @@ -182,6 +182,14 @@ groups="base.group_no_one" sequence="60" /> + + + diff --git a/addons/test_mail/tests/test_mail_activity_plan.py b/addons/test_mail/tests/test_mail_activity_plan.py index 9db491c3f67..cf97855d70b 100644 --- a/addons/test_mail/tests/test_mail_activity_plan.py +++ b/addons/test_mail/tests/test_mail_activity_plan.py @@ -197,7 +197,7 @@ class TestActivitySchedule(ActivityScheduleCase): self.assertFalse(form.plan_assignation_summary) form.plan_id = self.plan_onboarding self.assertEqual(form.plan_assignation_summary, - '
    • To-Do - Other: Plan training
    • To-Do - Other: Training
    ') + '
    • To-Do: Plan training
    • To-Do: Training
    ') self.assertTrue(form._get_modifier('plan_on_demand_user_id', 'invisible')) form.plan_id = self.plan_party self.assertIn('Book a place', form.plan_assignation_summary) @@ -208,11 +208,11 @@ class TestActivitySchedule(ActivityScheduleCase): self.assertPlanExecution(self.plan_party, test_records) # date_deadline specified, responsible specified - force_date_deadline = date(2050, 1, 15) + force_base_date_deadline = date(2050, 1, 15) force_responsible_id = self.user_admin form = self._instantiate_activity_schedule_wizard(test_records) form.plan_id = self.plan_party - form.plan_date_deadline = force_date_deadline + form.plan_date_deadline = force_base_date_deadline form.plan_on_demand_user_id = self.env['res.users'] self.assertTrue(form.has_error) self.assertIn(f'No responsible specified for {self.activity_type_todo.name}: Book a place', @@ -224,7 +224,7 @@ class TestActivitySchedule(ActivityScheduleCase): self.assertPlanExecution( self.plan_party, test_records, - force_date_deadline=force_date_deadline, + force_base_date_deadline=force_base_date_deadline, force_responsible_id=force_responsible_id) @users('admin')