diff --git a/addons/sale_timesheet/data/sale_service_demo.xml b/addons/sale_timesheet/data/sale_service_demo.xml
index 92d989fb2eb..bde8f354b42 100644
--- a/addons/sale_timesheet/data/sale_service_demo.xml
+++ b/addons/sale_timesheet/data/sale_service_demo.xml
@@ -1,5 +1,5 @@
-
+
timesheet
@@ -32,4 +32,4 @@
-
+
diff --git a/addons/sale_timesheet/models/account.py b/addons/sale_timesheet/models/account.py
index 0250d4252b4..c4e4573d7cb 100644
--- a/addons/sale_timesheet/models/account.py
+++ b/addons/sale_timesheet/models/account.py
@@ -1,12 +1,48 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp import models, api
+from odoo import api, models
class AccountAnalyticLine(models.Model):
_inherit = 'account.analytic.line'
+ @api.model
+ def create(self, values):
+ if values.get('task_id'):
+ task = self.env['project.task'].browse(values['task_id'])
+ values['so_line'] = task.sale_line_id.id or values.get('so_line', False)
+ values.update(self._get_timesheet_cost(values))
+ return super(AccountAnalyticLine, self).create(values)
+
+ @api.multi
+ def write(self, values):
+ if values.get('task_id'):
+ task = self.env['project.task'].browse(values['task_id'])
+ values['so_line'] = task.sale_line_id.id or values.get('so_line', False)
+ for line in self:
+ values.update(line._get_timesheet_cost(values))
+ super(AccountAnalyticLine, line).write(values)
+ return True
+
+ def _get_timesheet_cost(self, values):
+ values = values if values is not None else {}
+ if values.get('project_id') or self.project_id:
+ if values.get('amount'):
+ return {}
+ unit_amount = values.get('unit_amount', 0.0) or self.unit_amount
+ user_id = values.get('user_id') or self.user_id.id or self._default_user()
+ user = self.env['res.users'].browse([user_id])
+ emp = self.env['hr.employee'].search([('user_id', '=', user_id)], limit=1)
+ cost = emp and emp.timesheet_cost or 0.0
+ uom = (emp or user).company_id.project_time_mode_id
+ # Nominal employee cost = 1 * company project UoM (project_time_mode_id)
+ return {
+ 'amount': -unit_amount * cost,
+ 'product_uom_id': uom.id
+ }
+ return {}
+
def _get_sale_order_line(self, vals=None):
result = dict(vals or {})
if self.project_id:
@@ -26,45 +62,6 @@ class AccountAnalyticLine(models.Model):
'so_line': sol.id,
'product_id': sol.product_id.id,
})
- result = self._get_timesheet_cost(result)
+ result.update(self._get_timesheet_cost(result))
- result = super(AccountAnalyticLine, self)._get_sale_order_line(vals=result)
- return result
-
- def _get_timesheet_cost(self, vals=None):
- result = dict(vals or {})
- if result.get('project_id') or self.project_id:
- if result.get('amount'):
- return result
- unit_amount = result.get('unit_amount', 0.0) or self.unit_amount
- user_id = result.get('user_id') or self.user_id.id or self._default_user()
- user = self.env['res.users'].browse([user_id])
- emp = self.env['hr.employee'].search([('user_id', '=', user_id)], limit=1)
- cost = emp and emp.timesheet_cost or 0.0
- uom = (emp or user).company_id.project_time_mode_id
- # Nominal employee cost = 1 * company project UoM (project_time_mode_id)
- result.update(
- amount=(-unit_amount * cost),
- product_uom_id=uom.id
- )
- return result
-
- @api.model
- def _update_values(self, values):
- if values.get('task_id', False):
- task = self.env['project.task'].browse(values['task_id'])
- values['so_line'] = task.sale_line_id and task.sale_line_id.id or values.get('so_line', False)
-
- @api.multi
- def write(self, values):
- self._update_values(values)
- for line in self:
- values = line._get_timesheet_cost(vals=values)
- super(AccountAnalyticLine, line).write(values)
- return True
-
- @api.model
- def create(self, values):
- self._update_values(values)
- values = self._get_timesheet_cost(vals=values)
- return super(AccountAnalyticLine, self).create(values)
+ return super(AccountAnalyticLine, self)._get_sale_order_line(vals=result)
diff --git a/addons/sale_timesheet/models/hr.py b/addons/sale_timesheet/models/hr.py
index 5ee69e82d16..546b3d21534 100644
--- a/addons/sale_timesheet/models/hr.py
+++ b/addons/sale_timesheet/models/hr.py
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp import models, fields
+from odoo import fields, models
class HrEmployee(models.Model):
_inherit = 'hr.employee'
+
# FIXME: this field should be in module hr_timesheet, not sale_timesheet
- timesheet_cost = fields.Float(string='Timesheet Cost', default=0.0)
+ timesheet_cost = fields.Float('Timesheet Cost', default=0.0)
diff --git a/addons/sale_timesheet/models/procurement.py b/addons/sale_timesheet/models/procurement.py
index ba07285cb34..b8d34d70fd1 100644
--- a/addons/sale_timesheet/models/procurement.py
+++ b/addons/sale_timesheet/models/procurement.py
@@ -1,85 +1,76 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp.osv import fields, osv
-from openerp.tools.translate import _
+from odoo import api, fields, models, _
-class procurement_order(osv.osv):
- _name = "procurement.order"
- _inherit = "procurement.order"
- _columns = {
- 'task_id': fields.many2one('project.task', 'Task', copy=False),
- }
+class ProcurementOrder(models.Model):
+ _inherit = 'procurement.order'
- def _is_procurement_task(self, cr, uid, ids, context=None):
- procurement = self.browse(cr, uid, ids[0], context=context)
- return procurement.product_id.type == 'service' and procurement.product_id.track_service=='task' or False
+ task_id = fields.Many2one('project.task', 'Task', copy=False)
- def _assign(self, cr, uid, ids, context=None):
- procurement = self.browse(cr, uid, ids[0], context=context)
- res = super(procurement_order, self)._assign(cr, uid, ids, context=context)
+ def _is_procurement_task(self):
+ return self.product_id.type == 'service' and self.product_id.track_service == 'task'
+
+ @api.multi
+ def _assign(self):
+ self.ensure_one()
+ res = super(ProcurementOrder, self)._assign()
if not res:
- #if there isn't any specific procurement.rule defined for the product, we may want to create a task
- return procurement._is_procurement_task()
+ # if there isn't any specific procurement.rule defined for the product, we may want to create a task
+ return self._is_procurement_task()
return res
- def _run(self, cr, uid, ids, context=None):
- procurement = self.browse(cr, uid, ids[0], context=context)
- if procurement._is_procurement_task() and not procurement.task_id:
- #create a task for the procurement
- return self._create_service_task(cr, uid, procurement, context=context)
- return super(procurement_order, self)._run(cr, uid, ids, context=context)
+ @api.multi
+ def _run(self):
+ self.ensure_one()
+ if self._is_procurement_task() and not self.task_id:
+ # create a task for the procurement
+ return self._create_service_task()
+ return super(ProcurementOrder, self)._run()
- def _convert_qty_company_hours(self, cr, uid, procurement, context=None):
- product_uom = self.pool.get('product.uom')
- company_time_uom_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.project_time_mode_id
- if procurement.product_uom.id != company_time_uom_id.id and procurement.product_uom.category_id.id == company_time_uom_id.category_id.id:
- planned_hours = product_uom._compute_quantity(cr, uid, [procurement.product_uom.id], procurement.product_qty, company_time_uom_id)
+ def _convert_qty_company_hours(self):
+ company_time_uom_id = self.env.user.company_id.project_time_mode_id
+ if self.product_uom.id != company_time_uom_id.id and self.product_uom.category_id.id == company_time_uom_id.category_id.id:
+ planned_hours = self.product_uom._compute_quantity(self.product_qty, company_time_uom_id)
else:
- planned_hours = procurement.product_qty
+ planned_hours = self.product_qty
return planned_hours
- def _get_project(self, cr, uid, procurement, context=None):
- project_project = self.pool.get('project.project')
- project = procurement.product_id.project_id
- if not project and procurement.sale_line_id:
+ def _get_project(self):
+ Project = self.env['project.project']
+ project = self.product_id.project_id
+ if not project and self.sale_line_id:
# find the project corresponding to the analytic account of the sales order
- account = procurement.sale_line_id.order_id.project_id
+ account = self.sale_line_id.order_id.project_id
if not account:
- procurement.sale_line_id.order_id._create_analytic_account()
- account = procurement.sale_line_id.order_id.project_id
- project_ids = project_project.search(cr, uid, [('analytic_account_id', '=', account.id)])
- projects = project_project.browse(cr, uid, project_ids, context=context)
- project = projects and projects[0]
+ self.sale_line_id.order_id._create_analytic_account()
+ account = self.sale_line_id.order_id.project_id
+ project = Project.search([('analytic_account_id', '=', account.id)], limit=1)
if not project:
project_id = account.project_create({'name': account.name, 'use_tasks': True})
- project = project_project.browse(cr, uid, project_id, context=context)
+ project = Project.browse(project_id)
return project
- def _create_service_task(self, cr, uid, procurement, context=None):
- project_task = self.pool.get('project.task')
- project = self._get_project(cr, uid, procurement, context=context)
- planned_hours = self._convert_qty_company_hours(cr, uid, procurement, context=context)
- task_id = project_task.create(cr, uid, {
- 'name': '%s:%s' % (procurement.origin or '', procurement.product_id.name),
- 'date_deadline': procurement.date_planned,
+ def _create_service_task(self):
+ project = self._get_project()
+ planned_hours = self._convert_qty_company_hours()
+ task = self.env['project.task'].create({
+ 'name': '%s:%s' % (self.origin or '', self.product_id.name),
+ 'date_deadline': self.date_planned,
'planned_hours': planned_hours,
'remaining_hours': planned_hours,
- 'partner_id': procurement.sale_line_id and procurement.sale_line_id.order_id.partner_id.id or procurement.partner_dest_id.id,
- 'user_id': procurement.product_id.product_manager.id,
- 'procurement_id': procurement.id,
- 'description': procurement.name + '\n',
- 'project_id': project and project.id or False,
- 'company_id': procurement.company_id.id,
- },context=context)
- self.write(cr, uid, [procurement.id], {'task_id': task_id}, context=context)
- self.project_task_create_note(cr, uid, [procurement.id], context=context)
- return task_id
+ 'partner_id': self.sale_line_id.order_id.partner_id.id or self.partner_dest_id.id,
+ 'user_id': self.product_id.product_manager.id,
+ 'procurement_id': self.id,
+ 'description': self.name + '\n',
+ 'project_id': project.id,
+ 'company_id': self.company_id.id,
+ })
+ self.write({'task_id': task.id})
- def project_task_create_note(self, cr, uid, ids, context=None):
- for procurement in self.browse(cr, uid, ids, context=context):
- body = _("Task created")
- self.message_post(cr, uid, [procurement.id], body=body, context=context)
- if procurement.sale_line_id and procurement.sale_line_id.order_id:
- procurement.sale_line_id.order_id.message_post(body=body)
+ self.message_post(body=_("Task created"))
+ if self.sale_line_id.order_id:
+ self.sale_line_id.order_id.message_post(body=_("Task created"))
+
+ return task
diff --git a/addons/sale_timesheet/models/product.py b/addons/sale_timesheet/models/product.py
index bc67ec9b68c..e001e0ad47a 100644
--- a/addons/sale_timesheet/models/product.py
+++ b/addons/sale_timesheet/models/product.py
@@ -1,23 +1,25 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp import api, fields, models
+from odoo import api, fields, models
class ProductTemplate(models.Model):
_inherit = 'product.template'
- track_service = fields.Selection(selection_add=[('timesheet', 'Timesheets on project'), ('task', 'Create a task and track hours')])
- project_id = fields.Many2one('project.project', string='Project',
- help='Create a task under this project on sale order validation. This setting must be set for each company.',
- company_dependent=True)
- @api.onchange('type', 'invoice_policy')
- def onchange_type_timesheet(self):
+ track_service = fields.Selection(selection_add=[
+ ('timesheet', 'Timesheets on project'),
+ ('task', 'Create a task and track hours')])
+ project_id = fields.Many2one(
+ 'project.project', 'Project', company_dependent=True,
+ help='Create a task under this project on sale order validation. This setting must be set for each company.')
+
+ @api.onchange('type')
+ def _onchange_type(self):
if self.type == 'service':
self.track_service = 'timesheet'
else:
self.track_service = 'manual'
- return {}
class ProductProduct(models.Model):
diff --git a/addons/sale_timesheet/models/project.py b/addons/sale_timesheet/models/project.py
index 8b6637ece2c..c52d5c228b7 100644
--- a/addons/sale_timesheet/models/project.py
+++ b/addons/sale_timesheet/models/project.py
@@ -1,45 +1,34 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp.osv import fields, osv
-from openerp.exceptions import UserError
-from openerp.tools.translate import _
+from odoo import api, fields, models, _
+from odoo.exceptions import ValidationError
-class project_task(osv.osv):
- _name = "project.task"
+class ProjectTask(models.Model):
_inherit = "project.task"
- _columns = {
- 'procurement_id': fields.many2one('procurement.order', 'Procurement', ondelete='set null'),
- 'sale_line_id': fields.related('procurement_id', 'sale_line_id', type='many2one', relation='sale.order.line', store=True, string='Sales Order Line'),
- }
- def unlink(self, cr, uid, ids, context=None):
- if context is None:
- context = {}
- for task in self.browse(cr, uid, ids, context=context):
- if task.sale_line_id:
- raise UserError(_('You cannot delete a task related to a Sale Order. You can only archive this task.'))
- res = super(project_task, self).unlink(cr, uid, ids, context)
- return res
+ procurement_id = fields.Many2one('procurement.order', 'Procurement', ondelete='set null')
+ sale_line_id = fields.Many2one('sale.order.line', 'Sales Order Line', related='procurement_id.sale_line_id', store=True)
- def action_view_so(self, cr, uid, ids, context=None):
- task = self.browse(cr, uid, ids, context=context)[0]
+ @api.multi
+ def unlink(self):
+ if any(task.sale_line_id for task in self):
+ raise ValidationError(_('You cannot delete a task related to a Sale Order. You can only archive this task.'))
+ return super(ProjectTask, self).unlink()
+
+ @api.multi
+ def action_view_so(self):
+ self.ensure_one()
return {
"type": "ir.actions.act_window",
"res_model": "sale.order",
"views": [[False, "form"]],
- "res_id": task.sale_line_id.order_id.id,
+ "res_id": self.sale_line_id.order_id.id,
"context": {"create": False, "show_sale": True},
}
- def onchange_parent_id(self, cr, uid, ids, parent_id, context=None):
- if not parent_id:
- return {'value' : {'procurement_id': False, 'sale_line_id': False }}
- parent_task = self.browse(cr, uid, parent_id, context=context)
- return {
- 'value' : {
- 'procurement_id' : parent_task.procurement_id.id,
- 'sale_line_id' : parent_task.sale_line_id.id,
- }
- }
+ @api.onchange('parent_id')
+ def onchange_parent_id(self):
+ self.procurement_id = self.parent_id.procurement_id.id
+ self.sale_line_id = self.parent_id.sale_line_id.id
diff --git a/addons/sale_timesheet/models/res_company.py b/addons/sale_timesheet/models/res_company.py
index f8b279a8225..19d5ce45ea0 100644
--- a/addons/sale_timesheet/models/res_company.py
+++ b/addons/sale_timesheet/models/res_company.py
@@ -1,16 +1,14 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp import models, api, fields
+from odoo import models, api, fields
class ResCompany(models.Model):
_inherit = 'res.company'
@api.model
- def _get_uom_hours(self):
- try:
- return self.env.ref("product.product_uom_hour")
- except ValueError:
- return False
- project_time_mode_id = fields.Many2one('product.uom', string='Timesheet UoM', default=_get_uom_hours)
+ def _get_default_uom_id(self):
+ return self.env.ref("product.product_uom_hour", raise_if_not_found=False)
+
+ project_time_mode_id = fields.Many2one('product.uom', 'Timesheet UoM', default=_get_default_uom_id)
diff --git a/addons/sale_timesheet/models/sale_order.py b/addons/sale_timesheet/models/sale_order.py
index 51f288ca399..1ea09798345 100644
--- a/addons/sale_timesheet/models/sale_order.py
+++ b/addons/sale_timesheet/models/sale_order.py
@@ -1,10 +1,9 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp import models, api, fields
-from openerp.tools.translate import _
+from odoo import api, fields, models, _
-from openerp.exceptions import ValidationError
+from odoo.exceptions import ValidationError
class SaleOrder(models.Model):
@@ -31,6 +30,19 @@ class SaleOrder(models.Model):
order.timesheet_ids = []
order.timesheet_count = len(order.timesheet_ids)
+ @api.multi
+ @api.depends('order_line.product_id.project_id')
+ def _compute_tasks_ids(self):
+ for order in self:
+ order.tasks_ids = self.env['project.task'].search([('sale_line_id', 'in', order.order_line.ids)])
+ order.tasks_count = len(order.tasks_ids)
+
+ @api.multi
+ @api.depends('project_id.project_ids')
+ def _compute_project_project_id(self):
+ for order in self:
+ order.project_project_id = self.env['project.project'].search([('analytic_account_id', '=', order.project_id.id)])
+
@api.multi
@api.constrains('order_line')
def _check_multi_timesheet(self):
@@ -44,19 +56,24 @@ class SaleOrder(models.Model):
return {}
@api.multi
- @api.depends('order_line.product_id.project_id')
- def _compute_tasks_ids(self):
+ def action_confirm(self):
+ result = super(SaleOrder, self).action_confirm()
for order in self:
- order.tasks_ids = self.env['project.task'].search([('sale_line_id', 'in', order.order_line.ids)])
- order.tasks_count = len(order.tasks_ids)
+ if not order.project_project_id:
+ for line in order.order_line:
+ if line.product_id.track_service == 'timesheet':
+ if not order.project_id:
+ order._create_analytic_account(prefix=line.product_id.default_code or None)
+ order.project_id.project_create({'name': order.project_id.name, 'use_tasks': True})
+ break
+ return result
@api.multi
def action_view_task(self):
self.ensure_one()
- imd = self.env['ir.model.data']
- action = imd.xmlid_to_object('project.action_view_task')
- list_view_id = imd.xmlid_to_res_id('project.view_task_tree2')
- form_view_id = imd.xmlid_to_res_id('project.view_task_form2')
+ action = self.env.ref('project.action_view_task')
+ list_view_id = self.env.ref('project.view_task_tree2').id
+ form_view_id = self.env.ref('project.view_task_form2').id
result = {
'name': action.name,
@@ -76,18 +93,11 @@ class SaleOrder(models.Model):
result = {'type': 'ir.actions.act_window_close'}
return result
- @api.multi
- @api.depends('project_id.project_ids')
- def _compute_project_project_id(self):
- for order in self:
- order.project_project_id = self.env['project.project'].search([('analytic_account_id', '=', order.project_id.id)])
-
@api.multi
def action_view_project_project(self):
self.ensure_one()
- imd = self.env['ir.model.data']
- action = imd.xmlid_to_object('project.open_view_project_all')
- form_view_id = imd.xmlid_to_res_id('project.edit_project')
+ action = self.env.ref('project.open_view_project_all')
+ form_view_id = self.env.ref('project.edit_project').id
result = {
'name': action.name,
@@ -101,26 +111,12 @@ class SaleOrder(models.Model):
}
return result
- @api.multi
- def action_confirm(self):
- result = super(SaleOrder, self).action_confirm()
- for order in self:
- if not order.project_project_id:
- for line in order.order_line:
- if line.product_id.track_service == 'timesheet':
- if not order.project_id:
- order._create_analytic_account(prefix=line.product_id.default_code or None)
- order.project_id.project_create({'name': order.project_id.name, 'use_tasks': True})
- break
- return result
-
@api.multi
def action_view_timesheet(self):
self.ensure_one()
- imd = self.env['ir.model.data']
- action = imd.xmlid_to_object('hr_timesheet.act_hr_timesheet_line')
- list_view_id = imd.xmlid_to_res_id('hr_timesheet.hr_timesheet_line_tree')
- form_view_id = imd.xmlid_to_res_id('hr_timesheet.hr_timesheet_line_form')
+ action = self.env.ref('hr_timesheet.act_hr_timesheet_line')
+ list_view_id = self.env.ref('hr_timesheet.hr_timesheet_line_tree').id
+ form_view_id = self.env.ref('hr_timesheet.hr_timesheet_line_form').id
result = {
'name': action.name,
@@ -141,16 +137,16 @@ class SaleOrder(models.Model):
class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
- @api.multi
- def _compute_analytic(self, domain=None):
- if not domain:
- # To filter on analyic lines linked to an expense
- domain = [('so_line', 'in', self.ids), '|', ('amount', '<=', 0.0), ('project_id', '!=', False)]
- return super(SaleOrderLine, self)._compute_analytic(domain=domain)
-
@api.model
def create(self, values):
line = super(SaleOrderLine, self).create(values)
if line.state == 'sale' and not line.order_id.project_id and line.product_id.track_service in ['timesheet', 'task']:
line.order_id._create_analytic_account()
return line
+
+ @api.multi
+ def _compute_analytic(self, domain=None):
+ if not domain:
+ # To filter on analyic lines linked to an expense
+ domain = [('so_line', 'in', self.ids), '|', ('amount', '<=', 0.0), ('project_id', '!=', False)]
+ return super(SaleOrderLine, self)._compute_analytic(domain=domain)
diff --git a/addons/sale_timesheet/tests/test_sale_service.py b/addons/sale_timesheet/tests/test_sale_service.py
index ee9e23feea1..218eaafb30a 100644
--- a/addons/sale_timesheet/tests/test_sale_service.py
+++ b/addons/sale_timesheet/tests/test_sale_service.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp.addons.sale.tests.test_sale_common import TestSale
+from odoo.addons.sale.tests.test_sale_common import TestSale
class TestSaleService(TestSale):
diff --git a/addons/sale_timesheet/tests/test_sale_timesheet.py b/addons/sale_timesheet/tests/test_sale_timesheet.py
index 04b6a10afa9..309650aee2f 100644
--- a/addons/sale_timesheet/tests/test_sale_timesheet.py
+++ b/addons/sale_timesheet/tests/test_sale_timesheet.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp.tools import float_is_zero
+from odoo.tools import float_is_zero
-from openerp.addons.sale.tests.test_sale_common import TestSale
+from odoo.addons.sale.tests.test_sale_common import TestSale
class TestSaleTimesheet(TestSale):
diff --git a/addons/sale_timesheet/views/hr_views.xml b/addons/sale_timesheet/views/hr_views.xml
index bbba04e7282..01578bb5d07 100644
--- a/addons/sale_timesheet/views/hr_views.xml
+++ b/addons/sale_timesheet/views/hr_views.xml
@@ -1,17 +1,15 @@
-
-
-
- hr.timesheet.employee.extd_form
- hr.employee
-
-
-
-
-
-
-
-
-
-
-
+
+
+ hr.timesheet.employee.extd_form
+ hr.employee
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/sale_timesheet/views/procurement_views.xml b/addons/sale_timesheet/views/procurement_views.xml
index 63843516c0b..393ef3c8fba 100644
--- a/addons/sale_timesheet/views/procurement_views.xml
+++ b/addons/sale_timesheet/views/procurement_views.xml
@@ -1,15 +1,13 @@
-
-
-
- procurement.procurement.form.view.inherit
- procurement.order
-
-
-
-
-
+
+
+ procurement.procurement.form.view.inherit
+ procurement.order
+
+
+
+
-
-
-
+
+
+
\ No newline at end of file
diff --git a/addons/sale_timesheet/views/product_views.xml b/addons/sale_timesheet/views/product_views.xml
index 00d08ada78f..5525ae66d73 100644
--- a/addons/sale_timesheet/views/product_views.xml
+++ b/addons/sale_timesheet/views/product_views.xml
@@ -1,19 +1,17 @@
-
-
-
- product.template.timesheet.form
- product.template
-
-
-
- False
- {'invisible': [('type','!=','service')]}
-
-
-
-
+
+
+ product.template.timesheet.form
+ product.template
+
+
+
+ False
+ {'invisible': [('type','!=','service')]}
+
+
+
-
-
-
+
+
+
\ No newline at end of file
diff --git a/addons/sale_timesheet/views/project_task_views.xml b/addons/sale_timesheet/views/project_task_views.xml
index 9b954edcf4a..6b4f7dc435d 100644
--- a/addons/sale_timesheet/views/project_task_views.xml
+++ b/addons/sale_timesheet/views/project_task_views.xml
@@ -1,6 +1,5 @@
-
-
+
sale.service.form.view.inherit
project.task
@@ -17,10 +16,6 @@
-
- onchange_parent_id(parent_id)
-
-
-
+
diff --git a/addons/sale_timesheet/views/sale_order_views.xml b/addons/sale_timesheet/views/sale_order_views.xml
index 220ae93752b..4a782672e23 100644
--- a/addons/sale_timesheet/views/sale_order_views.xml
+++ b/addons/sale_timesheet/views/sale_order_views.xml
@@ -1,6 +1,5 @@
-
-
+
sale.order.form.sale.timesheet
sale.order
@@ -39,5 +38,4 @@
-
-
+