[MOV] sale_timesheet: reorganize files and split models and views into their own files

This commit is contained in:
Kinjal Mehta
2016-08-04 11:09:29 +02:00
committed by Thibault Delavallée
parent f1b58b1293
commit 572053d9f5
16 changed files with 246 additions and 215 deletions
+9 -7
View File
@@ -3,7 +3,6 @@
{
'name': 'Sales Timesheet',
'version': '1.0',
'category': 'Hidden',
'summary': 'Sell based on timesheets',
'description': """
@@ -16,13 +15,16 @@ have real delivered quantities in sales orders.
""",
'website': 'https://www.odoo.com/page/warehouse',
'depends': ['sale', 'hr_timesheet'],
'data': ['views/sale_timesheet_view.xml',
'data/sale_timesheet_data.xml',
'views/sale_service_view.xml',
'data': [
'data/sale_timesheet_data.xml',
'views/sale_order_views.xml',
'views/product_views.xml',
'views/hr_views.xml',
'views/project_task_views.xml',
'views/procurement_views.xml',
],
'demo': ['data/sale_timesheet_demo.xml',
'demo/sale_service_demo.xml',
'demo': [
'data/sale_service_demo.xml',
],
'installable': True,
'auto_install': True,
}
@@ -1,7 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<!--Resource: sale.order.line for services type product-->
<record id="product.service_order_01" model="product.product">
<field name="track_service">timesheet</field>
</record>
<record id="product.product_product_2" model="product.product">
<field name="name">Support Contract (on timesheet)</field>
<field name="track_service">timesheet</field>
</record>
<record id="line_services" model="sale.order.line">
<field name="order_id" ref="sale.sale_order_3"/>
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="product.service_order_01" model="product.product">
<field name="track_service">timesheet</field>
</record>
<record id="product.product_product_2" model="product.product">
<field name="name">Support Contract (on timesheet)</field>
<field name="track_service">timesheet</field>
</record>
</data>
</openerp>
+7 -2
View File
@@ -1,5 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import sale_timesheet
import sale_service
import account
import hr
import procurement
import product
import project
import res_company
import sale_order
+70
View File
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp import models, api
class AccountAnalyticLine(models.Model):
_inherit = 'account.analytic.line'
def _get_sale_order_line(self, vals=None):
result = dict(vals or {})
if self.project_id:
if result.get('so_line'):
sol = self.env['sale.order.line'].browse([result['so_line']])
else:
sol = self.so_line
if not sol:
sol = self.env['sale.order.line'].search([
('order_id.project_id', '=', self.account_id.id),
('state', '=', 'sale'),
('product_id.track_service', '=', 'timesheet'),
('product_id.type', '=', 'service')],
limit=1)
if sol:
result.update({
'so_line': sol.id,
'product_id': sol.product_id.id,
})
result = 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)
+10
View File
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp import models, fields
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)
@@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp import api, models
from openerp.osv import fields, osv
from openerp.exceptions import UserError
from openerp.tools.translate import _
@@ -85,53 +83,3 @@ class procurement_order(osv.osv):
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)
class project_task(osv.osv):
_name = "project.task"
_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
def action_view_so(self, cr, uid, ids, context=None):
task = self.browse(cr, uid, ids, context=context)[0]
return {
"type": "ir.actions.act_window",
"res_model": "sale.order",
"views": [[False, "form"]],
"res_id": task.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,
}
}
class ProductProduct(models.Model):
_inherit = 'product.product'
@api.multi
def _need_procurement(self):
for product in self:
if product.type == 'service' and product.track_service == 'task':
return True
return super(ProductProduct, self)._need_procurement()
+31
View File
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp 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):
if self.type == 'service':
self.track_service = 'timesheet'
else:
self.track_service = 'manual'
return {}
class ProductProduct(models.Model):
_inherit = 'product.product'
@api.multi
def _need_procurement(self):
for product in self:
if product.type == 'service' and product.track_service == 'task':
return True
return super(ProductProduct, self)._need_procurement()
+45
View File
@@ -0,0 +1,45 @@
# -*- 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 _
class project_task(osv.osv):
_name = "project.task"
_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
def action_view_so(self, cr, uid, ids, context=None):
task = self.browse(cr, uid, ids, context=context)[0]
return {
"type": "ir.actions.act_window",
"res_model": "sale.order",
"views": [[False, "form"]],
"res_id": task.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,
}
}
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp 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)
@@ -7,106 +7,6 @@ from openerp.tools.translate import _
from openerp.exceptions import ValidationError
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)
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)
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):
if self.type == 'service':
self.track_service = 'timesheet'
else:
self.track_service = 'manual'
return {}
class AccountAnalyticLine(models.Model):
_inherit = 'account.analytic.line'
def _get_sale_order_line(self, vals=None):
result = dict(vals or {})
if self.project_id:
if result.get('so_line'):
sol = self.env['sale.order.line'].browse([result['so_line']])
else:
sol = self.so_line
if not sol:
sol = self.env['sale.order.line'].search([
('order_id.project_id', '=', self.account_id.id),
('state', '=', 'sale'),
('product_id.track_service', '=', 'timesheet'),
('product_id.type', '=', 'service')],
limit=1)
if sol:
result.update({
'so_line': sol.id,
'product_id': sol.product_id.id,
})
result = 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)
class SaleOrder(models.Model):
_inherit = 'sale.order'
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="hr_timesheet_employee_extd_form" model="ir.ui.view">
<field name="name">hr.timesheet.employee.extd_form</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='active_group']" position="before">
<group string="Timesheets">
<field name="timesheet_cost"/>
</group>
</xpath>
</field>
</record>
</data>
</openerp>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_procurement_task_form" model="ir.ui.view">
<field name="name">procurement.procurement.form.view.inherit</field>
<field name="model">procurement.order</field>
<field name="inherit_id" ref="procurement.procurement_form_view"/>
<field name="arch" type="xml">
<field name="origin" position="after">
<field name="task_id"/>
</field>
</field>
</record>
</data>
</openerp>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_product_timesheet_form" model="ir.ui.view">
<field name="name">product.template.timesheet.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="sale.product_template_form_view_invoice_policy"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='track_service']" position="attributes">
<attribute name="invisible">False</attribute>
<attribute name="attrs">{'invisible': [('type','!=','service')]}</attribute>
</xpath>
<field name="track_service" position="after">
<field name="project_id" attrs="{'invisible':['|', ('type','!=','service'), ('track_service', '&lt;&gt;', 'task')]}"/>
</field>
</field>
</record>
</data>
</openerp>
@@ -1,17 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_procurement_task_form" model="ir.ui.view">
<field name="name">procurement.procurement.form.view.inherit</field>
<field name="model">procurement.order</field>
<field name="inherit_id" ref="procurement.procurement_form_view"/>
<field name="arch" type="xml">
<field name="origin" position="after">
<field name="task_id"/>
</field>
</field>
</record>
<record id="view_sale_service_inherit_form2" model="ir.ui.view">
<field name="name">sale.service.form.view.inherit</field>
<field name="model">project.task</field>
@@ -1,34 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_product_timesheet_form" model="ir.ui.view">
<field name="name">product.template.timesheet.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="sale.product_template_form_view_invoice_policy"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='track_service']" position="attributes">
<attribute name="invisible">False</attribute>
<attribute name="attrs">{'invisible': [('type','!=','service')]}</attribute>
</xpath>
<field name="track_service" position="after">
<field name="project_id" attrs="{'invisible':['|', ('type','!=','service'), ('track_service', '&lt;&gt;', 'task')]}"/>
</field>
</field>
</record>
<record id="hr_timesheet_employee_extd_form" model="ir.ui.view">
<field name="name">hr.timesheet.employee.extd_form</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='active_group']" position="before">
<group string="Timesheets">
<field name="timesheet_cost"/>
</group>
</xpath>
</field>
</record>
<record id="view_order_form_inherit_sale_timesheet" model="ir.ui.view">
<field name="name">sale.order.form.sale.timesheet</field>
<field name="model">sale.order</field>