diff --git a/golem_activity/__manifest__.py b/golem_activity/__manifest__.py index cf63b8e..cd2b276 100644 --- a/golem_activity/__manifest__.py +++ b/golem_activity/__manifest__.py @@ -18,7 +18,7 @@ { 'name': 'GOLEM activities', 'summary': 'Extends Odoo products for multi-activity', - 'version': '10.0.2.1.0', + 'version': '10.0.2.1.1', 'category': 'GOLEM', 'author': 'Fabien Bourgeois, Michel Dessenne', 'license': 'AGPL-3', diff --git a/golem_activity/models/golem_activity.py b/golem_activity/models/golem_activity.py index bb25069..6fffefb 100644 --- a/golem_activity/models/golem_activity.py +++ b/golem_activity/models/golem_activity.py @@ -108,15 +108,16 @@ class GolemActivity(models.Model): def _check_period(self): """ Checks if end date if after start date """ for activity in self: + season = activity.season_id if activity.date_start and activity.date_stop and \ activity.date_start > activity.date_stop: raise models.ValidationError(_('Start of the period cannot be ' 'after end of the period.')) - if activity.season_id.date_start > activity.date_start: + if season.date_start and season.date_start > activity.date_start: msg = _(u'Activity start date can not be set before ' 'linked season start.') raise models.ValidationError(msg) - if activity.season_id.date_end < activity.date_stop: + if season.date_end and season.date_end < activity.date_stop: msg = _(u'Activity end date can not be set after ' 'linked season end.') raise models.ValidationError(msg) diff --git a/golem_activity_queue/__init__.py b/golem_activity_queue/__init__.py new file mode 100644 index 0000000..8963423 --- /dev/null +++ b/golem_activity_queue/__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 models, wizard diff --git a/golem_activity_queue/__manifest__.py b/golem_activity_queue/__manifest__.py new file mode 100644 index 0000000..92087d1 --- /dev/null +++ b/golem_activity_queue/__manifest__.py @@ -0,0 +1,37 @@ +# -*- 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 . + +{ + 'name': 'GOLEM activity queues', + 'summary': 'GOLEM activity queues', + 'description': ''' GOLEM activity queue management ''', + 'version': '10.0.1.2.3', + 'category': 'GOLEM', + 'author': 'Youssef El Ouahby, Fabien Bourgeois', + 'license': 'AGPL-3', + 'application': True, + 'installable': True, + 'depends': ['golem_activity', 'golem_activity_registration'], + 'data': [ + 'security/ir.model.access.csv', + 'views/golem_activity_queue_views.xml', + 'views/golem_activity_views.xml', + 'views/golem_member_views.xml', + 'wizard/golem_activity_automated_queue_activate_views.xml' + ] +} diff --git a/golem_activity_queue/i18n/fr.po b/golem_activity_queue/i18n/fr.po new file mode 100644 index 0000000..e13c2c3 --- /dev/null +++ b/golem_activity_queue/i18n/fr.po @@ -0,0 +1,291 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * golem_activity_queue +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-03-07 18:55+0000\n" +"PO-Revision-Date: 2018-03-07 18:55+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_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_activity_id +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Activity" +msgstr "Activité" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_activity_id +msgid "Activity id" +msgstr "Activité liée" + +#. module: golem_activity_queue +#: model:ir.actions.act_window,name:golem_activity_queue.golem_activity_queue_action +#: model:ir.ui.menu,name:golem_activity_queue.golem_activity_queue_menu +msgid "Activity queue" +msgstr "Liste d'attente" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Add Queue" +msgstr "Ajouter une liste d'attente" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Add from queue" +msgstr "Ajouter depuis la liste d'attente" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_automated_queue_actiave_wizard_view_form +msgid "Are you sure you want to Add queue to this activity ?
\n" +" If yes please confirm if you want automated registration from queue to activity." +msgstr "Êtes-vous sûr de vouloir ajouter une liste d'attente à cette activité ?
\n" +" Si oui, merci de confirmer si vous souhaitez une inscription automatique depuis la liste d'attente." + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Are you sure you want to remove queue from this activity ? This will delete all elements currently registred in" +msgstr "Êtes-vous sûr de vouloir supprimer la liste d'attente pour cette activité ? Cela supprimera tous les membres inscrits dessus." + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Are you sure you want to switch to automated registration from queue mode ?" +msgstr "Êtes-vous sûr de vouloir passer à une inscription automatique depuis la liste d'attente ?" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Are you sure you want to switch to manual registration from queue mode ?" +msgstr "Êtes-vous sûr de vouloir passer à une inscription manuelle depuis la liste d'attente ?" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_auto_registration_from_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_auto_registration_from_queue +msgid "Auto registration from queue" +msgstr "Inscription automatique depuis la liste d'attente" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_automated_queue_actiave_wizard_view_form +msgid "Cancel" +msgstr "Annuler" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity.py:52 +#, python-format +msgid "Choose the activity to register in" +msgstr "Choisissez l'activité sur laquelle inscrire" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_automated_queue_actiave_wizard_view_form +msgid "Confirm" +msgstr "Confirmer" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_create_uid +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_create_date +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_create_date +msgid "Created on" +msgstr "Créé le" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_is_current +msgid "Current season?" +msgstr "Saison en cours?" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Default season" +msgstr "Saison par défaut" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_display_name +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Full Activity" +msgstr "Activité complète" + +#. module: golem_activity_queue +#: model:ir.model,name:golem_activity_queue.model_golem_activity +msgid "GOLEM Activity" +msgstr "Activité" + +#. module: golem_activity_queue +#: model:ir.model,name:golem_activity_queue.model_golem_activity_queue +msgid "GOLEM Activity Queue" +msgstr "Liste d'attente" + +#. module: golem_activity_queue +#: model:ir.model,name:golem_activity_queue.model_golem_member +msgid "GOLEM Member" +msgstr "Adhérent" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Group By" +msgstr "Grouper par" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_id +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_id +msgid "ID" +msgstr "ID" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard___last_update +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue___last_update +msgid "Last Modified on" +msgstr "Dernière Modification le" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_write_uid +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_write_date +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_member_id +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Member" +msgstr "Adhérent" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity.py:108 +#, python-format +msgid "No remaining place for the activity : {}, please discard changes and register in the queue." +msgstr "Plus de place disponible pour l'activité {}, veuillez annuler vos modifications et utiliser la liste d'attente." + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Not Full Activity" +msgstr "Activité disponible" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_activity_queue_ids +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_member_activity_queue_ids +msgid "Pending registration" +msgstr "Inscriptions en attente" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_activity_number +msgid "Pending registration number" +msgstr "Numéro de l'inscription en attente" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Queue" +msgstr "File d'attente" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_allowed +msgid "Queue allowed" +msgstr "Liste d'attente activée" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_member_form_inherit_golem_activity_queue +msgid "Queue list" +msgstr "Listes d'attente" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Register from Queue" +msgstr "Inscrire depuis la liste d'attente" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_automated_queue_actiave_wizard_view_form +msgid "Rejection reason" +msgstr "Motif du rejet" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_places_remain +msgid "Remaining places" +msgstr "Places restantes" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Remove Queue" +msgstr "Supprimer la liste d'attente" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_season_id +msgid "Season" +msgstr "Saison" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_sequence +msgid "Sequence" +msgstr "Séquence" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Switch to automated registration from queue" +msgstr "Passer à une inscription automatique depuis la liste d'attente" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Switch to manual registration from queue" +msgstr "Passer à une inscription manuelle depuis la liste d'attente" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity_queue.py:52 +#, python-format +msgid "The member your trying to add to the queue is already registered for this activity" +msgstr "L'adhérent que vous essayez d'ajouter à la liste d'attente est déjà inscrit à cette activité" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity.py:118 +#, python-format +msgid "There is a free place for the activity : {}, once you save it will be filled by the first member from queue" +msgstr "Il y a une place disponible sur l'activité {}, une fois sauvegardée un membre de la liste d'attente sera automatiquement inscrit" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity.py:122 +#, python-format +msgid "There is a free place for the activity : {}, you may fill it manually from the queue" +msgstr "Il y a une place disponible sur l'activité {}, vous pouvez inscrire un membre depuis la liste d'attente" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_member.py:39 +#, python-format +msgid "This activity : {} is already full, please discard changes and register in the queue." +msgstr "L'activité {} est complète, veuillez annuler vos modifications et enregistrer le membre dans la liste d'attente." + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity_queue.py:30 +#: sql_constraint:golem.activity.queue:0 +#, python-format +msgid "This member has already been registered for the queue." +msgstr "Le membre a déjà été inscrit sur la liste d'attente." + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity.py:112 +#: code:addons/golem_activity_queue/models/golem_activity.py:127 +#: code:addons/golem_activity_queue/models/golem_member.py:43 +#, python-format +msgid "Warning" +msgstr "Attention" + +#. module: golem_activity_queue +#: model:ir.model,name:golem_activity_queue.model_golem_activity_automated_queue_activate_wizard +msgid "golem.activity.automated.queue.activate.wizard" +msgstr "golem.activity.automated.queue.activate.wizard" diff --git a/golem_activity_queue/i18n/golem_activity_queue.pot b/golem_activity_queue/i18n/golem_activity_queue.pot new file mode 100644 index 0000000..a65633b --- /dev/null +++ b/golem_activity_queue/i18n/golem_activity_queue.pot @@ -0,0 +1,291 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * golem_activity_queue +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-03-07 18:54+0000\n" +"PO-Revision-Date: 2018-03-07 18:54+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_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_activity_id +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Activity" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_activity_id +msgid "Activity id" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.actions.act_window,name:golem_activity_queue.golem_activity_queue_action +#: model:ir.ui.menu,name:golem_activity_queue.golem_activity_queue_menu +msgid "Activity queue" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Add Queue" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Add from queue" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_automated_queue_actiave_wizard_view_form +msgid "Are you sure you want to Add queue to this activity ?
\n" +" If yes please confirm if you want automated registration from queue to activity." +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Are you sure you want to remove queue from this activity ? This will delete all elements currently registred in" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Are you sure you want to switch to automated registration from queue mode ?" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Are you sure you want to switch to manual registration from queue mode ?" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_auto_registration_from_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_auto_registration_from_queue +msgid "Auto registration from queue" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_automated_queue_actiave_wizard_view_form +msgid "Cancel" +msgstr "" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity.py:52 +#, python-format +msgid "Choose the activity to register in" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_automated_queue_actiave_wizard_view_form +msgid "Confirm" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_create_uid +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_create_uid +msgid "Created by" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_create_date +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_create_date +msgid "Created on" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_is_current +msgid "Current season?" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Default season" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_display_name +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_display_name +msgid "Display Name" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Full Activity" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model,name:golem_activity_queue.model_golem_activity +msgid "GOLEM Activity" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model,name:golem_activity_queue.model_golem_activity_queue +msgid "GOLEM Activity Queue" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model,name:golem_activity_queue.model_golem_member +msgid "GOLEM Member" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Group By" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_id +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_id +msgid "ID" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard___last_update +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue___last_update +msgid "Last Modified on" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_write_uid +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_automated_queue_activate_wizard_write_date +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_write_date +msgid "Last Updated on" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_member_id +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Member" +msgstr "" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity.py:108 +#, python-format +msgid "No remaining place for the activity : {}, please discard changes and register in the queue." +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_queue_view_search +msgid "Not Full Activity" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_activity_queue_ids +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_member_activity_queue_ids +msgid "Pending registration" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_activity_number +msgid "Pending registration number" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Queue" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_allowed +msgid "Queue allowed" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_member_form_inherit_golem_activity_queue +msgid "Queue list" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Register from Queue" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_automated_queue_actiave_wizard_view_form +msgid "Rejection reason" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_places_remain +msgid "Remaining places" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Remove Queue" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_season_id +msgid "Season" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model.fields,field_description:golem_activity_queue.field_golem_activity_queue_sequence +msgid "Sequence" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Switch to automated registration from queue" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.ui.view,arch_db:golem_activity_queue.golem_activity_form_inherit_golem_activity_queue +msgid "Switch to manual registration from queue" +msgstr "" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity_queue.py:52 +#, python-format +msgid "The member your trying to add to the queue is already registered for this activity" +msgstr "" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity.py:118 +#, python-format +msgid "There is a free place for the activity : {}, once you save it will be filled by the first member from queue" +msgstr "" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity.py:122 +#, python-format +msgid "There is a free place for the activity : {}, you may fill it manually from the queue" +msgstr "" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_member.py:39 +#, python-format +msgid "This activity : {} is already full, please discard changes and register in the queue." +msgstr "" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity_queue.py:30 +#: sql_constraint:golem.activity.queue:0 +#, python-format +msgid "This member has already been registered for the queue." +msgstr "" + +#. module: golem_activity_queue +#: code:addons/golem_activity_queue/models/golem_activity.py:112 +#: code:addons/golem_activity_queue/models/golem_activity.py:127 +#: code:addons/golem_activity_queue/models/golem_member.py:43 +#, python-format +msgid "Warning" +msgstr "" + +#. module: golem_activity_queue +#: model:ir.model,name:golem_activity_queue.model_golem_activity_automated_queue_activate_wizard +msgid "golem.activity.automated.queue.activate.wizard" +msgstr "" + diff --git a/golem_activity_queue/models/__init__.py b/golem_activity_queue/models/__init__.py new file mode 100644 index 0000000..e5a38ed --- /dev/null +++ b/golem_activity_queue/models/__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_activity_queue, golem_activity, golem_member diff --git a/golem_activity_queue/models/golem_activity.py b/golem_activity_queue/models/golem_activity.py new file mode 100644 index 0000000..732a801 --- /dev/null +++ b/golem_activity_queue/models/golem_activity.py @@ -0,0 +1,130 @@ +# -*- 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 Activity adaptations """ + +from odoo import models, fields, api, _ + +class GolemActivity(models.Model): + """ GOLEM Activity adaptations """ + _inherit = 'golem.activity' + + activity_queue_ids = fields.One2many('golem.activity.queue', + 'activity_id', 'Pending registration') + queue_allowed = fields.Boolean(default=True, readonly=True) + auto_registration_from_queue = fields.Boolean(default=True, readonly=True) + queue_activity_number = fields.Integer(compute="_compute_queue_activity_number", + store=True, string='Pending registration number') + + @api.multi + def auto_registration_toggle(self): + """ switch registration from queue mode """ + for activity in self: + activity.auto_registration_from_queue = not activity.auto_registration_from_queue + + @api.multi + def queue_allowed_toggle(self): + """ Toggle queue_alowed boolean """ + self.ensure_one() + activity = self[0] + if activity.queue_allowed: + if len(activity.activity_queue_ids) > 0: + activity.activity_queue_ids.unlink() + activity.write({'queue_allowed': False, + 'auto_registration_from_queue': False}) + else: + return { + 'name': _('Choose the activity to register in'), + 'type': 'ir.actions.act_window', + 'res_model': 'golem.activity.automated.queue.activate.wizard', + 'view_mode': 'form', + 'context': {'default_activity_id' : activity.id}, + 'target': 'new', + } + + @api.multi + def register_from_queue(self): + """ Registers from queue """ + for activity in self: + queues = activity.activity_queue_ids + if activity.queue_activity_number < activity.places_remain: + queues = queues[0:activity.queue_activity_number] + else: + queues = queues[0:activity.places_remain] + for queue in queues: + values = {'activity_id' : queue.activity_id.id, + 'member_id' : queue.member_id.id} + self.env['golem.activity.registration'].create(values) + queue.unlink() + + @api.constrains('activity_registration_ids') + def handle_queue_at_register(self): + """ Remove member from queue if he has been registered directly in + activity (only for manual queue processing) """ + for activity in self: + member_ids = activity.activity_registration_ids.mapped('member_id.id') + queues_to_remove = activity.activity_queue_ids.filtered( + lambda q: q.member_id.id in member_ids) + queues_to_remove.unlink() + + @api.constrains('activity_queue_ids', 'activity_registration_ids', + 'places_remain', 'queue_allowed', 'queue_activity_number', + 'auto_registration_from_queue') + def automated_register_from_queue(self): + """automated registration from queue""" + for activity in self: + if (activity.places_remain and activity.queue_allowed and + activity.queue_activity_number > 0 and + activity.auto_registration_from_queue): + activity.register_from_queue() + + @api.depends('activity_queue_ids') + def _compute_queue_activity_number(self): + """ compute number of queue registration for activity""" + for activity in self: + activity.queue_activity_number = len(activity.activity_queue_ids) + + @api.onchange('activity_registration_ids') + def _check_registration_number(self): + for activity in self: + # Needed to ensure that we are negative in places + activity._compute_places_remain() + if activity.places_remain < 0 and activity.queue_allowed: + message = _('No remaining place for the activity : {}, please' + ' discard changes and register in the queue.') + return { + 'warning' : { + 'title' : _('Warning'), + 'message': message.format(activity.name), + } + } + elif activity.places_remain > 0 and activity.queue_activity_number > 0: + if activity.auto_registration_from_queue: + warning_message = _('There is a free place for the activity' + ' : {}, once you save it will be filled' + ' by the first member from queue') + else: + warning_message = _('There is a free place for the activity' + ' : {}, you may fill it manually from ' + 'the queue') + return { + 'warning' : { + 'title' : _('Warning'), + 'message': warning_message.format(activity.name) + } + } 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..fd41edb --- /dev/null +++ b/golem_activity_queue/models/golem_activity_queue.py @@ -0,0 +1,53 @@ +# -*- 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 Activity Queue """ + +from odoo import models, fields, api, _ +from odoo.exceptions import ValidationError + +class GolemActivityQueue(models.Model): + """ GOLEM Activity Queue """ + _name = 'golem.activity.queue' + _order = 'sequence asc, id asc' + _description = 'GOLEM Activity Queue' + _sql_constraints = [('golem_activity_queue_uniq', 'UNIQUE (member_id, activity_id)', + _('This member has already been registered for the queue.'))] + + member_id = fields.Many2one('golem.member', required=True, + string='Member', ondelete='cascade', + index=True) + activity_id = fields.Many2one('golem.activity', required=True, + string='Activity', ondelete='cascade', + index=True) + season_id = fields.Many2one(related='activity_id.season_id') + is_current = fields.Boolean('Current season?', + related='activity_id.is_current', store=True) + + places_remain = fields.Integer(related='activity_id.places_remain') + sequence = fields.Integer() + + @api.constrains('member_id', 'activity_id') + def check_member_registration(self): + """ Forbid registration in queue when member is already registred in the + activity """ + for queue in self: + if queue.activity_id in \ + queue.member_id.activity_registration_all_ids.mapped('activity_id'): + raise ValidationError(_('The member your trying to add to the queue' + ' is already registered for this activity')) diff --git a/golem_activity_queue/models/golem_member.py b/golem_activity_queue/models/golem_member.py new file mode 100644 index 0000000..74f905e --- /dev/null +++ b/golem_activity_queue/models/golem_member.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 Member adaptations """ + +import logging +from odoo import models, fields, api, _ +_LOGGER = logging.getLogger(__name__) + +class GolemMember(models.Model): + """ GOLEM Member adaptations """ + _inherit = 'golem.member' + + activity_queue_ids = fields.One2many('golem.activity.queue', 'member_id', + string='Pending registration') + + @api.onchange('activity_registration_ids') + def _check_registration_number(self): + """ check activity registration number """ + for member in self: + for registration in member.activity_registration_ids: + activity = registration.activity_id + if activity.places_remain < 0 and activity.queue_allowed: + message = _('This activity : {} is already full, please' + ' discard changes and register in the queue.') + return { + 'warning' : { + 'title' : _('Warning'), + 'message': message.format(activity.name), + } + } 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..ed23a5f --- /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 +golem_activity_queue_user_rule,GOLEM Activity Queue User Rule,model_golem_activity_queue,golem_base.group_golem_user,1,1,1,1 +golem_activity_queue_manager_rule,GOLEM Activity Queue Manager Rule,model_golem_activity_queue,golem_base.group_golem_manager,1,1,1,1 diff --git a/golem_activity_queue/static/description/icon.png b/golem_activity_queue/static/description/icon.png new file mode 100644 index 0000000..794751a Binary files /dev/null and b/golem_activity_queue/static/description/icon.png differ diff --git a/golem_activity_queue/tests/__init__.py b/golem_activity_queue/tests/__init__.py new file mode 100644 index 0000000..721a338 --- /dev/null +++ b/golem_activity_queue/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_activity_queue, test_golem_activity, test_golem_member diff --git a/golem_activity_queue/tests/test_golem_activity.py b/golem_activity_queue/tests/test_golem_activity.py new file mode 100644 index 0000000..720f985 --- /dev/null +++ b/golem_activity_queue/tests/test_golem_activity.py @@ -0,0 +1,134 @@ +# -*- 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 Activity testing """ + +from odoo.tests.common import TransactionCase + + +class TestGolemActivity(TransactionCase): + """ GOLEM Activity Queue testing """ + + def setUp(self): + """ Bootstrap activity """ + super(TestGolemActivity, self).setUp() + self.season = self.env['golem.season'].create({'name': u'Season 1'}) + self.data_member_1 = {'lastname': u'LAST1', + 'firstname': u'First1', + 'season_ids':[(4, self.season.id, False)]} + self.data_member_2 = {'lastname': u'LAST2', + 'firstname': u'First2', + 'season_ids':[(4, self.season.id, False)]} + self.member = self.env['golem.member'] + type_id = self.env.ref('golem_activity.golem_activity_type_activity') + self.data_activity = { + 'name': u'Activity 1', + 'season_id': self.season.id, + 'type_id': type_id.id + } + self.activity = self.env['golem.activity'] + self.activity_registration = self.env['golem.activity.registration'] + self.activity_queue = self.env['golem.activity.queue'] + + def test_activity_creation(self): + """ Test activity defaults for queue """ + activity = self.activity.create(self.data_activity) + self.assertTrue(activity.queue_allowed) + self.assertTrue(activity.auto_registration_from_queue) + self.assertEqual(activity.queue_activity_number, 0) + self.assertFalse(activity.activity_registration_ids) + self.assertFalse(activity.activity_queue_ids) + + def test_auto_registration_toggle(self): + """ Test Toggle Autoregistration from queue """ + activity = self.activity.create(self.data_activity) + self.assertTrue(activity.auto_registration_from_queue) + activity.auto_registration_toggle() + self.assertFalse(activity.auto_registration_from_queue) + activity.auto_registration_toggle() + self.assertTrue(activity.auto_registration_from_queue) + + def test_queue_allowed_toggle(self): + """ Test Toggle queue_allowed """ + #création de 2 membre est une activité + member1 = self.member.create(self.data_member_1) + member2 = self.member.create(self.data_member_2) + activity = self.activity.create(self.data_activity) + registration_data = {'activity_id' : activity.id, 'member_id' : member1.id} + queue_data = {'activity_id' : activity.id, 'member_id' : member2.id} + + self.assertTrue(activity.queue_allowed) + activity.places = 1 + self.activity_registration.create(registration_data) + self.activity_queue.create(queue_data) + + self.assertTrue(activity.auto_registration_from_queue) + activity.queue_allowed_toggle() + self.assertFalse(activity.queue_allowed) + self.assertFalse(activity.activity_queue_ids) + + queue_activate_wizard_model = self.env['golem.activity.automated.queue.activate.wizard'] + queue_activate_wizard = queue_activate_wizard_model.create({'activity_id': activity.id}) + queue_activate_wizard.activate_queue() + self.assertTrue(activity.queue_allowed) + self.assertTrue(activity.auto_registration_from_queue) + + def test_auto_registration(self): + """ Test auto registration from queue """ + member1 = self.member.create(self.data_member_1) + member2 = self.member.create(self.data_member_2) + activity = self.activity.create(self.data_activity) + self.assertTrue(activity.queue_allowed) + self.assertTrue(activity.auto_registration_from_queue) + + registration_data = {'activity_id' : activity.id, 'member_id' : member1.id} + queue_data = {'activity_id' : activity.id, 'member_id' : member2.id} + + activity.places = 1 + registration = self.activity_registration.create(registration_data) + self.activity_queue.create(queue_data) + self.assertEqual(activity.activity_registration_ids[0].member_id, member1) + self.assertEqual(activity.activity_queue_ids[0].member_id, member2) + + registration.unlink() + self.assertEqual(activity.activity_registration_ids[0].member_id, member2) + self.assertFalse(activity.activity_queue_ids) + + def test_delete_queue_member(self): + """ Test Delete Queue member if they directly register """ + member1 = self.member.create(self.data_member_1) + member2 = self.member.create(self.data_member_2) + activity = self.activity.create(self.data_activity) + self.assertTrue(activity.queue_allowed) + self.assertTrue(activity.auto_registration_from_queue) + activity.auto_registration_toggle() + self.assertFalse(activity.auto_registration_from_queue) + + registration_data = {'activity_id' : activity.id, 'member_id' : member1.id} + queue_data = {'activity_id' : activity.id, 'member_id' : member2.id} + + activity.places = 1 + registration = self.activity_registration.create(registration_data) + self.activity_queue.create(queue_data) + self.assertEqual(activity.activity_registration_ids[0].member_id, member1) + self.assertEqual(activity.activity_queue_ids[0].member_id, member2) + registration.unlink() + + activity.activity_registration_ids = [(0, False, queue_data)] + self.assertFalse(activity.activity_queue_ids) + self.assertEqual(activity.activity_registration_ids[0].member_id, member2) diff --git a/golem_activity_queue/tests/test_golem_activity_queue.py b/golem_activity_queue/tests/test_golem_activity_queue.py new file mode 100644 index 0000000..193e898 --- /dev/null +++ b/golem_activity_queue/tests/test_golem_activity_queue.py @@ -0,0 +1,70 @@ +# -*- 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 Activity Queue testing """ + +from odoo.tests.common import TransactionCase +from odoo.exceptions import ValidationError + + +class TestGolemActivityQueue(TransactionCase): + """ GOLEM Activity Queue testing """ + + def setUp(self, *args, **kwargs): + """ Bootstrap ActivityQueue """ + super(TestGolemActivityQueue, self).setUp(*args, **kwargs) + + self.season = self.env['golem.season'].create({'name': u'Season 1'}) + self.data_member_1 = {'lastname': u'LAST1', + 'firstname': u'First1', + 'season_ids':[(4, self.season.id, False)]} + self.data_member_2 = {'lastname': u'LAST2', + 'firstname': u'First2', + 'season_ids':[(4, self.season.id, False)]} + self.member = self.env['golem.member'] + type_id = self.env.ref('golem_activity.golem_activity_type_activity') + self.data_activity = { + 'name': u'Activity 1', + 'season_id': self.season.id, + 'type_id': type_id.id + } + self.activity = self.env['golem.activity'] + self.activity_queue = self.env['golem.activity.queue'] + self.activity_registration = self.env['golem.activity.registration'] + + def test_activity_queue_basic(self): + """ Test activity queue basics """ + member1 = self.member.create(self.data_member_1) + activity = self.activity.create(self.data_activity) + activity.auto_registration_from_queue = False + activity_queue = self.activity_queue.create({'activity_id': activity.id, + 'member_id': member1.id}) + self.assertEqual(activity.activity_queue_ids[0], activity_queue) + self.assertEqual(member1.activity_queue_ids[0], activity_queue) + + def test_check_member_registration(self): + """ Test activity queue fordib if already in activity """ + member1 = self.member.create(self.data_member_1) + activity = self.activity.create(self.data_activity) + self.activity_registration.create({'activity_id': activity.id, + 'member_id': member1.id}) + self.assertEqual(activity.activity_registration_ids[0].member_id, member1) + with self.assertRaises(ValidationError) as err: + self.activity_queue.create({'activity_id': activity.id, + 'member_id': member1.id}) + self.assertIn('already registered for this activity', err.exception.args[0]) diff --git a/golem_activity_queue/tests/test_golem_member.py b/golem_activity_queue/tests/test_golem_member.py new file mode 100644 index 0000000..d05e05e --- /dev/null +++ b/golem_activity_queue/tests/test_golem_member.py @@ -0,0 +1,74 @@ +# -*- 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 Member testing """ + +from odoo.tests.common import TransactionCase + + +class TestGolemMember(TransactionCase): + """ GOLEM member testing """ + + def setUp(self, *args, **kwargs): + """ Bootstrap member """ + super(TestGolemMember, self).setUp(*args, **kwargs) + #création du saison + self.season = self.env['golem.season'].create({'name': u'Season 1'}) + self.data_member_1 = {'lastname': u'LAST1', + 'firstname': u'First1', + 'season_ids':[(4, self.season.id, False)]} + self.data_member_2 = {'lastname': u'LAST2', + 'firstname': u'First2', + 'season_ids':[(4, self.season.id, False)]} + self.member = self.env['golem.member'] + type_id = self.env.ref('golem_activity.golem_activity_type_activity') + self.data_activity = { + 'name': u'Activity 1', + 'season_id': self.season.id, + 'type_id': type_id.id + } + self.activity = self.env['golem.activity'] + self.activity_registration = self.env['golem.activity.registration'] + self.activity_queue = self.env['golem.activity.queue'] + + def test_member_creation(self): + """ Test member queue default """ + member1 = self.member.create(self.data_member_1) + self.assertFalse(member1.activity_queue_ids) + + def test_automated_registration(self): + """ Test automated registration """ + member1 = self.member.create(self.data_member_1) + member2 = self.member.create(self.data_member_2) + activity = self.activity.create(self.data_activity) + + registration_data = {'activity_id' : activity.id, 'member_id' : member1.id} + queue_data = {'activity_id' : activity.id, 'member_id' : member2.id} + self.assertTrue(activity.queue_allowed) + self.assertTrue(activity.auto_registration_from_queue) + + activity.places = 1 + registration = self.activity_registration.create(registration_data) + self.activity_queue.create(queue_data) + + self.assertEqual(activity.activity_registration_ids[0].member_id, member1) + self.assertEqual(activity.activity_queue_ids[0].member_id, member2) + + registration.unlink() + self.assertEqual(activity.activity_registration_ids[0].member_id, member2) + self.assertFalse(activity.activity_queue_ids) 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..8df637f --- /dev/null +++ b/golem_activity_queue/views/golem_activity_queue_views.xml @@ -0,0 +1,97 @@ + + + + + + + + + GOLEM Activity Queue Form + golem.activity.queue + +
+ + + + + + + +
+
+
+ + + + GOLEM Activity Queue Search + golem.activity.queue + + + + + + + + + + + + + + + + + + + + GOLEM Activity Queue Tree + golem.activity.queue + + + + + + + + + + + + + + + + + + +
+
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..4ef83f9 --- /dev/null +++ b/golem_activity_queue/views/golem_activity_views.xml @@ -0,0 +1,81 @@ + + + + + + + + + Add the queue registration items to activity form + golem.activity + + + + + + + + + + + + + + + + + + + + + + +

+ Please save the resource before fixing the timetable availibility" +

+ + + +
+ +
+ + +
+ +
+
+ + + + GOLEM Resource search + golem.resource + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/golem_resource/wizard/__init__.py b/golem_resource/wizard/__init__.py new file mode 100644 index 0000000..9a0c408 --- /dev/null +++ b/golem_resource/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_resource/wizard/golem_reservation_rejection.py b/golem_resource/wizard/golem_reservation_rejection.py new file mode 100644 index 0000000..7fdc781 --- /dev/null +++ b/golem_resource/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.resource.reservation', required=True) + reason = fields.Text(required=True) + + @api.multi + def reject(self): + """ Sets reservation status to rejected and add reason """ + self.ensure_one() + rejection = self[0] + 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 new file mode 100644 index 0000000..0bb4048 --- /dev/null +++ b/golem_resource/wizard/golem_reservation_rejection_views.xml @@ -0,0 +1,42 @@ + + + + + + + + GOLEM Reservation Rejection Wizard Form + golem.reservation.rejection.wizard + +
+ + + + +
+
+
+
+
+ +
+
diff --git a/golem_season/__manifest__.py b/golem_season/__manifest__.py index bb58a2e..47c72f9 100644 --- a/golem_season/__manifest__.py +++ b/golem_season/__manifest__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright 2016 Fabien Bourgeois +# Copyright 2016-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,12 +18,18 @@ { 'name': 'GOLEM seasons', 'summary': 'GOLEM non-profit seasons management', - 'version': '10.0.1.0.0', + 'description': '''GOLEM non-profit seasons management : + - add season with name and period ; + - choose on per default season ; + - link optionnally one or many memberships types''', + 'version': '10.0.1.1.1', 'category': 'GOLEM', 'author': 'Fabien Bourgeois', 'license': 'AGPL-3', 'application': False, 'installable': True, 'depends': ['golem_base'], - 'data': ['security/ir.model.access.csv', 'views/golem_season_views.xml'] + 'data': ['security/ir.model.access.csv', + 'views/golem_season_views.xml', + 'views/membership_views.xml'] } diff --git a/golem_season/i18n/fr.po b/golem_season/i18n/fr.po index 3ea8a9d..6cb9ee9 100644 --- a/golem_season/i18n/fr.po +++ b/golem_season/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-18 14:18+0000\n" -"PO-Revision-Date: 2018-01-18 14:18+0000\n" +"POT-Creation-Date: 2018-03-06 07:14+0000\n" +"PO-Revision-Date: 2018-03-06 07:14+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -31,7 +31,7 @@ msgid "Created on" msgstr "Créé le" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:75 +#: code:addons/golem_season/models/golem_season.py:73 #, python-format msgid "Current period cannot be included into another existing period." msgstr "La période actuelle est en conflit avec une période existante." @@ -57,7 +57,7 @@ msgid "Display Name" msgstr "Nom affiché" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:71 +#: code:addons/golem_season/models/golem_season.py:69 #, python-format msgid "End of the period is in range of an existing period." msgstr "La fin de la période est en conflit avec une période existante." @@ -93,15 +93,21 @@ msgstr "Dernière mise à jour par" msgid "Last Updated on" msgstr "Dernière mise à jour le" +#. module: golem_season +#: model:ir.model.fields,field_description:golem_season.field_product_product_membership_season_id +#: model:ir.model.fields,field_description:golem_season.field_product_template_membership_season_id +msgid "Linked season" +msgstr "Saison liée" + #. module: golem_season #: model:ir.ui.view,arch_db:golem_season.golem_season_view_form msgid "Make this season as default" msgstr "Activer cette saison par défaut" #. module: golem_season -#: model:ir.model.fields,field_description:golem_season.field_golem_season_membership_id -msgid "Membership type" -msgstr "Type d'adhésion" +#: model:ir.model.fields,field_description:golem_season.field_golem_season_membership_ids +msgid "Membership types" +msgstr "Types d'adhésion" #. module: golem_season #: model:ir.model.fields,field_description:golem_season.field_golem_season_date_end @@ -113,8 +119,14 @@ msgstr "Fin de la période" msgid "Period start" msgstr "Début de la période" +#. module: golem_season +#: model:ir.model,name:golem_season.model_product_template +msgid "Product Template" +msgstr "Modèle d'article" + #. module: golem_season #: model:ir.ui.view,arch_db:golem_season.golem_season_view_form +#: model:ir.ui.view,arch_db:golem_season.membership_product_search_form_view_inherit_golem_season msgid "Season" msgstr "Saison" @@ -129,25 +141,25 @@ msgid "Seasons" msgstr "Saisons" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:62 +#: code:addons/golem_season/models/golem_season.py:60 #, python-format msgid "Start of the period cannot be after end of the period." msgstr "Le début de la période ne peut être postérieur à sa fin." #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:67 +#: code:addons/golem_season/models/golem_season.py:65 #, python-format msgid "Start of the period is in range of an existing period." msgstr "Le début de la période est en conflit avec une période existante." #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:58 +#: code:addons/golem_season/models/golem_season.py:56 #, python-format msgid "The date end is required" msgstr "The date end is required" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:60 +#: code:addons/golem_season/models/golem_season.py:58 #, python-format msgid "The date start is required" msgstr "The date start is required" @@ -160,8 +172,7 @@ msgid "This season name has already been used." msgstr "Ce nom pour la saison a déjà été utilisé. Merci d'en choisir un autre." #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:114 +#: code:addons/golem_season/models/golem_season.py:112 #, python-format msgid "You can't delete the default season" msgstr "Vous ne pouvez pas supprimer la saison par défaut" - diff --git a/golem_season/i18n/golem_season.pot b/golem_season/i18n/golem_season.pot index 8f0b739..114008a 100644 --- a/golem_season/i18n/golem_season.pot +++ b/golem_season/i18n/golem_season.pot @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-18 14:18+0000\n" -"PO-Revision-Date: 2018-01-18 14:18+0000\n" +"POT-Creation-Date: 2018-03-06 07:14+0000\n" +"PO-Revision-Date: 2018-03-06 07:14+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -31,7 +31,7 @@ msgid "Created on" msgstr "" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:75 +#: code:addons/golem_season/models/golem_season.py:73 #, python-format msgid "Current period cannot be included into another existing period." msgstr "" @@ -57,7 +57,7 @@ msgid "Display Name" msgstr "" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:71 +#: code:addons/golem_season/models/golem_season.py:69 #, python-format msgid "End of the period is in range of an existing period." msgstr "" @@ -93,14 +93,20 @@ msgstr "" msgid "Last Updated on" msgstr "" +#. module: golem_season +#: model:ir.model.fields,field_description:golem_season.field_product_product_membership_season_id +#: model:ir.model.fields,field_description:golem_season.field_product_template_membership_season_id +msgid "Linked season" +msgstr "" + #. module: golem_season #: model:ir.ui.view,arch_db:golem_season.golem_season_view_form msgid "Make this season as default" msgstr "" #. module: golem_season -#: model:ir.model.fields,field_description:golem_season.field_golem_season_membership_id -msgid "Membership type" +#: model:ir.model.fields,field_description:golem_season.field_golem_season_membership_ids +msgid "Membership types" msgstr "" #. module: golem_season @@ -113,8 +119,14 @@ msgstr "" msgid "Period start" msgstr "" +#. module: golem_season +#: model:ir.model,name:golem_season.model_product_template +msgid "Product Template" +msgstr "" + #. module: golem_season #: model:ir.ui.view,arch_db:golem_season.golem_season_view_form +#: model:ir.ui.view,arch_db:golem_season.membership_product_search_form_view_inherit_golem_season msgid "Season" msgstr "" @@ -129,25 +141,25 @@ msgid "Seasons" msgstr "" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:62 +#: code:addons/golem_season/models/golem_season.py:60 #, python-format msgid "Start of the period cannot be after end of the period." msgstr "" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:67 +#: code:addons/golem_season/models/golem_season.py:65 #, python-format msgid "Start of the period is in range of an existing period." msgstr "" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:58 +#: code:addons/golem_season/models/golem_season.py:56 #, python-format msgid "The date end is required" msgstr "" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:60 +#: code:addons/golem_season/models/golem_season.py:58 #, python-format msgid "The date start is required" msgstr "" @@ -160,7 +172,7 @@ msgid "This season name has already been used." msgstr "" #. module: golem_season -#: code:addons/golem_season/models/golem_season.py:114 +#: code:addons/golem_season/models/golem_season.py:112 #, python-format msgid "You can't delete the default season" msgstr "" diff --git a/golem_season/models/__init__.py b/golem_season/models/__init__.py index c7a55cc..7b57d01 100644 --- a/golem_season/models/__init__.py +++ b/golem_season/models/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright 2016 Fabien Bourgeois +# Copyright 2016-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 @@ -15,4 +15,4 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from . import golem_season +from . import product_template, golem_season diff --git a/golem_season/models/golem_season.py b/golem_season/models/golem_season.py index ecfd059..d1b0ece 100644 --- a/golem_season/models/golem_season.py +++ b/golem_season/models/golem_season.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright 2016 Fabien Bourgeois +# Copyright 2016-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 @@ -28,24 +28,22 @@ class GolemSeason(models.Model): _('This season name has already been used.'))] name = fields.Char('Season name', copy=False, required=True) - - membership_id = fields.Many2one('product.template', 'Membership type', - domain="[('membership', '=', True)]") - - + membership_ids = fields.One2many('product.template', 'membership_season_id', + string='Membership types', + domain=[('membership', '=', True)]) member_counter = fields.Integer('Counter for member number generation', readonly=True, default=1) date_start = fields.Date('Period start') date_end = fields.Date('Period end') - @api.onchange('membership_id') + @api.onchange('membership_ids') def _onchange_season_dates(self): """ Sets defaults dates according to membership type """ for season in self: - if season.membership_id and not season.date_start: + if season.membership_ids and not season.date_start: season.update({ - 'date_start': season.membership_id.membership_date_from, - 'date_end': season.membership_id.membership_date_to + 'date_start': season.membership_ids[0].membership_date_from, + 'date_end': season.membership_ids[0].membership_date_to }) @api.constrains('date_start', 'date_end') diff --git a/golem_season/models/product_template.py b/golem_season/models/product_template.py new file mode 100644 index 0000000..163bc45 --- /dev/null +++ b/golem_season/models/product_template.py @@ -0,0 +1,37 @@ +# -*- 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 . + +""" Product adaptations """ + +from odoo import models, fields, api + +class ProductTemplate(models.Model): + """ Product Template adaptations """ + _inherit = 'product.template' + + membership_season_id = fields.Many2one('golem.season', 'Linked season', index=True) + + @api.onchange('membership_season_id') + def onchange_season(self): + """ Adapts period to selected season if needed """ + for product in self: + if product.membership and product.membership_season_id \ + and not product.membership_date_from: + product.update({ + 'membership_date_from': product.membership_season_id.date_start, + 'membership_date_to': product.membership_season_id.date_end + }) diff --git a/golem_season/tests/test_golem_season.py b/golem_season/tests/test_golem_season.py index 3d5c403..a79aee2 100644 --- a/golem_season/tests/test_golem_season.py +++ b/golem_season/tests/test_golem_season.py @@ -65,14 +65,25 @@ class TestGolemSeason(TransactionCase): 'date_start' : False, 'date_end': '2009-11-01'}) - - def test__onchange_season_dates(self): + def test_membership(self): """ Test if membership """ - membership = self.env['product.template'].create({'name': 'Name', - 'membership': True, - 'membership_date_from': '2017-11-01', - 'membership_date_to': '2018-11-01'}) - - new_season = self.env['golem.season'].create({'name': 'Name', - 'membership_id': membership.id}) - self.assertEqual(new_season.membership_id, membership) + new_season = self.env['golem.season'].create({'name': 'Name'}) + membership = self.env['product.template'].create({ + 'name': 'Name', + 'season_id': new_season.id, + 'membership': True, + 'membership_date_from': '2017-11-01', + 'membership_date_to': '2018-11-01' + }) + self.assertEqual(new_season.membership_ids[0], membership) + self.assertEqual(membership.season_id, new_season) + membership2 = self.env['product.template'].create({ + 'name': 'Name2', + 'membership': True, + 'membership_date_from': '2017-11-01', + 'membership_date_to': '2018-11-01' + }) + new_season.membership_ids = [(4, membership2.id, False)] + self.assertEqual(len(new_season.membership_ids), 2) + self.assertEqual(new_season.membership_ids[1], membership2) + self.assertEqual(membership2.season_id, new_season) diff --git a/golem_season/views/golem_season_views.xml b/golem_season/views/golem_season_views.xml index 698fbe2..9783ce5 100644 --- a/golem_season/views/golem_season_views.xml +++ b/golem_season/views/golem_season_views.xml @@ -35,8 +35,9 @@ along with this program. If not, see . - + + + + + + + + + + Membership Product Form adaptations + product.template + + + + + + + + + + + Membership Product Search adaptations + product.template + + + + + + + + + + + + +