From d81434375822de92e360cc4199749b5c1751066f Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Wed, 7 Feb 2018 01:44:48 +0100 Subject: [PATCH 001/109] 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 002/109] 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 003/109] =?UTF-8?q?Ajout=20d'un=20mod=C3=A8le=20hour=20pou?= =?UTF-8?q?r=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 004/109] 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 005/109] 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 006/109] =?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 007/109] =?UTF-8?q?R=C3=A9alisation=20des=20am=C3=A9liorat?= =?UTF-8?q?ions=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 008/109] =?UTF-8?q?1er=20version=20du=20mod=C3=A8le=20rese?= =?UTF-8?q?rvation,=20avec=20contraintes=20de=20disponibilit=C3=A9=20opera?= =?UTF-8?q?tionnelles?= 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 009/109] =?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 010/109] 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 011/109] =?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 012/109] 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 013/109] [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 015/109] [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 016/109] [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 017/109] [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 018/109] [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 019/109] [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 020/109] [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 021/109] [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 022/109] [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 023/109] [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 024/109] [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 025/109] [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 026/109] [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 027/109] [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 028/109] [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 029/109] [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 030/109] [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 031/109] [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 032/109] [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 033/109] [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 034/109] [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', From cb74acb4e6a077f2c7f06a7de22e42d5b7fe2f32 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Mon, 19 Feb 2018 06:49:35 +0100 Subject: [PATCH 035/109] [ADD]GOLEM Resource tests [IMP]Resource validation to False, check dates --- golem_resource/models/golem_resource.py | 11 +++- golem_resource/tests/__init__.py | 19 ++++++ golem_resource/tests/test_golem_resource.py | 69 +++++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 golem_resource/tests/__init__.py create mode 100644 golem_resource/tests/test_golem_resource.py diff --git a/golem_resource/models/golem_resource.py b/golem_resource/models/golem_resource.py index 1afd616..092a812 100644 --- a/golem_resource/models/golem_resource.py +++ b/golem_resource/models/golem_resource.py @@ -19,6 +19,7 @@ """ GOLEM Resources management """ from odoo import models, fields, api +from odoo.exceptions import ValidationError class GolemResource(models.Model): @@ -30,7 +31,7 @@ class GolemResource(models.Model): name = fields.Char(required=True, index=True) active = fields.Boolean(default=True) - validation_required = fields.Boolean(default=True, + validation_required = fields.Boolean(default=False, string='Is validation required ?') type_id = fields.Many2one('golem.resource.type', index=True, string='Resource Type') @@ -53,3 +54,11 @@ class GolemResource(models.Model): """ Toggles active boolean """ for resource in self: resource.active = not resource.active + + @api.constrains('avaibility_start', 'avaibility_stop') + def _check_date_consistency(self): + """ Checks date consistency """ + for resource in self: + if resource.avaibility_stop <= resource.avaibility_start: + raise ValidationError(_('End availibility should be after than ' + 'start availibility')) diff --git a/golem_resource/tests/__init__.py b/golem_resource/tests/__init__.py new file mode 100644 index 0000000..4eb2e86 --- /dev/null +++ b/golem_resource/tests/__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 test_golem_resource, test_golem_resource_timetable diff --git a/golem_resource/tests/test_golem_resource.py b/golem_resource/tests/test_golem_resource.py new file mode 100644 index 0000000..903b83d --- /dev/null +++ b/golem_resource/tests/test_golem_resource.py @@ -0,0 +1,69 @@ +# -*- 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 testing """ + +from odoo.tests.common import TransactionCase +from odoo.exceptions import ValidationError + + +class TestGolemResource(TransactionCase): + """ GOLEM Resource testing """ + + def setUp(self, *args, **kwargs): + """ Bootstrap Resource """ + super(TestGolemResource, self).setUp(*args, **kwargs) + self.data = { + 'name': 'Resource', + 'avaibility_start': '2018-01-01', + 'avaibility_stop': '2020-01-01' + } + self.resource = self.env['golem.resource'] + + def test_resource_basic(self): + """ Test resource bases """ + resource = self.resource.create(self.data) + self.assertTrue(resource.active) + self.assertFalse(resource.validation_required) + self.assertEqual(resource.avaibility_start, '2018-01-01') + self.assertEqual(resource.avaibility_stop, '2020-01-01') + self.assertFalse(resource.supervisor_id) + self.assertFalse(resource.product_tmpl_id) + self.assertFalse(resource.timetable_ids) + self.assertFalse(resource.reservation_ids) + + def test_resource_active(self): + """ Test resource active """ + resource = self.resource.create(self.data) + self.assertTrue(resource.active) + resource.active_toggle() + self.assertFalse(resource.active) + resource.active_toggle() + self.assertTrue(resource.active) + + def test_resource_dates(self): + """ Test resource dates : stop can not be after start """ + self.data.update({'avaibility_stop': '2017-01-01'}) + with self.assertRaises(ValidationError): + self.resource.create(self.data) + + def test_resource_dates_equal(self): + """ Test resource dates : stop can not be equal to start """ + self.data.update({'avaibility_stop': self.data['avaibility_start']}) + with self.assertRaises(ValidationError): + self.resource.create(self.data) From 94f905b90ebeb95bcf8700b7a73f6101ed5a5944 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Mon, 19 Feb 2018 06:50:04 +0100 Subject: [PATCH 036/109] [ADD]GOLEM Resource Timetable tests [IMP]Do not allow equal times between start and stop --- .../models/golem_resource_timetable.py | 2 +- .../tests/test_golem_resource_timetable.py | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 golem_resource/tests/test_golem_resource_timetable.py diff --git a/golem_resource/models/golem_resource_timetable.py b/golem_resource/models/golem_resource_timetable.py index 7eef3d7..e3eb8c9 100644 --- a/golem_resource/models/golem_resource_timetable.py +++ b/golem_resource/models/golem_resource_timetable.py @@ -51,5 +51,5 @@ class GolemTimetable(models.Model): def _check_time_consistency(self): """ Checks time consistency """ for timetable in self: - if timetable.time_stop < timetable.time_start: + if timetable.time_stop <= timetable.time_start: raise ValidationError(_('End time should be after than start time')) diff --git a/golem_resource/tests/test_golem_resource_timetable.py b/golem_resource/tests/test_golem_resource_timetable.py new file mode 100644 index 0000000..3e396e7 --- /dev/null +++ b/golem_resource/tests/test_golem_resource_timetable.py @@ -0,0 +1,58 @@ +# -*- 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 testing """ + +from odoo.tests.common import TransactionCase +from odoo.exceptions import ValidationError + + +class TestGolemResourceTimetable(TransactionCase): + """ GOLEM Resource Timetable testing """ + + def setUp(self, *args, **kwargs): + """ Bootstrap timetable """ + super(TestGolemResourceTimetable, self).setUp(*args, **kwargs) + self.resource = self.env['golem.resource'].create({ + 'name': 'Resource', + 'validation_required': False, + 'avaibility_start': '2018-01-01', + 'avaibility_stop': '2020-01-01' + }) + self.timetable = self.env['golem.resource.timetable'] + self.data = {'resource_id': self.resource.id, + 'weekday': '0', + 'time_start': 8.0, + 'time_stop': 10.0} + + def test_timetable_basic(self): + """ Test Timetable bases """ + timetable = self.timetable.create(self.data) + self.assertEqual(timetable.resource_id, self.resource) + self.assertEqual(timetable.time_start, 8.0) + self.assertEqual(timetable.time_stop, 10.0) + self.assertEqual(timetable, self.resource.timetable_ids[0]) + + def test_timetable_times(self): + """ Test timetable times : stop can not be equal or after start """ + self.data.update({'time_stop': 7.0}) + with self.assertRaises(ValidationError): + self.timetable.create(self.data) + self.data.update({'time_stop': self.data['time_start']}) + with self.assertRaises(ValidationError): + self.timetable.create(self.data) From 896259dd7f4584dff6f4e8322e3980dd3a82ea75 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Mon, 19 Feb 2018 08:00:55 +0100 Subject: [PATCH 037/109] [IMP]GOLEM Resource Reservation : do not allow same hour for start and stop + usage of ValidationError instead of UserError --- golem_resource/__manifest__.py | 2 +- .../models/golem_resource_reservation.py | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/golem_resource/__manifest__.py b/golem_resource/__manifest__.py index a0dcb5c..cda9627 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.1', + 'version': '10.0.1.6.2', 'category': 'GOLEM', 'author': 'Youssef El Ouahby, Fabien Bourgeois', 'license': 'AGPL-3', diff --git a/golem_resource/models/golem_resource_reservation.py b/golem_resource/models/golem_resource_reservation.py index fe4a6a3..f654d70 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, ValidationError +from odoo.exceptions import ValidationError class GolemResourceReservation(models.Model): @@ -103,7 +103,7 @@ class GolemResourceReservation(models.Model): def _check_hour_consistency(self): """ Checks hour consistency """ for reservation in self: - if reservation.hour_stop < reservation.hour_start: + if reservation.hour_stop <= reservation.hour_start: raise ValidationError(_('End time should be after than start time')) @api.multi @@ -150,8 +150,8 @@ class GolemResourceReservation(models.Model): 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) + verr = _('You do not have permissions to validate or reject a reservation.') + raise ValidationError(verr) @api.constrains('state') def check_confirmed(self): @@ -161,10 +161,10 @@ class GolemResourceReservation(models.Model): # 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 ' + verr = _('Not allowed, the resource is not available in ' 'this period, please choose another périod before ' 'confirming') - raise UserError(uerr) + raise ValidationError(verr) # Check if reservation is not taking place out the avaibility timetables is_day_allowed = False for timetable in reservation.resource_id.timetable_ids: @@ -174,14 +174,14 @@ class GolemResourceReservation(models.Model): is_day_allowed = True if reservation.hour_start < timetable.time_start or \ reservation.hour_stop > timetable.time_stop: - uerr = _('Not allowed, the resource is not available ' + verr = _('Not allowed, the resource is not available ' 'during this period, please choose another ' 'time before confirming.') - raise UserError(uerr) + raise ValidationError(verr) if not is_day_allowed: - uerr = _('Not allowed, the resource is not available ' + verr = _('Not allowed, the resource is not available ' 'this day. Please choose another date.') - raise UserError(uerr) + raise ValidationError(verr) # 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), @@ -192,8 +192,8 @@ class GolemResourceReservation(models.Model): 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 ' + verr = _('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(other_res.date_start, - other_res.date_stop)) + raise ValidationError(verr.format(other_res.date_start, + other_res.date_stop)) From 8490e8995947a31b00de6af39fabe00849fd5b91 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Mon, 19 Feb 2018 08:01:20 +0100 Subject: [PATCH 038/109] [TYPO] --- golem_resource/tests/test_golem_resource.py | 10 +++++----- golem_resource/tests/test_golem_resource_timetable.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/golem_resource/tests/test_golem_resource.py b/golem_resource/tests/test_golem_resource.py index 903b83d..cd12140 100644 --- a/golem_resource/tests/test_golem_resource.py +++ b/golem_resource/tests/test_golem_resource.py @@ -33,11 +33,11 @@ class TestGolemResource(TransactionCase): 'avaibility_start': '2018-01-01', 'avaibility_stop': '2020-01-01' } - self.resource = self.env['golem.resource'] + self.resource_obj = self.env['golem.resource'] def test_resource_basic(self): """ Test resource bases """ - resource = self.resource.create(self.data) + resource = self.resource_obj.create(self.data) self.assertTrue(resource.active) self.assertFalse(resource.validation_required) self.assertEqual(resource.avaibility_start, '2018-01-01') @@ -49,7 +49,7 @@ class TestGolemResource(TransactionCase): def test_resource_active(self): """ Test resource active """ - resource = self.resource.create(self.data) + resource = self.resource_obj.create(self.data) self.assertTrue(resource.active) resource.active_toggle() self.assertFalse(resource.active) @@ -60,10 +60,10 @@ class TestGolemResource(TransactionCase): """ Test resource dates : stop can not be after start """ self.data.update({'avaibility_stop': '2017-01-01'}) with self.assertRaises(ValidationError): - self.resource.create(self.data) + self.resource_obj.create(self.data) def test_resource_dates_equal(self): """ Test resource dates : stop can not be equal to start """ self.data.update({'avaibility_stop': self.data['avaibility_start']}) with self.assertRaises(ValidationError): - self.resource.create(self.data) + self.resource_obj.create(self.data) diff --git a/golem_resource/tests/test_golem_resource_timetable.py b/golem_resource/tests/test_golem_resource_timetable.py index 3e396e7..52d644b 100644 --- a/golem_resource/tests/test_golem_resource_timetable.py +++ b/golem_resource/tests/test_golem_resource_timetable.py @@ -34,7 +34,7 @@ class TestGolemResourceTimetable(TransactionCase): 'avaibility_start': '2018-01-01', 'avaibility_stop': '2020-01-01' }) - self.timetable = self.env['golem.resource.timetable'] + self.timetable_obj = self.env['golem.resource.timetable'] self.data = {'resource_id': self.resource.id, 'weekday': '0', 'time_start': 8.0, @@ -42,7 +42,7 @@ class TestGolemResourceTimetable(TransactionCase): def test_timetable_basic(self): """ Test Timetable bases """ - timetable = self.timetable.create(self.data) + timetable = self.timetable_obj.create(self.data) self.assertEqual(timetable.resource_id, self.resource) self.assertEqual(timetable.time_start, 8.0) self.assertEqual(timetable.time_stop, 10.0) @@ -52,7 +52,7 @@ class TestGolemResourceTimetable(TransactionCase): """ Test timetable times : stop can not be equal or after start """ self.data.update({'time_stop': 7.0}) with self.assertRaises(ValidationError): - self.timetable.create(self.data) + self.timetable_obj.create(self.data) self.data.update({'time_stop': self.data['time_start']}) with self.assertRaises(ValidationError): - self.timetable.create(self.data) + self.timetable_obj.create(self.data) From 2f22a7c6d73cc2a18cba4c768b2605e4c8e18282 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Mon, 19 Feb 2018 08:01:35 +0100 Subject: [PATCH 039/109] [ADD]GOLEM Resource Reservation testing --- golem_resource/tests/__init__.py | 2 +- .../tests/test_golem_resource_reservation.py | 186 ++++++++++++++++++ 2 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 golem_resource/tests/test_golem_resource_reservation.py diff --git a/golem_resource/tests/__init__.py b/golem_resource/tests/__init__.py index 4eb2e86..f1243a5 100644 --- a/golem_resource/tests/__init__.py +++ b/golem_resource/tests/__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 test_golem_resource, test_golem_resource_timetable +from . import test_golem_resource, test_golem_resource_timetable, test_golem_resource_reservation diff --git a/golem_resource/tests/test_golem_resource_reservation.py b/golem_resource/tests/test_golem_resource_reservation.py new file mode 100644 index 0000000..4e69df1 --- /dev/null +++ b/golem_resource/tests/test_golem_resource_reservation.py @@ -0,0 +1,186 @@ +# -*- 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 testing """ + +import logging +from odoo.tests.common import TransactionCase +from odoo.exceptions import ValidationError +_LOGGER = logging.getLogger(__name__) + + +class TestGolemResourceReservation(TransactionCase): + """ GOLEM Resource Reservation testing """ + + def setUp(self, *args, **kwargs): + """ Bootstrap Resource Reservation """ + super(TestGolemResourceReservation, self).setUp(*args, **kwargs) + self.resource = self.env['golem.resource'].create({ + 'name': 'Resource', + 'avaibility_start': '2018-01-01', + 'avaibility_stop': '2020-01-01' + }) + self.resource_val = self.env['golem.resource'].create({ + 'name': 'Resource to validate', + 'avaibility_start': '2018-01-01', + 'avaibility_stop': '2020-01-01', + 'validation_required': True + }) + + self.timetable_obj = self.env['golem.resource.timetable'] + timetable_data = {'resource_id': self.resource.id, 'weekday': '0', + 'time_start': 8.0, 'time_stop': 12.0} + self.timetable_obj.create(timetable_data) + timetable_data['resource_id'] = self.resource_val.id + self.timetable_obj.create(timetable_data) + + self.partner = self.env['res.partner'].create({'firstname': 'John', + 'lastname': 'DOE', + 'is_company': False}) + + self.data = { + 'resource_id': self.resource.id, + 'date': '2018-02-05', # is monday + 'hour_start': 11.0, + 'hour_stop': 12.0, + 'partner_id': self.partner.id + } + self.res_obj = self.env['golem.resource.reservation'] + + def test_reservation_basic(self): + """ Test reservation bases """ + reservation = self.res_obj.create(self.data) + self.assertEqual(reservation.partner_id, self.partner) + self.assertEqual(reservation.user_id, self.env.user) + self.assertEqual(reservation.hour_start, 11.0) + self.assertEqual(reservation.hour_stop, 12.0) + self.assertEqual(reservation.state, 'draft') + self.assertFalse(reservation.rejection_reason) + self.assertEqual(reservation.name, 'Resource/2018-02-05') + self.assertEqual(reservation.date_start, '2018-02-05 11:00:00') + self.assertEqual(reservation.date_stop, '2018-02-05 12:00:00') + self.assertEqual(reservation.resource_id, self.resource) + self.assertEqual(len(reservation.resource_timetable_ids), 1) + self.assertEqual(reservation.resource_id.reservation_ids[0], reservation) + + def test_reservation_hours(self): + """ Test thats stop hour can not be after or equal start hour """ + self.data['hour_stop'] = 7.0 + with self.assertRaises(ValidationError): + self.res_obj.create(self.data) + with self.assertRaises(ValidationError): + self.res_obj.create({ + 'resource_id': self.resource.id, 'date': '2018-02-05', + 'hour_start': 12.0, 'hour_stop': 12.0, + 'partner_id': self.partner.id + }) + + def test_state_basic(self): + """ Tests basic state methods """ + reservation = self.res_obj.create(self.data) + self.assertEqual(reservation.state, 'draft') + reservation.state_draft() + self.assertEqual(reservation.state, 'draft') + reservation.state_canceled() + self.assertEqual(reservation.state, 'canceled') + reservation.state_validated() + self.assertEqual(reservation.state, 'validated') + reservation.state_draft() + self.assertEqual(reservation.state, 'draft') + reservation.state_confirm() # Here the reservation is OK, pass the checks + self.assertEqual(reservation.state, 'validated') + + def test_state_rejected(self): + """ Tests state rejected """ + self.data['resource_id'] = self.resource_val.id + reservation = self.res_obj.create(self.data) + self.assertEqual(reservation.state, 'draft') + reservation.state_confirm() + self.assertEqual(reservation.state, 'confirmed') + # We may have called the wizard here + reservation.write({'state': 'rejected', 'rejection_reason': 'Reason'}) + self.assertEqual(reservation.state, 'rejected') + self.assertEqual(reservation.rejection_reason, 'Reason') + + def test_confirm_access(self): + """ Test that only golem_manager can confirm or reject reservation """ + self.data['resource_id'] = self.resource_val.id + reservation = self.res_obj.create(self.data) + self.assertEqual(reservation.state, 'draft') + reservation.state_confirm() + reservation.state_validated() # OK there, as admin is GOLEM Manager + reservation.state_canceled() + reservation.state_draft() + reservation.state_confirm() + # Removes group GOLEM manager from current user + group_manager = self.env.ref('golem_base.group_golem_manager') + self.env.user.groups_id = [(2, group_manager.id, False)] + with self.assertRaises(ValidationError) as err: + reservation.state_validated() + self.assertIn('do not have permissions to validate', err.exception.args[0]) + + def test_confirmed_period(self): + """ Test allowed period """ + self.data['date'] = '2012-01-01' # Out of period + reservation = self.res_obj.create(self.data) + with self.assertRaises(ValidationError) as err: + reservation.state_confirm() + self.assertIn('not available in this period', err.exception.args[0]) + + def test_confirmed_allowed_day(self): + """ Test allowed day """ + self.data['date'] = '2018-02-06' # Bad day + reservation = self.res_obj.create(self.data) + with self.assertRaises(ValidationError) as err: + reservation.state_confirm() + self.assertIn('not available this day', err.exception.args[0]) + + def test_confirmed_allowed_hours(self): + """ Test allowed hours """ + self.data['hour_stop'] = 14.0 # Out of range stop hour + reservation = self.res_obj.create(self.data) + with self.assertRaises(ValidationError) as err: + reservation.state_confirm() + self.assertIn('please choose another time', err.exception.args[0]) + reservation = self.res_obj.create({'resource_id': self.resource.id, + 'date': '2018-02-05', + 'hour_start': 5.0, # Out of range start hour + 'hour_stop': 12.0, + 'partner_id': self.partner.id}) + with self.assertRaises(ValidationError) as err: + reservation.state_confirm() + self.assertIn('please choose another time', err.exception.args[0]) + + def test_confirmed_other_res(self): + """ Test if there are other reservations in conflict """ + reservation = self.res_obj.create(self.data) + reservation.state_confirm() + reservation2 = self.res_obj.create({ + 'resource_id': self.resource.id, 'date': '2018-02-05', + 'hour_start': 10.0, 'hour_stop': 11.0, # OK, no conflict + 'partner_id': self.partner.id + }) + reservation2.state_confirm() + reservation3 = self.res_obj.create({ + 'resource_id': self.resource.id, 'date': '2018-02-05', + 'hour_start': 10.0, 'hour_stop': 10.5, # Conflict with 2nd res + 'partner_id': self.partner.id + }) + with self.assertRaises(ValidationError) as err: + reservation3.state_confirm() + self.assertIn('resource is already taken', err.exception.args[0]) From 211a44ab4e22e5f973148c20e19401342812a333 Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Mon, 19 Feb 2018 09:49:03 +0100 Subject: [PATCH 040/109] [i18n]GOMEM Resource i18n and french translation --- golem_resource/i18n/fr.po | 488 ++++++++++++++++++++++++ golem_resource/i18n/golem_resource.pot | 489 +++++++++++++++++++++++++ 2 files changed, 977 insertions(+) create mode 100644 golem_resource/i18n/fr.po create mode 100644 golem_resource/i18n/golem_resource.pot diff --git a/golem_resource/i18n/fr.po b/golem_resource/i18n/fr.po new file mode 100644 index 0000000..3b384a7 --- /dev/null +++ b/golem_resource/i18n/fr.po @@ -0,0 +1,488 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * golem_resource +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-19 08:39+0000\n" +"PO-Revision-Date: 2018-02-19 08:39+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: golem_resource +#: model:ir.model.fields,help:golem_resource.field_golem_resource_product_tmpl_id +msgid "A generic product can be linked, in order to sell reservations (work in progress)" +msgstr "Un article générique peut être lié, dans l'objectif de monétiser des réservations (à venir)" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_active +msgid "Active" +msgstr "Actif" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "Archived" +msgstr "Archivé" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_form +msgid "Availibility configuration" +msgstr "Configuration des disponibilités" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_avaibility_start +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_resource_avaibility_start +msgid "Availibility start date" +msgstr "Début de disponibilité" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_avaibility_stop +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_resource_avaibility_stop +msgid "Availibility stop date" +msgstr "Fin de disponibilité" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_resource_timetable_ids +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_ids +msgid "Availibility timetable" +msgstr "Tableau des disponibilités" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_reservation_rejection_wizard_view_form +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Cancel" +msgstr "Annuler" + +#. module: golem_resource +#: selection:golem.resource.reservation,state:0 +msgid "Canceled" +msgstr "Annulé" + +#. module: golem_resource +#: model:ir.ui.menu,name:golem_resource.resource_configuration_menu +msgid "Configuration" +msgstr "Configuration" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Confirm" +msgstr "Confirmer" + +#. module: golem_resource +#: selection:golem.resource.reservation,state:0 +msgid "Confirmed" +msgstr "Confirmé" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_create_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_create_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_create_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_create_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_create_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_create_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_create_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_create_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_create_date +msgid "Created on" +msgstr "Créé le" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_date +msgid "Date" +msgstr "Date" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_date_start +msgid "Date start" +msgstr "Date de début" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_date_stop +msgid "Date stop" +msgstr "Date de fin" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Day" +msgstr "Jour" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_display_name +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_display_name +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_display_name +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_display_name +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: golem_resource +#: selection:golem.resource.reservation,state:0 +msgid "Draft" +msgstr "Brouillon" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource.py:63 +#, python-format +msgid "End availibility should be after than start availibility" +msgstr "La fin de disponibilité ne peut pas être après le début" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:107 +#: code:addons/golem_resource/models/golem_resource_timetable.py:55 +#, python-format +msgid "End time should be after than start time" +msgstr "L'heure de fin ne peut pas être après l'heure de début" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:37 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Friday" +msgstr "Vendredi" + +#. module: golem_resource +#: model:ir.model,name:golem_resource.model_golem_resource_reservation +msgid "GOLEM Reservation Model" +msgstr "GOLEM Reservation Model" + +#. module: golem_resource +#: model:ir.model,name:golem_resource.model_golem_resource +msgid "GOLEM Resource Model" +msgstr "GOLEM Resource Model" + +#. module: golem_resource +#: model:ir.model,name:golem_resource.model_golem_resource_type +msgid "GOLEM Resource Type" +msgstr "GOLEM Resource Type" + +#. module: golem_resource +#: model:ir.model,name:golem_resource.model_golem_resource_timetable +msgid "Golem Timetable" +msgstr "Golem Timetable" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_id +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_id +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_id +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_id +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_id +msgid "ID" +msgstr "ID" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_validation_required +msgid "Is validation required ?" +msgstr "Une validation est-elle nécessaire ?" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard___last_update +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource___last_update +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation___last_update +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable___last_update +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type___last_update +msgid "Last Modified on" +msgstr "Dernière Modification le" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_write_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_write_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_write_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_write_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_write_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_write_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_write_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_write_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_product_tmpl_id +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "Linked product" +msgstr "Article lié" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_resource_id +msgid "Linked resource" +msgstr "Ressource liée" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:33 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Monday" +msgstr "Lundi" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Month" +msgstr "Mois" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_name +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_name +msgid "Name" +msgstr "Nom" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:195 +#, python-format +msgid "Not allowed, the resource is already taken during this period : from {} to {} this day, please choose another périod before confirming." +msgstr "Interdit : la ressource est déjà réservée durant cette période : de {} à {} ce jour, merci de choisir une autre période avant de confirmer." + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:177 +#, python-format +msgid "Not allowed, the resource is not available during this period, please choose another time before confirming." +msgstr "Interdit : la ressource n'est pas disponible durant cette période, merci de choisir d'autres horaires avant de confirmer à nouveau." + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:164 +#, python-format +msgid "Not allowed, the resource is not available in this period, please choose another périod before confirming" +msgstr "Interdit : la ressource n'est pas disponible durant cette période, merci de choisir d'autres dates avant de confirmer à nouveau." + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:182 +#, python-format +msgid "Not allowed, the resource is not available this day. Please choose another date." +msgstr "Interdit : la ressource n'est pas disponible ce jour de la semaine. Merci de choisir un autre jour." + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_partner_id +msgid "On behalf of" +msgstr "Pour le compte de" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Partner" +msgstr "Partenaire" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:139 +#, python-format +msgid "Please enter the rejection reason" +msgstr "Merci de saisir le motif du refus" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_form +msgid "Please save the resource before fixing the timetable availibility\"" +msgstr "Merci de sauvegarder la ressource avant de pouvoir définir ses disponibilités\"" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_reason +msgid "Reason" +msgstr "Motif" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_reservation_rejection_wizard_view_form +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Reject" +msgstr "Rejet" + +#. module: golem_resource +#: selection:golem.resource.reservation,state:0 +msgid "Rejected" +msgstr "Rejeté" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_rejection_reason +#: model:ir.ui.view,arch_db:golem_resource.golem_reservation_rejection_wizard_view_form +msgid "Rejection reason" +msgstr "Motif du rejet" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Reservation" +msgstr "Réservation" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_reservation_id +msgid "Reservation id" +msgstr "Reservation id" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Reservation to Validate" +msgstr "Réservation à valider" + +#. module: golem_resource +#: model:ir.actions.act_window,name:golem_resource.golem_resource_reservation_action +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_ids +#: model:ir.ui.menu,name:golem_resource.golem_resource_reservation_menu +msgid "Reservations" +msgstr "Réservations" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_resource_id +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Resource" +msgstr "Ressource" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_id_4449 +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_name +msgid "Resource Type" +msgstr "Type de ressource" + +#. module: golem_resource +#: model:ir.actions.act_window,name:golem_resource.golem_resource_type_action +#: model:ir.ui.menu,name:golem_resource.resource_cofiguration_type_menu +msgid "Resource Types" +msgstr "Types de ressource" + +#. module: golem_resource +#: sql_constraint:golem.resource.type:0 +msgid "Resource type must be unique." +msgstr "Le type de ressource doit être unique." + +#. module: golem_resource +#: model:ir.actions.act_window,name:golem_resource.golem_resource_action +#: model:ir.ui.menu,name:golem_resource.golem_resource_menu +#: model:ir.ui.menu,name:golem_resource.resource_list_menu +msgid "Resources" +msgstr "Resources" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:38 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Saturday" +msgstr "Samedi" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Set to draft" +msgstr "Brouillon" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_time_start +msgid "Start" +msgstr "Début" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_hour_start +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_timetable_view_tree +msgid "Start hour" +msgstr "Heure de début" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_state +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "State" +msgstr "État" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_time_stop +msgid "Stop" +msgstr "Fin" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_hour_stop +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_timetable_view_tree +msgid "Stop hour" +msgstr "Heure de fin" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:39 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Sunday" +msgstr "Dimanche" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_supervisor_id +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "Supervisor" +msgstr "Responsable" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:36 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Thursday" +msgstr "Jeudi" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:34 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Tuesday" +msgstr "Mardi" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "Type" +msgstr "Type" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_user_id +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "User" +msgstr "Utilisateur" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Validate" +msgstr "Valider" + +#. module: golem_resource +#: selection:golem.resource.reservation,state:0 +msgid "Validated" +msgstr "Validé" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:35 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Wednesday" +msgstr "Mercredi" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Week" +msgstr "Semaine" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_weekday +msgid "Weekday" +msgstr "Jour" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "With validation" +msgstr "Avec validation" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "Without validation" +msgstr "Sans validation" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:153 +#, python-format +msgid "You do not have permissions to validate or reject a reservation." +msgstr "Vous n'avez pas les autorisations nécessaires pour valider ou rejeter une réservation." + +#. module: golem_resource +#: model:ir.model,name:golem_resource.model_golem_reservation_rejection_wizard +msgid "golem.reservation.rejection.wizard" +msgstr "golem.reservation.rejection.wizard" diff --git a/golem_resource/i18n/golem_resource.pot b/golem_resource/i18n/golem_resource.pot new file mode 100644 index 0000000..685e04d --- /dev/null +++ b/golem_resource/i18n/golem_resource.pot @@ -0,0 +1,489 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * golem_resource +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-19 08:39+0000\n" +"PO-Revision-Date: 2018-02-19 08:39+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: golem_resource +#: model:ir.model.fields,help:golem_resource.field_golem_resource_product_tmpl_id +msgid "A generic product can be linked, in order to sell reservations (work in progress)" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_active +msgid "Active" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "Archived" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_form +msgid "Availibility configuration" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_avaibility_start +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_resource_avaibility_start +msgid "Availibility start date" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_avaibility_stop +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_resource_avaibility_stop +msgid "Availibility stop date" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_resource_timetable_ids +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_ids +msgid "Availibility timetable" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_reservation_rejection_wizard_view_form +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Cancel" +msgstr "" + +#. module: golem_resource +#: selection:golem.resource.reservation,state:0 +msgid "Canceled" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.menu,name:golem_resource.resource_configuration_menu +msgid "Configuration" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Confirm" +msgstr "" + +#. module: golem_resource +#: selection:golem.resource.reservation,state:0 +msgid "Confirmed" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_create_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_create_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_create_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_create_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_create_uid +msgid "Created by" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_create_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_create_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_create_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_create_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_create_date +msgid "Created on" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_date +msgid "Date" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_date_start +msgid "Date start" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_date_stop +msgid "Date stop" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Day" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_display_name +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_display_name +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_display_name +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_display_name +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_display_name +msgid "Display Name" +msgstr "" + +#. module: golem_resource +#: selection:golem.resource.reservation,state:0 +msgid "Draft" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource.py:63 +#, python-format +msgid "End availibility should be after than start availibility" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:107 +#: code:addons/golem_resource/models/golem_resource_timetable.py:55 +#, python-format +msgid "End time should be after than start time" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:37 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Friday" +msgstr "" + +#. module: golem_resource +#: model:ir.model,name:golem_resource.model_golem_resource_reservation +msgid "GOLEM Reservation Model" +msgstr "" + +#. module: golem_resource +#: model:ir.model,name:golem_resource.model_golem_resource +msgid "GOLEM Resource Model" +msgstr "" + +#. module: golem_resource +#: model:ir.model,name:golem_resource.model_golem_resource_type +msgid "GOLEM Resource Type" +msgstr "" + +#. module: golem_resource +#: model:ir.model,name:golem_resource.model_golem_resource_timetable +msgid "Golem Timetable" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_id +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_id +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_id +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_id +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_id +msgid "ID" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_validation_required +msgid "Is validation required ?" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard___last_update +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource___last_update +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation___last_update +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable___last_update +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type___last_update +msgid "Last Modified on" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_write_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_write_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_write_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_write_uid +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_write_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_write_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_write_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_write_date +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_write_date +msgid "Last Updated on" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_product_tmpl_id +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "Linked product" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_resource_id +msgid "Linked resource" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:33 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Monday" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Month" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_name +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_name +msgid "Name" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:195 +#, python-format +msgid "Not allowed, the resource is already taken during this period : from {} to {} this day, please choose another périod before confirming." +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:177 +#, python-format +msgid "Not allowed, the resource is not available during this period, please choose another time before confirming." +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:164 +#, python-format +msgid "Not allowed, the resource is not available in this period, please choose another périod before confirming" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:182 +#, python-format +msgid "Not allowed, the resource is not available this day. Please choose another date." +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_partner_id +msgid "On behalf of" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Partner" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:139 +#, python-format +msgid "Please enter the rejection reason" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_form +msgid "Please save the resource before fixing the timetable availibility\"" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_reason +msgid "Reason" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_reservation_rejection_wizard_view_form +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Reject" +msgstr "" + +#. module: golem_resource +#: selection:golem.resource.reservation,state:0 +msgid "Rejected" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_rejection_reason +#: model:ir.ui.view,arch_db:golem_resource.golem_reservation_rejection_wizard_view_form +msgid "Rejection reason" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Reservation" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_reservation_rejection_wizard_reservation_id +msgid "Reservation id" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Reservation to Validate" +msgstr "" + +#. module: golem_resource +#: model:ir.actions.act_window,name:golem_resource.golem_resource_reservation_action +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_ids +#: model:ir.ui.menu,name:golem_resource.golem_resource_reservation_menu +msgid "Reservations" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_resource_id +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Resource" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_id_4449 +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_type_name +msgid "Resource Type" +msgstr "" + +#. module: golem_resource +#: model:ir.actions.act_window,name:golem_resource.golem_resource_type_action +#: model:ir.ui.menu,name:golem_resource.resource_cofiguration_type_menu +msgid "Resource Types" +msgstr "" + +#. module: golem_resource +#: sql_constraint:golem.resource.type:0 +msgid "Resource type must be unique." +msgstr "" + +#. module: golem_resource +#: model:ir.actions.act_window,name:golem_resource.golem_resource_action +#: model:ir.ui.menu,name:golem_resource.golem_resource_menu +#: model:ir.ui.menu,name:golem_resource.resource_list_menu +msgid "Resources" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:38 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Saturday" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Set to draft" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_time_start +msgid "Start" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_hour_start +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_timetable_view_tree +msgid "Start hour" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_state +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "State" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_time_stop +msgid "Stop" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_hour_stop +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_timetable_view_tree +msgid "Stop hour" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:39 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Sunday" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_supervisor_id +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "Supervisor" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:36 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Thursday" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:34 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Tuesday" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "Type" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_reservation_user_id +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "User" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_form +msgid "Validate" +msgstr "" + +#. module: golem_resource +#: selection:golem.resource.reservation,state:0 +msgid "Validated" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_timetable.py:35 +#: selection:golem.resource.timetable,weekday:0 +#, python-format +msgid "Wednesday" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_reservation_view_search +msgid "Week" +msgstr "" + +#. module: golem_resource +#: model:ir.model.fields,field_description:golem_resource.field_golem_resource_timetable_weekday +msgid "Weekday" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "With validation" +msgstr "" + +#. module: golem_resource +#: model:ir.ui.view,arch_db:golem_resource.golem_resource_view_search +msgid "Without validation" +msgstr "" + +#. module: golem_resource +#: code:addons/golem_resource/models/golem_resource_reservation.py:153 +#, python-format +msgid "You do not have permissions to validate or reject a reservation." +msgstr "" + +#. module: golem_resource +#: model:ir.model,name:golem_resource.model_golem_reservation_rejection_wizard +msgid "golem.reservation.rejection.wizard" +msgstr "" + From cc23e92232861a6002232fee46ca0a4dc790bda2 Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Thu, 15 Feb 2018 14:16:51 +0100 Subject: [PATCH 041/109] 1er version du golem_activity_queue --- golem_activity_queue/__init__.py | 18 +++++++++ golem_activity_queue/__manifest__.py | 29 ++++++++++++++ golem_activity_queue/models/__init__.py | 18 +++++++++ .../models/golem_activity_queue.py | 38 +++++++++++++++++++ .../security/ir.model.access.csv | 3 ++ 5 files changed, 106 insertions(+) create mode 100644 golem_activity_queue/__init__.py create mode 100644 golem_activity_queue/__manifest__.py create mode 100644 golem_activity_queue/models/__init__.py create mode 100644 golem_activity_queue/models/golem_activity_queue.py create mode 100644 golem_activity_queue/security/ir.model.access.csv diff --git a/golem_activity_queue/__init__.py b/golem_activity_queue/__init__.py new file mode 100644 index 0000000..feff6f0 --- /dev/null +++ b/golem_activity_queue/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +# 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 models diff --git a/golem_activity_queue/__manifest__.py b/golem_activity_queue/__manifest__.py new file mode 100644 index 0000000..128de52 --- /dev/null +++ b/golem_activity_queue/__manifest__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +# 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 . + +{ + 'name': 'GOLEM activities queue', + 'summary': 'GOLEM activities queue', + 'version': '10.0.2.1.0', + 'category': 'GOLEM', + 'author': 'Youssef Elouahby', + 'license': 'AGPL-3', + 'application': True, + 'installable': True, + 'depends': ['golem_activity', 'golem_activity_registration'], + 'data': ['views/golem_activity_queue_views.xml'] +} diff --git a/golem_activity_queue/models/__init__.py b/golem_activity_queue/models/__init__.py new file mode 100644 index 0000000..0ff98f0 --- /dev/null +++ b/golem_activity_queue/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_activity_queue diff --git a/golem_activity_queue/models/golem_activity_queue.py b/golem_activity_queue/models/golem_activity_queue.py new file mode 100644 index 0000000..5871b0d --- /dev/null +++ b/golem_activity_queue/models/golem_activity_queue.py @@ -0,0 +1,38 @@ +# -*- 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 . + +""" GOLEM activities related models """ + +from odoo import models, fields, api, _ + +class GolemActivity(models.Model): + """ GOLEM Activity """ + _name = 'golem.activity' + + #ajout d'un champs O2M vers activity_id + activity_queue_id = fields.One2many('golem.activity.queue', 'activity_id') + # un boolen pour determiner si une fille d'attente est autorisé + allows_queue = fields.Boolean(required=False) + +class GolemActivityQueue(models.Model): + """ GOLEM Activity Queue """ + _name = 'golem.activity.queue' + _description = 'GOLEM Activity Queue' + + activity_id = fields.Many2one('golem.activity', required=True) + season_id = fields.Many2one('golem.season', related='golem.activity.season_id') + member_id = fields.Many2one('golem.member', required=True) diff --git a/golem_activity_queue/security/ir.model.access.csv b/golem_activity_queue/security/ir.model.access.csv new file mode 100644 index 0000000..2bcb93b --- /dev/null +++ b/golem_activity_queue/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_activity_queue_user,Access GOLEM Activity Queue User,model_golem_activity_queue,golem_base.group_golem_user,1,1,1,0 +access_golem_activity_queue_manager,Access GOLEM Activity Queue Manager,model_golem_activity_queue,golem_base.group_golem_manager,1,1,1,1 From a64d865648aed84fea454ceefd60b970ddab38c6 Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Fri, 16 Feb 2018 00:27:35 +0100 Subject: [PATCH 042/109] Ajout du popup qui ne s'affiche pas encore --- golem_activity_queue/__manifest__.py | 4 +- .../models/golem_activity_queue.py | 63 +++++++++++++++++-- .../views/golem_activity_queue_views.xml | 26 ++++++++ .../views/golem_activity_views.xml | 48 ++++++++++++++ 4 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 golem_activity_queue/views/golem_activity_queue_views.xml create mode 100644 golem_activity_queue/views/golem_activity_views.xml diff --git a/golem_activity_queue/__manifest__.py b/golem_activity_queue/__manifest__.py index 128de52..60ec6b3 100644 --- a/golem_activity_queue/__manifest__.py +++ b/golem_activity_queue/__manifest__.py @@ -25,5 +25,7 @@ 'application': True, 'installable': True, 'depends': ['golem_activity', 'golem_activity_registration'], - 'data': ['views/golem_activity_queue_views.xml'] + 'data': ['views/golem_activity_queue_views.xml', + 'views/golem_activity_views.xml', + ] } diff --git a/golem_activity_queue/models/golem_activity_queue.py b/golem_activity_queue/models/golem_activity_queue.py index 5871b0d..ad3a43d 100644 --- a/golem_activity_queue/models/golem_activity_queue.py +++ b/golem_activity_queue/models/golem_activity_queue.py @@ -19,14 +19,69 @@ from odoo import models, fields, api, _ +class YesNoQueuePopUp(models.TransientModel): + """GOLEM Resource wizard""" + _name = "golem.queuepopup" + + + yes_no = fields.Char(default='Do you want to proceed?') + + @api.multi + def yes(self): + pass + # sure continue! + + @api.multi + def no(self): + pass # don't do anything stupid + + class GolemActivity(models.Model): - """ GOLEM Activity """ - _name = 'golem.activity' + """ GOLEM Activity adaptations """ + _inherit = 'golem.activity' + #ajout d'un champs O2M vers activity_id activity_queue_id = fields.One2many('golem.activity.queue', 'activity_id') # un boolen pour determiner si une fille d'attente est autorisé - allows_queue = fields.Boolean(required=False) + queue_allowed = fields.Boolean(default=True) + + @api.multi + @api.constrains('places_remain') + def _check_remaining_places(self): + """ Forbid inscription when there is no more place """ + for activity in self: + if activity.places_remain < 5: + + if self.queue_allowed: + print "__________________________ test ______________________" + return { + 'name' : _('Please enter the reseaon of rejection'), + 'type' : 'ir.actions.act_window', + 'res_model' : 'golem.queuepopup', + 'view_mode': 'form', + 'view_type': 'form', + 'target': 'new', + } + + return { + 'name' : _('Do you want to add your registration to the queue?'), + 'type' : 'ir.actions.act_window', + 'res_model' : 'golem.queuepopup', + 'view_mode': 'form', + 'view_type': 'form', + 'target': 'new', + } + print "________________________________test 2 __________________" + + + else: + emsg = _('Sorry, there is no more place man !') + raise models.ValidationError(emsg) + + + + class GolemActivityQueue(models.Model): """ GOLEM Activity Queue """ @@ -34,5 +89,5 @@ class GolemActivityQueue(models.Model): _description = 'GOLEM Activity Queue' activity_id = fields.Many2one('golem.activity', required=True) - season_id = fields.Many2one('golem.season', related='golem.activity.season_id') + season_id = fields.Many2one(related='activity_id.season_id') member_id = fields.Many2one('golem.member', required=True) diff --git a/golem_activity_queue/views/golem_activity_queue_views.xml b/golem_activity_queue/views/golem_activity_queue_views.xml new file mode 100644 index 0000000..0ab8d6f --- /dev/null +++ b/golem_activity_queue/views/golem_activity_queue_views.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + diff --git a/golem_activity_queue/views/golem_activity_views.xml b/golem_activity_queue/views/golem_activity_views.xml new file mode 100644 index 0000000..d259888 --- /dev/null +++ b/golem_activity_queue/views/golem_activity_views.xml @@ -0,0 +1,48 @@ + + + + + + + Activity Registrations and Places + golem.activity + + + + + + + + + + queuepopup.form + golem.queuepopup + form + +
+ + + +
+
+
+
From 9fdb1cbddc9ce71a10f158831e9afccd4078133c Mon Sep 17 00:00:00 2001 From: eloyoussef Date: Mon, 19 Feb 2018 14:03:13 +0100 Subject: [PATCH 043/109] Ajout warning au cas de depassement de place --- .../models/golem_activity_queue.py | 67 ++++++++++++++----- .../views/golem_activity_queue_views.xml | 39 ++++++++++- .../views/golem_activity_views.xml | 12 ++-- 3 files changed, 94 insertions(+), 24 deletions(-) diff --git a/golem_activity_queue/models/golem_activity_queue.py b/golem_activity_queue/models/golem_activity_queue.py index ad3a43d..7c70bfc 100644 --- a/golem_activity_queue/models/golem_activity_queue.py +++ b/golem_activity_queue/models/golem_activity_queue.py @@ -24,16 +24,23 @@ class YesNoQueuePopUp(models.TransientModel): _name = "golem.queuepopup" - yes_no = fields.Char(default='Do you want to proceed?') + #yes_no = fields.Char(default='Do you want to proceed?') @api.multi - def yes(self): - pass - # sure continue! + def queueYes(self): + print "########################################################" + return { + 'name' : _('Do you want to add your registration to the queue?'), + 'type' : 'ir.actions.act_window', + 'res_model' : 'golem.activity.queue', + 'view_mode': 'form', + 'view_type': 'form', + 'target': 'new', + } @api.multi - def no(self): - pass # don't do anything stupid + def queueNo(self): + pass # don't do anything class GolemActivity(models.Model): @@ -46,39 +53,53 @@ class GolemActivity(models.Model): # un boolen pour determiner si une fille d'attente est autorisé queue_allowed = fields.Boolean(default=True) + def queue_register(self): + return { + 'name' : _('Register in the queue'), + 'type' : 'ir.actions.act_window', + 'res_model' : 'golem.activity.queue', + 'view_mode': 'form', + 'view_type': 'form', + 'target': 'new', + } + + @api.onchange('activity_registration_ids') + def _checkRemain(self): + + if len(self.activity_registration_ids) > self.places and self.queue_allowed: + return { + 'warning' : { + 'title' : _('Warning'), + 'message': _('No remaining place, please register in the queue'), + } + } + + """ @api.multi @api.constrains('places_remain') def _check_remaining_places(self): - """ Forbid inscription when there is no more place """ + #Forbid inscription when there is no more place for activity in self: if activity.places_remain < 5: if self.queue_allowed: print "__________________________ test ______________________" - return { - 'name' : _('Please enter the reseaon of rejection'), - 'type' : 'ir.actions.act_window', - 'res_model' : 'golem.queuepopup', - 'view_mode': 'form', - 'view_type': 'form', - 'target': 'new', - } - return { 'name' : _('Do you want to add your registration to the queue?'), 'type' : 'ir.actions.act_window', - 'res_model' : 'golem.queuepopup', + 'res_model' : 'golem.activity.queue', 'view_mode': 'form', 'view_type': 'form', 'target': 'new', } print "________________________________test 2 __________________" + raise models.ValidationError("erreur") else: emsg = _('Sorry, there is no more place man !') raise models.ValidationError(emsg) - +""" @@ -91,3 +112,13 @@ class GolemActivityQueue(models.Model): activity_id = fields.Many2one('golem.activity', required=True) season_id = fields.Many2one(related='activity_id.season_id') member_id = fields.Many2one('golem.member', required=True) + + def call_up_wizard(self): + return { + 'name': 'Are you sure?', + 'type': 'ir.actions.act_window', + 'res_model': 'golem.queuepopup', + 'view_mode': 'form', + 'view_type': 'form', + 'target': 'new', + } diff --git a/golem_activity_queue/views/golem_activity_queue_views.xml b/golem_activity_queue/views/golem_activity_queue_views.xml index 0ab8d6f..3ec3536 100644 --- a/golem_activity_queue/views/golem_activity_queue_views.xml +++ b/golem_activity_queue/views/golem_activity_queue_views.xml @@ -20,7 +20,44 @@ along with this program. If not, see . - + + + queue.form + golem.activity.queue + +
+ + + + + + + +
+
+
+ + + +queue.tree +golem.activity.queue + + + + + + + + + + + Resources Type + golem.activity.queue + form + + + +
diff --git a/golem_activity_queue/views/golem_activity_views.xml b/golem_activity_queue/views/golem_activity_views.xml index d259888..c8b1be5 100644 --- a/golem_activity_queue/views/golem_activity_views.xml +++ b/golem_activity_queue/views/golem_activity_views.xml @@ -27,6 +27,9 @@ along with this program. If not, see . + +