summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorThibault Delavallée <tde@odoo.com>2016-11-07 12:04:00 +0100
committerThibault Delavallée <tde@odoo.com>2017-01-18 10:26:53 +0100
commit2b90398cb6f5986167ca9306dd327659960c78a6 (patch)
tree6830667792200553967255403dbb6ef17a17f624 /addons
parent2015cfd175865634caea5f3e7d1c55f224631baf (diff)
[REF] resource: strengthen link between companies and calendars
Purpose of this commit is to always have a default calendar for each company and ensure it is correctly set on resources. Some cleaning is also performed in resource models to remove unused fields, improve labels and make views a bit more odoo-ish. * [REF] res_company: add a m2o to the default calendar to use in the company as well as a o2m linking all resource calendars used in the company. Some code has been added to correctly update existing companies when installing the module; * [REF] resource_calendar * [REM] manager field on resource.calendar: this field is never used and is not necessary anyway * [ADD] global_leave_ids: filter leaves on a calendar to see global company leaves * [IMP] better default company / calendar computation to ensure there is always a calendar attached to a resource * [IMP] improve resource and calendar views in order to look more like other odoo views
Diffstat (limited to 'addons')
-rw-r--r--addons/resource/__manifest__.py5
-rw-r--r--addons/resource/data/resource_data.xml22
-rw-r--r--addons/resource/models/__init__.py1
-rw-r--r--addons/resource/models/res_company.py28
-rw-r--r--addons/resource/models/resource.py68
-rw-r--r--addons/resource/tests/test_resource.py3
-rw-r--r--addons/resource/views/res_company_views.xml16
-rw-r--r--addons/resource/views/resource_views.xml71
8 files changed, 169 insertions, 45 deletions
diff --git a/addons/resource/__manifest__.py b/addons/resource/__manifest__.py
index 0993a088d80..9c7342cc521 100644
--- a/addons/resource/__manifest__.py
+++ b/addons/resource/__manifest__.py
@@ -19,6 +19,9 @@ associated to every resource. It also manages the leaves of every resource.
'security/ir.model.access.csv',
'security/resource_security.xml',
'views/resource_views.xml',
+ 'views/res_company_views.xml',
+ ],
+ 'demo': [
+ 'data/resource_demo.xml'
],
- 'demo': ['data/resource_demo.xml'],
}
diff --git a/addons/resource/data/resource_data.xml b/addons/resource/data/resource_data.xml
index f6721316fb1..08281205c56 100644
--- a/addons/resource/data/resource_data.xml
+++ b/addons/resource/data/resource_data.xml
@@ -2,19 +2,15 @@
<odoo>
<record id="resource_calendar_std" model="resource.calendar">
<field name="name">Standard 40 Hours/Week</field>
- <field name="attendance_ids" eval="[
-(5, 0),
-(0, 0, {'name': 'Monday Morning', 'dayofweek': '0', 'hour_from': 8, 'hour_to': 12}),
-(0, 0, {'name': 'Monday Evening', 'dayofweek': '0', 'hour_from': 13, 'hour_to': 17}),
-(0, 0, {'name': 'Tuesday Morning', 'dayofweek': '1', 'hour_from': 8, 'hour_to': 12}),
-(0, 0, {'name': 'Tuesday Evening', 'dayofweek': '1', 'hour_from': 13, 'hour_to': 17}),
-(0, 0, {'name': 'Wednesday Morning', 'dayofweek': '2', 'hour_from': 8, 'hour_to': 12}),
-(0, 0, {'name': 'Wednesday Evening', 'dayofweek': '2', 'hour_from': 13, 'hour_to': 17}),
-(0, 0, {'name': 'Thursday Morning', 'dayofweek': '3', 'hour_from': 8, 'hour_to': 12}),
-(0, 0, {'name': 'Thursday Evening', 'dayofweek': '3', 'hour_from': 13, 'hour_to': 17}),
-(0, 0, {'name': 'Friday Morning', 'dayofweek': '4', 'hour_from': 8, 'hour_to': 12}),
-(0, 0, {'name': 'Friday Evening', 'dayofweek': '4', 'hour_from': 13, 'hour_to': 17}),
-]"/>
<field name="company_id" ref="base.main_company"/>
</record>
+
+ <record id="base.main_company" model="res.company">
+ <field name="resource_calendar_id" ref="resource_calendar_std"/>
+ </record>
+
+ <function id="_init_data_resource_calendar"
+ model="res.company"
+ name="_init_data_resource_calendar"
+ eval="[]"/>
</odoo>
diff --git a/addons/resource/models/__init__.py b/addons/resource/models/__init__.py
index 4ca401409b4..9cf3e07f76d 100644
--- a/addons/resource/models/__init__.py
+++ b/addons/resource/models/__init__.py
@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import resource
+import res_company
diff --git a/addons/resource/models/res_company.py b/addons/resource/models/res_company.py
new file mode 100644
index 00000000000..0ed03b69043
--- /dev/null
+++ b/addons/resource/models/res_company.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, fields, models, _
+
+
+class ResCompany(models.Model):
+ _inherit = 'res.company'
+
+ resource_calendar_ids = fields.One2many(
+ 'resource.calendar', 'company_id', 'Working Hours')
+ resource_calendar_id = fields.Many2one(
+ 'resource.calendar', 'Default Working Hours', ondelete='restrict')
+
+ @api.model
+ def _init_data_resource_calendar(self):
+ for company in self.search([('resource_calendar_id', '=', False)]):
+ company.resource_calendar_id = self.env['resource.calendar'].create({'name': _('Standard 40 hours/week')}).id
+
+ @api.model
+ def create(self, values):
+ if not values.get('resource_calendar_id'):
+ values['resource_calendar_id'] = self.env['resource.calendar'].create({'name': _('Standard 40 hours/week')}).id
+ company = super(ResCompany, self).create(values)
+ # calendar created from form view: no company_id set because record was still not created
+ if not company.resource_calendar_id.company_id:
+ company.resource_calendar_id.company_id = company.id
+ return company
diff --git a/addons/resource/models/resource.py b/addons/resource/models/resource.py
index 582716e4801..12f7c38bd3a 100644
--- a/addons/resource/models/resource.py
+++ b/addons/resource/models/resource.py
@@ -28,15 +28,40 @@ class ResourceCalendar(models.Model):
_name = "resource.calendar"
_description = "Resource Calendar"
+ @api.model
+ def default_get(self, fields):
+ res = super(ResourceCalendar, self).default_get(fields)
+ if not res.get('name') and res.get('company_id'):
+ res['name'] = _('Working Hours of %s') % self.env['res.company'].browse(res['company_id']).name
+ return res
+
+ def _get_default_attendance_ids(self):
+ return [
+ (0, 0, {'name': _('Monday Morning'), 'dayofweek': '0', 'hour_from': 8, 'hour_to': 12}),
+ (0, 0, {'name': _('Monday Evening'), 'dayofweek': '0', 'hour_from': 13, 'hour_to': 17}),
+ (0, 0, {'name': _('Tuesday Morning'), 'dayofweek': '1', 'hour_from': 8, 'hour_to': 12}),
+ (0, 0, {'name': _('Tuesday Evening'), 'dayofweek': '1', 'hour_from': 13, 'hour_to': 17}),
+ (0, 0, {'name': _('Wednesday Morning'), 'dayofweek': '2', 'hour_from': 8, 'hour_to': 12}),
+ (0, 0, {'name': _('Wednesday Evening'), 'dayofweek': '2', 'hour_from': 13, 'hour_to': 17}),
+ (0, 0, {'name': _('Thursday Morning'), 'dayofweek': '3', 'hour_from': 8, 'hour_to': 12}),
+ (0, 0, {'name': _('Thursday Evening'), 'dayofweek': '3', 'hour_from': 13, 'hour_to': 17}),
+ (0, 0, {'name': _('Friday Morning'), 'dayofweek': '4', 'hour_from': 8, 'hour_to': 12}),
+ (0, 0, {'name': _('Friday Evening'), 'dayofweek': '4', 'hour_from': 13, 'hour_to': 17})
+ ]
+
name = fields.Char(required=True)
- company_id = fields.Many2one('res.company', string='Company',
+ company_id = fields.Many2one(
+ 'res.company', 'Company',
default=lambda self: self.env['res.company']._company_default_get())
attendance_ids = fields.One2many(
- 'resource.calendar.attendance', 'calendar_id', string='Working Time',
- copy=True)
- manager = fields.Many2one('res.users', string='Workgroup Manager', default=lambda self: self.env.uid)
+ 'resource.calendar.attendance', 'calendar_id', 'Working Time',
+ copy=True, default=_get_default_attendance_ids)
leave_ids = fields.One2many(
- 'resource.calendar.leaves', 'calendar_id', string='Leaves')
+ 'resource.calendar.leaves', 'calendar_id', 'Leaves')
+ global_leave_ids = fields.One2many(
+ 'resource.calendar.leaves', 'calendar_id', 'Global Leaves',
+ domain=[('resource_id', '=', False)]
+ )
# --------------------------------------------------
# Utility methods
@@ -669,9 +694,18 @@ class ResourceResource(models.Model):
_name = "resource.resource"
_description = "Resource Detail"
+ @api.model
+ def default_get(self, fields):
+ res = super(ResourceResource, self).default_get(fields)
+ if not fields or 'calendar_id' in fields and not res.get('calendar_id') and res.get('company_id'):
+ company = self.env['res.company'].browse(res['company_id'])
+ res['calendar_id'] = company.resource_calendar_id.id
+ return res
+
name = fields.Char(required=True)
code = fields.Char(copy=False)
- active = fields.Boolean(track_visibility='onchange', default=True,
+ active = fields.Boolean(
+ 'Active', default=True, track_visibility='onchange',
help="If the active field is set to False, it will allow you to hide the resource record without removing it.")
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env['res.company']._company_default_get())
resource_type = fields.Selection([
@@ -679,7 +713,8 @@ class ResourceResource(models.Model):
('material', 'Material')
], string='Resource Type', required=True, default='user')
user_id = fields.Many2one('res.users', string='User', help='Related user name for the resource to manage its access.')
- time_efficiency = fields.Float(string='Efficiency Factor', required=True, default=100,
+ time_efficiency = fields.Float(
+ 'Efficiency Factor', default=100, required=True,
help="This field is used to calculate the the expected duration of a work order at this work center. For example, if a work order takes one hour and the efficiency factor is 100%, then the expected duration will be one hour. If the efficiency factor is 200%, however the expected duration will be 30 minutes.")
calendar_id = fields.Many2one("resource.calendar", string='Working Time', help="Define the schedule of resource")
@@ -723,16 +758,20 @@ class ResourceResource(models.Model):
if intervals and intervals[0]:
yield dt.date()
+
class ResourceCalendarLeaves(models.Model):
_name = "resource.calendar.leaves"
_description = "Leave Detail"
- name = fields.Char()
- company_id = fields.Many2one('res.company', related='calendar_id.company_id', string="Company", store=True, readonly=True)
- calendar_id = fields.Many2one('resource.calendar', string='Working Time')
- date_from = fields.Datetime(string='Start Date', required=True)
- date_to = fields.Datetime(string='End Date', required=True)
- resource_id = fields.Many2one("resource.resource", string='Resource',
+ name = fields.Char('Reason')
+ company_id = fields.Many2one(
+ 'res.company', related='calendar_id.company_id', string="Company",
+ readonly=True, store=True)
+ calendar_id = fields.Many2one('resource.calendar', 'Working Hours')
+ date_from = fields.Datetime('Start Date', required=True)
+ date_to = fields.Datetime('End Date', required=True)
+ resource_id = fields.Many2one(
+ "resource.resource", 'Resource',
help="If empty, this is a generic holiday for the company. If a resource is set, the holiday/leave is only for this resource")
@api.constrains('date_from', 'date_to')
@@ -742,7 +781,8 @@ class ResourceCalendarLeaves(models.Model):
@api.onchange('resource_id')
def onchange_resource(self):
- self.calendar_id = self.resource_id.calendar_id
+ if self.resource_id:
+ self.calendar_id = self.resource_id.calendar_id
def seconds(td):
assert isinstance(td, timedelta)
diff --git a/addons/resource/tests/test_resource.py b/addons/resource/tests/test_resource.py
index e1c68d46349..beafd44223e 100644
--- a/addons/resource/tests/test_resource.py
+++ b/addons/resource/tests/test_resource.py
@@ -355,7 +355,8 @@ class TestWorkDays(TestResourceCommon):
def test_no_calendar(self):
""" If a resource has no resource calendar, they don't work """
r = self.env['resource.resource'].create({
- 'name': "NoCalendar"
+ 'name': "NoCalendar",
+ 'calendar_id': False,
})
self.assertEqual(
diff --git a/addons/resource/views/res_company_views.xml b/addons/resource/views/res_company_views.xml
new file mode 100644
index 00000000000..356694ad9d1
--- /dev/null
+++ b/addons/resource/views/res_company_views.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="res_company_view_form_inherit_resource" model="ir.ui.view">
+ <field name="name">res.company.view.form.inherit.resource</field>
+ <field name="model">res.company</field>
+ <field name="inherit_id" ref="base.view_company_form"/>
+ <field name="arch" type="xml">
+ <field name="website" position="before">
+ <field name="id" invisible="1"/>
+ <field name="resource_calendar_id" required="1"
+ domain="[('company_id', '=', id)]"
+ context="{'default_company_id': id}"/>
+ </field>
+ </field>
+ </record>
+</odoo>
diff --git a/addons/resource/views/resource_views.xml b/addons/resource/views/resource_views.xml
index 97860f4338a..9fc2eea3583 100644
--- a/addons/resource/views/resource_views.xml
+++ b/addons/resource/views/resource_views.xml
@@ -9,9 +9,10 @@
<search string="Search Resource">
<field name="name" string="Resource"/>
<field name="resource_type"/>
- <filter string="Inactive" domain="[('active','=',False)]"/>
- <field name="user_id" string="User"/>
+ <field name="user_id"/>
+ <field name="calendar_id"/>
<field name="company_id" groups="base.group_multi_company"/>
+ <filter string="Inactive" domain="[('active','=',False)]"/>
<group expand="0" string="Group By">
<filter string="User" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Type" domain="[]" context="{'group_by':'resource_type'}"/>
@@ -68,16 +69,27 @@
<field name="help">Resources allow you to create and manage resources that should be involved in a specific project phase. You can also set their efficiency level and workload based on their weekly working hours.</field>
</record>
+ <record id="resource_resource_action_from_calendar" model="ir.actions.act_window">
+ <field name="name">Resources</field>
+ <field name="res_model">resource.resource</field>
+ <field name="view_mode">tree,form</field>
+ <field name="context">{
+ 'default_calendar_id': active_id,
+ 'search_default_calendar_id': active_id}</field>
+ <field name="search_view_id" ref="view_resource_resource_search"/>
+ <field name="help">Resources allow you to create and manage resources that should be involved in a specific project phase. You can also set their efficiency level and workload based on their weekly working hours.</field>
+ </record>
+
<!-- RESOURCE.CALENDAR.LEAVES -->
<record id="view_resource_calendar_leaves_search" model="ir.ui.view">
<field name="name">resource.calendar.leaves.search</field>
<field name="model">resource.calendar.leaves</field>
<field name="arch" type="xml">
<search string="Search Working Period Leaves">
- <field name="name" string="Reason"/>
- <field name="resource_id" string="Resource"/>
- <field name="company_id" string="Company" groups="base.group_multi_company"/>
- <field name="calendar_id" string="Working Period"/>
+ <field name="name"/>
+ <field name="resource_id"/>
+ <field name="company_id" groups="base.group_multi_company"/>
+ <field name="calendar_id"/>
<group expand="0" string="Group By">
<filter string="Resource" domain="[]" context="{'group_by':'resource_id'}"/>
<filter string="Company" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
@@ -140,6 +152,16 @@
<field name="search_view_id" ref="view_resource_calendar_leaves_search"/>
</record>
+ <record id="resource_calendar_leaves_action_from_calendar" model="ir.actions.act_window">
+ <field name="name">Resource Leaves</field>
+ <field name="res_model">resource.calendar.leaves</field>
+ <field name="view_mode">tree,form,calendar</field>
+ <field name="context">{
+ 'default_calendar_id': active_id,
+ 'search_default_calendar_id': active_id}</field>
+ <field name="search_view_id" ref="view_resource_calendar_leaves_search"/>
+ </record>
+
<act_window
id="resource_calendar_closing_days"
name="Closing Days"
@@ -201,7 +223,6 @@
<field name="arch" type="xml">
<search string="Search Working Time">
<field name="name" string="Working Time"/>
- <field name="manager"/>
<field name="company_id" groups="base.group_multi_company"/>
</search>
</field>
@@ -213,17 +234,36 @@
<field name="arch" type="xml">
<form string="Working Time">
<sheet string="Working Time">
+ <div class="oe_button_box" name="button_box">
+ <button name="%(resource_calendar_leaves_action_from_calendar)d" type="action"
+ string="Leaves" icon="fa-calendar-times-o"
+ class="oe_stat_button"
+ groups="base.group_user"/>
+ <button name="%(resource_resource_action_from_calendar)d" type="action"
+ string="Work Resources" icon="fa-cogs"
+ class="oe_stat_button"
+ groups="base.group_user"/>
+ </div>
<group>
- <group>
+ <h1>
<field name="name"/>
- </group>
- <group>
- <field name="manager"/>
- <field name="company_id" groups="base.group_multi_company"/>
- </group>
- <field name="attendance_ids"/>
- <field name="leave_ids" context="{'default_calendar_id': id}"/>
+ </h1>
+ <field name="company_id" groups="base.group_multi_company"/>
</group>
+ <notebook>
+ <page string="Working Hours">
+ <field name="attendance_ids"/>
+ </page>
+ <page string="Global Leaves">
+ <field name="global_leave_ids">
+ <tree editable="top">
+ <field name="name"/>
+ <field name="date_from"/>
+ <field name="date_to"/>
+ </tree>
+ </field>
+ </page>
+ </notebook>
</sheet>
</form>
</field>
@@ -235,7 +275,6 @@
<field name="arch" type="xml">
<tree string="Working Time">
<field name="name"/>
- <field name="manager"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree>
</field>