From d81434375822de92e360cc4199749b5c1751066f Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Wed, 7 Feb 2018 01:44:48 +0100 Subject: [PATCH 01/34] first version of golem ressource, models : resources and reservation --- golem_ressources/__init__.py | 18 ++++ golem_ressources/__manifest__.py | 33 ++++++ golem_ressources/models/__init__.py | 18 ++++ golem_ressources/models/golem_resources.py | 77 +++++++++++++ golem_ressources/security/ir.model.access.csv | 3 + .../views/golem_reservation_views.xml | 80 ++++++++++++++ .../views/golem_resources_views.xml | 102 ++++++++++++++++++ 7 files changed, 331 insertions(+) create mode 100644 golem_ressources/__init__.py create mode 100644 golem_ressources/__manifest__.py create mode 100644 golem_ressources/models/__init__.py create mode 100644 golem_ressources/models/golem_resources.py create mode 100644 golem_ressources/security/ir.model.access.csv create mode 100644 golem_ressources/views/golem_reservation_views.xml create mode 100644 golem_ressources/views/golem_resources_views.xml diff --git a/golem_ressources/__init__.py b/golem_ressources/__init__.py new file mode 100644 index 0000000..2fca3d2 --- /dev/null +++ b/golem_ressources/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from . import models diff --git a/golem_ressources/__manifest__.py b/golem_ressources/__manifest__.py new file mode 100644 index 0000000..0ba9576 --- /dev/null +++ b/golem_ressources/__manifest__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +{ + 'name': 'GOLEM non-profit resources', + 'summary': 'Extends Odoo resources for MJC', + 'version': '10.0.1.0.0', + 'category': 'GOLEM', + 'author': 'Youssef El ouahby', + 'license': 'AGPL-3', + 'application': True, + 'installable': True, + 'depends': ['golem_base', 'golem_activity', 'golem_season', + 'odoo_partner_merge'], + 'data': ['views/golem_resources_views.xml', + 'views/golem_reservation_views.xml', + 'security/ir.model.access.csv', + ] +} diff --git a/golem_ressources/models/__init__.py b/golem_ressources/models/__init__.py new file mode 100644 index 0000000..43371e7 --- /dev/null +++ b/golem_ressources/models/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from . import golem_resources diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py new file mode 100644 index 0000000..d0a37b4 --- /dev/null +++ b/golem_ressources/models/golem_resources.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +# Copyright 2017 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + + + +from odoo import models, fields, api + +class GolemResources(models.Model): + """ GOLEM Resources """ + _name = 'golem.resources' + _description = 'GOLEM Resources' + + name = fields.Char() + resource_type = fields.Many2one("golem.resourcetype", string="Resource type") + resource_responsible = fields.Many2one("res.partner", string="Resource Responsible") + article_link = fields.Many2one("product.template", string="Article Link") + #Configuration de disponibilité + start_of_availability_date = fields.Date(string="Start of availibility date ") + end_of_availability_date = fields.Date(string="End of availibility date ") + weekdays_of_availibility = fields.Many2many('golem.weekday', string="Weekdays of availibility") + + +class GolemReservation(models.Model): + """ GOLEM Reservation """ + _name = 'golem.reservation' + _description = 'GOLEM Reservation' + + start_date = fields.Datetime(string='Start date') + end_date = fields.Datetime(string='End date') + linked_resource = fields.Many2one('golem.resources', string="Linked resource") + user = fields.Many2one('res.users', required=True) + on_behalf_of = fields.Many2one('res.partner', required=True) + status = fields.Selection([ + ('draft', "Draft"), + ('confirmed', "Confirmed"), + ('canceled', "Canceled"), + ], default='draft') + + @api.multi + def status_draft(self): + self.status = 'draft' + + @api.multi + def status_confirm(self): + self.status = 'confirmed' + + @api.multi + def status_canceled(self): + self.status = 'canceled' + +class GolemResourceType(models.Model): + """ GOLEM Resource Type """ + _name = 'golem.resourcetype' + _description = 'GOLEM Resource Type' + + name = fields.Char(string='Resource Type') + +class GolemWeekDays(models.Model): + """ GOLEM Week Days """ + _name = 'golem.weekday' + _description = 'GOLEM Week Day' + + name = fields.Char(string='Week Day') diff --git a/golem_ressources/security/ir.model.access.csv b/golem_ressources/security/ir.model.access.csv new file mode 100644 index 0000000..a269e71 --- /dev/null +++ b/golem_ressources/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_golem_resources_user,Access GOLEM Resources User,model_golem_resources,golem_base.group_golem_user,1,0,0,0 +access_golem_resources_manager,Access GOLEM Resources Manager,model_golem_resources,golem_base.group_golem_manager,1,1,1,1 diff --git a/golem_ressources/views/golem_reservation_views.xml b/golem_ressources/views/golem_reservation_views.xml new file mode 100644 index 0000000..12883e5 --- /dev/null +++ b/golem_ressources/views/golem_reservation_views.xml @@ -0,0 +1,80 @@ + + + + + + reservation.calendar + golem.reservation + + + + + + + + + + reservation.tree + golem.reservation + + + + + + + + + + + + + reservation.form + golem.reservation + +
+
+
+ + + + + + + + + +
+
+
+ + Reservation + golem.reservation + tree,form,calendar + + +
+
diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_ressources/views/golem_resources_views.xml new file mode 100644 index 0000000..6008b34 --- /dev/null +++ b/golem_ressources/views/golem_resources_views.xml @@ -0,0 +1,102 @@ + + + + + + Sunday + + + Monday + + + Tuesday + + + wednesday + + + Thursday + + + Friday + + + Saturday + + + resource.search + golem.resources + + + + + + + + + + + resource.tree + golem.resources + + + + + + + + + + + + + + resource.form + golem.resources + +
+ + + + + + + + + + + + + + + + +
+
+
+ + + Resources + golem.resources + tree,form,search + + + +
+
From 7eda2d4a98036a73a00036aab046c6355c8df723 Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Wed, 7 Feb 2018 10:16:12 +0100 Subject: [PATCH 02/34] Comments added to models --- golem_ressources/models/golem_resources.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index d0a37b4..907a56d 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -18,7 +18,7 @@ from odoo import models, fields, api - +#modèle de base : ressources class GolemResources(models.Model): """ GOLEM Resources """ _name = 'golem.resources' @@ -28,12 +28,13 @@ class GolemResources(models.Model): resource_type = fields.Many2one("golem.resourcetype", string="Resource type") resource_responsible = fields.Many2one("res.partner", string="Resource Responsible") article_link = fields.Many2one("product.template", string="Article Link") - #Configuration de disponibilité + + #Configuration de disponibilité(période, jours et horaire) start_of_availability_date = fields.Date(string="Start of availibility date ") end_of_availability_date = fields.Date(string="End of availibility date ") weekdays_of_availibility = fields.Many2many('golem.weekday', string="Weekdays of availibility") - +#modèle gestion des reservation class GolemReservation(models.Model): """ GOLEM Reservation """ _name = 'golem.reservation' @@ -62,6 +63,7 @@ class GolemReservation(models.Model): def status_canceled(self): self.status = 'canceled' +#modèle de base pour identifier le type de la ressource class GolemResourceType(models.Model): """ GOLEM Resource Type """ _name = 'golem.resourcetype' @@ -69,8 +71,9 @@ class GolemResourceType(models.Model): name = fields.Char(string='Resource Type') -class GolemWeekDays(models.Model): - """ GOLEM Week Days """ +#modèle de base pour stocker les jours de la semaine +class GolemWeekDay(models.Model): + """ GOLEM Week Day """ _name = 'golem.weekday' _description = 'GOLEM Week Day' From 25acf52d5ec0dd5ebfe59d8f9f1ec0945e672297 Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Wed, 7 Feb 2018 18:13:02 +0100 Subject: [PATCH 03/34] =?UTF-8?q?Ajout=20d'un=20mod=C3=A8le=20hour=20pour?= =?UTF-8?q?=20la=20gestion=20des=20horaires=20de=20disponibilit=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- golem_ressources/models/golem_resources.py | 19 +++++++++++++++++++ .../views/golem_resources_views.xml | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index 907a56d..5f929c5 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -25,6 +25,7 @@ class GolemResources(models.Model): _description = 'GOLEM Resources' name = fields.Char() + active = fields.Boolean(default=False) resource_type = fields.Many2one("golem.resourcetype", string="Resource type") resource_responsible = fields.Many2one("res.partner", string="Resource Responsible") article_link = fields.Many2one("product.template", string="Article Link") @@ -33,6 +34,13 @@ class GolemResources(models.Model): start_of_availability_date = fields.Date(string="Start of availibility date ") end_of_availability_date = fields.Date(string="End of availibility date ") weekdays_of_availibility = fields.Many2many('golem.weekday', string="Weekdays of availibility") + #horaire = fields.Many2many("golem.hour", string="horaire ") + + @api.multi + def active_change(self): + self.active = not self.active + + #modèle gestion des reservation class GolemReservation(models.Model): @@ -78,3 +86,14 @@ class GolemWeekDay(models.Model): _description = 'GOLEM Week Day' name = fields.Char(string='Week Day') + +#modèle de gestion horaire +class GolemHour(models.Model): + """ Golem Hour """ + _name = "golem.hour" + _description = "Golem Hour" + + resource_id = fields.Many2one("golem.resources", required=True) + name = fields.Many2one("golem.weekday", required=True) + start_time = fields.Float(required=True) + end_time = fields.Float(required=True) diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_ressources/views/golem_resources_views.xml index 6008b34..bbadd71 100644 --- a/golem_ressources/views/golem_resources_views.xml +++ b/golem_ressources/views/golem_resources_views.xml @@ -70,6 +70,12 @@ along with this program. If not, see . golem.resources
+
+ +
@@ -83,6 +89,7 @@ along with this program. If not, see . + From 4cec86337287ca62c4153a323b0cb5e14a6b4aea Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Thu, 8 Feb 2018 00:58:23 +0100 Subject: [PATCH 04/34] Adding comments to views and fixing the availibility configuration --- golem_ressources/models/golem_resources.py | 10 ++--- .../views/golem_reservation_views.xml | 2 +- .../views/golem_resources_views.xml | 38 ++++++++++++++----- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index 5f929c5..e257049 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -34,7 +34,7 @@ class GolemResources(models.Model): start_of_availability_date = fields.Date(string="Start of availibility date ") end_of_availability_date = fields.Date(string="End of availibility date ") weekdays_of_availibility = fields.Many2many('golem.weekday', string="Weekdays of availibility") - #horaire = fields.Many2many("golem.hour", string="horaire ") + timetable = fields.One2many("golem.timetable", "resource_id", string="Availibility timetable") @api.multi def active_change(self): @@ -88,10 +88,10 @@ class GolemWeekDay(models.Model): name = fields.Char(string='Week Day') #modèle de gestion horaire -class GolemHour(models.Model): - """ Golem Hour """ - _name = "golem.hour" - _description = "Golem Hour" +class GolemTimetable(models.Model): + """ Golem Timetable """ + _name = "golem.timetable" + _description = "Golem Timetable" resource_id = fields.Many2one("golem.resources", required=True) name = fields.Many2one("golem.weekday", required=True) diff --git a/golem_ressources/views/golem_reservation_views.xml b/golem_ressources/views/golem_reservation_views.xml index 12883e5..867579f 100644 --- a/golem_ressources/views/golem_reservation_views.xml +++ b/golem_ressources/views/golem_reservation_views.xml @@ -1,6 +1,6 @@ + Sunday @@ -38,6 +39,9 @@ along with this program. If not, see . Saturday + + + resource.search golem.resources @@ -50,6 +54,8 @@ along with this program. If not, see . + + resource.tree golem.resources @@ -65,6 +71,8 @@ along with this program. If not, see . + + resource.form golem.resources @@ -79,17 +87,24 @@ along with this program. If not, see . - - - - + + + + - - - - - + + + + + + + + + + + + @@ -97,11 +112,14 @@ along with this program. If not, see . + Resources golem.resources tree,form,search + + From 3a42ea0a5451612f7ea58c68c5efdc4acaed7d48 Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Thu, 8 Feb 2018 12:02:46 +0100 Subject: [PATCH 05/34] finalisation du smart button et contraint d'heure --- golem_ressources/__manifest__.py | 4 ++-- golem_ressources/models/golem_resources.py | 6 ++++++ golem_ressources/views/golem_resources_views.xml | 12 ++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/golem_ressources/__manifest__.py b/golem_ressources/__manifest__.py index 0ba9576..f42d1e1 100644 --- a/golem_ressources/__manifest__.py +++ b/golem_ressources/__manifest__.py @@ -24,8 +24,8 @@ 'license': 'AGPL-3', 'application': True, 'installable': True, - 'depends': ['golem_base', 'golem_activity', 'golem_season', - 'odoo_partner_merge'], + 'depends': ['product', + ], 'data': ['views/golem_resources_views.xml', 'views/golem_reservation_views.xml', 'security/ir.model.access.csv', diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index e257049..e653e03 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -97,3 +97,9 @@ class GolemTimetable(models.Model): name = fields.Many2one("golem.weekday", required=True) start_time = fields.Float(required=True) end_time = fields.Float(required=True) + + @api.constraint('start_time','end_time') + def _check_time_consistency(self): + for r in self: + if r.end_time < r.start_time: + raise ValidationError("End time should be higher than start time") diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_ressources/views/golem_resources_views.xml index a3b6614..d207476 100644 --- a/golem_ressources/views/golem_resources_views.xml +++ b/golem_ressources/views/golem_resources_views.xml @@ -78,13 +78,13 @@ along with this program. If not, see . golem.resources -
- -
+
+ +
From 15a23e460f2d48d3a404bc58529f0e01f9427afb Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Thu, 8 Feb 2018 12:22:52 +0100 Subject: [PATCH 06/34] =?UTF-8?q?Am=C3=A9liorations=20syntaxiques?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- golem_ressources/models/golem_resources.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index e653e03..c5084e5 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -17,7 +17,7 @@ -from odoo import models, fields, api +from odoo import models, fields, api, exceptions #modèle de base : ressources class GolemResources(models.Model): """ GOLEM Resources """ @@ -98,8 +98,8 @@ class GolemTimetable(models.Model): start_time = fields.Float(required=True) end_time = fields.Float(required=True) - @api.constraint('start_time','end_time') + @api.constrains('start_time', 'end_time') def _check_time_consistency(self): for r in self: if r.end_time < r.start_time: - raise ValidationError("End time should be higher than start time") + raise exceptions.ValidationError('End time should be higher than start time') From 7dc2213593c8c5dc1a76791641a1c7821b31ee6b Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Thu, 8 Feb 2018 23:21:33 +0100 Subject: [PATCH 07/34] =?UTF-8?q?R=C3=A9alisation=20des=20am=C3=A9lioratio?= =?UTF-8?q?ns=20propos=C3=A9s.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- golem_ressources/models/golem_resources.py | 40 +++++++++++-------- .../views/golem_resources_views.xml | 34 +++++++++++++--- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index c5084e5..4a2b2e6 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -17,23 +17,22 @@ -from odoo import models, fields, api, exceptions +from odoo import models, fields, api, _, exceptions #modèle de base : ressources class GolemResources(models.Model): """ GOLEM Resources """ _name = 'golem.resources' _description = 'GOLEM Resources' - name = fields.Char() - active = fields.Boolean(default=False) - resource_type = fields.Many2one("golem.resourcetype", string="Resource type") - resource_responsible = fields.Many2one("res.partner", string="Resource Responsible") - article_link = fields.Many2one("product.template", string="Article Link") + name = fields.Char(required=True) + active = fields.Boolean(default=True) + resource_type = fields.Many2one("golem.resourcetype") + resource_responsible = fields.Many2one("res.partner") + article_link = fields.Many2one("product.template") #Configuration de disponibilité(période, jours et horaire) - start_of_availability_date = fields.Date(string="Start of availibility date ") - end_of_availability_date = fields.Date(string="End of availibility date ") - weekdays_of_availibility = fields.Many2many('golem.weekday', string="Weekdays of availibility") + start_of_availability_date = fields.Date(required=True) + end_of_availability_date = fields.Date(required=True) timetable = fields.One2many("golem.timetable", "resource_id", string="Availibility timetable") @api.multi @@ -48,9 +47,9 @@ class GolemReservation(models.Model): _name = 'golem.reservation' _description = 'GOLEM Reservation' - start_date = fields.Datetime(string='Start date') - end_date = fields.Datetime(string='End date') - linked_resource = fields.Many2one('golem.resources', string="Linked resource") + start_date = fields.Datetime() + end_date = fields.Datetime() + linked_resource = fields.Many2one('golem.resources', required=True) user = fields.Many2one('res.users', required=True) on_behalf_of = fields.Many2one('res.partner', required=True) status = fields.Selection([ @@ -65,19 +64,27 @@ class GolemReservation(models.Model): @api.multi def status_confirm(self): - self.status = 'confirmed' + #self.status = 'confirmed' + exceptions.ValidationError('not allowed') @api.multi def status_canceled(self): self.status = 'canceled' + @api.constrains('status') + def _onConfirmReservation(self): + if(self.status == 'confrimed'): + exceptions.UserError('not allowed') + #exceptions.ValidationError('not allowed') + + #modèle de base pour identifier le type de la ressource class GolemResourceType(models.Model): """ GOLEM Resource Type """ _name = 'golem.resourcetype' _description = 'GOLEM Resource Type' - name = fields.Char(string='Resource Type') + name = fields.Char(string='Resource Type',required=True) #modèle de base pour stocker les jours de la semaine class GolemWeekDay(models.Model): @@ -100,6 +107,5 @@ class GolemTimetable(models.Model): @api.constrains('start_time', 'end_time') def _check_time_consistency(self): - for r in self: - if r.end_time < r.start_time: - raise exceptions.ValidationError('End time should be higher than start time') + if self.end_time < self.start_time: + raise exceptions.ValidationError(_('End time should be higher than start time')) diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_ressources/views/golem_resources_views.xml index d207476..3e4f74a 100644 --- a/golem_ressources/views/golem_resources_views.xml +++ b/golem_ressources/views/golem_resources_views.xml @@ -67,7 +67,6 @@ along with this program. If not, see . - @@ -92,14 +91,17 @@ along with this program. If not, see . + - - - - + +
From 3766f49805d4c0f2854f2f3319c11624948ef043 Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Sat, 10 Feb 2018 00:05:36 +0100 Subject: [PATCH 08/34] =?UTF-8?q?1er=20version=20du=20mod=C3=A8le=20reserv?= =?UTF-8?q?ation,=20avec=20contraintes=20de=20disponibilit=C3=A9=20operati?= =?UTF-8?q?onnelles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- golem_ressources/models/golem_resources.py | 20 ++++++++++++++----- .../views/golem_reservation_views.xml | 7 ++++++- .../views/golem_resources_views.xml | 12 +++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index 4a2b2e6..a57d17d 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -18,6 +18,9 @@ from odoo import models, fields, api, _, exceptions +import logging + +_logger = logging.getLogger(__name__) #modèle de base : ressources class GolemResources(models.Model): """ GOLEM Resources """ @@ -34,6 +37,7 @@ class GolemResources(models.Model): start_of_availability_date = fields.Date(required=True) end_of_availability_date = fields.Date(required=True) timetable = fields.One2many("golem.timetable", "resource_id", string="Availibility timetable") + reservation = fields.One2many("golem.reservation", "linked_resource") @api.multi def active_change(self): @@ -52,6 +56,7 @@ class GolemReservation(models.Model): linked_resource = fields.Many2one('golem.resources', required=True) user = fields.Many2one('res.users', required=True) on_behalf_of = fields.Many2one('res.partner', required=True) + #statut=fields.Char() status = fields.Selection([ ('draft', "Draft"), ('confirmed', "Confirmed"), @@ -64,8 +69,8 @@ class GolemReservation(models.Model): @api.multi def status_confirm(self): - #self.status = 'confirmed' - exceptions.ValidationError('not allowed') + self.status = 'confirmed' + @api.multi def status_canceled(self): @@ -73,9 +78,14 @@ class GolemReservation(models.Model): @api.constrains('status') def _onConfirmReservation(self): - if(self.status == 'confrimed'): - exceptions.UserError('not allowed') - #exceptions.ValidationError('not allowed') + if self.status == 'confirmed': + if(self.start_date < self.linked_resource.start_of_availability_date or self.end_date > self.linked_resource.end_of_availability_date ): + raise exceptions.UserError('Not allowed, the resource is not available in this period, please choose another périod before confirming %s' % self.linked_resource.start_of_availability_date) + else : + for reservation in self.linked_resource.reservation : + if(self.id != reservation.id and reservation.status == 'confirmed' and not (self.end_date < reservation.start_date or self.start_date > reservation.end_date)): + raise exceptions.UserError("Not allowed, the resource is taken during this period, please choose another période before confirming ") + #modèle de base pour identifier le type de la ressource diff --git a/golem_ressources/views/golem_reservation_views.xml b/golem_ressources/views/golem_reservation_views.xml index 867579f..bd38ff0 100644 --- a/golem_ressources/views/golem_reservation_views.xml +++ b/golem_ressources/views/golem_reservation_views.xml @@ -17,6 +17,7 @@ along with this program. If not, see . --> + reservation.calendar golem.reservation @@ -29,6 +30,8 @@ along with this program. If not, see . + + reservation.tree golem.reservation @@ -39,10 +42,12 @@ along with this program. If not, see . - + + + reservation.form golem.reservation diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_ressources/views/golem_resources_views.xml index 3e4f74a..790009c 100644 --- a/golem_ressources/views/golem_resources_views.xml +++ b/golem_ressources/views/golem_resources_views.xml @@ -108,6 +108,18 @@ along with this program. If not, see . + + + + + + + + + + + + From 6e4cae64f4939ccac68aa3db1387290a7d942a86 Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Mon, 12 Feb 2018 16:05:52 +0100 Subject: [PATCH 09/34] =?UTF-8?q?prendre=20en=20compte=20les=20remarques?= =?UTF-8?q?=20relatives=20aux=20r=C3=A9servation=20sur=20une=20p=C3=A9riod?= =?UTF-8?q?e=20d'indisponibilit=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- golem_ressources/models/golem_resources.py | 25 +++++++++++- .../views/golem_resources_views.xml | 40 +++++++++---------- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index a57d17d..7fc6b20 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -54,8 +54,8 @@ class GolemReservation(models.Model): start_date = fields.Datetime() end_date = fields.Datetime() linked_resource = fields.Many2one('golem.resources', required=True) - user = fields.Many2one('res.users', required=True) - on_behalf_of = fields.Many2one('res.partner', required=True) + user = fields.Many2one('res.users', required=True, default=lambda self: self.env.user) + on_behalf_of = fields.Many2one('res.partner', required=True, default=lambda self: self.env['res.partner']) #statut=fields.Char() status = fields.Selection([ ('draft', "Draft"), @@ -79,9 +79,29 @@ class GolemReservation(models.Model): @api.constrains('status') def _onConfirmReservation(self): if self.status == 'confirmed': + #verifyin is the reservation is taking place out of the resource availibility period if(self.start_date < self.linked_resource.start_of_availability_date or self.end_date > self.linked_resource.end_of_availability_date ): raise exceptions.UserError('Not allowed, the resource is not available in this period, please choose another périod before confirming %s' % self.linked_resource.start_of_availability_date) else : + #verifying if the reservation is taking place out the availibility timetable + #defining a boolean flag, which will determine if the day of the reservation is available + r_allowed = False + for day in self.linked_resource.timetable : + #if the day is available, look for the time if it's inside the resource timetable availibility + if day.name.id_day == fields.Datetime.from_string(self.start_date).weekday(): + start_hour = fields.Datetime.from_string(self.start_date).hour + start_min = float(fields.Datetime.from_string(self.start_date).minute) #+(int(fields.Datetime.from_string(self.start_date).min))/100 + start_time_r = start_hour + start_min/100 + start_hour = fields.Datetime.from_string(self.end_date).hour + start_min = float(fields.Datetime.from_string(self.end_date).minute) #+(int(fields.Datetime.from_string(self.start_date).min))/100 + end_time_r = start_hour + start_min/100 + #if the time is suitable, the flag state is changed + if(start_time_r > day.start_time and end_time_r < day.end_time): + r_allowed = True + #if the flag is changed no erreur is raised. + if(not r_allowed): + raise exceptions.UserError("Not allowed, the resource is not available during this timetable, please choose another time before confirming ") + #verifying if the resource is already taken during this period for reservation in self.linked_resource.reservation : if(self.id != reservation.id and reservation.status == 'confirmed' and not (self.end_date < reservation.start_date or self.start_date > reservation.end_date)): raise exceptions.UserError("Not allowed, the resource is taken during this period, please choose another période before confirming ") @@ -103,6 +123,7 @@ class GolemWeekDay(models.Model): _description = 'GOLEM Week Day' name = fields.Char(string='Week Day') + id_day = fields.Integer() #modèle de gestion horaire class GolemTimetable(models.Model): diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_ressources/views/golem_resources_views.xml index 790009c..48057d1 100644 --- a/golem_ressources/views/golem_resources_views.xml +++ b/golem_ressources/views/golem_resources_views.xml @@ -18,26 +18,34 @@ along with this program. If not, see . - + + Sunday + 6 + + + Monday + 0 + + + Tuesday + 1 - Monday + wednesday + 2 - Tuesday + Thursday + 3 - wednesday + Friday + 4 - Thursday - - - Friday - - Saturday + 5 @@ -108,18 +116,6 @@ along with this program. If not, see .
- - - - - - - - - - - - From b389be7bbc6d96c15eca5bf378d3911cd812fc79 Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Tue, 13 Feb 2018 14:00:16 +0100 Subject: [PATCH 10/34] Adding fields to resources and reservation : Validation --- golem_ressources/models/golem_resources.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index 7fc6b20..8d00a7f 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -18,9 +18,7 @@ from odoo import models, fields, api, _, exceptions -import logging -_logger = logging.getLogger(__name__) #modèle de base : ressources class GolemResources(models.Model): """ GOLEM Resources """ @@ -29,6 +27,7 @@ class GolemResources(models.Model): name = fields.Char(required=True) active = fields.Boolean(default=True) + validation_required = fields.Boolean(default=True) resource_type = fields.Many2one("golem.resourcetype") resource_responsible = fields.Many2one("res.partner") article_link = fields.Many2one("product.template") @@ -61,6 +60,8 @@ class GolemReservation(models.Model): ('draft', "Draft"), ('confirmed', "Confirmed"), ('canceled', "Canceled"), + ('validated', "Validated"), + ('rejected', "Rejected"), ], default='draft') @api.multi From eccc2178828ddf662b7e177ebe598f043c267b61 Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Tue, 13 Feb 2018 15:04:55 +0100 Subject: [PATCH 11/34] =?UTF-8?q?Ajout=20des=20boutons=20de=20validation?= =?UTF-8?q?=20et=20du=20filtre=20sur=20la=20liste=20des=20r=C3=A9s=C3=A9rv?= =?UTF-8?q?ation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- golem_ressources/models/golem_resources.py | 10 +++++ .../views/golem_reservation_views.xml | 37 ++++++++++++++++--- .../views/golem_resources_views.xml | 2 + 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index 8d00a7f..77a5351 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -77,6 +77,14 @@ class GolemReservation(models.Model): def status_canceled(self): self.status = 'canceled' + @api.multi + def status_validated(self): + self.status = 'validated' + + @api.multi + def status_rejected(self): + self.status = 'rejected' + @api.constrains('status') def _onConfirmReservation(self): if self.status == 'confirmed': @@ -106,6 +114,8 @@ class GolemReservation(models.Model): for reservation in self.linked_resource.reservation : if(self.id != reservation.id and reservation.status == 'confirmed' and not (self.end_date < reservation.start_date or self.start_date > reservation.end_date)): raise exceptions.UserError("Not allowed, the resource is taken during this period, please choose another période before confirming ") + elif (not self.linked_resource.validation_required): + self.status = 'validated' diff --git a/golem_ressources/views/golem_reservation_views.xml b/golem_ressources/views/golem_reservation_views.xml index bd38ff0..fbee2cf 100644 --- a/golem_ressources/views/golem_reservation_views.xml +++ b/golem_ressources/views/golem_reservation_views.xml @@ -43,6 +43,7 @@ along with this program. If not, see . + @@ -55,11 +56,17 @@ along with this program. If not, see .
@@ -74,10 +81,30 @@ along with this program. If not, see .
+ + + + reservation.search + golem.reservation + + + + + + + + + + + + + + Reservation golem.reservation - tree,form,calendar + tree,search,form,calendar diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_ressources/views/golem_resources_views.xml index 48057d1..2f69a75 100644 --- a/golem_ressources/views/golem_resources_views.xml +++ b/golem_ressources/views/golem_resources_views.xml @@ -70,6 +70,7 @@ along with this program. If not, see . + @@ -95,6 +96,7 @@ along with this program. If not, see . + From 02aef2093a0775e39ce67f2ef6a53020f139ef01 Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Wed, 14 Feb 2018 13:44:37 +0100 Subject: [PATCH 12/34] Ajout du wizard en cas de refus + Validation au cas ou ressource le permet --- golem_ressources/models/golem_resources.py | 36 ++++++++++++++++++- .../views/golem_reservation_views.xml | 16 +++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index 77a5351..8b1f62c 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -19,6 +19,27 @@ from odoo import models, fields, api, _, exceptions +#Wizard pour recuperer le motif du refus d'une réservation et le stocker sur la reservation +class myWizard(models.TransientModel): + """GOLEM Resource wizard""" + _name = "golem.reourceswizard" + + # recuperer la reservation courant + def _default_reservation(self): + return self.env['golem.reservation'].browse(self._context.get('active_id')) + + rejection_reason = fields.Text() + + #override la methode d'ecriture de wizard pour stocker le motif du refus sur la reservation + @api.model + def create(self, vals): + #récuperation de la reservation actuelle + record = self.env['golem.reservation'].browse(self._context.get('active_id')) + #stockage du motif sur la reservation + record.rejection_reason = vals['rejection_reason'] + new_record = super(myWizard, self).create(vals) + return new_record + #modèle de base : ressources class GolemResources(models.Model): """ GOLEM Resources """ @@ -55,7 +76,7 @@ class GolemReservation(models.Model): linked_resource = fields.Many2one('golem.resources', required=True) user = fields.Many2one('res.users', required=True, default=lambda self: self.env.user) on_behalf_of = fields.Many2one('res.partner', required=True, default=lambda self: self.env['res.partner']) - #statut=fields.Char() + rejection_reason = fields.Text() status = fields.Selection([ ('draft', "Draft"), ('confirmed', "Confirmed"), @@ -71,6 +92,8 @@ class GolemReservation(models.Model): @api.multi def status_confirm(self): self.status = 'confirmed' + if( not self.linked_resource.validation_required) : + self.status='validated' @api.multi @@ -81,9 +104,20 @@ class GolemReservation(models.Model): def status_validated(self): self.status = 'validated' + @api.multi def status_rejected(self): self.status = 'rejected' + #lancement du wizard une fois l'administrateur rejet une reservation + return { + 'name' : _('Please enter the reseaon of rejection'), + 'type' : 'ir.actions.act_window', + 'res_model' : 'golem.reourceswizard', + 'view_mode': 'form', + 'view_type': 'form', + 'target': 'new', + } + @api.constrains('status') def _onConfirmReservation(self): diff --git a/golem_ressources/views/golem_reservation_views.xml b/golem_ressources/views/golem_reservation_views.xml index fbee2cf..e076f06 100644 --- a/golem_ressources/views/golem_reservation_views.xml +++ b/golem_ressources/views/golem_reservation_views.xml @@ -68,6 +68,7 @@ along with this program. If not, see . string="Reject" statuss="confirmed" class="oe_highlight"/> + @@ -76,6 +77,7 @@ along with this program. If not, see . + @@ -108,5 +110,19 @@ along with this program. If not, see . + + + + wizard.form + golem.reourceswizard + +
+ + + +
+
+
+ From 9f9459df45a134c2955ebdcf76df8b3c7fa89895 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 07:27:32 +0100 Subject: [PATCH 13/34] [TYPO]Add updated copyright notices --- golem_ressources/__init__.py | 3 ++- golem_ressources/__manifest__.py | 7 ++++--- golem_ressources/models/__init__.py | 3 ++- golem_ressources/models/golem_resources.py | 3 ++- golem_ressources/views/golem_reservation_views.xml | 1 + golem_ressources/views/golem_resources_views.xml | 1 + 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/golem_ressources/__init__.py b/golem_ressources/__init__.py index 2fca3d2..1fced20 100644 --- a/golem_ressources/__init__.py +++ b/golem_ressources/__init__.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- -# Copyright 2016 Fabien Bourgeois +# Copyright 2018 Youssef El Ouahby +# Copyright 2018 Fabien Bourgeois # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as diff --git a/golem_ressources/__manifest__.py b/golem_ressources/__manifest__.py index f42d1e1..e610aff 100644 --- a/golem_ressources/__manifest__.py +++ b/golem_ressources/__manifest__.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- -# Copyright 2016 Fabien Bourgeois +# Copyright 2018 Youssef El Ouahby +# Copyright 2018 Fabien Bourgeois # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -18,9 +19,9 @@ { 'name': 'GOLEM non-profit resources', 'summary': 'Extends Odoo resources for MJC', - 'version': '10.0.1.0.0', + 'version': '10.0.1.0.1', 'category': 'GOLEM', - 'author': 'Youssef El ouahby', + 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', 'application': True, 'installable': True, diff --git a/golem_ressources/models/__init__.py b/golem_ressources/models/__init__.py index 43371e7..e917ac0 100644 --- a/golem_ressources/models/__init__.py +++ b/golem_ressources/models/__init__.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- -# Copyright 2016 Fabien Bourgeois +# Copyright 2018 Youssef El Ouahby +# Copyright 2018 Fabien Bourgeois # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index 8b1f62c..28d7713 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- -# Copyright 2017 Fabien Bourgeois +# Copyright 2018 Youssef El Ouahby +# Copyright 2018 Fabien Bourgeois # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as diff --git a/golem_ressources/views/golem_reservation_views.xml b/golem_ressources/views/golem_reservation_views.xml index e076f06..1154616 100644 --- a/golem_ressources/views/golem_reservation_views.xml +++ b/golem_ressources/views/golem_reservation_views.xml @@ -1,5 +1,6 @@ diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_ressources/views/golem_resources_views.xml index 165fcec..bc71e73 100644 --- a/golem_ressources/views/golem_resources_views.xml +++ b/golem_ressources/views/golem_resources_views.xml @@ -151,10 +151,16 @@ along with this program. If not, see . tree - - - + + + + From 661c7fecfefc12ecae151ba193c80b7c794edee5 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 08:20:39 +0100 Subject: [PATCH 15/34] [IMP]GOLEM Resource reservation rejection : enhance quality, use more common idioms --- golem_ressources/__manifest__.py | 2 +- golem_ressources/models/golem_resources.py | 48 ++++++++----------- .../views/golem_reservation_views.xml | 19 +++++--- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/golem_ressources/__manifest__.py b/golem_ressources/__manifest__.py index 00b2f04..f1a91f3 100644 --- a/golem_ressources/__manifest__.py +++ b/golem_ressources/__manifest__.py @@ -20,7 +20,7 @@ 'name': 'GOLEM non-profit resources', 'summary': 'GOLEM resources management', 'description': ''' GOLEM resources management ''', - 'version': '10.0.1.0.2', + 'version': '10.0.1.0.3', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index 28d7713..89acf7b 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -16,30 +16,25 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - +""" GOLEM Resources management """ from odoo import models, fields, api, _, exceptions -#Wizard pour recuperer le motif du refus d'une réservation et le stocker sur la reservation -class myWizard(models.TransientModel): - """GOLEM Resource wizard""" - _name = "golem.reourceswizard" +class GolemResourceRejectionWizard(models.TransientModel): + """GOLEM Resource wizard : refusal reason for a reservation """ + _name = "golem.resource.rejection.wizard" - # recuperer la reservation courant - def _default_reservation(self): - return self.env['golem.reservation'].browse(self._context.get('active_id')) + reservation_id = fields.Many2one('golem.reservation', required=True) + reason = fields.Text(required=True) - rejection_reason = fields.Text() + @api.multi + def validate(self, vals): + """ Sets reservation status to rejected and add reason """ + self.ensure_one() + rejection = self[0] + rejection.reservation_id.write({'status': 'rejected', + 'rejection_reason': rejection.reason}) - #override la methode d'ecriture de wizard pour stocker le motif du refus sur la reservation - @api.model - def create(self, vals): - #récuperation de la reservation actuelle - record = self.env['golem.reservation'].browse(self._context.get('active_id')) - #stockage du motif sur la reservation - record.rejection_reason = vals['rejection_reason'] - new_record = super(myWizard, self).create(vals) - return new_record #modèle de base : ressources class GolemResources(models.Model): @@ -108,16 +103,15 @@ class GolemReservation(models.Model): @api.multi def status_rejected(self): - self.status = 'rejected' - #lancement du wizard une fois l'administrateur rejet une reservation - return { - 'name' : _('Please enter the reseaon of rejection'), - 'type' : 'ir.actions.act_window', - 'res_model' : 'golem.reourceswizard', + """ Wizard call for reservation reject """ + self.ensure_one() + reservation_id = self[0] + return {'name' : _('Please enter the rejection reason'), + 'type' : 'ir.actions.act_window', + 'res_model' : 'golem.resource.rejection.wizard', + 'context': {'default_reservation_id': reservation_id.id}, 'view_mode': 'form', - 'view_type': 'form', - 'target': 'new', - } + 'target': 'new'} @api.constrains('status') diff --git a/golem_ressources/views/golem_reservation_views.xml b/golem_ressources/views/golem_reservation_views.xml index 1a968d5..8ece16c 100644 --- a/golem_ressources/views/golem_reservation_views.xml +++ b/golem_ressources/views/golem_reservation_views.xml @@ -110,17 +110,22 @@ along with this program. If not, see . tree,search,form,calendar + parent="resources_menu" action="action_reservation" sequence="20" /> - - - wizard.form - golem.reourceswizard + + GOLEM Resource Rejection Wizard Form + golem.resource.rejection.wizard -
+ - + + +
+
From 2b70d2c1b00a2966a8b557be8c655bb94523d775 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 08:55:13 +0100 Subject: [PATCH 16/34] [REF]GOLEM Resources : wizard should be in wizard folder --- golem_ressources/__init__.py | 2 +- golem_ressources/__manifest__.py | 3 +- golem_ressources/models/golem_resources.py | 17 +------- .../views/golem_reservation_views.xml | 18 -------- golem_ressources/wizard/__init__.py | 19 +++++++++ .../wizard/golem_reservation_rejection.py | 36 ++++++++++++++++ .../golem_reservation_rejection_views.xml | 42 +++++++++++++++++++ 7 files changed, 101 insertions(+), 36 deletions(-) create mode 100644 golem_ressources/wizard/__init__.py create mode 100644 golem_ressources/wizard/golem_reservation_rejection.py create mode 100644 golem_ressources/wizard/golem_reservation_rejection_views.xml diff --git a/golem_ressources/__init__.py b/golem_ressources/__init__.py index 1fced20..f95e908 100644 --- a/golem_ressources/__init__.py +++ b/golem_ressources/__init__.py @@ -16,4 +16,4 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from . import models +from . import models, wizard diff --git a/golem_ressources/__manifest__.py b/golem_ressources/__manifest__.py index f1a91f3..7874a49 100644 --- a/golem_ressources/__manifest__.py +++ b/golem_ressources/__manifest__.py @@ -20,7 +20,7 @@ 'name': 'GOLEM non-profit resources', 'summary': 'GOLEM resources management', 'description': ''' GOLEM resources management ''', - 'version': '10.0.1.0.3', + 'version': '10.0.1.0.4', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', @@ -29,5 +29,6 @@ 'depends': ['product'], 'data': ['views/golem_resources_views.xml', 'views/golem_reservation_views.xml', + 'wizard/golem_reservation_rejection_views.xml', 'security/ir.model.access.csv'] } diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index 89acf7b..11e38fe 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -20,21 +20,6 @@ from odoo import models, fields, api, _, exceptions -class GolemResourceRejectionWizard(models.TransientModel): - """GOLEM Resource wizard : refusal reason for a reservation """ - _name = "golem.resource.rejection.wizard" - - reservation_id = fields.Many2one('golem.reservation', required=True) - reason = fields.Text(required=True) - - @api.multi - def validate(self, vals): - """ Sets reservation status to rejected and add reason """ - self.ensure_one() - rejection = self[0] - rejection.reservation_id.write({'status': 'rejected', - 'rejection_reason': rejection.reason}) - #modèle de base : ressources class GolemResources(models.Model): @@ -108,7 +93,7 @@ class GolemReservation(models.Model): reservation_id = self[0] return {'name' : _('Please enter the rejection reason'), 'type' : 'ir.actions.act_window', - 'res_model' : 'golem.resource.rejection.wizard', + 'res_model' : 'golem.reservation.rejection.wizard', 'context': {'default_reservation_id': reservation_id.id}, 'view_mode': 'form', 'target': 'new'} diff --git a/golem_ressources/views/golem_reservation_views.xml b/golem_ressources/views/golem_reservation_views.xml index 8ece16c..14e0af2 100644 --- a/golem_ressources/views/golem_reservation_views.xml +++ b/golem_ressources/views/golem_reservation_views.xml @@ -112,23 +112,5 @@ along with this program. If not, see . - - GOLEM Resource Rejection Wizard Form - golem.resource.rejection.wizard - -
- - - - -
-
-
-
-
- diff --git a/golem_ressources/wizard/__init__.py b/golem_ressources/wizard/__init__.py new file mode 100644 index 0000000..9a0c408 --- /dev/null +++ b/golem_ressources/wizard/__init__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +# Copyright 2018 Youssef El Ouahby +# Copyright 2018 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from . import golem_reservation_rejection diff --git a/golem_ressources/wizard/golem_reservation_rejection.py b/golem_ressources/wizard/golem_reservation_rejection.py new file mode 100644 index 0000000..01484ab --- /dev/null +++ b/golem_ressources/wizard/golem_reservation_rejection.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- + +# Copyright 2018 Youssef El Ouahby +# Copyright 2018 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +""" GOLEM Resources management """ + +from odoo import models, fields, api + +class GolemReservationRejectionWizard(models.TransientModel): + """GOLEM Resource wizard : refusal reason for a reservation """ + _name = "golem.reservation.rejection.wizard" + + reservation_id = fields.Many2one('golem.reservation', required=True) + reason = fields.Text(required=True) + + @api.multi + def validate(self): + """ Sets reservation status to rejected and add reason """ + self.ensure_one() + rejection = self[0] + rejection.reservation_id.write({'status': 'rejected', + 'rejection_reason': rejection.reason}) diff --git a/golem_ressources/wizard/golem_reservation_rejection_views.xml b/golem_ressources/wizard/golem_reservation_rejection_views.xml new file mode 100644 index 0000000..97f2e83 --- /dev/null +++ b/golem_ressources/wizard/golem_reservation_rejection_views.xml @@ -0,0 +1,42 @@ + + + + + + + + GOLEM Reservation Rejection Wizard Form + golem.reservation.rejection.wizard + +
+ + + + +
+
+
+
+
+ +
+
From fe0d57dffc1b0622bc3e676b9cd57770766aba90 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 12:25:11 +0100 Subject: [PATCH 17/34] [REF]GOLEM Resources : huge code refactoring, renamings etc. --- golem_ressources/__manifest__.py | 2 +- golem_ressources/models/golem_resources.py | 247 +++++++++++------- golem_ressources/security/ir.model.access.csv | 4 +- .../views/golem_reservation_views.xml | 125 +++++---- .../views/golem_resources_views.xml | 161 +++++------- .../wizard/golem_reservation_rejection.py | 2 +- .../golem_reservation_rejection_views.xml | 2 +- 7 files changed, 285 insertions(+), 258 deletions(-) diff --git a/golem_ressources/__manifest__.py b/golem_ressources/__manifest__.py index 7874a49..941404b 100644 --- a/golem_ressources/__manifest__.py +++ b/golem_ressources/__manifest__.py @@ -20,7 +20,7 @@ 'name': 'GOLEM non-profit resources', 'summary': 'GOLEM resources management', 'description': ''' GOLEM resources management ''', - 'version': '10.0.1.0.4', + 'version': '10.0.1.1.0', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', diff --git a/golem_ressources/models/golem_resources.py b/golem_ressources/models/golem_resources.py index 11e38fe..7cfe84c 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_ressources/models/golem_resources.py @@ -18,73 +18,120 @@ """ GOLEM Resources management """ -from odoo import models, fields, api, _, exceptions +from math import modf +from odoo import models, fields, api, _ +from odoo.exceptions import UserError, ValidationError #modèle de base : ressources -class GolemResources(models.Model): - """ GOLEM Resources """ - _name = 'golem.resources' - _description = 'GOLEM Resources' +class GolemResource(models.Model): + """ GOLEM Resource Model """ + _name = 'golem.resource' + _description = 'GOLEM Resource Model' - name = fields.Char(required=True) + name = fields.Char(required=True, index=True) active = fields.Boolean(default=True) - validation_required = fields.Boolean(default=True) - resource_type = fields.Many2one("golem.resourcetype") - resource_responsible = fields.Many2one("res.partner") - article_link = fields.Many2one("product.template") + validation_required = fields.Boolean(default=True, + string='Is validation required ?') + type_id = fields.Many2one('golem.resource.type', + index=True, string='Resource Type') + supervisor_id = fields.Many2one('res.partner', index=True, string='Supervisor') + product_tmpl_id = fields.Many2one('product.template', index=True, + string='Linked product') - #Configuration de disponibilité(période, jours et horaire) - start_of_availability_date = fields.Date(required=True) - end_of_availability_date = fields.Date(required=True) - timetable = fields.One2many("golem.timetable", "resource_id", string="Availibility timetable") - reservation = fields.One2many("golem.reservation", "linked_resource") + avaibility_start = fields.Date(required=True, string='Availibility start date') + avaibility_stop = fields.Date(required=True, string='Availibility stop date') + timetable_ids = fields.One2many('golem.resource.timetable', 'resource_id', + string='Availibility timetable') + reservation_ids = fields.One2many('golem.resource.reservation', 'resource_id', + string='Reservations') @api.multi - def active_change(self): - self.active = not self.active + def active_toggle(self): + """ Toggles active boolean """ + for resource in self: + resource.active = not resource.active +class GolemResourceReservation(models.Model): + """ GOLEM Resource Reservation Model """ + _name = 'golem.resource.reservation' + _description = 'GOLEM Reservation Model' -#modèle gestion des reservation -class GolemReservation(models.Model): - """ GOLEM Reservation """ - _name = 'golem.reservation' - _description = 'GOLEM Reservation' + name = fields.Char(compute='_compute_name', store=True) + # TODO: handle multiple days reservation + date = fields.Date(required=True, index=True) + hour_start = fields.Float('Start hour', required=True) + hour_stop = fields.Float('Stop hour', required=True) + date_start = fields.Datetime(compute='_compute_date_start', store=True, index=True) + date_stop = fields.Datetime(compute='_compute_date_stop', store=True, index=True) - start_date = fields.Datetime() - end_date = fields.Datetime() - linked_resource = fields.Many2one('golem.resources', required=True) - user = fields.Many2one('res.users', required=True, default=lambda self: self.env.user) - on_behalf_of = fields.Many2one('res.partner', required=True, default=lambda self: self.env['res.partner']) - rejection_reason = fields.Text() + resource_id = fields.Many2one('golem.resource', required=True, index=True, + string='Resource') + user_id = fields.Many2one('res.users', required=True, index=True, + string='User', + default=lambda self: self.env.user) + partner_id = fields.Many2one('res.partner', string='On behalf of', + required=True, index=True) status = fields.Selection([ - ('draft', "Draft"), - ('confirmed', "Confirmed"), - ('canceled', "Canceled"), - ('validated', "Validated"), - ('rejected', "Rejected"), + ('draft', 'Draft'), + ('confirmed', 'Confirmed'), + ('canceled', 'Canceled'), + ('validated', 'Validated'), + ('rejected', 'Rejected'), ], default='draft') + rejection_reason = fields.Text() + + @api.depends('resource_id', 'date') + def _compute_name(self): + """ Computes reservation name """ + for reservation in self: + reservation.name = u'{}/{}'.format(reservation.resource_id.name, + reservation.date) + + @api.depends('date', 'hour_start') + def _compute_date_start(self): + """ Computes Date start """ + for reservation in self: + hour_start, minute_start = modf(reservation.hour_start) + minute_start = int(round(minute_start * 60)) + reservation.date_start = u'{} {}:{}'.format(reservation.date, + hour_start, minute_start) + + @api.depends('date', 'hour_stop') + def _compute_date_stop(self): + """ Computes Date stop """ + for reservation in self: + hour_stop, minute_stop = modf(reservation.hour_stop) + minute_stop = int(round(minute_stop * 60)) + reservation.date_stop = u'{} {}:{}'.format(reservation.date, + hour_stop, minute_stop) + @api.multi def status_draft(self): - self.status = 'draft' + """ Status to draft """ + self.write({'status': 'draft'}) @api.multi def status_confirm(self): - self.status = 'confirmed' - if( not self.linked_resource.validation_required) : - self.status='validated' + """ Confirms reservation, or validates it if not workflow is involved """ + for reservation in self: + if reservation.resource_id.validation_required: + reservation.status = 'confirmed' + else: + reservation.status_validated() @api.multi def status_canceled(self): - self.status = 'canceled' + """ Status to cancel """ + self.write({'status': 'canceled'}) @api.multi def status_validated(self): - self.status = 'validated' - + """ Status to validated """ + self.write({'status': 'validated'}) @api.multi def status_rejected(self): @@ -100,68 +147,84 @@ class GolemReservation(models.Model): @api.constrains('status') - def _onConfirmReservation(self): - if self.status == 'confirmed': - #verifyin is the reservation is taking place out of the resource availibility period - if(self.start_date < self.linked_resource.start_of_availability_date or self.end_date > self.linked_resource.end_of_availability_date ): - raise exceptions.UserError('Not allowed, the resource is not available in this period, please choose another périod before confirming %s' % self.linked_resource.start_of_availability_date) - else : - #verifying if the reservation is taking place out the availibility timetable - #defining a boolean flag, which will determine if the day of the reservation is available - r_allowed = False - for day in self.linked_resource.timetable : - #if the day is available, look for the time if it's inside the resource timetable availibility - if day.name.id_day == fields.Datetime.from_string(self.start_date).weekday(): - start_hour = fields.Datetime.from_string(self.start_date).hour - start_min = float(fields.Datetime.from_string(self.start_date).minute) #+(int(fields.Datetime.from_string(self.start_date).min))/100 - start_time_r = start_hour + start_min/100 - start_hour = fields.Datetime.from_string(self.end_date).hour - start_min = float(fields.Datetime.from_string(self.end_date).minute) #+(int(fields.Datetime.from_string(self.start_date).min))/100 - end_time_r = start_hour + start_min/100 - #if the time is suitable, the flag state is changed - if(start_time_r > day.start_time and end_time_r < day.end_time): - r_allowed = True - #if the flag is changed no erreur is raised. - if(not r_allowed): - raise exceptions.UserError("Not allowed, the resource is not available during this timetable, please choose another time before confirming ") - #verifying if the resource is already taken during this period - for reservation in self.linked_resource.reservation : - if(self.id != reservation.id and reservation.status == 'confirmed' and not (self.end_date < reservation.start_date or self.start_date > reservation.end_date)): - raise exceptions.UserError("Not allowed, the resource is taken during this period, please choose another période before confirming ") - elif (not self.linked_resource.validation_required): - self.status = 'validated' + def check_confirmed(self): + """ Check date coherence on reservation confirmation """ + for reservation in self: + if reservation.status == 'confirmed': + # Check is reservation is not taking place out of the resource avaibility period + if reservation.date < reservation.resource_id.avaibility_start or \ + reservation.date > reservation.resource_id.avaibility_stop: + uerr = _('Not allowed, the resource is not available in ' + 'this period, please choose another périod before ' + 'confirming') + raise UserError(uerr) + # Check if reservation is not taking place out the avaibility timetables + is_day_allowed = False + for timetable in reservation.resource_id.timetable_ids: + # Check for the time according to resource timetable avaibility + date = fields.Datetime.from_string(reservation.date) + if int(timetable.weekday) == date.weekday(): + is_day_allowed = True + if reservation.hour_start < timetable.date_start or \ + reservation.hour_stop > timetable.date_stop: + uerr = _('Not allowed, the resource is not available ' + 'during this period, please choose another ' + 'time before confirming.') + raise UserError(uerr) + if not is_day_allowed: + uerr = _('Not allowed, the resource is not available ' + 'this day. Please choose another date.') + raise UserError(uerr) + # Check if the resource is already taken during this period + # PERF : check the date, not iterate over all reservations + domain = [('resource_id', '=', reservation.resource_id.id), + ('date', '=', reservation.date), + ('status', '=', 'confirmed'), + ('id', '!=', reservation.id)] + reservations = self.env['golem.resource.reservation'].search(domain) + for other_res in reservations: + if (other_res.hour_start < reservation.hour_start < other_res.hour_stop) or \ + (other_res.hour_start < reservation.hour_stop < other_res.hour_stop): + uerr = _('Not allowed, the resource is already taken ' + 'during this period : from {} to {} this day, ' + 'please choose another périod before confirming.') + raise UserError(uerr.format(reservation.date_start, + reservation.date_stop)) + # Finally, validate the reservation if all checks have passed + if reservation.resource_id.validation_required: + reservation.status = 'validated' - -#modèle de base pour identifier le type de la ressource class GolemResourceType(models.Model): """ GOLEM Resource Type """ - _name = 'golem.resourcetype' + _name = 'golem.resource.type' _description = 'GOLEM Resource Type' + _sql_constraints = [('golem_resource_type_name_uniq', + 'UNIQUE (name)', + 'Resource type must be unique.')] - name = fields.Char(string='Resource Type',required=True) + name = fields.Char(string='Resource Type', required=True, index=True) -#modèle de base pour stocker les jours de la semaine -class GolemWeekDay(models.Model): - """ GOLEM Week Day """ - _name = 'golem.weekday' - _description = 'GOLEM Week Day' - - name = fields.Char(string='Week Day') - id_day = fields.Integer() - -#modèle de gestion horaire class GolemTimetable(models.Model): """ Golem Timetable """ - _name = "golem.timetable" + _name = "golem.resource.timetable" _description = "Golem Timetable" + _rec_name = 'weekday' - resource_id = fields.Many2one("golem.resources", required=True) - name = fields.Many2one("golem.weekday", required=True) - start_time = fields.Float(required=True) - end_time = fields.Float(required=True) + resource_id = fields.Many2one('golem.resource', required=True, + string='Linked resource') + weekday = fields.Selection([('0', _('Monday')), + ('1', _('Tuesday')), + ('2', _('Wednesday')), + ('3', _('Thursday')), + ('4', _('Friday')), + ('5', _('Saturday')), + ('6', _('Sunday'))], copy=False) + time_start = fields.Float(required=True, string='Start') + time_stop = fields.Float(required=True, string='Stop') - @api.constrains('start_time', 'end_time') + @api.constrains('time_start', 'time_stop') def _check_time_consistency(self): - if self.end_time < self.start_time: - raise exceptions.ValidationError(_('End time should be higher than start time')) + for timetable in self: + if timetable.time_stop < timetable.time_start: + raise ValidationError(_('End time should be after than start time')) diff --git a/golem_ressources/security/ir.model.access.csv b/golem_ressources/security/ir.model.access.csv index a269e71..ae785a3 100644 --- a/golem_ressources/security/ir.model.access.csv +++ b/golem_ressources/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_golem_resources_user,Access GOLEM Resources User,model_golem_resources,golem_base.group_golem_user,1,0,0,0 -access_golem_resources_manager,Access GOLEM Resources Manager,model_golem_resources,golem_base.group_golem_manager,1,1,1,1 +access_golem_resource_user,Access GOLEM Resources User,model_golem_resource,golem_base.group_golem_user,1,0,0,0 +access_golem_resource_manager,Access GOLEM Resources Manager,model_golem_resource,golem_base.group_golem_manager,1,1,1,1 \ No newline at end of file diff --git a/golem_ressources/views/golem_reservation_views.xml b/golem_ressources/views/golem_reservation_views.xml index 14e0af2..2588a83 100644 --- a/golem_ressources/views/golem_reservation_views.xml +++ b/golem_ressources/views/golem_reservation_views.xml @@ -18,99 +18,96 @@ along with this program. If not, see . --> - - - reservation.calendar - golem.reservation + + + + GOLEM Resource Reservation Calendar + golem.resource.reservation - - - - + + + + - - - reservation.tree - golem.reservation + + + GOLEM Resource Reservation Tree + golem.resource.reservation - - - - - - - - + + + + + + + - - - reservation.form - golem.reservation + + + GOLEM Resource Reservation Form + golem.resource.reservation -
+
- - - - - - + + + + + + - +
- - - reservation.search - golem.reservation + + + GOLEM Resource Reservation Search + golem.resource.reservation - - - - - - - - + + + + + + + + - - - Reservation - golem.reservation - tree,search,form,calendar - - + + + + +
diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_ressources/views/golem_resources_views.xml index bc71e73..7c3930e 100644 --- a/golem_ressources/views/golem_resources_views.xml +++ b/golem_ressources/views/golem_resources_views.xml @@ -18,104 +18,76 @@ along with this program. If not, see . --> - - - Sunday - 6 - - - Monday - 0 - - - Tuesday - 1 - - - wednesday - 2 - - - Thursday - 3 - - - Friday - 4 - - - Saturday - 5 - - - - - - resource.search - golem.resources + + + GOLEM Resource search + golem.resource - - - - - + + + + + - - - resource.tree - golem.resources + + + GOLEM Resource Tree + golem.resource - - - - - - - - + + + + + + + + - - - resource.form - golem.resources + + + GOLEM Resource Form + golem.resource -
+ -
-
- - - + + + - - + + - - - Resources - golem.resources - tree,form,search - + + - - - - resourcetype.tree - golem.resourcetype + + + GOLEM Resource Type Tree + golem.resource.type - - + + - - - Resources Type - golem.resourcetype - tree - - - + + + + - + + parent="golem_resource_menu" groups="golem_base.group_golem_manager" + sequence="90" /> + action="golem_resource_type_action" sequence="10" /> + diff --git a/golem_ressources/wizard/golem_reservation_rejection.py b/golem_ressources/wizard/golem_reservation_rejection.py index 01484ab..c171966 100644 --- a/golem_ressources/wizard/golem_reservation_rejection.py +++ b/golem_ressources/wizard/golem_reservation_rejection.py @@ -24,7 +24,7 @@ class GolemReservationRejectionWizard(models.TransientModel): """GOLEM Resource wizard : refusal reason for a reservation """ _name = "golem.reservation.rejection.wizard" - reservation_id = fields.Many2one('golem.reservation', required=True) + reservation_id = fields.Many2one('golem.resource.reservation', required=True) reason = fields.Text(required=True) @api.multi diff --git a/golem_ressources/wizard/golem_reservation_rejection_views.xml b/golem_ressources/wizard/golem_reservation_rejection_views.xml index 97f2e83..8cfef27 100644 --- a/golem_ressources/wizard/golem_reservation_rejection_views.xml +++ b/golem_ressources/wizard/golem_reservation_rejection_views.xml @@ -20,7 +20,7 @@ along with this program. If not, see . - + GOLEM Reservation Rejection Wizard Form golem.reservation.rejection.wizard From e1f2a2a47af7d9b848759c105e8b9b36f475e28f Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 13:42:23 +0100 Subject: [PATCH 18/34] [ADD]GOLEM Resource : new base security for all models --- golem_ressources/security/ir.model.access.csv | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/golem_ressources/security/ir.model.access.csv b/golem_ressources/security/ir.model.access.csv index ae785a3..8474a35 100644 --- a/golem_ressources/security/ir.model.access.csv +++ b/golem_ressources/security/ir.model.access.csv @@ -1,3 +1,9 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_golem_resource_user,Access GOLEM Resources User,model_golem_resource,golem_base.group_golem_user,1,0,0,0 -access_golem_resource_manager,Access GOLEM Resources Manager,model_golem_resource,golem_base.group_golem_manager,1,1,1,1 \ No newline at end of file +access_golem_resource_user,Access GOLEM Resource User,model_golem_resource,golem_base.group_golem_user,1,0,0,0 +access_golem_resource_manager,Access GOLEM Resource Manager,model_golem_resource,golem_base.group_golem_manager,1,1,1,1 +access_golem_resource_type_user,Access GOLEM Resource Type User,model_golem_resource_type,golem_base.group_golem_user,1,0,0,0 +access_golem_resource_type_manager,Access GOLEM Resource Type Manager,model_golem_resource_type,golem_base.group_golem_manager,1,1,1,1 +access_golem_resource_reservation_user,Access GOLEM Resource Reservation User,model_golem_resource_reservation,golem_base.group_golem_user,1,0,0,0 +access_golem_resource_reservation_manager,Access GOLEM Resource Reservation Manager,model_golem_resource_reservation,golem_base.group_golem_manager,1,1,1,1 +access_golem_resource_timetable_user,Access GOLEM Resource Timetable User,model_golem_resource_timetable,golem_base.group_golem_user,1,0,0,0 +access_golem_resource_timetable_manager,Access GOLEM Resource Timetable Manager,model_golem_resource_timetable,golem_base.group_golem_manager,1,1,1,1 From 2c7fb639844d01c29ad75122ee05d523deb78fd4 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 13:51:46 +0100 Subject: [PATCH 19/34] [REF]GOLEM Resource : view reorganization --- .../views/golem_resources_views.xml | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_ressources/views/golem_resources_views.xml index 7c3930e..0a9b19b 100644 --- a/golem_ressources/views/golem_resources_views.xml +++ b/golem_ressources/views/golem_resources_views.xml @@ -19,20 +19,6 @@ along with this program. If not, see . - - - GOLEM Resource search - golem.resource - - - - - - - - - - GOLEM Resource Tree @@ -50,6 +36,16 @@ along with this program. If not, see . + + GOLEM Resource Type Tree + golem.resource.type + + + + + + + GOLEM Resource Form @@ -97,22 +93,23 @@ along with this program. If not, see . - - - - - - GOLEM Resource Type Tree - golem.resource.type + + + GOLEM Resource search + golem.resource - + - + + + + + From 14729e73f167a8c469360e5b9307052b7b0bc752 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 13:55:53 +0100 Subject: [PATCH 20/34] [MOV]Rename golem_ressources module to golem_resource, and apply the same thing of filenames --- {golem_ressources => golem_resource}/__init__.py | 0 .../__manifest__.py | 4 ++-- .../models/__init__.py | 2 +- .../models/golem_resource.py | 1 - .../security/ir.model.access.csv | 0 .../static/description/icon.png | Bin .../views/golem_reservation_views.xml | 0 .../views/golem_resource_views.xml | 4 ++-- .../wizard/__init__.py | 0 .../wizard/golem_reservation_rejection.py | 0 .../wizard/golem_reservation_rejection_views.xml | 0 11 files changed, 5 insertions(+), 6 deletions(-) rename {golem_ressources => golem_resource}/__init__.py (100%) rename {golem_ressources => golem_resource}/__manifest__.py (94%) rename {golem_ressources => golem_resource}/models/__init__.py (96%) rename golem_ressources/models/golem_resources.py => golem_resource/models/golem_resource.py (99%) rename {golem_ressources => golem_resource}/security/ir.model.access.csv (100%) rename {golem_ressources => golem_resource}/static/description/icon.png (100%) rename {golem_ressources => golem_resource}/views/golem_reservation_views.xml (100%) rename golem_ressources/views/golem_resources_views.xml => golem_resource/views/golem_resource_views.xml (97%) rename {golem_ressources => golem_resource}/wizard/__init__.py (100%) rename {golem_ressources => golem_resource}/wizard/golem_reservation_rejection.py (100%) rename {golem_ressources => golem_resource}/wizard/golem_reservation_rejection_views.xml (100%) diff --git a/golem_ressources/__init__.py b/golem_resource/__init__.py similarity index 100% rename from golem_ressources/__init__.py rename to golem_resource/__init__.py diff --git a/golem_ressources/__manifest__.py b/golem_resource/__manifest__.py similarity index 94% rename from golem_ressources/__manifest__.py rename to golem_resource/__manifest__.py index 941404b..10b32de 100644 --- a/golem_ressources/__manifest__.py +++ b/golem_resource/__manifest__.py @@ -20,14 +20,14 @@ 'name': 'GOLEM non-profit resources', 'summary': 'GOLEM resources management', 'description': ''' GOLEM resources management ''', - 'version': '10.0.1.1.0', + 'version': '10.0.1.1.1', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', 'application': True, 'installable': True, 'depends': ['product'], - 'data': ['views/golem_resources_views.xml', + 'data': ['views/golem_resource_views.xml', 'views/golem_reservation_views.xml', 'wizard/golem_reservation_rejection_views.xml', 'security/ir.model.access.csv'] diff --git a/golem_ressources/models/__init__.py b/golem_resource/models/__init__.py similarity index 96% rename from golem_ressources/models/__init__.py rename to golem_resource/models/__init__.py index e917ac0..6d47599 100644 --- a/golem_ressources/models/__init__.py +++ b/golem_resource/models/__init__.py @@ -16,4 +16,4 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from . import golem_resources +from . import golem_resource diff --git a/golem_ressources/models/golem_resources.py b/golem_resource/models/golem_resource.py similarity index 99% rename from golem_ressources/models/golem_resources.py rename to golem_resource/models/golem_resource.py index 7cfe84c..672f484 100644 --- a/golem_ressources/models/golem_resources.py +++ b/golem_resource/models/golem_resource.py @@ -23,7 +23,6 @@ from odoo import models, fields, api, _ from odoo.exceptions import UserError, ValidationError -#modèle de base : ressources class GolemResource(models.Model): """ GOLEM Resource Model """ _name = 'golem.resource' diff --git a/golem_ressources/security/ir.model.access.csv b/golem_resource/security/ir.model.access.csv similarity index 100% rename from golem_ressources/security/ir.model.access.csv rename to golem_resource/security/ir.model.access.csv diff --git a/golem_ressources/static/description/icon.png b/golem_resource/static/description/icon.png similarity index 100% rename from golem_ressources/static/description/icon.png rename to golem_resource/static/description/icon.png diff --git a/golem_ressources/views/golem_reservation_views.xml b/golem_resource/views/golem_reservation_views.xml similarity index 100% rename from golem_ressources/views/golem_reservation_views.xml rename to golem_resource/views/golem_reservation_views.xml diff --git a/golem_ressources/views/golem_resources_views.xml b/golem_resource/views/golem_resource_views.xml similarity index 97% rename from golem_ressources/views/golem_resources_views.xml rename to golem_resource/views/golem_resource_views.xml index 0a9b19b..30a1a20 100644 --- a/golem_ressources/views/golem_resources_views.xml +++ b/golem_resource/views/golem_resource_views.xml @@ -116,8 +116,8 @@ along with this program. If not, see . - + Date: Sun, 18 Feb 2018 14:10:30 +0100 Subject: [PATCH 21/34] [REF]GOLEM Resources : now each model has its file, its view too (better for debugging) --- golem_resource/__manifest__.py | 5 +- golem_resource/models/__init__.py | 5 +- golem_resource/models/golem_resource.py | 181 +----------------- .../models/golem_resource_reservation.py | 165 ++++++++++++++++ .../models/golem_resource_timetable.py | 46 +++++ golem_resource/models/golem_resource_type.py | 31 +++ ...l => golem_resource_reservation_views.xml} | 0 .../views/golem_resource_type_views.xml | 43 +++++ golem_resource/views/golem_resource_views.xml | 15 -- 9 files changed, 293 insertions(+), 198 deletions(-) create mode 100644 golem_resource/models/golem_resource_reservation.py create mode 100644 golem_resource/models/golem_resource_timetable.py create mode 100644 golem_resource/models/golem_resource_type.py rename golem_resource/views/{golem_reservation_views.xml => golem_resource_reservation_views.xml} (100%) create mode 100644 golem_resource/views/golem_resource_type_views.xml diff --git a/golem_resource/__manifest__.py b/golem_resource/__manifest__.py index 10b32de..eb6f91e 100644 --- a/golem_resource/__manifest__.py +++ b/golem_resource/__manifest__.py @@ -20,7 +20,7 @@ 'name': 'GOLEM non-profit resources', 'summary': 'GOLEM resources management', 'description': ''' GOLEM resources management ''', - 'version': '10.0.1.1.1', + 'version': '10.0.1.2.0', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', @@ -28,7 +28,8 @@ 'installable': True, 'depends': ['product'], 'data': ['views/golem_resource_views.xml', - 'views/golem_reservation_views.xml', + 'views/golem_resource_type_views.xml', + 'views/golem_resource_reservation_views.xml', 'wizard/golem_reservation_rejection_views.xml', 'security/ir.model.access.csv'] } diff --git a/golem_resource/models/__init__.py b/golem_resource/models/__init__.py index 6d47599..d3aab06 100644 --- a/golem_resource/models/__init__.py +++ b/golem_resource/models/__init__.py @@ -16,4 +16,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from . import golem_resource +from . import golem_resource_type, \ + golem_resource_timetable, \ + golem_resource, \ + golem_resource_reservation diff --git a/golem_resource/models/golem_resource.py b/golem_resource/models/golem_resource.py index 672f484..06bbfa8 100644 --- a/golem_resource/models/golem_resource.py +++ b/golem_resource/models/golem_resource.py @@ -18,9 +18,7 @@ """ GOLEM Resources management """ -from math import modf -from odoo import models, fields, api, _ -from odoo.exceptions import UserError, ValidationError +from odoo import models, fields, api class GolemResource(models.Model): @@ -50,180 +48,3 @@ class GolemResource(models.Model): """ Toggles active boolean """ for resource in self: resource.active = not resource.active - - -class GolemResourceReservation(models.Model): - """ GOLEM Resource Reservation Model """ - _name = 'golem.resource.reservation' - _description = 'GOLEM Reservation Model' - - name = fields.Char(compute='_compute_name', store=True) - # TODO: handle multiple days reservation - date = fields.Date(required=True, index=True) - hour_start = fields.Float('Start hour', required=True) - hour_stop = fields.Float('Stop hour', required=True) - date_start = fields.Datetime(compute='_compute_date_start', store=True, index=True) - date_stop = fields.Datetime(compute='_compute_date_stop', store=True, index=True) - - resource_id = fields.Many2one('golem.resource', required=True, index=True, - string='Resource') - user_id = fields.Many2one('res.users', required=True, index=True, - string='User', - default=lambda self: self.env.user) - partner_id = fields.Many2one('res.partner', string='On behalf of', - required=True, index=True) - status = fields.Selection([ - ('draft', 'Draft'), - ('confirmed', 'Confirmed'), - ('canceled', 'Canceled'), - ('validated', 'Validated'), - ('rejected', 'Rejected'), - ], default='draft') - - rejection_reason = fields.Text() - - @api.depends('resource_id', 'date') - def _compute_name(self): - """ Computes reservation name """ - for reservation in self: - reservation.name = u'{}/{}'.format(reservation.resource_id.name, - reservation.date) - - @api.depends('date', 'hour_start') - def _compute_date_start(self): - """ Computes Date start """ - for reservation in self: - hour_start, minute_start = modf(reservation.hour_start) - minute_start = int(round(minute_start * 60)) - reservation.date_start = u'{} {}:{}'.format(reservation.date, - hour_start, minute_start) - - @api.depends('date', 'hour_stop') - def _compute_date_stop(self): - """ Computes Date stop """ - for reservation in self: - hour_stop, minute_stop = modf(reservation.hour_stop) - minute_stop = int(round(minute_stop * 60)) - reservation.date_stop = u'{} {}:{}'.format(reservation.date, - hour_stop, minute_stop) - - @api.multi - def status_draft(self): - """ Status to draft """ - self.write({'status': 'draft'}) - - @api.multi - def status_confirm(self): - """ Confirms reservation, or validates it if not workflow is involved """ - for reservation in self: - if reservation.resource_id.validation_required: - reservation.status = 'confirmed' - else: - reservation.status_validated() - - - @api.multi - def status_canceled(self): - """ Status to cancel """ - self.write({'status': 'canceled'}) - - @api.multi - def status_validated(self): - """ Status to validated """ - self.write({'status': 'validated'}) - - @api.multi - def status_rejected(self): - """ Wizard call for reservation reject """ - self.ensure_one() - reservation_id = self[0] - return {'name' : _('Please enter the rejection reason'), - 'type' : 'ir.actions.act_window', - 'res_model' : 'golem.reservation.rejection.wizard', - 'context': {'default_reservation_id': reservation_id.id}, - 'view_mode': 'form', - 'target': 'new'} - - - @api.constrains('status') - def check_confirmed(self): - """ Check date coherence on reservation confirmation """ - for reservation in self: - if reservation.status == 'confirmed': - # Check is reservation is not taking place out of the resource avaibility period - if reservation.date < reservation.resource_id.avaibility_start or \ - reservation.date > reservation.resource_id.avaibility_stop: - uerr = _('Not allowed, the resource is not available in ' - 'this period, please choose another périod before ' - 'confirming') - raise UserError(uerr) - # Check if reservation is not taking place out the avaibility timetables - is_day_allowed = False - for timetable in reservation.resource_id.timetable_ids: - # Check for the time according to resource timetable avaibility - date = fields.Datetime.from_string(reservation.date) - if int(timetable.weekday) == date.weekday(): - is_day_allowed = True - if reservation.hour_start < timetable.date_start or \ - reservation.hour_stop > timetable.date_stop: - uerr = _('Not allowed, the resource is not available ' - 'during this period, please choose another ' - 'time before confirming.') - raise UserError(uerr) - if not is_day_allowed: - uerr = _('Not allowed, the resource is not available ' - 'this day. Please choose another date.') - raise UserError(uerr) - # Check if the resource is already taken during this period - # PERF : check the date, not iterate over all reservations - domain = [('resource_id', '=', reservation.resource_id.id), - ('date', '=', reservation.date), - ('status', '=', 'confirmed'), - ('id', '!=', reservation.id)] - reservations = self.env['golem.resource.reservation'].search(domain) - for other_res in reservations: - if (other_res.hour_start < reservation.hour_start < other_res.hour_stop) or \ - (other_res.hour_start < reservation.hour_stop < other_res.hour_stop): - uerr = _('Not allowed, the resource is already taken ' - 'during this period : from {} to {} this day, ' - 'please choose another périod before confirming.') - raise UserError(uerr.format(reservation.date_start, - reservation.date_stop)) - # Finally, validate the reservation if all checks have passed - if reservation.resource_id.validation_required: - reservation.status = 'validated' - - -class GolemResourceType(models.Model): - """ GOLEM Resource Type """ - _name = 'golem.resource.type' - _description = 'GOLEM Resource Type' - _sql_constraints = [('golem_resource_type_name_uniq', - 'UNIQUE (name)', - 'Resource type must be unique.')] - - name = fields.Char(string='Resource Type', required=True, index=True) - -class GolemTimetable(models.Model): - """ Golem Timetable """ - _name = "golem.resource.timetable" - _description = "Golem Timetable" - _rec_name = 'weekday' - - resource_id = fields.Many2one('golem.resource', required=True, - string='Linked resource') - weekday = fields.Selection([('0', _('Monday')), - ('1', _('Tuesday')), - ('2', _('Wednesday')), - ('3', _('Thursday')), - ('4', _('Friday')), - ('5', _('Saturday')), - ('6', _('Sunday'))], copy=False) - time_start = fields.Float(required=True, string='Start') - time_stop = fields.Float(required=True, string='Stop') - - @api.constrains('time_start', 'time_stop') - def _check_time_consistency(self): - for timetable in self: - if timetable.time_stop < timetable.time_start: - raise ValidationError(_('End time should be after than start time')) diff --git a/golem_resource/models/golem_resource_reservation.py b/golem_resource/models/golem_resource_reservation.py new file mode 100644 index 0000000..b54a8d5 --- /dev/null +++ b/golem_resource/models/golem_resource_reservation.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- + +# Copyright 2018 Youssef El Ouahby +# Copyright 2018 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +""" GOLEM Resource Reservation """ + +from math import modf +from odoo import models, fields, api, _ +from odoo.exceptions import UserError + + +class GolemResourceReservation(models.Model): + """ GOLEM Resource Reservation Model """ + _name = 'golem.resource.reservation' + _description = 'GOLEM Reservation Model' + + name = fields.Char(compute='_compute_name', store=True) + # TODO: handle multiple days reservation + date = fields.Date(required=True, index=True) + hour_start = fields.Float('Start hour', required=True) + hour_stop = fields.Float('Stop hour', required=True) + date_start = fields.Datetime(compute='_compute_date_start', store=True, index=True) + date_stop = fields.Datetime(compute='_compute_date_stop', store=True, index=True) + + resource_id = fields.Many2one('golem.resource', required=True, index=True, + string='Resource') + user_id = fields.Many2one('res.users', required=True, index=True, + string='User', + default=lambda self: self.env.user) + partner_id = fields.Many2one('res.partner', string='On behalf of', + required=True, index=True) + status = fields.Selection([ + ('draft', 'Draft'), + ('confirmed', 'Confirmed'), + ('canceled', 'Canceled'), + ('validated', 'Validated'), + ('rejected', 'Rejected'), + ], default='draft') + + rejection_reason = fields.Text() + + @api.depends('resource_id', 'date') + def _compute_name(self): + """ Computes reservation name """ + for reservation in self: + reservation.name = u'{}/{}'.format(reservation.resource_id.name, + reservation.date) + + @api.depends('date', 'hour_start') + def _compute_date_start(self): + """ Computes Date start """ + for reservation in self: + hour_start, minute_start = modf(reservation.hour_start) + minute_start = int(round(minute_start * 60)) + reservation.date_start = u'{} {}:{}'.format(reservation.date, + hour_start, minute_start) + + @api.depends('date', 'hour_stop') + def _compute_date_stop(self): + """ Computes Date stop """ + for reservation in self: + hour_stop, minute_stop = modf(reservation.hour_stop) + minute_stop = int(round(minute_stop * 60)) + reservation.date_stop = u'{} {}:{}'.format(reservation.date, + hour_stop, minute_stop) + + @api.multi + def status_draft(self): + """ Status to draft """ + self.write({'status': 'draft'}) + + @api.multi + def status_confirm(self): + """ Confirms reservation, or validates it if not workflow is involved """ + for reservation in self: + if reservation.resource_id.validation_required: + reservation.status = 'confirmed' + else: + reservation.status_validated() + + + @api.multi + def status_canceled(self): + """ Status to cancel """ + self.write({'status': 'canceled'}) + + @api.multi + def status_validated(self): + """ Status to validated """ + self.write({'status': 'validated'}) + + @api.multi + def status_rejected(self): + """ Wizard call for reservation reject """ + self.ensure_one() + reservation_id = self[0] + return {'name' : _('Please enter the rejection reason'), + 'type' : 'ir.actions.act_window', + 'res_model' : 'golem.reservation.rejection.wizard', + 'context': {'default_reservation_id': reservation_id.id}, + 'view_mode': 'form', + 'target': 'new'} + + + @api.constrains('status') + def check_confirmed(self): + """ Check date coherence on reservation confirmation """ + for reservation in self: + if reservation.status == 'confirmed': + # Check is reservation is not taking place out of the resource avaibility period + if reservation.date < reservation.resource_id.avaibility_start or \ + reservation.date > reservation.resource_id.avaibility_stop: + uerr = _('Not allowed, the resource is not available in ' + 'this period, please choose another périod before ' + 'confirming') + raise UserError(uerr) + # Check if reservation is not taking place out the avaibility timetables + is_day_allowed = False + for timetable in reservation.resource_id.timetable_ids: + # Check for the time according to resource timetable avaibility + date = fields.Datetime.from_string(reservation.date) + if int(timetable.weekday) == date.weekday(): + is_day_allowed = True + if reservation.hour_start < timetable.date_start or \ + reservation.hour_stop > timetable.date_stop: + uerr = _('Not allowed, the resource is not available ' + 'during this period, please choose another ' + 'time before confirming.') + raise UserError(uerr) + if not is_day_allowed: + uerr = _('Not allowed, the resource is not available ' + 'this day. Please choose another date.') + raise UserError(uerr) + # Check if the resource is already taken during this period + # PERF : check the date, not iterate over all reservations + domain = [('resource_id', '=', reservation.resource_id.id), + ('date', '=', reservation.date), + ('status', '=', 'confirmed'), + ('id', '!=', reservation.id)] + reservations = self.env['golem.resource.reservation'].search(domain) + for other_res in reservations: + if (other_res.hour_start < reservation.hour_start < other_res.hour_stop) or \ + (other_res.hour_start < reservation.hour_stop < other_res.hour_stop): + uerr = _('Not allowed, the resource is already taken ' + 'during this period : from {} to {} this day, ' + 'please choose another périod before confirming.') + raise UserError(uerr.format(reservation.date_start, + reservation.date_stop)) + # Finally, validate the reservation if all checks have passed + if reservation.resource_id.validation_required: + reservation.status = 'validated' diff --git a/golem_resource/models/golem_resource_timetable.py b/golem_resource/models/golem_resource_timetable.py new file mode 100644 index 0000000..54e63a2 --- /dev/null +++ b/golem_resource/models/golem_resource_timetable.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +# Copyright 2018 Youssef El Ouahby +# Copyright 2018 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +""" GOLEM Resource Timetable """ + +from odoo import models, fields, api, _ +from odoo.exceptions import ValidationError + +class GolemTimetable(models.Model): + """ Golem Timetable """ + _name = "golem.resource.timetable" + _description = "Golem Timetable" + _rec_name = 'weekday' + + resource_id = fields.Many2one('golem.resource', required=True, + string='Linked resource') + weekday = fields.Selection([('0', _('Monday')), + ('1', _('Tuesday')), + ('2', _('Wednesday')), + ('3', _('Thursday')), + ('4', _('Friday')), + ('5', _('Saturday')), + ('6', _('Sunday'))], copy=False) + time_start = fields.Float(required=True, string='Start') + time_stop = fields.Float(required=True, string='Stop') + + @api.constrains('time_start', 'time_stop') + def _check_time_consistency(self): + for timetable in self: + if timetable.time_stop < timetable.time_start: + raise ValidationError(_('End time should be after than start time')) diff --git a/golem_resource/models/golem_resource_type.py b/golem_resource/models/golem_resource_type.py new file mode 100644 index 0000000..229b059 --- /dev/null +++ b/golem_resource/models/golem_resource_type.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- + +# Copyright 2018 Youssef El Ouahby +# Copyright 2018 Fabien Bourgeois +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +""" GOLEM Resource Type """ + +from odoo import models, fields + +class GolemResourceType(models.Model): + """ GOLEM Resource Type """ + _name = 'golem.resource.type' + _description = 'GOLEM Resource Type' + _sql_constraints = [('golem_resource_type_name_uniq', + 'UNIQUE (name)', + 'Resource type must be unique.')] + + name = fields.Char(string='Resource Type', required=True, index=True) diff --git a/golem_resource/views/golem_reservation_views.xml b/golem_resource/views/golem_resource_reservation_views.xml similarity index 100% rename from golem_resource/views/golem_reservation_views.xml rename to golem_resource/views/golem_resource_reservation_views.xml diff --git a/golem_resource/views/golem_resource_type_views.xml b/golem_resource/views/golem_resource_type_views.xml new file mode 100644 index 0000000..ca21927 --- /dev/null +++ b/golem_resource/views/golem_resource_type_views.xml @@ -0,0 +1,43 @@ + + + + + + + + GOLEM Resource Type Tree + golem.resource.type + + + + + + + + + + + + + + + diff --git a/golem_resource/views/golem_resource_views.xml b/golem_resource/views/golem_resource_views.xml index 30a1a20..369d482 100644 --- a/golem_resource/views/golem_resource_views.xml +++ b/golem_resource/views/golem_resource_views.xml @@ -36,16 +36,6 @@ along with this program. If not, see . - - GOLEM Resource Type Tree - golem.resource.type - - - - - - - GOLEM Resource Form @@ -110,8 +100,6 @@ along with this program. If not, see . - . - From 2223b889308321df2d49f4f51a5f688b0ea3030f Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 14:53:53 +0100 Subject: [PATCH 22/34] [IMP]GOLEM Resource : small enhancements around form and timetable model --- golem_resource/__manifest__.py | 2 +- golem_resource/models/golem_resource.py | 5 +- .../models/golem_resource_timetable.py | 10 +++- golem_resource/views/golem_resource_views.xml | 60 ++++++++++++------- 4 files changed, 54 insertions(+), 23 deletions(-) diff --git a/golem_resource/__manifest__.py b/golem_resource/__manifest__.py index eb6f91e..273994b 100644 --- a/golem_resource/__manifest__.py +++ b/golem_resource/__manifest__.py @@ -20,7 +20,7 @@ 'name': 'GOLEM non-profit resources', 'summary': 'GOLEM resources management', 'description': ''' GOLEM resources management ''', - 'version': '10.0.1.2.0', + 'version': '10.0.1.3.0', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', diff --git a/golem_resource/models/golem_resource.py b/golem_resource/models/golem_resource.py index 06bbfa8..9774004 100644 --- a/golem_resource/models/golem_resource.py +++ b/golem_resource/models/golem_resource.py @@ -34,7 +34,10 @@ class GolemResource(models.Model): index=True, string='Resource Type') supervisor_id = fields.Many2one('res.partner', index=True, string='Supervisor') product_tmpl_id = fields.Many2one('product.template', index=True, - string='Linked product') + string='Linked product', + help='A generic product can be linked, in ' + 'order to sell reservations (work in ' + 'progress)') avaibility_start = fields.Date(required=True, string='Availibility start date') avaibility_stop = fields.Date(required=True, string='Availibility stop date') diff --git a/golem_resource/models/golem_resource_timetable.py b/golem_resource/models/golem_resource_timetable.py index 54e63a2..9fe8c87 100644 --- a/golem_resource/models/golem_resource_timetable.py +++ b/golem_resource/models/golem_resource_timetable.py @@ -35,12 +35,20 @@ class GolemTimetable(models.Model): ('3', _('Thursday')), ('4', _('Friday')), ('5', _('Saturday')), - ('6', _('Sunday'))], copy=False) + ('6', _('Sunday'))], required=True) time_start = fields.Float(required=True, string='Start') time_stop = fields.Float(required=True, string='Stop') + @api.onchange('time_start') + def onchange_time_start(self): + """ Propose automatically stop hour after start hour had been filled """ + for line in self: + if line.time_start and not line.time_stop: + line.time_stop = line.time_start + 1 + @api.constrains('time_start', 'time_stop') def _check_time_consistency(self): + """ Checks time consistency """ for timetable in self: if timetable.time_stop < timetable.time_start: raise ValidationError(_('End time should be after than start time')) diff --git a/golem_resource/views/golem_resource_views.xml b/golem_resource/views/golem_resource_views.xml index 369d482..20b9632 100644 --- a/golem_resource/views/golem_resource_views.xml +++ b/golem_resource/views/golem_resource_views.xml @@ -50,33 +50,40 @@ along with this program. If not, see . options="{'terminology': 'archive'}" /> - - - - - - - + + + + + - - - - - + + + -
@@ -93,6 +100,19 @@ along with this program. If not, see . + + + + + + +
From d1c178aa8ca760a74cf33cc037d5e269f1e38841 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 16:41:01 +0100 Subject: [PATCH 23/34] [IMP]GOLEM Resource : many enhancements like correct usage of states and readonly everytime but not on draft, access checking server side for validate/reject, fixes on main constraint --- .../models/golem_resource_reservation.py | 113 +++++++++++------- golem_resource/security/ir.model.access.csv | 2 +- 2 files changed, 71 insertions(+), 44 deletions(-) diff --git a/golem_resource/models/golem_resource_reservation.py b/golem_resource/models/golem_resource_reservation.py index b54a8d5..c860b9f 100644 --- a/golem_resource/models/golem_resource_reservation.py +++ b/golem_resource/models/golem_resource_reservation.py @@ -20,7 +20,7 @@ from math import modf from odoo import models, fields, api, _ -from odoo.exceptions import UserError +from odoo.exceptions import UserError, ValidationError class GolemResourceReservation(models.Model): @@ -30,28 +30,33 @@ class GolemResourceReservation(models.Model): name = fields.Char(compute='_compute_name', store=True) # TODO: handle multiple days reservation - date = fields.Date(required=True, index=True) - hour_start = fields.Float('Start hour', required=True) - hour_stop = fields.Float('Stop hour', required=True) + date = fields.Date(required=True, index=True, readonly=True, + states={'draft': [('readonly', False)]}) + hour_start = fields.Float('Start hour', required=True, readonly=True, + states={'draft': [('readonly', False)]}) + hour_stop = fields.Float('Stop hour', required=True, readonly=True, + states={'draft': [('readonly', False)]}) date_start = fields.Datetime(compute='_compute_date_start', store=True, index=True) date_stop = fields.Datetime(compute='_compute_date_stop', store=True, index=True) resource_id = fields.Many2one('golem.resource', required=True, index=True, - string='Resource') - user_id = fields.Many2one('res.users', required=True, index=True, - string='User', - default=lambda self: self.env.user) + string='Resource', readonly=True, + states={'draft': [('readonly', False)]}) + user_id = fields.Many2one('res.users', required=True, index=True, readonly=True, + string='User', default=lambda self: self.env.user, + states={'draft': [('readonly', False)]}) partner_id = fields.Many2one('res.partner', string='On behalf of', - required=True, index=True) - status = fields.Selection([ + required=True, index=True, readonly=True, + states={'draft': [('readonly', False)]}) + state = fields.Selection([ + ('canceled', 'Canceled'), ('draft', 'Draft'), ('confirmed', 'Confirmed'), - ('canceled', 'Canceled'), ('validated', 'Validated'), - ('rejected', 'Rejected'), + ('rejected', 'Rejected') ], default='draft') - rejection_reason = fields.Text() + rejection_reason = fields.Text(readonly=True) @api.depends('resource_id', 'date') def _compute_name(self): @@ -64,47 +69,63 @@ class GolemResourceReservation(models.Model): def _compute_date_start(self): """ Computes Date start """ for reservation in self: - hour_start, minute_start = modf(reservation.hour_start) + minute_start, hour_start = modf(reservation.hour_start) + hour_start = int(hour_start) minute_start = int(round(minute_start * 60)) - reservation.date_start = u'{} {}:{}'.format(reservation.date, - hour_start, minute_start) + reservation.date_start = u'{} {}:{}:00'.format(reservation.date, + hour_start, minute_start) @api.depends('date', 'hour_stop') def _compute_date_stop(self): """ Computes Date stop """ for reservation in self: - hour_stop, minute_stop = modf(reservation.hour_stop) + minute_stop, hour_stop = modf(reservation.hour_stop) + hour_stop = int(hour_stop) minute_stop = int(round(minute_stop * 60)) - reservation.date_stop = u'{} {}:{}'.format(reservation.date, - hour_stop, minute_stop) + reservation.date_stop = u'{} {}:{}:00'.format(reservation.date, + hour_stop, minute_stop) + + @api.onchange('hour_start') + def onchange_hour_start(self): + """ Propose automatically stop hour after start hour had been filled """ + for reservation in self: + if reservation.hour_start and not reservation.hour_stop: + reservation.hour_stop = reservation.hour_start + 1 + + @api.constrains('hour_start', 'hour_stop') + def _check_hour_consistency(self): + """ Checks hour consistency """ + for reservation in self: + if reservation.hour_stop < reservation.hour_start: + raise ValidationError(_('End time should be after than start time')) @api.multi - def status_draft(self): + def state_draft(self): """ Status to draft """ - self.write({'status': 'draft'}) + self.write({'state': 'draft'}) @api.multi - def status_confirm(self): + def state_confirm(self): """ Confirms reservation, or validates it if not workflow is involved """ for reservation in self: - if reservation.resource_id.validation_required: - reservation.status = 'confirmed' - else: - reservation.status_validated() + # Needed, for constraint checking + reservation.state = 'confirmed' + if not reservation.resource_id.validation_required: + reservation.state = 'validated' @api.multi - def status_canceled(self): + def state_canceled(self): """ Status to cancel """ - self.write({'status': 'canceled'}) + self.write({'state': 'canceled'}) @api.multi - def status_validated(self): + def state_validated(self): """ Status to validated """ - self.write({'status': 'validated'}) + self.write({'state': 'validated'}) @api.multi - def status_rejected(self): + def state_rejected(self): """ Wizard call for reservation reject """ self.ensure_one() reservation_id = self[0] @@ -116,11 +137,20 @@ class GolemResourceReservation(models.Model): 'target': 'new'} - @api.constrains('status') + @api.constrains('state') + def check_access(self): + """ Checks access when state is updated """ + reservation = self[0] + if reservation.state in ('rejected', 'validated'): + if not self.env.user.has_group('golem_base.group_golem_manager'): + uerr = _('You do not have permissions to validate or reject a reservation.') + raise UserError(uerr) + + @api.constrains('state') def check_confirmed(self): """ Check date coherence on reservation confirmation """ for reservation in self: - if reservation.status == 'confirmed': + if reservation.state == 'confirmed': # Check is reservation is not taking place out of the resource avaibility period if reservation.date < reservation.resource_id.avaibility_start or \ reservation.date > reservation.resource_id.avaibility_stop: @@ -135,8 +165,8 @@ class GolemResourceReservation(models.Model): date = fields.Datetime.from_string(reservation.date) if int(timetable.weekday) == date.weekday(): is_day_allowed = True - if reservation.hour_start < timetable.date_start or \ - reservation.hour_stop > timetable.date_stop: + if reservation.hour_start < timetable.time_start or \ + reservation.hour_stop > timetable.time_stop: uerr = _('Not allowed, the resource is not available ' 'during this period, please choose another ' 'time before confirming.') @@ -149,17 +179,14 @@ class GolemResourceReservation(models.Model): # PERF : check the date, not iterate over all reservations domain = [('resource_id', '=', reservation.resource_id.id), ('date', '=', reservation.date), - ('status', '=', 'confirmed'), + ('state', 'in', ('confirmed', 'validated')), ('id', '!=', reservation.id)] reservations = self.env['golem.resource.reservation'].search(domain) for other_res in reservations: - if (other_res.hour_start < reservation.hour_start < other_res.hour_stop) or \ - (other_res.hour_start < reservation.hour_stop < other_res.hour_stop): + if (other_res.hour_start <= reservation.hour_start <= other_res.hour_stop) or \ + (other_res.hour_start <= reservation.hour_stop <= other_res.hour_stop): uerr = _('Not allowed, the resource is already taken ' 'during this period : from {} to {} this day, ' 'please choose another périod before confirming.') - raise UserError(uerr.format(reservation.date_start, - reservation.date_stop)) - # Finally, validate the reservation if all checks have passed - if reservation.resource_id.validation_required: - reservation.status = 'validated' + raise UserError(uerr.format(other_res.date_start, + other_res.date_stop)) diff --git a/golem_resource/security/ir.model.access.csv b/golem_resource/security/ir.model.access.csv index 8474a35..88def47 100644 --- a/golem_resource/security/ir.model.access.csv +++ b/golem_resource/security/ir.model.access.csv @@ -3,7 +3,7 @@ access_golem_resource_user,Access GOLEM Resource User,model_golem_resource,golem access_golem_resource_manager,Access GOLEM Resource Manager,model_golem_resource,golem_base.group_golem_manager,1,1,1,1 access_golem_resource_type_user,Access GOLEM Resource Type User,model_golem_resource_type,golem_base.group_golem_user,1,0,0,0 access_golem_resource_type_manager,Access GOLEM Resource Type Manager,model_golem_resource_type,golem_base.group_golem_manager,1,1,1,1 -access_golem_resource_reservation_user,Access GOLEM Resource Reservation User,model_golem_resource_reservation,golem_base.group_golem_user,1,0,0,0 +access_golem_resource_reservation_user,Access GOLEM Resource Reservation User,model_golem_resource_reservation,golem_base.group_golem_user,1,1,1,0 access_golem_resource_reservation_manager,Access GOLEM Resource Reservation Manager,model_golem_resource_reservation,golem_base.group_golem_manager,1,1,1,1 access_golem_resource_timetable_user,Access GOLEM Resource Timetable User,model_golem_resource_timetable,golem_base.group_golem_user,1,0,0,0 access_golem_resource_timetable_manager,Access GOLEM Resource Timetable Manager,model_golem_resource_timetable,golem_base.group_golem_manager,1,1,1,1 From 8c59738e3b37d8dfa8bc7b01d7bf30a6f1a1adee Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 16:41:50 +0100 Subject: [PATCH 24/34] [IMP]GOLEM Resource reservation form : better organization, fields as invisible when not needed, buttons too --- .../golem_resource_reservation_views.xml | 58 +++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/golem_resource/views/golem_resource_reservation_views.xml b/golem_resource/views/golem_resource_reservation_views.xml index 2588a83..22da6e1 100644 --- a/golem_resource/views/golem_resource_reservation_views.xml +++ b/golem_resource/views/golem_resource_reservation_views.xml @@ -38,12 +38,12 @@ along with this program. If not, see . golem.resource.reservation - - + + - +
@@ -55,27 +55,39 @@ along with this program. If not, see .
-
+ + + + - - - - - - + + + + + + + + + + + +
@@ -93,9 +105,9 @@ along with this program. If not, see . - + + domain="[('state', '=', 'confirmed')]" />
From 3fbb3fe187a2a6c3d49fe18f0248500c4b06067c Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 16:42:29 +0100 Subject: [PATCH 25/34] [TYPO]GOLEM Resource : better meaning for reject/validate --- golem_resource/__manifest__.py | 2 +- golem_resource/views/golem_resource_views.xml | 2 +- golem_resource/wizard/golem_reservation_rejection.py | 4 ++-- golem_resource/wizard/golem_reservation_rejection_views.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/golem_resource/__manifest__.py b/golem_resource/__manifest__.py index 273994b..e663f4a 100644 --- a/golem_resource/__manifest__.py +++ b/golem_resource/__manifest__.py @@ -20,7 +20,7 @@ 'name': 'GOLEM non-profit resources', 'summary': 'GOLEM resources management', 'description': ''' GOLEM resources management ''', - 'version': '10.0.1.3.0', + 'version': '10.0.1.4.0', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', diff --git a/golem_resource/views/golem_resource_views.xml b/golem_resource/views/golem_resource_views.xml index 20b9632..3fb8442 100644 --- a/golem_resource/views/golem_resource_views.xml +++ b/golem_resource/views/golem_resource_views.xml @@ -54,7 +54,7 @@ along with this program. If not, see . - + diff --git a/golem_resource/wizard/golem_reservation_rejection.py b/golem_resource/wizard/golem_reservation_rejection.py index c171966..7fdc781 100644 --- a/golem_resource/wizard/golem_reservation_rejection.py +++ b/golem_resource/wizard/golem_reservation_rejection.py @@ -28,9 +28,9 @@ class GolemReservationRejectionWizard(models.TransientModel): reason = fields.Text(required=True) @api.multi - def validate(self): + def reject(self): """ Sets reservation status to rejected and add reason """ self.ensure_one() rejection = self[0] - rejection.reservation_id.write({'status': 'rejected', + rejection.reservation_id.write({'state': 'rejected', 'rejection_reason': rejection.reason}) diff --git a/golem_resource/wizard/golem_reservation_rejection_views.xml b/golem_resource/wizard/golem_reservation_rejection_views.xml index 8cfef27..0bb4048 100644 --- a/golem_resource/wizard/golem_reservation_rejection_views.xml +++ b/golem_resource/wizard/golem_reservation_rejection_views.xml @@ -30,7 +30,7 @@ along with this program. If not, see .
-
From 1182d1299b0be24c6949863ee06eebaf9a49c144 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 16:55:24 +0100 Subject: [PATCH 26/34] [IMP]GOLEM Resource Reservation tree : new fields, and search : new filters, groups... --- .../golem_resource_reservation_views.xml | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/golem_resource/views/golem_resource_reservation_views.xml b/golem_resource/views/golem_resource_reservation_views.xml index 22da6e1..9bc9599 100644 --- a/golem_resource/views/golem_resource_reservation_views.xml +++ b/golem_resource/views/golem_resource_reservation_views.xml @@ -38,10 +38,10 @@ along with this program. If not, see . golem.resource.reservation - - - + + + @@ -108,6 +108,20 @@ along with this program. If not, see . + + + + + + +
From bf5314f54ff99e3dadde06b94d3b218e3c0ce4aa Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 16:55:44 +0100 Subject: [PATCH 27/34] [ADD]GOLEM Resource Type : new direct search on name --- golem_resource/views/golem_resource_type_views.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/golem_resource/views/golem_resource_type_views.xml b/golem_resource/views/golem_resource_type_views.xml index ca21927..cc94a87 100644 --- a/golem_resource/views/golem_resource_type_views.xml +++ b/golem_resource/views/golem_resource_type_views.xml @@ -30,6 +30,17 @@ along with this program. If not, see .
+ + + GOLEM Resource Type Search + golem.resource.type + + + + + + + From 5c87abbbbc5865018d1366700725f28c39d62e1c Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 17:17:32 +0100 Subject: [PATCH 28/34] [IMP]GOLEM Resource Reservation : display avaibility period and timetable on reservation --- .../models/golem_resource_reservation.py | 4 +++ .../golem_resource_reservation_views.xml | 29 ++++++++++--------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/golem_resource/models/golem_resource_reservation.py b/golem_resource/models/golem_resource_reservation.py index c860b9f..a57da76 100644 --- a/golem_resource/models/golem_resource_reservation.py +++ b/golem_resource/models/golem_resource_reservation.py @@ -42,6 +42,10 @@ class GolemResourceReservation(models.Model): resource_id = fields.Many2one('golem.resource', required=True, index=True, string='Resource', readonly=True, states={'draft': [('readonly', False)]}) + resource_avaibility_start = fields.Date(related='resource_id.avaibility_start') + resource_avaibility_stop = fields.Date(related='resource_id.avaibility_stop') + resource_timetable_ids = fields.One2many(related='resource_id.timetable_ids') + user_id = fields.Many2one('res.users', required=True, index=True, readonly=True, string='User', default=lambda self: self.env.user, states={'draft': [('readonly', False)]}) diff --git a/golem_resource/views/golem_resource_reservation_views.xml b/golem_resource/views/golem_resource_reservation_views.xml index 9bc9599..ae3d01a 100644 --- a/golem_resource/views/golem_resource_reservation_views.xml +++ b/golem_resource/views/golem_resource_reservation_views.xml @@ -70,25 +70,26 @@ along with this program. If not, see . - + + - - - - - - + + + - - - + + + + + + + + + - - - From 6933755fdde24ce7bbcf2a07206784e1c093f2da Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 17:18:09 +0100 Subject: [PATCH 29/34] [ADD]GOLEM Resource : timetable own tree --- golem_resource/__manifest__.py | 3 +- .../views/golem_resource_timetable_views.xml | 37 +++++++++++++++++++ golem_resource/views/golem_resource_views.xml | 11 +----- 3 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 golem_resource/views/golem_resource_timetable_views.xml diff --git a/golem_resource/__manifest__.py b/golem_resource/__manifest__.py index e663f4a..c99e531 100644 --- a/golem_resource/__manifest__.py +++ b/golem_resource/__manifest__.py @@ -20,7 +20,7 @@ 'name': 'GOLEM non-profit resources', 'summary': 'GOLEM resources management', 'description': ''' GOLEM resources management ''', - 'version': '10.0.1.4.0', + 'version': '10.0.1.5.0', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', @@ -30,6 +30,7 @@ 'data': ['views/golem_resource_views.xml', 'views/golem_resource_type_views.xml', 'views/golem_resource_reservation_views.xml', + 'views/golem_resource_timetable_views.xml', 'wizard/golem_reservation_rejection_views.xml', 'security/ir.model.access.csv'] } diff --git a/golem_resource/views/golem_resource_timetable_views.xml b/golem_resource/views/golem_resource_timetable_views.xml new file mode 100644 index 0000000..9e532ea --- /dev/null +++ b/golem_resource/views/golem_resource_timetable_views.xml @@ -0,0 +1,37 @@ + + + + + + + + GOLEM Resource Timetable Tree + golem.resource.timetable + + + + + + + + + + + + diff --git a/golem_resource/views/golem_resource_views.xml b/golem_resource/views/golem_resource_views.xml index 3fb8442..d3f959b 100644 --- a/golem_resource/views/golem_resource_views.xml +++ b/golem_resource/views/golem_resource_views.xml @@ -73,16 +73,7 @@ along with this program. If not, see . - - - - - - - + attrs="{'readonly': [('id', '=', False)]}" />
From a5d4e5feb3466ecb5cf89f3f45626d1c45cddbdc Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 17:29:16 +0100 Subject: [PATCH 30/34] [FIX]GOLEM Resource Reservation : dot not allow edit on avaibility fields from reservation form --- golem_resource/views/golem_resource_reservation_views.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/golem_resource/views/golem_resource_reservation_views.xml b/golem_resource/views/golem_resource_reservation_views.xml index ae3d01a..877bb3b 100644 --- a/golem_resource/views/golem_resource_reservation_views.xml +++ b/golem_resource/views/golem_resource_reservation_views.xml @@ -74,8 +74,8 @@ along with this program. If not, see . - - + + From 977e817326115c4f9807d70191b0122b16555d20 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 17:30:11 +0100 Subject: [PATCH 31/34] [ADD]GOLEM Resource : add social abilities on resource and reservation, and track fields on reservation --- golem_resource/__manifest__.py | 2 +- golem_resource/models/golem_resource.py | 1 + .../models/golem_resource_reservation.py | 18 ++++++++++-------- .../views/golem_resource_reservation_views.xml | 4 ++++ golem_resource/views/golem_resource_views.xml | 4 ++++ 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/golem_resource/__manifest__.py b/golem_resource/__manifest__.py index c99e531..e3a6ebb 100644 --- a/golem_resource/__manifest__.py +++ b/golem_resource/__manifest__.py @@ -20,7 +20,7 @@ 'name': 'GOLEM non-profit resources', 'summary': 'GOLEM resources management', 'description': ''' GOLEM resources management ''', - 'version': '10.0.1.5.0', + 'version': '10.0.1.6.0', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', diff --git a/golem_resource/models/golem_resource.py b/golem_resource/models/golem_resource.py index 9774004..a529e99 100644 --- a/golem_resource/models/golem_resource.py +++ b/golem_resource/models/golem_resource.py @@ -25,6 +25,7 @@ class GolemResource(models.Model): """ GOLEM Resource Model """ _name = 'golem.resource' _description = 'GOLEM Resource Model' + _inherit = 'mail.thread' name = fields.Char(required=True, index=True) active = fields.Boolean(default=True) diff --git a/golem_resource/models/golem_resource_reservation.py b/golem_resource/models/golem_resource_reservation.py index a57da76..a461ced 100644 --- a/golem_resource/models/golem_resource_reservation.py +++ b/golem_resource/models/golem_resource_reservation.py @@ -27,6 +27,7 @@ class GolemResourceReservation(models.Model): """ GOLEM Resource Reservation Model """ _name = 'golem.resource.reservation' _description = 'GOLEM Reservation Model' + _inherit = 'mail.thread' name = fields.Char(compute='_compute_name', store=True) # TODO: handle multiple days reservation @@ -41,6 +42,7 @@ class GolemResourceReservation(models.Model): resource_id = fields.Many2one('golem.resource', required=True, index=True, string='Resource', readonly=True, + track_visibility='onchange', states={'draft': [('readonly', False)]}) resource_avaibility_start = fields.Date(related='resource_id.avaibility_start') resource_avaibility_stop = fields.Date(related='resource_id.avaibility_stop') @@ -51,16 +53,16 @@ class GolemResourceReservation(models.Model): states={'draft': [('readonly', False)]}) partner_id = fields.Many2one('res.partner', string='On behalf of', required=True, index=True, readonly=True, + track_visibility='onchange', states={'draft': [('readonly', False)]}) - state = fields.Selection([ - ('canceled', 'Canceled'), - ('draft', 'Draft'), - ('confirmed', 'Confirmed'), - ('validated', 'Validated'), - ('rejected', 'Rejected') - ], default='draft') + state = fields.Selection([('canceled', 'Canceled'), + ('draft', 'Draft'), + ('confirmed', 'Confirmed'), + ('validated', 'Validated'), + ('rejected', 'Rejected')], + default='draft', track_visibility='onchange') - rejection_reason = fields.Text(readonly=True) + rejection_reason = fields.Text(readonly=True, track_visibility='onchange') @api.depends('resource_id', 'date') def _compute_name(self): diff --git a/golem_resource/views/golem_resource_reservation_views.xml b/golem_resource/views/golem_resource_reservation_views.xml index 877bb3b..0ed86a1 100644 --- a/golem_resource/views/golem_resource_reservation_views.xml +++ b/golem_resource/views/golem_resource_reservation_views.xml @@ -91,6 +91,10 @@ along with this program. If not, see .
+
+ + +
diff --git a/golem_resource/views/golem_resource_views.xml b/golem_resource/views/golem_resource_views.xml index d3f959b..8b56051 100644 --- a/golem_resource/views/golem_resource_views.xml +++ b/golem_resource/views/golem_resource_views.xml @@ -77,6 +77,10 @@ along with this program. If not, see . +
+ + +
From 518d2c8348ed29a93fceb7f72d37925accad4d04 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 17:36:01 +0100 Subject: [PATCH 32/34] [IMP]GOLEM Resource : add ordering --- golem_resource/models/golem_resource.py | 1 + golem_resource/models/golem_resource_reservation.py | 1 + golem_resource/models/golem_resource_timetable.py | 1 + golem_resource/models/golem_resource_type.py | 1 + 4 files changed, 4 insertions(+) diff --git a/golem_resource/models/golem_resource.py b/golem_resource/models/golem_resource.py index a529e99..1afd616 100644 --- a/golem_resource/models/golem_resource.py +++ b/golem_resource/models/golem_resource.py @@ -26,6 +26,7 @@ class GolemResource(models.Model): _name = 'golem.resource' _description = 'GOLEM Resource Model' _inherit = 'mail.thread' + _order = 'name asc' name = fields.Char(required=True, index=True) active = fields.Boolean(default=True) diff --git a/golem_resource/models/golem_resource_reservation.py b/golem_resource/models/golem_resource_reservation.py index a461ced..b1de33b 100644 --- a/golem_resource/models/golem_resource_reservation.py +++ b/golem_resource/models/golem_resource_reservation.py @@ -28,6 +28,7 @@ class GolemResourceReservation(models.Model): _name = 'golem.resource.reservation' _description = 'GOLEM Reservation Model' _inherit = 'mail.thread' + _order = 'date desc,hour_start asc' name = fields.Char(compute='_compute_name', store=True) # TODO: handle multiple days reservation diff --git a/golem_resource/models/golem_resource_timetable.py b/golem_resource/models/golem_resource_timetable.py index 9fe8c87..7eef3d7 100644 --- a/golem_resource/models/golem_resource_timetable.py +++ b/golem_resource/models/golem_resource_timetable.py @@ -26,6 +26,7 @@ class GolemTimetable(models.Model): _name = "golem.resource.timetable" _description = "Golem Timetable" _rec_name = 'weekday' + _order = 'weekday asc,time_start asc' resource_id = fields.Many2one('golem.resource', required=True, string='Linked resource') diff --git a/golem_resource/models/golem_resource_type.py b/golem_resource/models/golem_resource_type.py index 229b059..c13cd02 100644 --- a/golem_resource/models/golem_resource_type.py +++ b/golem_resource/models/golem_resource_type.py @@ -24,6 +24,7 @@ class GolemResourceType(models.Model): """ GOLEM Resource Type """ _name = 'golem.resource.type' _description = 'GOLEM Resource Type' + _order = 'name asc' _sql_constraints = [('golem_resource_type_name_uniq', 'UNIQUE (name)', 'Resource type must be unique.')] From 05d5cc5cda3f5c7014196678a6514a72dc7f94e6 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 17:36:32 +0100 Subject: [PATCH 33/34] [FIX]GOLEM Resource : reservation can end at the same time new begin --- golem_resource/models/golem_resource_reservation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/golem_resource/models/golem_resource_reservation.py b/golem_resource/models/golem_resource_reservation.py index b1de33b..fe4a6a3 100644 --- a/golem_resource/models/golem_resource_reservation.py +++ b/golem_resource/models/golem_resource_reservation.py @@ -190,8 +190,8 @@ class GolemResourceReservation(models.Model): ('id', '!=', reservation.id)] reservations = self.env['golem.resource.reservation'].search(domain) for other_res in reservations: - if (other_res.hour_start <= reservation.hour_start <= other_res.hour_stop) or \ - (other_res.hour_start <= reservation.hour_stop <= other_res.hour_stop): + if (other_res.hour_start < reservation.hour_start < other_res.hour_stop) or \ + (other_res.hour_start < reservation.hour_stop < other_res.hour_stop): uerr = _('Not allowed, the resource is already taken ' 'during this period : from {} to {} this day, ' 'please choose another périod before confirming.') From 4c9921c8d8f389e83093e7bfc39066efe56b02a1 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Sun, 18 Feb 2018 17:36:46 +0100 Subject: [PATCH 34/34] [UPD]Bump GOLEM Resource version --- golem_resource/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/golem_resource/__manifest__.py b/golem_resource/__manifest__.py index e3a6ebb..a0dcb5c 100644 --- a/golem_resource/__manifest__.py +++ b/golem_resource/__manifest__.py @@ -20,7 +20,7 @@ 'name': 'GOLEM non-profit resources', 'summary': 'GOLEM resources management', 'description': ''' GOLEM resources management ''', - 'version': '10.0.1.6.0', + 'version': '10.0.1.6.1', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3',