diff options
| -rw-r--r-- | addons/hr_timesheet/tests/test_timesheet.py | 1 | ||||
| -rw-r--r-- | addons/pad_project/models/project.py | 5 | ||||
| -rw-r--r-- | addons/pad_project/views/project_views.xml | 8 | ||||
| -rw-r--r-- | addons/project/models/project.py | 38 | ||||
| -rw-r--r-- | addons/project/views/project_views.xml | 120 | ||||
| -rw-r--r-- | addons/project/views/rating_views.xml | 3 | ||||
| -rw-r--r-- | addons/rating/views/rating_rating_views.xml | 2 | ||||
| -rw-r--r-- | addons/sale_timesheet/data/sale_timesheet_filters.xml | 2 | ||||
| -rw-r--r-- | addons/sale_timesheet/report/project_profitability_report_analysis_views.xml | 1 |
9 files changed, 108 insertions, 72 deletions
diff --git a/addons/hr_timesheet/tests/test_timesheet.py b/addons/hr_timesheet/tests/test_timesheet.py index 4113b052ea0..fdd64970c79 100644 --- a/addons/hr_timesheet/tests/test_timesheet.py +++ b/addons/hr_timesheet/tests/test_timesheet.py @@ -21,6 +21,7 @@ class TestCommonTimesheet(TransactionCase): self.partner = self.env['res.partner'].create({ 'name': 'Customer Task', 'email': 'customer@task.com', + 'phone': '42', }) self.analytic_account = self.env['account.analytic.account'].create({ diff --git a/addons/pad_project/models/project.py b/addons/pad_project/models/project.py index 919755b9987..abc0342671a 100644 --- a/addons/pad_project/models/project.py +++ b/addons/pad_project/models/project.py @@ -42,8 +42,11 @@ class ProjectTask(models.Model): class ProjectProject(models.Model): - _inherit = "project.project" + _name = "project.project" + _inherit = ["project.project", 'pad.common'] + _description = 'Project' + description_pad = fields.Char('Pad URL', pad_content_field='description', copy=False) use_pads = fields.Boolean("Use collaborative pads", default=True, help="Use collaborative pad for the tasks on this project.") diff --git a/addons/pad_project/views/project_views.xml b/addons/pad_project/views/project_views.xml index d4dee168f2a..3539d850e5c 100644 --- a/addons/pad_project/views/project_views.xml +++ b/addons/pad_project/views/project_views.xml @@ -20,6 +20,14 @@ <field name="model">project.project</field> <field name="inherit_id" ref="project.edit_project"/> <field name="arch" type="xml"> + <xpath expr="//field[@name='description']" position="attributes"> + <attribute name="attrs">{'invisible': [('use_pads', '=', True)], 'readonly': [('use_pads', '=', True)]}</attribute> + </xpath> + <field name="description" position="after"> + <field name="use_pads" invisible="1"/> + <field name="description_pad" widget="pad" nolabel="1" + attrs="{'invisible': [('use_pads', '=', False)], 'readonly': [('use_pads', '=', False)]}"/> + </field> <xpath expr="//div[@id='rating_settings']" position="after"> <div class="col-lg-6 o_setting_box" id="pad_settings"> <div class="o_setting_left_pane"> diff --git a/addons/project/models/project.py b/addons/project/models/project.py index d2b8e97d264..d24d6e4e4b3 100644 --- a/addons/project/models/project.py +++ b/addons/project/models/project.py @@ -155,11 +155,17 @@ class Project(models.Model): return [(6, 0, [self.env.uid])] name = fields.Char("Name", index=True, required=True, tracking=True) - description = fields.Text() + description = fields.Html() active = fields.Boolean(default=True, help="If the active field is set to False, it will allow you to hide the project without removing it.") sequence = fields.Integer(default=10, help="Gives the sequence order when displaying a list of Projects.") partner_id = fields.Many2one('res.partner', string='Customer', auto_join=True, tracking=True, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") + partner_email = fields.Char( + compute='_compute_partner_email', inverse='_inverse_partner_email', + string='Email', readonly=False, store=True) + partner_phone = fields.Char( + compute='_compute_partner_phone', inverse='_inverse_partner_phone', + string="Phone", readonly=False, store=True) company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company) currency_id = fields.Many2one('res.currency', related="company_id.currency_id", string="Currency", readonly=True) analytic_account_id = fields.Many2one('account.analytic.account', string="Analytic Account", copy=False, ondelete='set null', @@ -237,6 +243,28 @@ class Project(models.Model): ('project_date_greater', 'check(date >= date_start)', 'Error! project start-date must be lower than project end-date.') ] + @api.depends('partner_id.email') + def _compute_partner_email(self): + for project in self: + if project.partner_id and project.partner_id.email != project.partner_email: + project.partner_email = project.partner_id.email + + def _inverse_partner_email(self): + for project in self: + if project.partner_id and project.partner_email != project.partner_id.email: + project.partner_id.email = project.partner_email + + @api.depends('partner_id.phone') + def _compute_partner_phone(self): + for project in self: + if project.partner_id and project.partner_phone != project.partner_id.phone: + project.partner_phone = project.partner_id.phone + + def _inverse_partner_phone(self): + for project in self: + if project.partner_id and project.partner_phone != project.partner_id.phone: + project.partner_id.phone = project.partner_phone + def _compute_alias_enabled(self): for project in self: project.alias_enabled = project.alias_domain and project.alias_id.alias_name @@ -396,7 +424,11 @@ class Project(models.Model): self.mapped('tasks').message_subscribe( partner_ids=partner_ids, channel_ids=channel_ids, subtype_ids=task_subtypes) if partner_ids: - self.allowed_portal_user_ids |= self.env['res.partner'].browse(partner_ids).user_ids.filtered('share') + all_users = self.env['res.partner'].browse(partner_ids).user_ids + portal_users = all_users.filtered('share') + internal_users = all_users - portal_users + self.allowed_portal_user_ids |= portal_users + self.allowed_internal_user_ids |= internal_users return res def message_unsubscribe(self, partner_ids=None, channel_ids=None): @@ -1384,7 +1416,7 @@ class ProjectTags(models.Model): return randint(1, 11) name = fields.Char('Name', required=True) - color = fields.Integer(string='Color Index', default=_get_default_color) + color = fields.Integer(string='Color', default=_get_default_color) _sql_constraints = [ ('name_uniq', 'unique (name)', "Tag name already exists!"), diff --git a/addons/project/views/project_views.xml b/addons/project/views/project_views.xml index 115164f23c9..9c23ab71bc8 100644 --- a/addons/project/views/project_views.xml +++ b/addons/project/views/project_views.xml @@ -64,7 +64,7 @@ <field name="search_view_id" ref="view_task_search_form"/> <field name="help" type="html"> <p class="o_view_nocontent_smiling_face"> - Click <i>Create</i> to start a new task + No tasks found. Let's create one! </p><p> To get things done, use activities and status on tasks.<br/> Chat in real time or by email to collaborate efficiently. @@ -79,7 +79,7 @@ <field name="search_view_id" ref="project.view_task_search_form"/> <field name="help" type="html"> <p class="o_view_nocontent_smiling_face"> - Click <i>Create</i> to start a new task + No tasks found. Let's create one! </p><p> To get things done, use activities and status on tasks.<br/> Chat in real time or by email to collaborate efficiently. @@ -284,22 +284,44 @@ </div> </div> </div> - <field name="description" placeholder="Describe your project..."/> <notebook> + <page name="description_page" string="Description"> + <field name="description" nolabel="1" placeholder="Describe your project..." type="html"/> + <div class="oe_clear"/> + </page> <page name="settings" string="Settings"> <group> <group> <field name="active" invisible="1"/> <field name="user_id" string="Project Manager" widget="many2one_avatar_user" attrs="{'readonly':[('active','=',False)]}" domain="[('share', '=', False)]"/> <field name="partner_id" string="Customer"/> + <field name="partner_phone" widget="phone" + attrs="{'invisible': [('partner_id', '=', False)]}"/> + <field name="partner_email" widget="email" + attrs="{'invisible': [('partner_id', '=', False)]}"/> <div name="alias_def" colspan="2" attrs="{'invisible': [('alias_domain', '=', False)]}"> - <label for="alias_enabled" class="font-weight-bold" string="Create tasks by sending an email to"/> - <field name="alias_enabled"/> - <span attrs="{'invisible': [('alias_enabled', '=', False)]}"> - <field name="alias_name" class="oe_inline" attrs="{'required': [('alias_enabled', '=', True)]}"/>@<field name="alias_domain" class="oe_inline" readonly="1" /> + <!-- Always display the whole alias in edit mode. It depends in read only --> + <label for="alias_enabled" class="font-weight-bold" string="Create tasks by sending an email"/> + <field name="alias_enabled" invisible="1"/> + <span> + <span class="font-weight-bold oe_read_only" attrs="{'invisible': [('alias_name', '=', False)]}">to </span> + <span class="font-weight-bold oe_edit_only">to </span> + <field name="alias_name" class="oe_inline"/> + <span class="oe_read_only" attrs="{'invisible': [('alias_name', '=', False)]}">@</span> + <span class="oe_edit_only">@</span> + <field name="alias_domain" + attrs="{'invisible': [('alias_name', '=', False)]}" + class="oe_inline oe_read_only" + readonly="1"/> + <field name="alias_domain" + class="oe_inline oe_edit_only" + readonly="1"/> </span> </div> - <field name="alias_contact" class="oe_inline oe_edit_only" string="Accept Emails From" attrs="{'invisible': ['|', ('alias_domain', '=', False), ('alias_enabled', '=', False)]}"/> + <!-- the alias contact must appear when the user start typing and it must disappear + when the string is deleted. --> + <field name="alias_contact" class="oe_inline oe_edit_only" string="Accept Emails From" + attrs="{'invisible': ['|', ('alias_name', '=', ''), ('alias_name', '=', False)]}"/> </group> <group> <field name="analytic_account_id" domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]" context="{'default_partner_id': partner_id}" groups="analytic.group_analytic_accounting"/> @@ -404,7 +426,7 @@ <field name="sequence" optional="show" widget="handle"/> <field name="message_needaction" invisible="1"/> <field name="active" invisible="1"/> - <field name="name" string="Name"/> + <field name="name" string="Name" class="font-weight-bold"/> <field name="user_id" optional="show" string="Project Manager" widget="many2one_avatar_user"/> <field name="partner_id" optional="show" string="Customer"/> <field name="analytic_account_id" optional="hide"/> @@ -416,37 +438,6 @@ </field> </record> - <record id="project_view_kanban" model="ir.ui.view"> - <field name="name">project.project.kanban</field> - <field name="model">project.project</field> - <field name="arch" type="xml"> - <kanban class="o_kanban_mobile"> - <field name="user_id" string="Project Manager"/> - <templates> - <t t-name="kanban-box"> - <div t-attf-class="oe_kanban_content oe_kanban_global_click o_kanban_get_form"> - <div class="row"> - <div class="col-12"> - <strong><field name="name" string="Project Name"/></strong> - </div> - </div> - <div class="row"> - <div class="col-8"> - <field name="partner_id" string="Contact"/> - </div> - <div class="col-4"> - <div class="oe_kanban_bottom_right float-right"> - <field name="user_id" widget="many2one_avatar_user"/> - </div> - </div> - </div> - </div> - </t> - </templates> - </kanban> - </field> - </record> - <record id="project_project_view_form_simplified" model="ir.ui.view"> <field name="name">project.project.view.form.simplified</field> <field name="model">project.project</field> @@ -459,12 +450,10 @@ <field name="allow_recurring_tasks" groups="project.group_project_recurring_tasks" /> </group> <div name="alias_def" colspan="2" attrs="{'invisible': [('alias_domain', '=', False)]}"> - <label for="alias_enabled" class="oe_inline" string="Create tasks by sending an email to"/> - <field name="alias_enabled"/> - <span attrs="{'invisible': [('alias_enabled', '=', False)]}"> - <field name="alias_name" class="oe_inline" attrs="{'required': [('alias_enabled', '=', True)]}" placeholder="e.g. office-party"/> - @ - <field name="alias_domain" class="oe_inline" readonly="1" /> + <label for="alias_name" class="oe_inline" string="Create tasks by sending an email to"/> + <field name="alias_enabled" invisible="1"/> + <span> + <field name="alias_name" class="oe_inline" placeholder="e.g. office-party"/>@<field name="alias_domain" class="oe_inline" readonly="1" /> </span> </div> </form> @@ -585,7 +574,7 @@ <field name="target">main</field> <field name="help" type="html"> <p class="o_view_nocontent_smiling_face"> - Create a project + No projects found. Let's create one! </p><p> Projects regroup tasks on the same topic and each have their own dashboard. </p> @@ -599,12 +588,12 @@ <field name="view_mode">tree,kanban,form</field> <field name="view_ids" eval="[(5, 0, 0), (0, 0, {'view_mode': 'tree', 'view_id': ref('view_project')}), - (0, 0, {'view_mode': 'kanban', 'view_id': ref('project_view_kanban')})]"/> + (0, 0, {'view_mode': 'kanban', 'view_id': ref('view_project_kanban')})]"/> <field name="search_view_id" ref="view_project_project_filter"/> <field name="context">{}</field> <field name="help" type="html"> <p class="o_view_nocontent_smiling_face"> - Create a project + No projects found. Let's create one! </p><p> Projects regroup tasks on the same topic and each have their own dashboard. </p> @@ -677,14 +666,14 @@ </group> <group> <field name="project_id" required="1" domain="[('active', '=', True), ('company_id', '=', company_id)]"/> - <field name="user_id" - class="o_task_user_field" - domain="[('share', '=', False)]"/> <field name="parent_id" domain="[('parent_id', '=', False)]" attrs="{'invisible' : [('allow_subtasks', '=', False)]}" /> + <field name="user_id" + class="o_task_user_field" + domain="[('share', '=', False)]"/> <field name="date_deadline" widget="remaining_days" attrs="{'invisible': [('is_closed', '=', True)]}"/> <field name="recurring_task" attrs="{'invisible': [('allow_recurring_tasks', '=', False)]}" /> <field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color', 'no_create_edit': True}"/> @@ -861,7 +850,7 @@ <span class="fa fa-ellipsis-v"/> </a> <div class="dropdown-menu" role="menu"> - <a t-if="widget.editable" role="menuitem" type="set_cover" data-auto-open="1" class="dropdown-item" data-field="displayed_image_id">Set Cover Image</a> + <a t-if="widget.editable" role="menuitem" type="set_cover" class="dropdown-item" data-field="displayed_image_id">Set Cover Image</a> <a name="%(portal.portal_share_action)d" role="menuitem" type="action" class="dropdown-item">Share</a> <a t-if="widget.editable" role="menuitem" type="edit" class="dropdown-item">Edit</a> <a t-if="widget.editable" role="menuitem" class="dropdown-item" name="toggle_active" type="object"> @@ -915,18 +904,17 @@ <tree string="Tasks" multi_edit="1" sample="1"> <field name="message_needaction" invisible="1" readonly="1"/> <field name="is_closed" invisible="1" /> - <field name="sequence" invisible="not context.get('seq_visible', False)" readonly="1"/> + <field name="sequence" invisible="1" readonly="1"/> <field name="name"/> - <!-- YTI TODO user_invisible and seq_visible seem to be useless --> - <field name="project_id" invisible="context.get('user_invisible', False)" optional="show" readonly="1"/> + <field name="project_id" optional="show" readonly="1"/> <field name="partner_id" optional="hide"/> <field name="parent_id" groups="project.group_subtask_project" optional="hide"/> - <field name="user_id" invisible="context.get('user_invisible', False)" optional="show" widget="many2one_avatar_user"/> + <field name="user_id" optional="show" widget="many2one_avatar_user"/> <field name="company_id" groups="base.group_multi_company" optional="show"/> <field name="activity_ids" widget="list_activity" optional="show"/> <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="tag_ids" optional="hide" widget="many2many_tags" options="{'color_field': 'color'}"/> </tree> </field> </record> @@ -1013,10 +1001,10 @@ <field name="search_view_id" ref="view_task_search_form"/> <field name="help" type="html"> <p class="o_view_nocontent_smiling_face"> - Create a new task + No tasks found. Let's create one! </p><p> - Odoo's project management allows you to manage the pipeline of your tasks efficiently.<br/> - You can track progress, discuss on tasks, attach documents, etc. + To get things done, use activities and status on tasks.<br/> + Chat in real time or by email to collaborate efficiently. </p> </field> </record> @@ -1029,10 +1017,10 @@ <field name="search_view_id" ref="view_task_search_form"/> <field name="help" type="html"> <p class="o_view_nocontent_smiling_face"> - Create a new task + No tasks found. Let's create one! </p><p> - Odoo's project management allows you to manage the pipeline of your tasks efficiently.<br/> - You can track progress, discuss on tasks, attach documents, etc. + To get things done, use activities and status on tasks.<br/> + Chat in real time or by email to collaborate efficiently. </p> </field> </record> @@ -1136,10 +1124,10 @@ <field name="res_model">project.tags</field> <field name="help" type="html"> <p class="o_view_nocontent_smiling_face"> - Create a new tag + No tags found. Let's create one! </p> <p> - Tags are perfect to categorize your tasks. + Tags are perfect to categorize your tasks. </p> </field> </record> diff --git a/addons/project/views/rating_views.xml b/addons/project/views/rating_views.xml index 08b133554fc..48a01e909bb 100644 --- a/addons/project/views/rating_views.xml +++ b/addons/project/views/rating_views.xml @@ -42,6 +42,9 @@ <div name="rating_image_container" position="replace"> <field name="rating_text" string="Rating"/> </div> + <xpath expr="//field[@name='is_internal']" position="attributes"> + <attribute name="invisible">1</attribute> + </xpath> </field> </record> diff --git a/addons/rating/views/rating_rating_views.xml b/addons/rating/views/rating_rating_views.xml index 758103dc695..07dddb12892 100644 --- a/addons/rating/views/rating_rating_views.xml +++ b/addons/rating/views/rating_rating_views.xml @@ -54,7 +54,7 @@ <field name="name">rating.rating.kanban</field> <field name="model">rating.rating</field> <field name="arch" type="xml"> - <kanban create="false"> + <kanban create="false" sample="1"> <field name="rating"/> <field name="res_name"/> <field name="feedback"/> diff --git a/addons/sale_timesheet/data/sale_timesheet_filters.xml b/addons/sale_timesheet/data/sale_timesheet_filters.xml index 2894ad05c76..3794aff0342 100644 --- a/addons/sale_timesheet/data/sale_timesheet_filters.xml +++ b/addons/sale_timesheet/data/sale_timesheet_filters.xml @@ -7,7 +7,7 @@ <field name="user_id" eval="False"/> <field name="is_default" eval="True"/> <field name="context">{ - 'group_by': ['project_id', 'sale_line_id'], + 'group_by': ['line_date'], 'pivot_measures': ['amount_untaxed_to_invoice', 'amount_untaxed_invoiced', 'timesheet_cost', 'timesheet_unit_amount'] }</field> </record> diff --git a/addons/sale_timesheet/report/project_profitability_report_analysis_views.xml b/addons/sale_timesheet/report/project_profitability_report_analysis_views.xml index b6d8b72adf8..2f28170dabb 100644 --- a/addons/sale_timesheet/report/project_profitability_report_analysis_views.xml +++ b/addons/sale_timesheet/report/project_profitability_report_analysis_views.xml @@ -25,6 +25,7 @@ <field name="amount_untaxed_invoiced" type="measure"/> <field name="timesheet_cost" type="measure"/> <field name="other_revenues" type="measure"/> + <field name="margin" type="measure"/> </graph> </field> </record> |
