diff options
| author | Thibault Delavallée <tde@odoo.com> | 2016-11-07 12:04:00 +0100 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2017-01-18 10:26:53 +0100 |
| commit | 2b90398cb6f5986167ca9306dd327659960c78a6 (patch) | |
| tree | 6830667792200553967255403dbb6ef17a17f624 /addons | |
| parent | 2015cfd175865634caea5f3e7d1c55f224631baf (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__.py | 5 | ||||
| -rw-r--r-- | addons/resource/data/resource_data.xml | 22 | ||||
| -rw-r--r-- | addons/resource/models/__init__.py | 1 | ||||
| -rw-r--r-- | addons/resource/models/res_company.py | 28 | ||||
| -rw-r--r-- | addons/resource/models/resource.py | 68 | ||||
| -rw-r--r-- | addons/resource/tests/test_resource.py | 3 | ||||
| -rw-r--r-- | addons/resource/views/res_company_views.xml | 16 | ||||
| -rw-r--r-- | addons/resource/views/resource_views.xml | 71 |
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> |
