diff options
| author | jdoutreloux <jud@odoo.com> | 2019-12-24 09:03:08 +0000 |
|---|---|---|
| committer | jdoutreloux <jud@odoo.com> | 2020-02-12 14:01:03 +0000 |
| commit | fdcab45992e7215b20af879f1a01135905ab2eaa (patch) | |
| tree | e9c302d5fc80f4f35ccdb6d84af14405935582d1 /addons | |
| parent | 1bbe7c034c9def4981e1433ea6c388954c0e25c1 (diff) | |
[IMP] sale_timesheet : set the partner_id on the wizard for sale order creation.
The partner_id on the wizard for sale order creation (from project and from tasks) is now set with the one
on the project or on the task if it is set.
Some fields were moved to community (from sale_timesheet_enterprise).
Concerned fields : allow_billable (project and task),
allow_timesheet_timer (project)
This also move timesheet_product_id to community.
This field was being added in industry_fsm_sale and was required
if allow_billable and allow_timesheets were true. But those 2
other fields are already available once sale_timesheet is
installed.
The field timesheet_product_id is thus being moved to
sale_timesheet for more coherence.
Task-2157571
closes odoo/odoo#44509
Related: odoo/enterprise#8118
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
Diffstat (limited to 'addons')
| -rw-r--r-- | addons/sale_timesheet/__manifest__.py | 1 | ||||
| -rw-r--r-- | addons/sale_timesheet/data/sale_service_data.xml | 12 | ||||
| -rw-r--r-- | addons/sale_timesheet/models/project.py | 45 | ||||
| -rw-r--r-- | addons/sale_timesheet/static/img/product_product_time_product.png | bin | 0 -> 5370 bytes | |||
| -rw-r--r-- | addons/sale_timesheet/views/project_task_views.xml | 27 | ||||
| -rw-r--r-- | addons/sale_timesheet/wizard/project_create_sale_order.py | 3 | ||||
| -rw-r--r-- | addons/sale_timesheet/wizard/project_task_create_sale_order.py | 3 |
7 files changed, 74 insertions, 17 deletions
diff --git a/addons/sale_timesheet/__manifest__.py b/addons/sale_timesheet/__manifest__.py index 5afefc9b7ec..63c503ec8c7 100644 --- a/addons/sale_timesheet/__manifest__.py +++ b/addons/sale_timesheet/__manifest__.py @@ -15,6 +15,7 @@ have real delivered quantities in sales orders. """, 'depends': ['sale_project', 'hr_timesheet'], 'data': [ + 'data/sale_service_data.xml', 'security/ir.model.access.csv', 'security/sale_timesheet_security.xml', 'views/account_invoice_views.xml', diff --git a/addons/sale_timesheet/data/sale_service_data.xml b/addons/sale_timesheet/data/sale_service_data.xml new file mode 100644 index 00000000000..b0042b6acdc --- /dev/null +++ b/addons/sale_timesheet/data/sale_service_data.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <data noupdate="1"> + <record id="time_product" model="product.product"> + <field name="name">Service on Timesheet</field> + <field name="type">service</field> + <field name="list_price">40</field> + <field name="service_policy">delivered_timesheet</field> + <field name="image_1920" type="base64" file="sale_timesheet/static/img/product_product_time_product.png"/> + </record> + </data> +</odoo> diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py index a4a050d9649..48c1bf95259 100644 --- a/addons/sale_timesheet/models/project.py +++ b/addons/sale_timesheet/models/project.py @@ -5,9 +5,20 @@ from odoo import api, fields, models, _ from odoo.exceptions import ValidationError +# YTI PLEASE SPLIT ME class Project(models.Model): _inherit = 'project.project' + @api.model + def default_get(self, fields): + """ Pre-fill timesheet product as "Time" data product when creating new project allowing billable tasks by default. """ + result = super(Project, self).default_get(fields) + if 'timesheet_product_id' in fields and result.get('allow_billable') and result.get('allow_timesheets') and not result.get('timesheet_product_id'): + default_product = self.env.ref('sale_timesheet.time_product', False) + if default_product: + result['timesheet_product_id'] = default_product.id + return result + billable_type = fields.Selection([ ('task_rate', 'At Task Rate'), ('employee_rate', 'At Employee Rate'), @@ -22,6 +33,18 @@ class Project(models.Model): "By extension, it defines the rate at which an employee's time on the project is billed.") allow_billable = fields.Boolean("Bill from Tasks") display_create_order = fields.Boolean(compute='_compute_display_create_order') + timesheet_product_id = fields.Many2one( + 'product.product', string='Timesheet Product', + domain="""[ + ('type', '=', 'service'), + ('invoice_policy', '=', 'delivery'), + ('service_type', '=', 'timesheet'), + '|', ('company_id', '=', False), ('company_id', '=', company_id)]""", + help='Select a Service product with which you would like to bill your time spent on tasks.') + + _sql_constraints = [ + ('timesheet_product_required_if_billable_and_timesheets', "CHECK((allow_billable = 't' AND allow_timesheets = 't' AND timesheet_product_id IS NOT NULL) OR (allow_billable = 'f') OR (allow_timesheets = 'f'))", 'The timesheet product is required when the task can be billed and timesheets are allowed.'), + ] @api.depends('billable_type', 'allow_billable', 'sale_order_id', 'partner_id') def _compute_display_create_order(self): @@ -51,14 +74,24 @@ class Project(models.Model): if self.billable_type == 'no': self.sale_line_employee_ids = False - @api.onchange('allow_billable') - def _onchange_allow_billable(self): + @api.depends('allow_timesheets', 'allow_billable') + def _compute_timesheet_product_id(self): + default_product = self.env.ref('sale_timesheet.time_product', False) + for project in self: + if not project.allow_timesheets or not project.allow_billable: + project.timesheet_product_id = False + elif not project.timesheet_product_id: + project.timesheet_product_id = default_product + + @api.depends('allow_billable') + def _compute_allow_billable(self): """ In order to keep task billable type as 'task_rate' using sale_timesheet usual flow. (see _compute_billable_type method in sale_timesheet) """ - if self.allow_billable: - self.sale_order_id = False - self.sale_line_employee_ids = False + self.filtered(lambda p: p.allow_billable).update({ + 'sale_order_id': False, + 'sale_line_employee_ids': False, + }) @api.constrains('sale_line_id', 'billable_type') def _check_sale_line_type(self): @@ -118,6 +151,7 @@ class Project(models.Model): "context": { 'active_id': self.id, 'active_model': 'project.project', + 'default_product_id': self.timesheet_product_id.id, }, } @@ -233,6 +267,7 @@ class ProjectTask(models.Model): 'active_id': self.id, 'active_model': 'project.task', 'form_view_initial_mode': 'edit', + 'default_product_id': self.project_id.timesheet_product_id.id, }, } diff --git a/addons/sale_timesheet/static/img/product_product_time_product.png b/addons/sale_timesheet/static/img/product_product_time_product.png Binary files differnew file mode 100644 index 00000000000..c9d7a77d4f5 --- /dev/null +++ b/addons/sale_timesheet/static/img/product_product_time_product.png diff --git a/addons/sale_timesheet/views/project_task_views.xml b/addons/sale_timesheet/views/project_task_views.xml index b5c7aa3caba..064b16676b1 100644 --- a/addons/sale_timesheet/views/project_task_views.xml +++ b/addons/sale_timesheet/views/project_task_views.xml @@ -4,7 +4,7 @@ <record id="project_project_view_form" model="ir.ui.view"> <field name="name">project.project.form.inherit</field> <field name="model">project.project</field> - <field name="inherit_id" ref="project.edit_project"/> + <field name="inherit_id" ref="hr_timesheet.project_invoice_form"/> <field name="arch" type="xml"> <xpath expr="//header" position="inside"> <button name="action_make_billable" string="Create Sales Order" type="object" attrs="{'invisible': [('display_create_order', '=', False)]}" groups="sales_team.group_sale_salesman"/> @@ -26,25 +26,18 @@ </field> </page> </xpath> - </field> - </record> - - <record id="project_view_form_inherit" model="ir.ui.view"> - <field name="name">project.view.form.inherit</field> - <field name="model">project.project</field> - <field name="inherit_id" ref="hr_timesheet.project_invoice_form"/> - <field name="arch" type="xml"> <xpath expr="//div[@id='timesheet_settings']/.." position="after"> <div class="row mt16 o_settings_container"> <div class="col-lg-6 o_setting_box" id="allow_billable_container" attrs="{'invisible': [('billable_type', '=', 'employee_rate')]}"> <div class="o_setting_left_pane"> - <field name="allow_billable"/> + <field name="allow_billable" attrs="{'readonly': [('sale_order_id', '!=', False)]}"/> </div> <div class="o_setting_right_pane"> <label for="allow_billable"/> <div class="text-muted" id="allow_billable_setting"> Invoice your time and material from tasks </div> + <field name="timesheet_product_id" attrs="{'invisible': ['|', ('allow_billable', '=', False), ('allow_timesheets', '=', False)], 'required': ['&', ('allow_billable', '=', True), ('allow_timesheets', '=', True)]}"/> </div> </div> </div> @@ -52,6 +45,20 @@ </field> </record> + <record id="project_project_view_form_simplified_inherit" model="ir.ui.view"> + <field name="name">project.project.view.form.simplified.inherit</field> + <field name="model">project.project</field> + <field name="inherit_id" ref="hr_timesheet.project_project_view_form_simplified_inherit"/> + <field name="arch" type="xml"> + <field name="allow_timesheet_timer" position="after"> + <field name="billable_type" invisible="1"/> + <field name="company_id" invisible="1"/> + <field name="allow_billable" attrs="{'invisible': [('billable_type', '=', 'employee_rate')]}"/> + <field name="timesheet_product_id" attrs="{'invisible': ['|', ('allow_billable', '=', False), ('allow_timesheets', '=', False)], 'required': ['&', ('allow_billable', '=', True), ('allow_timesheets', '=', True)]}"/> + </field> + </field> + </record> + <record id="project_project_view_kanban_inherit_sale_timesheet" model="ir.ui.view"> <field name="name">project.project.kanban.inherit.sale.timesheet</field> <field name="model">project.project</field> diff --git a/addons/sale_timesheet/wizard/project_create_sale_order.py b/addons/sale_timesheet/wizard/project_create_sale_order.py index 7b6029e8296..aad2648a0d0 100644 --- a/addons/sale_timesheet/wizard/project_create_sale_order.py +++ b/addons/sale_timesheet/wizard/project_create_sale_order.py @@ -23,7 +23,8 @@ class ProjectCreateSalesOrder(models.TransientModel): if project.billable_type != 'no': raise UserError(_("The project is already billable.")) result['project_id'] = active_id - result['partner_id'] = project.partner_id.id + if not result.get('partner_id', False): + result['partner_id'] = project.partner_id.id return result project_id = fields.Many2one('project.project', "Project", domain=[('sale_line_id', '=', False)], help="Project for which we are creating a sales order", required=True) diff --git a/addons/sale_timesheet/wizard/project_task_create_sale_order.py b/addons/sale_timesheet/wizard/project_task_create_sale_order.py index e697f95592c..ffabb0ac9c7 100644 --- a/addons/sale_timesheet/wizard/project_task_create_sale_order.py +++ b/addons/sale_timesheet/wizard/project_task_create_sale_order.py @@ -23,7 +23,8 @@ class ProjectTaskCreateSalesOrder(models.TransientModel): if task.billable_type != 'no': raise UserError(_("The task is already billable.")) result['task_id'] = active_id - result['partner_id'] = task.partner_id.id + if not result.get('partner_id', False): + result['partner_id'] = task.partner_id.id return result task_id = fields.Many2one('project.task', "Task", domain=[('sale_line_id', '=', False)], help="Task for which we are creating a sales order", required=True) |
