diff --git a/event_session/README.rst b/event_session/README.rst new file mode 100644 index 000000000..f9d80111c --- /dev/null +++ b/event_session/README.rst @@ -0,0 +1,51 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +==================================== +Create and assign sessions to events +==================================== + +This module allows to create sessions associated with events. + +Usage +===== + +You can either: + +* Go to Events > Sessions and create some sessions associated with an event. +* Go to an event and use the sessions wizard to create all your event sessions + according to a given schedule. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Contributors +------------ + +* Sergio Teruel +* David Vidal +* Nikos Tsirintanis + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/event_session/__init__.py b/event_session/__init__.py new file mode 100644 index 000000000..1c15bc7ee --- /dev/null +++ b/event_session/__init__.py @@ -0,0 +1,3 @@ +from . import models +from . import wizards +from . import tests diff --git a/event_session/__manifest__.py b/event_session/__manifest__.py new file mode 100644 index 000000000..98e245b5e --- /dev/null +++ b/event_session/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2017 David Vidal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + 'name': 'Event Sessions', + 'version': '11.0.1.0.0', + 'author': 'Tecnativa, ' + 'Odoo Community Association (OCA)', + "license": "AGPL-3", + 'website': 'https://github.com/oca/event.git', + 'category': 'Marketing', + 'summary': 'Sessions in events', + 'depends': ['event'], + 'data': [ + 'security/ir.model.access.csv', + 'security/event_session_security.xml', + 'views/event_session_view.xml', + 'views/event_view.xml', + 'wizards/wizard_event_session_view.xml', + ], + 'installable': True, +} diff --git a/event_session/i18n/es.po b/event_session/i18n/es.po new file mode 100644 index 000000000..17dc5d038 --- /dev/null +++ b/event_session/i18n/es.po @@ -0,0 +1,582 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * event_session +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-14 11:25+0000\n" +"PO-Revision-Date: 2017-06-14 13:27+0200\n" +"Last-Translator: David \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 1.8.7.1\n" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_session_count +msgid "# of Event Sessions" +msgstr "# de Sesiones del Evento" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_active +msgid "Active" +msgstr "Activo" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_registration +msgid "Attendee" +msgstr "Asistentes" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_registration_ids +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Attendees" +msgstr "Asistentes" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Attendees on this session" +msgstr "Asistentes a esta sesión" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_available_expected +msgid "Available Expected Seats" +msgstr "Plazas disponibles previstas" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_available +msgid "Available Seats" +msgstr "Plazas disponibles" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_seats_available_expected +msgid "Available expected seats" +msgstr "Plazas disponibles previstas" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_seats_available +msgid "Available seats" +msgstr "Plazas disponibles" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_delete_existing_sessions +msgid "Check in order to delete every previous session for this event" +msgstr "Seleccionar para borrar todas las sesiones existentes en este evento." + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_company_id +msgid "Company" +msgstr "Compañía" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_fridays +msgid "Create sessions on Fridays" +msgstr "Crear sesiones los viernes" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_mondays +msgid "Create sessions on Mondays" +msgstr "Crear sesiones los lunes" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_saturdays +msgid "Create sessions on Saturdays" +msgstr "Crear sesiones los sábados" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_sundays +msgid "Create sessions on Sundays" +msgstr "Crear sesiones los domingos" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_thursdays +msgid "Create sessions on Thursdays" +msgstr "Crear sesiones los jueves" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_tuesdays +msgid "Create sessions on Tuesdays" +msgstr "Crear sesiones los martes" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_wednesdays +msgid "Create sessions on Wednesdays" +msgstr "Crear sesiones los miércoles" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_create_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_create_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_create_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_create_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_create_date +msgid "Created on" +msgstr "Creado el" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Dates and event data" +msgstr "Datos de evento y fechas" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_delete_existing_sessions +msgid "Delete existing sessions" +msgstr "Borrar sesiones existentes" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_display_name +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_display_name +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Email Schedule" +msgstr "Programación de correo electrónico" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_date_end +msgid "End Date" +msgstr "Fecha finalización" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_end_located +msgid "End Date Located" +msgstr "Fecha de finalización localizada" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_end_time +msgid "End time" +msgstr "Hora de fin" + +#. module: event_session +#: code:addons/event_session/models/event_session.py:252 +#, python-format +msgid "Ending and starting time can't be the same!" +msgstr "La hora de comienzo y de fin no puede ser la misma" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_event +#: model:ir.model.fields,field_description:event_session.field_event_session_event_id +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Event" +msgstr "Evento" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Event Session" +msgstr "Sesión de evento" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Event Sesssion" +msgstr "Sesión de evento" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_id +msgid "Event id" +msgstr "Evento" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_session +msgid "Event session" +msgstr "Sesión" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_fridays +msgid "Fridays" +msgstr "Viernes" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_available_pc +msgid "Full %" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.session_view_event_form +msgid "Generate Sessions" +msgstr "Generar sesiones" + +#. module: event_session +#: model:ir.actions.act_window,name:event_session.act_wizard_event_session +msgid "Generate Sessions Wizard" +msgstr "Asistente para generar sesiones" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Generate sessions" +msgstr "Generar sesiones" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Group By" +msgstr "Agrupar por" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_session_hour_ids +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Hours" +msgstr "Horas" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_id +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_id +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_id +msgid "ID" +msgstr "ID" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_name +msgid "It will be generated according to given parameters" +msgstr "Se generarán de acuerdo con los parámetros dados" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session___last_update +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session___last_update +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours___last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_write_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_write_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_write_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_write_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: event_session +#: selection:event.session,seats_availability:0 +msgid "Limited" +msgstr "Limitados" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_event_mail_ids +msgid "Mail Schedule" +msgstr "Programación de correo" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_mail_template_id +msgid "Mail Schedule Template" +msgstr "Plantilla de programación de correos" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_availability +msgid "Maximum Attendees" +msgstr "Asistentes máximos" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_max +msgid "Maximum seats" +msgstr "Número máximo de asistentes" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_min +msgid "Minimum seats" +msgstr "Plazas mínimas" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_mondays +msgid "Mondays" +msgstr "Lunes" + +#. module: event_session +#: code:addons/event_session/models/event_session.py:232 +#, python-format +msgid "No more available seats for this session." +msgstr "No hay más plazas disponibles para esta sesión." + +#. module: event_session +#: code:addons/event_session/models/event.py:59 +#, python-format +msgid "No more seats available for this event." +msgstr "No hay más plazas disponibles para este evento." + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_expected +msgid "Number of Expected Attendees" +msgstr "Número previsto de asistentes" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_used +msgid "Number of Participants" +msgstr "Número de asistentes" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Origin" +msgstr "Origen" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Other options" +msgstr "Otras opciones" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Partner" +msgstr "Empresa" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_mail_registration +msgid "Registration Mail Scheduler" +msgstr "Registro de Programador de Correo Electrónico" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Registrations" +msgstr "Registros" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_reserved +msgid "Reserved Seats" +msgstr "Plazas reservadas" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_saturdays +msgid "Saturdays" +msgstr "Sábados" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Schedule" +msgstr "Programar" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_seats_expected +msgid "Seats expected" +msgstr "Plazas previstas" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_mail_scheduler_template_session_id +#: model:ir.model.fields,field_description:event_session.field_event_mail_session_id +#: model:ir.model.fields,field_description:event_session.field_event_registration_session_id +#: model:ir.model.fields,field_description:event_session.field_event_session_name +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_session_id +#: model:ir.ui.view,arch_db:event_session.view_event_session_calendar +#: model:ir.ui.view,arch_db:event_session.view_report_event_registration_search +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Session" +msgstr "Sesión" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_end +msgid "Session date end" +msgstr "Fecha de fin de sesión" + +#. module: event_session +#: code:addons/event_session/models/event_session.py:243 +#, python-format +msgid "Session date is out of this event dates range" +msgstr "La fecha de la sesión está fuera del rango de fechas de este evento" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_name +msgid "Session info" +msgstr "Información de la sesión" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_begin +msgid "Session start date" +msgstr "Fecha de inicio de sesión" + +#. module: event_session +#: model:ir.actions.act_window,name:event_session.act_event_session_event_form +#: model:ir.actions.act_window,name:event_session.act_event_session_form +#: model:ir.model.fields,field_description:event_session.field_event_event_session_ids +#: model:ir.ui.menu,name:event_session.event_session_menu +#: model:ir.ui.view,arch_db:event_session.view_event_form +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Sessions" +msgstr "Sesiones" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_form +msgid "Sessions availables for this event" +msgstr "Sesiones disponibles para este evento" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_event_date_begin +msgid "" +"Set it up in the event configurationSessions will be generated from this date" +msgstr "" +"Establécela en la configuración del evento. Se generarán sesiones a partir " +"de esta fecha." + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_event_date_end +#: model:ir.model.fields,help:event_session.field_wizard_event_session_event_date_tz +msgid "" +"Set it up in the event configurationSessions will be generated up to this " +"date" +msgstr "" +"Establécela en la configuración del evento. Se generarán sesiones a hasta " +"esta fecha." + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_date_begin +msgid "Start Date" +msgstr "Fecha de inicio" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_begin_located +msgid "Start Date Located" +msgstr "Fecha de inicio localizada" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_start_time +msgid "Start time" +msgstr "Hora de incio" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "State" +msgstr "Estado" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_sundays +msgid "Sundays" +msgstr "Domingos" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:86 +#: code:addons/event_session/wizards/wizard_event_session.py:91 +#, python-format +msgid "There are overlapping hours!" +msgstr "¡Hay horarios superpuestos!" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:204 +#, python-format +msgid "There are sessions with no duration!" +msgstr "¡Hay horarios con duración nula!" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_thursdays +msgid "Thursdays" +msgstr "Jueves" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_tz +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_date_tz +msgid "Timezone" +msgstr "Zona horaria" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total available expected seats" +msgstr "Total plazas disponibles previstas" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total available seats" +msgstr "Total plazas disponibles" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_event_sessions_count +#: model:ir.model.fields,field_description:event_session.field_event_registration_event_sessions_count +msgid "Total event sessions" +msgstr "Sesiones de evento totales" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats" +msgstr "Total plazas" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats expected" +msgstr "Total plazas previstas" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats reserved" +msgstr "Total plazas reservadas" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats unconfirmed" +msgstr "Total plazas sin confirmar" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_tuesdays +msgid "Tuesdays" +msgstr "Martes" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_unconfirmed +msgid "Unconfirmed Seat Reservations" +msgstr "Reservas de plazas no confirmadas" + +#. module: event_session +#: selection:event.session,seats_availability:0 +msgid "Unlimited" +msgstr "Ilimitados" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_wednesdays +msgid "Wednesdays" +msgstr "Miércoles" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Weekdays" +msgstr "Días de la semana" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_wizard_event_session_id +msgid "Wizard event session id" +msgstr "Wizard event session id" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:181 +#, python-format +msgid "You must select at least one weekday" +msgstr "Debes seleccionar al menos un día de la semana" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:213 +#, python-format +msgid "You've entered invalid hours!" +msgstr "¡Las horas introducidas son erróneas!" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_mail +msgid "event.mail" +msgstr "event.mail" + +#. module: event_session +#: model:ir.model,name:event_session.model_report_event_registration +msgid "report.event.registration" +msgstr "report.event.registration" + +#. module: event_session +#: model:ir.model,name:event_session.model_wizard_event_session +msgid "wizard.event.session" +msgstr "wizard.event.session" + +#. module: event_session +#: model:ir.model,name:event_session.model_wizard_event_session_hours +msgid "wizard.event.session.hours" +msgstr "wizard.event.session.hours" diff --git a/event_session/i18n/event_session.pot b/event_session/i18n/event_session.pot new file mode 100644 index 000000000..ae81e3263 --- /dev/null +++ b/event_session/i18n/event_session.pot @@ -0,0 +1,572 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * event_session +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \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: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_session_count +msgid "# of Event Sessions" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_active +msgid "Active" +msgstr "" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_registration +msgid "Attendee" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_registration_ids +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Attendees" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Attendees on this session" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_available_expected +msgid "Available Expected Seats" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_available +msgid "Available Seats" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_seats_available_expected +msgid "Available expected seats" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_seats_available +msgid "Available seats" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Cancel" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_delete_existing_sessions +msgid "Check in order to delete every previous session for this event" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_company_id +msgid "Company" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_fridays +msgid "Create sessions on Fridays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_mondays +msgid "Create sessions on Mondays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_saturdays +msgid "Create sessions on Saturdays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_sundays +msgid "Create sessions on Sundays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_thursdays +msgid "Create sessions on Thursdays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_tuesdays +msgid "Create sessions on Tuesdays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_wednesdays +msgid "Create sessions on Wednesdays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_create_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_create_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_create_uid +msgid "Created by" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_create_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_create_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_create_date +msgid "Created on" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Dates and event data" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_delete_existing_sessions +msgid "Delete existing sessions" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_display_name +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_display_name +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_display_name +msgid "Display Name" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Email Schedule" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_date_end +msgid "End Date" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_end_located +msgid "End Date Located" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_end_time +msgid "End time" +msgstr "" + +#. module: event_session +#: code:addons/event_session/models/event_session.py:252 +#, python-format +msgid "Ending and starting time can't be the same!" +msgstr "" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_event +#: model:ir.model.fields,field_description:event_session.field_event_session_event_id +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Event" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Event Session" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Event Sesssion" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_id +msgid "Event id" +msgstr "" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_session +msgid "Event session" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_fridays +msgid "Fridays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_available_pc +msgid "Full %" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.session_view_event_form +msgid "Generate Sessions" +msgstr "" + +#. module: event_session +#: model:ir.actions.act_window,name:event_session.act_wizard_event_session +msgid "Generate Sessions Wizard" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Generate sessions" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Group By" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_session_hour_ids +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Hours" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_id +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_id +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_id +msgid "ID" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_name +msgid "It will be generated according to given parameters" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session___last_update +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session___last_update +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours___last_update +msgid "Last Modified on" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_write_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_write_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_write_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_write_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_write_date +msgid "Last Updated on" +msgstr "" + +#. module: event_session +#: selection:event.session,seats_availability:0 +msgid "Limited" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_event_mail_ids +msgid "Mail Schedule" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_mail_template_id +msgid "Mail Schedule Template" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_availability +msgid "Maximum Attendees" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_max +msgid "Maximum seats" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_min +msgid "Minimum seats" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_mondays +msgid "Mondays" +msgstr "" + +#. module: event_session +#: code:addons/event_session/models/event_session.py:232 +#, python-format +msgid "No more available seats for this session." +msgstr "" + +#. module: event_session +#: code:addons/event_session/models/event.py:59 +#, python-format +msgid "No more seats available for this event." +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_expected +msgid "Number of Expected Attendees" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_used +msgid "Number of Participants" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Origin" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Other options" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Partner" +msgstr "" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_mail_registration +msgid "Registration Mail Scheduler" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Registrations" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_reserved +msgid "Reserved Seats" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_saturdays +msgid "Saturdays" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Schedule" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_seats_expected +msgid "Seats expected" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_mail_scheduler_template_session_id +#: model:ir.model.fields,field_description:event_session.field_event_mail_session_id +#: model:ir.model.fields,field_description:event_session.field_event_registration_session_id +#: model:ir.model.fields,field_description:event_session.field_event_session_name +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_session_id +#: model:ir.ui.view,arch_db:event_session.view_event_session_calendar +#: model:ir.ui.view,arch_db:event_session.view_report_event_registration_search +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Session" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_end +msgid "Session date end" +msgstr "" + +#. module: event_session +#: code:addons/event_session/models/event_session.py:243 +#, python-format +msgid "Session date is out of this event dates range" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_name +msgid "Session info" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_begin +msgid "Session start date" +msgstr "" + +#. module: event_session +#: model:ir.actions.act_window,name:event_session.act_event_session_event_form +#: model:ir.actions.act_window,name:event_session.act_event_session_form +#: model:ir.model.fields,field_description:event_session.field_event_event_session_ids +#: model:ir.ui.menu,name:event_session.event_session_menu +#: model:ir.ui.view,arch_db:event_session.view_event_form +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Sessions" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_form +msgid "Sessions availables for this event" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_event_date_begin +msgid "Set it up in the event configurationSessions will be generated from this date" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_event_date_end +#: model:ir.model.fields,help:event_session.field_wizard_event_session_event_date_tz +msgid "Set it up in the event configurationSessions will be generated up to this date" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_date_begin +msgid "Start Date" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_begin_located +msgid "Start Date Located" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_start_time +msgid "Start time" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "State" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_sundays +msgid "Sundays" +msgstr "" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:86 +#: code:addons/event_session/wizards/wizard_event_session.py:91 +#, python-format +msgid "There are overlapping hours!" +msgstr "" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:204 +#, python-format +msgid "There are sessions with no duration!" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_thursdays +msgid "Thursdays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_tz +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_date_tz +msgid "Timezone" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total available expected seats" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total available seats" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_event_sessions_count +#: model:ir.model.fields,field_description:event_session.field_event_registration_event_sessions_count +msgid "Total event sessions" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats expected" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats reserved" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats unconfirmed" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_tuesdays +msgid "Tuesdays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_unconfirmed +msgid "Unconfirmed Seat Reservations" +msgstr "" + +#. module: event_session +#: selection:event.session,seats_availability:0 +msgid "Unlimited" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_wednesdays +msgid "Wednesdays" +msgstr "" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Weekdays" +msgstr "" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_wizard_event_session_id +msgid "Wizard event session id" +msgstr "" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:181 +#, python-format +msgid "You must select at least one weekday" +msgstr "" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:213 +#, python-format +msgid "You've entered invalid hours!" +msgstr "" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_mail +msgid "event.mail" +msgstr "" + +#. module: event_session +#: model:ir.model,name:event_session.model_report_event_registration +msgid "report.event.registration" +msgstr "" + +#. module: event_session +#: model:ir.model,name:event_session.model_wizard_event_session +msgid "wizard.event.session" +msgstr "" + +#. module: event_session +#: model:ir.model,name:event_session.model_wizard_event_session_hours +msgid "wizard.event.session.hours" +msgstr "" + diff --git a/event_session/i18n/nl.po b/event_session/i18n/nl.po new file mode 100644 index 000000000..0e7adc98b --- /dev/null +++ b/event_session/i18n/nl.po @@ -0,0 +1,578 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * event_session +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2018-09-20 17:38+0000\n" +"Last-Translator: lfreeke \n" +"Language-Team: none\n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.1.1\n" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_session_count +msgid "# of Event Sessions" +msgstr "# of evenementsessies" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_active +msgid "Active" +msgstr "Actief" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_registration +msgid "Attendee" +msgstr "Deelnemer" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_registration_ids +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Attendees" +msgstr "Deelnemers" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Attendees on this session" +msgstr "Deelnemers in deze sessie" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_available_expected +msgid "Available Expected Seats" +msgstr "Verwachte beschikbare plaatsen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_available +msgid "Available Seats" +msgstr "Beschikbare plaatsen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_seats_available_expected +msgid "Available expected seats" +msgstr "Verwachte beschikbare plaatsen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_seats_available +msgid "Available seats" +msgstr "Beschikbare plaatsen" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Cancel" +msgstr "Annuleer" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_delete_existing_sessions +msgid "Check in order to delete every previous session for this event" +msgstr "Vink aan om alle voorgaande sessie voor dit evenement te verwijderen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_company_id +msgid "Company" +msgstr "Bedrijf" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_fridays +msgid "Create sessions on Fridays" +msgstr "Maak sessies aan op vrijdag" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_mondays +msgid "Create sessions on Mondays" +msgstr "Maak sessies aan op maandag" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_saturdays +msgid "Create sessions on Saturdays" +msgstr "Maak sessies aan op zaterdag" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_sundays +msgid "Create sessions on Sundays" +msgstr "Maak sessies aan op zondag" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_thursdays +msgid "Create sessions on Thursdays" +msgstr "Maak sessies aan op donderdag" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_tuesdays +msgid "Create sessions on Tuesdays" +msgstr "Maak sessies aan op dinsdag" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_wednesdays +msgid "Create sessions on Wednesdays" +msgstr "Maak sessies aan op woensdag" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_create_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_create_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_create_uid +msgid "Created by" +msgstr "Aangemaakt door" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_create_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_create_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_create_date +msgid "Created on" +msgstr "Aangemaakt op" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Dates and event data" +msgstr "Datums en evenementgegevens" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_delete_existing_sessions +msgid "Delete existing sessions" +msgstr "Verwijder bestaande sessies" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_display_name +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_display_name +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_display_name +msgid "Display Name" +msgstr "Weergave naam" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Email Schedule" +msgstr "Email schema" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_date_end +msgid "End Date" +msgstr "Einddatum" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_end_located +msgid "End Date Located" +msgstr "Einddatum locatie" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_end_time +msgid "End time" +msgstr "Eindtijd" + +#. module: event_session +#: code:addons/event_session/models/event_session.py:252 +#, python-format +msgid "Ending and starting time can't be the same!" +msgstr "Eind- en begintijd kunnen niet hetzelfde zijn!" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_event +#: model:ir.model.fields,field_description:event_session.field_event_session_event_id +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Event" +msgstr "Evenement" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Event Session" +msgstr "Evenementsessie" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Event Sesssion" +msgstr "Evenementsessie" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_id +msgid "Event id" +msgstr "Evenement id" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_session +msgid "Event session" +msgstr "Evenementsessie" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_fridays +msgid "Fridays" +msgstr "Vrijdag" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_available_pc +msgid "Full %" +msgstr "Volledig %" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.session_view_event_form +msgid "Generate Sessions" +msgstr "Maak sessies aan" + +#. module: event_session +#: model:ir.actions.act_window,name:event_session.act_wizard_event_session +msgid "Generate Sessions Wizard" +msgstr "Maak sessies aan wizard" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Generate sessions" +msgstr "Maak sessies aan" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Group By" +msgstr "Groepeer op" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_session_hour_ids +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Hours" +msgstr "Uren" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_id +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_id +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_id +msgid "ID" +msgstr "ID" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_name +msgid "It will be generated according to given parameters" +msgstr "Het zal worden gegenereerd door de gekozen parameters" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session___last_update +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session___last_update +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours___last_update +msgid "Last Modified on" +msgstr "Laatst gewijzigd op" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_write_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_write_uid +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_write_uid +msgid "Last Updated by" +msgstr "Laatst bijgewerkt door" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_write_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_write_date +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_write_date +msgid "Last Updated on" +msgstr "Laatst bijgewerkt op" + +#. module: event_session +#: selection:event.session,seats_availability:0 +msgid "Limited" +msgstr "Gelimiteerd" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_event_mail_ids +msgid "Mail Schedule" +msgstr "Mail planner" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_mail_template_id +msgid "Mail Schedule Template" +msgstr "Mail planner sjabloon" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_availability +msgid "Maximum Attendees" +msgstr "Maximaal aantal deelnemers" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_max +msgid "Maximum seats" +msgstr "Maximaal aantal plaatsen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_min +msgid "Minimum seats" +msgstr "Minimaal aantal plaatsen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_mondays +msgid "Mondays" +msgstr "Maandag" + +#. module: event_session +#: code:addons/event_session/models/event_session.py:232 +#, python-format +msgid "No more available seats for this session." +msgstr "Geen plaatsen meer beschikbaar voor deze sessie." + +#. module: event_session +#: code:addons/event_session/models/event.py:59 +#, python-format +msgid "No more seats available for this event." +msgstr "Er zijn geen plaatsen meer beschikbaar voor dit evenement." + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_expected +msgid "Number of Expected Attendees" +msgstr "Aantal verwachtte deelnemers" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_used +msgid "Number of Participants" +msgstr "Aantal deelnemers" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Origin" +msgstr "Bron" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Other options" +msgstr "Andere opties" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Partner" +msgstr "Relatie" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_mail_registration +msgid "Registration Mail Scheduler" +msgstr "Registratiemail planner" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "Registrations" +msgstr "Inschrijvingen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_reserved +msgid "Reserved Seats" +msgstr "Gereserveerde plaatsen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_saturdays +msgid "Saturdays" +msgstr "Zaterdag" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Schedule" +msgstr "Planning" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_seats_expected +msgid "Seats expected" +msgstr "Verwachte plaatsen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_mail_scheduler_template_session_id +#: model:ir.model.fields,field_description:event_session.field_event_mail_session_id +#: model:ir.model.fields,field_description:event_session.field_event_registration_session_id +#: model:ir.model.fields,field_description:event_session.field_event_session_name +#: model:ir.model.fields,field_description:event_session.field_report_event_registration_session_id +#: model:ir.ui.view,arch_db:event_session.view_event_session_calendar +#: model:ir.ui.view,arch_db:event_session.view_report_event_registration_search +#: model:ir.ui.view,arch_db:event_session.view_session_search +msgid "Session" +msgstr "Sessie" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_end +msgid "Session date end" +msgstr "Sessie einddatum" + +#. module: event_session +#: code:addons/event_session/models/event_session.py:243 +#, python-format +msgid "Session date is out of this event dates range" +msgstr "Sessiedatum is niet in hetzelfde bereik als de evenementdatum" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_name +msgid "Session info" +msgstr "Sessie info" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_begin +msgid "Session start date" +msgstr "Sessie begindatum" + +#. module: event_session +#: model:ir.actions.act_window,name:event_session.act_event_session_event_form +#: model:ir.actions.act_window,name:event_session.act_event_session_form +#: model:ir.model.fields,field_description:event_session.field_event_event_session_ids +#: model:ir.ui.menu,name:event_session.event_session_menu +#: model:ir.ui.view,arch_db:event_session.view_event_form +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Sessions" +msgstr "Sessies" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_form +msgid "Sessions availables for this event" +msgstr "Beschikbare sessies voor dit evenement" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_event_date_begin +msgid "Set it up in the event configurationSessions will be generated from this date" +msgstr "" +"Instellen in de evenement configuratie. Er worden sessies vanaf deze datum " +"gegenereerd" + +#. module: event_session +#: model:ir.model.fields,help:event_session.field_wizard_event_session_event_date_end +#: model:ir.model.fields,help:event_session.field_wizard_event_session_event_date_tz +msgid "Set it up in the event configurationSessions will be generated up to this date" +msgstr "" +"Instellen in de evenement configuratie. Er worden sessies vanaf deze datum " +"gegenereerd" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_date_begin +msgid "Start Date" +msgstr "Begindatum" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_begin_located +msgid "Start Date Located" +msgstr "Startdatum locatie" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_start_time +msgid "Start time" +msgstr "Begintijd" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_form +msgid "State" +msgstr "Status" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_sundays +msgid "Sundays" +msgstr "Zondag" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:86 +#: code:addons/event_session/wizards/wizard_event_session.py:91 +#, python-format +msgid "There are overlapping hours!" +msgstr "Er zijn overlappende uren!" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:204 +#, python-format +msgid "There are sessions with no duration!" +msgstr "Er zijn sessies zonder tijdsduur!" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_thursdays +msgid "Thursdays" +msgstr "Donderdag" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_date_tz +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_event_date_tz +msgid "Timezone" +msgstr "Tijdzone" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total available expected seats" +msgstr "Totaal aantal verwachte beschikbare plaatsen" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total available seats" +msgstr "Totaal aantal beschikbare plaatsen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_event_sessions_count +#: model:ir.model.fields,field_description:event_session.field_event_registration_event_sessions_count +msgid "Total event sessions" +msgstr "Totaal aantal evenementsessies" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats" +msgstr "Totaal aantal plaatsen" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats expected" +msgstr "Totaal aantal verwachte plaatsen" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats reserved" +msgstr "Totaal aantal gereserveerde plaatsen" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.view_event_session_tree +msgid "Total seats unconfirmed" +msgstr "Totaal aantal onbevestigde plaatsen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_tuesdays +msgid "Tuesdays" +msgstr "Dinsdag" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_event_session_seats_unconfirmed +msgid "Unconfirmed Seat Reservations" +msgstr "Onbevestigd gereserveerde plaatsen" + +#. module: event_session +#: selection:event.session,seats_availability:0 +msgid "Unlimited" +msgstr "Onbeperkt" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_wednesdays +msgid "Wednesdays" +msgstr "Woensdag" + +#. module: event_session +#: model:ir.ui.view,arch_db:event_session.generator_view_form +msgid "Weekdays" +msgstr "Weekdagen" + +#. module: event_session +#: model:ir.model.fields,field_description:event_session.field_wizard_event_session_hours_wizard_event_session_id +msgid "Wizard event session id" +msgstr "Wizard evenementensessie id" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:181 +#, python-format +msgid "You must select at least one weekday" +msgstr "U moet minstens één weekdag selecteren" + +#. module: event_session +#: code:addons/event_session/wizards/wizard_event_session.py:213 +#, python-format +msgid "You've entered invalid hours!" +msgstr "U heeft ongeldig uren ingevoerd!" + +#. module: event_session +#: model:ir.model,name:event_session.model_event_mail +msgid "event.mail" +msgstr "event.mail" + +#. module: event_session +#: model:ir.model,name:event_session.model_report_event_registration +msgid "report.event.registration" +msgstr "report.event.registration" + +#. module: event_session +#: model:ir.model,name:event_session.model_wizard_event_session +msgid "wizard.event.session" +msgstr "wizard.event.session" + +#. module: event_session +#: model:ir.model,name:event_session.model_wizard_event_session_hours +msgid "wizard.event.session.hours" +msgstr "wizard.event.session.hours" diff --git a/event_session/models/__init__.py b/event_session/models/__init__.py new file mode 100644 index 000000000..6640fada4 --- /dev/null +++ b/event_session/models/__init__.py @@ -0,0 +1,4 @@ +from . import event +from . import event_session +from . import event_mail +from . import res_config_settings diff --git a/event_session/models/event.py b/event_session/models/event.py new file mode 100644 index 000000000..80491e6d5 --- /dev/null +++ b/event_session/models/event.py @@ -0,0 +1,110 @@ +# Copyright 2017 David Vidal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError + + +class EventEvent(models.Model): + _inherit = 'event.event' + + session_ids = fields.One2many( + comodel_name='event.session', + inverse_name='event_id', + string='Sessions', + ) + sessions_count = fields.Integer( + compute='_compute_sessions_count', + string='Total event sessions', + store=True, + ) + seats_available_expected = fields.Integer( + compute='_compute_seats_available_expected', + string='Available expected seats', + readonly=True, + store=True, + ) + draft_state = fields.Integer( + compute='_compute_state_numbers', + string=' # No of Draft Registrations', + store=True, + ) + cancel_state = fields.Integer( + compute='_compute_state_numbers', + string=' # No of Cancelled Registrations', + store=True, + ) + confirm_state = fields.Integer( + compute='_compute_state_numbers', + string=' # No of Confirmed Registrations', + store=True, + ) + + @api.multi + @api.depends('session_ids') + def _compute_sessions_count(self): + for event in self: + event.sessions_count = len(event.session_ids) + + @api.multi + @api.constrains('seats_max', 'seats_available') + def _check_seats_limit(self): + for event in self: + if not event.session_ids: + return super(EventEvent, event)._check_seats_limit() + + @api.multi + @api.depends('seats_max', 'seats_expected') + def _compute_seats_available_expected(self): + for this in self: + seats = this.seats_max - this.seats_expected + this.seats_available_expected = seats + + @api.multi + @api.depends('registration_ids.state') + def _compute_state_numbers(self): + for this in self: + this.draft_state = len(this.registration_ids.filtered( + lambda x: x.state == 'draft' + )) + this.cancel_state = len(this.registration_ids.filtered( + lambda x: x.state == 'cancel' + )) + this.confirm_state = len(this.registration_ids.filtered( + lambda x: x.state == 'confirm' + )) + + +class EventRegistration(models.Model): + _inherit = 'event.registration' + + event_sessions_count = fields.Integer( + related='event_id.sessions_count', + readonly=True, + ) + session_id = fields.Many2one( + comodel_name='event.session', + string='Session', + ondelete='restrict', + ) + + @api.multi + @api.constrains('event_id', 'session_id', 'state') + def _check_seats_limit(self): + for registration in self.filtered('session_id'): + if (registration.session_id.seats_availability == 'limited' and + registration.session_id.seats_available < 1 and + registration.state == 'open'): + raise ValidationError( + _('No more seats available for this event.')) + + @api.multi + def confirm_registration(self): + for reg in self: + if not reg.event_id.session_ids: + super(EventRegistration, reg).confirm_registration() + reg.state = 'open' + onsubscribe_schedulers = \ + reg.session_id.event_mail_ids.filtered( + lambda s: s.interval_type == 'after_sub') + onsubscribe_schedulers.execute() diff --git a/event_session/models/event_mail.py b/event_session/models/event_mail.py new file mode 100644 index 000000000..3366e920b --- /dev/null +++ b/event_session/models/event_mail.py @@ -0,0 +1,108 @@ +# Copyright 2017 David Vidal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models +import logging + +_logger = logging.getLogger(__name__) + +try: + from odoo.addons.event.models.event_mail import _INTERVALS +except ImportError: + _logger.debug('Can not import events module.') + + +class EventMailScheduler(models.Model): + _inherit = 'event.mail' + + event_id = fields.Many2one( + required=False, + ) + session_id = fields.Many2one( + comodel_name='event.session', + string='Session', + ondelete='cascade', + ) + event_mail_template_id = fields.Many2one( + comodel_name='event.mail.template', + string='Event Mail Template', + ondelete='cascade', + ) + + @api.multi + @api.depends('mail_sent', 'interval_type', 'event_id.registration_ids', + 'mail_registration_ids') + def _compute_done(self): + super(EventMailScheduler, self)._compute_done() + for event_mail in self: + if (event_mail.session_id and + event_mail.interval_type not in + ['before_event', 'after_event']): + event_mail.done = ( + True if event_mail.event_id.sessions_count > 0 and + not event_mail.session_id else + len(event_mail.mail_registration_ids) == len( + event_mail.session_id.registration_ids) and + all(line.mail_sent for line in + event_mail.mail_registration_ids) + ) + + @api.multi + @api.depends('event_id.state', 'event_id.date_begin', 'interval_type', + 'interval_unit', 'interval_nbr') + def _compute_scheduled_date(self): + super(EventMailScheduler, self)._compute_scheduled_date() + for event_mail in self: + if not event_mail.session_id: + continue + if event_mail.event_id.state not in ['confirm', 'done']: + event_mail.scheduled_date = False + else: + if event_mail.interval_type == 'after_sub': + date, sign = event_mail.session_id.create_date, 1 + elif event_mail.interval_type == 'before_event': + date, sign = event_mail.session_id.date_begin, -1 + else: + date, sign = event_mail.session_id.date_end, 1 + event_mail.scheduled_date = ( + fields.Datetime.from_string(date) + _INTERVALS[ + event_mail.interval_unit + ](sign * event_mail.interval_nbr) + ) + + +class EventMailRegistration(models.Model): + _inherit = 'event.mail.registration' + + @api.multi + @api.depends('registration_id', 'scheduler_id.interval_unit', + 'scheduler_id.interval_type') + def _compute_scheduled_date(self): + super(EventMailRegistration, self)._compute_scheduled_date() + for event_mail_reg in self: + if (event_mail_reg.registration_id and + event_mail_reg.registration_id.session_id): + date_open = event_mail_reg.registration_id.date_open + date_open_datetime = date_open and fields.Datetime.from_string( + date_open) or fields.datetime.now() + event_mail_reg.scheduled_date = ( + date_open_datetime + + _INTERVALS[event_mail_reg.scheduler_id.interval_unit]( + event_mail_reg.scheduler_id.interval_nbr)) + + +class EventMailTemplate(models.Model): + _name = 'event.mail.template' + + @api.model + def _default_scheduler_template_ids(self): + return self.env['event.type'].with_context( + by_pass_config_template=True)._get_default_event_type_mail_ids() + + name = fields.Char() + scheduler_template_ids = fields.One2many( + comodel_name='event.mail', + inverse_name='event_mail_template_id', + string='Mail Schedule', + default=_default_scheduler_template_ids, + ) diff --git a/event_session/models/event_session.py b/event_session/models/event_session.py new file mode 100644 index 000000000..f997005c0 --- /dev/null +++ b/event_session/models/event_session.py @@ -0,0 +1,278 @@ +# Copyright 2017 David Vidal +# Copyright 2017 Tecnativa - Pedro M. Baeza +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError +from locale import setlocale, LC_ALL + + +class EventSession(models.Model): + _name = 'event.session' + _description = 'Event session' + + name = fields.Char( + string='Session', required=True, compute="_compute_name", store=True, + default='/', + ) + active = fields.Boolean( + default=True, + ) + company_id = fields.Many2one( + comodel_name='res.company', + related='event_id.company_id', + store=True, + ) + event_id = fields.Many2one( + comodel_name='event.event', + string='Event', + ) + seats_min = fields.Integer( + string='Minimum seats', + ) + seats_max = fields.Integer( + string="Maximum seats", + ) + seats_availability = fields.Selection( + [('limited', 'Limited'), ('unlimited', 'Unlimited')], + 'Maximum Attendees', required=True, default='unlimited', + ) + seats_reserved = fields.Integer( + string='Reserved Seats', store=True, readonly=True, + compute='_compute_seats', + ) + seats_available = fields.Integer( + oldname='register_avail', string='Available Seats', + store=True, readonly=True, compute='_compute_seats') + seats_unconfirmed = fields.Integer( + oldname='register_prospect', string='Unconfirmed Seat Reservations', + store=True, readonly=True, compute='_compute_seats') + seats_used = fields.Integer( + oldname='register_attended', string='Number of Participants', + store=True, readonly=True, compute='_compute_seats') + seats_expected = fields.Integer( + string='Number of Expected Attendees', + readonly=True, compute='_compute_seats', + store=True) + seats_available_expected = fields.Integer( + string='Available Expected Seats', + readonly=True, compute='_compute_seats', + store=True) + seats_available_pc = fields.Float( + string='Full %', + readonly=True, + compute='_compute_seats', + ) + date_tz = fields.Selection( + string='Timezone', related="event_id.date_tz", + ) + date_begin = fields.Datetime( + string="Session start date", + required=True, + default=lambda self: self.event_id.date_begin, + ) + date_end = fields.Datetime( + string="Session date end", + required=True, + default=lambda self: self.event_id.date_end, + ) + date_begin_located = fields.Datetime( + string='Start Date Located', compute='_compute_date_begin_located', + ) + date_end_located = fields.Datetime( + string='End Date Located', compute='_compute_date_end_located', + ) + registration_ids = fields.One2many( + comodel_name='event.registration', + inverse_name='session_id', + string='Attendees', + state={'done': [('readonly', True)]}, + ) + event_mail_ids = fields.One2many( + comodel_name='event.mail', + inverse_name='session_id', + string='Mail Schedule', + copy=True + ) + + @api.multi + @api.depends('date_begin', 'date_end') + def _compute_name(self): + setlocale(LC_ALL, locale=(self.env.lang, 'UTF-8')) + for session in self: + if not (session.date_begin and session.date_end): + session.name = '/' + continue + date_begin = fields.Datetime.from_string( + session.date_begin_located) + date_end = fields.Datetime.from_string(session.date_end_located) + dt_format = '%A %d/%m/%y %H:%M' + name = date_begin.strftime(dt_format) + if date_begin.date() == date_end.date(): + dt_format = '%H:%M' + name += " - " + date_end.strftime(dt_format) + session.name = name.capitalize() + + def _session_mails_from_template(self, event_id, mail_template=None): + vals = [(6, 0, [])] + if not mail_template: + mail_template = self.env['ir.default'].get( + 'res.config.settings', 'event_mail_template_id') + if not mail_template: + # Not template scheduler defined in event settings + return vals + if isinstance(mail_template, int): + mail_template = self.env['event.mail.template'].browse( + mail_template) + for scheduler in mail_template.scheduler_template_ids: + vals.append((0, 0, { + 'event_id': event_id, + 'interval_nbr': scheduler.interval_nbr, + 'interval_unit': scheduler.interval_unit, + 'interval_type': scheduler.interval_type, + 'template_id': scheduler.template_id.id, + })) + return vals + + @api.multi + def name_get(self): + """Redefine the name_get method to show the event name with the event + session. + """ + res = [] + for item in self: + res.append((item.id, "[%s] %s" % (item.event_id.name, item.name))) + return res + + @api.model + def create(self, vals): + # Config availabilities based on event + if vals.get('event_id', False): + event = self.env['event.event'].browse(vals.get('event_id')) + vals['seats_availability'] = event.seats_availability + vals['seats_max'] = event.seats_max + if not vals.get('event_mail_ids', False): + vals.update({ + 'event_mail_ids': + self._session_mails_from_template(vals['event_id']) + }) + return super(EventSession, self).create(vals) + + @api.multi + def unlink(self): + for this in self: + if this.registration_ids: + raise ValidationError(_("You are trying to delete one or more \ + sessions with active registrations")) + return super(EventSession, self).unlink() + + @api.multi + @api.depends('seats_max', 'registration_ids.state') + def _compute_seats(self): + """Determine reserved, available, reserved but unconfirmed and used + seats by session. + """ + # aggregate registrations by event session and by state + if len(self.ids) > 0: + state_field = { + 'draft': 'seats_unconfirmed', + 'open': 'seats_reserved', + 'done': 'seats_used', + } + result = self.env['event.registration'].read_group([ + ('session_id', 'in', self.ids), + ('state', 'in', ['draft', 'open', 'done']) + ], ['state', 'session_id'], ['session_id', 'state'], lazy=False) + for res in result: + session = self.browse(res['session_id'][0]) + session[state_field[res['state']]] += res['__count'] + # compute seats_available + for session in self: + if session.seats_max > 0: + session.seats_available = session.seats_max - ( + session.seats_reserved + session.seats_used) + session.seats_expected = ( + session.seats_unconfirmed + session.seats_reserved + + session.seats_used) + session.seats_available_expected = ( + session.seats_max - session.seats_expected) + if session.seats_max > 0: + session.seats_available_pc = ( + session.seats_expected * 100 / float(session.seats_max)) + + @api.multi + @api.depends('date_tz', 'date_begin') + def _compute_date_begin_located(self): + for session in self.filtered('date_begin'): + self_in_tz = session.with_context( + tz=(session.date_tz or 'UTC') + ) + date_begin = fields.Datetime.from_string(session.date_begin) + session.date_begin_located = fields.Datetime.to_string( + fields.Datetime.context_timestamp(self_in_tz, date_begin), + ) + + @api.multi + @api.depends('date_tz', 'date_end') + def _compute_date_end_located(self): + for session in self.filtered('date_end'): + self_in_tz = session.with_context( + tz=(session.date_tz or 'UTC') + ) + date_end = fields.Datetime.from_string(session.date_end) + session.date_end_located = fields.Datetime.to_string( + fields.Datetime.context_timestamp(self_in_tz, date_end), + ) + + @api.onchange('event_id') + def onchange_event_id(self): + self.update({ + 'seats_min': self.event_id.seats_min, + 'seats_max': self.event_id.seats_max, + 'seats_availability': self.event_id.seats_availability, + 'date_begin': self.event_id.date_begin, + 'date_end': self.event_id.date_end, + }) + + @api.multi + @api.constrains('seats_max', 'seats_available') + def _check_seats_limit(self): + for session in self: + if (session.seats_availability == 'limited' and + session.seats_max and session.seats_available < 0): + raise ValidationError( + _('No more available seats for this session.')) + + @api.multi + @api.constrains('date_begin', 'date_end') + def _check_dates(self): + for session in self: + if (self.event_id.date_end < session.date_begin or + session.date_begin < self.event_id.date_begin or + self.event_id.date_begin > session.date_end or + session.date_end > self.event_id.date_end): + raise ValidationError( + _("Session date is out of this event dates range") + ) + + @api.multi + @api.constrains('date_begin', 'date_end') + def _check_zero_duration(self): + for session in self: + if session.date_begin == session.date_end: + raise ValidationError( + _("Ending and starting time can't be the same!") + ) + + @api.multi + def button_open_registration(self): + """Opens session registrations""" + self.ensure_one() + action = self.env.ref( + 'event.act_event_registration_from_event').read()[0] + action['domain'] = [('id', 'in', self.registration_ids.ids)] + action['context'] = { + 'default_event_id': self.event_id.id, + 'default_session_id': self.id, + } + return action diff --git a/event_session/models/res_config_settings.py b/event_session/models/res_config_settings.py new file mode 100644 index 000000000..79c360ab3 --- /dev/null +++ b/event_session/models/res_config_settings.py @@ -0,0 +1,20 @@ +# Copyright 2016 Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + event_mail_template_id = fields.Many2one( + comodel_name='event.mail', + string='Mail Template', + ) + + @api.multi + def set_default_event_mail_template_id(self): + self.env['ir.default'].set( + 'res.config.settings', 'event_mail_template_id', + self.event_mail_template_id.id + ) diff --git a/event_session/security/event_session_security.xml b/event_session/security/event_session_security.xml new file mode 100644 index 000000000..bb25bc6fa --- /dev/null +++ b/event_session/security/event_session_security.xml @@ -0,0 +1,11 @@ + + + + + Event Session: multi-company + + + ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id]),] + + + diff --git a/event_session/security/ir.model.access.csv b/event_session/security/ir.model.access.csv new file mode 100644 index 000000000..9ec0f59eb --- /dev/null +++ b/event_session/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_event_session_user,event.session.user,event_session.model_event_session,event.group_event_user,1,0,0,0 +access_event_session_admin,event.session.admin,event_session.model_event_session,event.group_event_manager,1,1,1,1 +access_event_mail_template,access_event_mail_template,model_event_mail_template,base.group_user,1,0,0,0 diff --git a/event_session/tests/__init__.py b/event_session/tests/__init__.py new file mode 100644 index 000000000..b24bf22b9 --- /dev/null +++ b/event_session/tests/__init__.py @@ -0,0 +1 @@ +from . import test_session diff --git a/event_session/tests/test_session.py b/event_session/tests/test_session.py new file mode 100644 index 000000000..315c124f0 --- /dev/null +++ b/event_session/tests/test_session.py @@ -0,0 +1,249 @@ +# Copyright 2017 Tecnativa - David Vidal +# Copyright 2017 Tecnativa - Pedro M. Baeza +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0). +from dateutil.relativedelta import relativedelta + +from odoo import _, fields +from odoo.tests import common +from odoo.exceptions import ValidationError + + +class EventSession(common.SavepointCase): + + @classmethod + def setUpClass(cls): + super(EventSession, cls).setUpClass() + cls.event = cls.env['event.event'].create({ + 'name': 'Test event', + 'date_begin': '2017-05-26 20:00:00', + 'date_end': '2017-05-30 22:00:00', + 'seats_availability': 'limited', + 'seats_max': '5', + 'seats_min': '1', + }) + cls.session = cls.env['event.session'].create({ + 'date_begin': '2017-05-26 20:00:00', + 'date_end': '2017-05-26 22:00:00', + 'event_id': cls.event.id, + 'seats_availability': cls.event.seats_availability, + 'seats_max': cls.event.seats_max, + 'seats_min': cls.event.seats_min, + }) + cls.attendee = cls.env['event.registration'].create({ + 'name': 'Test attendee', + 'event_id': cls.event.id, + 'session_id': cls.session.id, + }) + cls.wizard = cls.env['wizard.event.session'].create({ + 'event_id': cls.event.id, + 'mondays': True, + 'tuesdays': True, + 'wednesdays': True, + 'thursdays': False, + 'fridays': True, + 'sundays': True, + 'saturdays': True, + 'delete_existing_sessions': False, + 'session_hour_ids': [ + (0, 0, {'start_time': 20.0, 'end_time': 21.0}), + ], + }) + cls.template = cls.env['event.mail.template'].create({ + 'name': 'Template test 01', + 'scheduler_template_ids': [(0, 0, { + 'interval_nbr': 15, + 'interval_unit': 'days', + 'interval_type': 'before_event', + 'template_id': cls.env.ref('event.event_reminder').id})], + }) + cls.scheduler = cls.env['event.mail'].create({ + 'event_id': cls.event.id, + 'session_id': cls.session.id, + 'interval_type': 'after_sub', + 'template_id': cls.template.id, + }) + cls.mail_registration = cls.env['event.mail.registration'].create({ + 'scheduler_id': cls.scheduler.id, + 'registration_id': cls.attendee.id, + }) + + def test_session_name_get(self): + self.assertEqual( + self.session.name_get()[0][1], '[Test event] ' + self.session.name, + ) + + def test_check_beginning_date(self): + self.session.date_begin = '2017-05-26 20:00:00' + with self.assertRaises(ValidationError): + self.session.date_begin = '2017-05-26 19:59:59' + with self.assertRaises(ValidationError): + self.session.date_end = '2017-05-30 22:00:01' + + def test_check_end_date(self): + self.session.date_end = '2017-05-30 22:00:00' + with self.assertRaises(ValidationError): + self.session.date_end = '2017-05-30 22:00:01' + with self.assertRaises(ValidationError): + self.session.date_end = '2017-05-26 19:59:59' + + def test_check_zero_duration(self): + with self.assertRaises(ValidationError), self.cr.savepoint(): + self.session.write({ + 'date_begin': '2017-05-28 22:00:00', + 'date_end': '2017-05-28 22:00:00', + }) + + def test_open_registrations(self): + # registrations button + res = self.session.button_open_registration() + attendees = self.env['event.registration'].search([ + ['session_id', '=', self.session.id] + ]) + self.assertEqual(res['domain'], [('id', 'in', attendees.ids)]) + + def test_assign_mail_template(self): + vals = ({ + 'event_mail_ids': + self.session._session_mails_from_template(self.event.id) + }) + self.session.write(vals) + self.assertEqual(len(self.session.event_mail_ids), 0) + vals = ({ + 'event_mail_ids': + self.session._session_mails_from_template(self.event.id, + self.template) + }) + self.session.write(vals) + self.assertEqual(len(self.session.event_mail_ids), 1) + + def test_session_seats(self): + """ Session seat """ + self.assertEqual( + self.event.seats_available, + self.session.seats_available) + self.assertEqual( + self.event.seats_unconfirmed, + self.session.seats_unconfirmed + ) + self.assertEqual( + self.event.seats_used, + self.session.seats_used + ) + with self.assertRaises(ValidationError), self.cr.savepoint(): + # check limit regs + for i in range(int(self.session.seats_available)+1): + self.env['event.registration'].create({ + 'name': 'Test Attendee', + 'event_id': self.event.id, + 'session_id': self.session.id, + 'state': 'open', + }) + + def test_compute_name(self): + vals = { + 'date_begin': '2017-05-28 22:00:00', + 'date_end': '2017-05-28 23:00:00', + } + session = self.env['event.session'].new(vals) + self.assertEqual(session.name, 'Sunday 28/05/17 22:00 - 23:00') + session.date_begin = session.date_end = False + self.assertEqual(session.name, '/') + + def test_wizard(self): + """Test Session Generation Wizard""" + self.event.date_end = '2017-06-11 23:59:59' + self.event.date_begin = '2017-06-05 00:00:00' + self.wizard.delete_existing_session = True + self.wizard.action_generate_sessions() + # delete previous sessions + self.wizard.update({'delete_existing_sessions': True}) + self.wizard.update({'event_mail_template_id': self.template}) + with self.assertRaises(ValidationError) as error, self.cr.savepoint(): + self.wizard.action_generate_sessions() + self.assertEqual(error, _("You are trying to delete one or more \ + sessions with active registrations")) + self.attendee.session_id = False + self.wizard.action_generate_sessions() + sessions = self.env['event.session'].search([ + ['event_id', '=', self.event.id] + ]) + self.assertEqual(len(sessions), 6) + for session in sessions: + self.assertTrue(session.event_mail_ids) + self.assertEqual(session.seats_max, self.event.seats_max) + self.assertEqual(session.seats_availability, + self.event.seats_availability) + with self.assertRaises(ValidationError), self.cr.savepoint(): + # session duration = 0 + self.wizard.update({'session_hour_ids': [ + (0, 0, {'start_time': 20.0, 'end_time': 20.0}), + ], + }) + with self.assertRaises(ValidationError), self.cr.savepoint(): + # hour invalidity + self.wizard.update({'session_hour_ids': [ + (0, 0, {'start_time': 24.0, 'end_time': 24.1}), + ], + }) + with self.assertRaises(ValidationError), self.cr.savepoint(): + # schedules overlap + self.wizard.update({'session_hour_ids': [ + (0, 0, {'start_time': 20.0, 'end_time': 21.0}), + (0, 0, {'start_time': 20.5, 'end_time': 21.5}), + ], + }) + with self.assertRaises(ValidationError), self.cr.savepoint(): + self.wizard.update({'session_hour_ids': [ + (0, 0, {'start_time': 20.0, 'end_time': 21.0}), + (0, 0, {'start_time': 19.5, 'end_time': 21.5}), + ], + }) + with self.assertRaises(ValidationError), self.cr.savepoint(): + # weekday not set + self.wizard.update({ + 'mondays': False, + 'tuesdays': False, + 'wednesdays': False, + 'thursdays': False, + 'fridays': False, + 'sundays': False, + 'saturdays': False, + }) + self.wizard.action_generate_sessions() + + def test_event_mail_compute_scheduled_date(self): + self.assertFalse(self.scheduler.scheduled_date) + self.scheduler.event_id.update({'state': 'confirm'}) + date = fields.Datetime.from_string( + self.scheduler.session_id.create_date + ) + relativedelta(hours=+1) + self.assertEqual( + self.scheduler.scheduled_date, + fields.Datetime.to_string(date) + ) + self.scheduler.update({'interval_type': 'before_event'}) + date = fields.Datetime.from_string( + self.scheduler.session_id.date_begin + ) + relativedelta(hours=-1) + self.assertEqual( + self.scheduler.scheduled_date, + fields.Datetime.to_string(date) + ) + self.scheduler.update({'interval_type': 'after_event'}) + date = fields.Datetime.from_string( + self.scheduler.session_id.date_end + ) + relativedelta(hours=+1) + self.assertEqual( + self.scheduler.scheduled_date, + fields.Datetime.to_string(date) + ) + + def test_event_mail_registration_compute_scheduled_date(self): + self.scheduler.update({'interval_unit': 'days'}) + date = fields.Datetime.from_string( + self.mail_registration.registration_id.date_open + ) + relativedelta(days=+1) + self.assertEqual( + self.mail_registration.scheduled_date, + fields.Datetime.to_string(date) + ) diff --git a/event_session/views/event_session_view.xml b/event_session/views/event_session_view.xml new file mode 100644 index 000000000..6a7c87ac2 --- /dev/null +++ b/event_session/views/event_session_view.xml @@ -0,0 +1,160 @@ + + + + + event.session.search + event.session + + + + + + + + + + + + + event.session.form + event.session + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + event.session.tree + event.session + + + + + + + + + + + + + + + + + + + + event.session.calendar + event.session + + + + + + + + + + event.session.pivot + event.session + + + + + + + + + + + + event.session + form + Sessions + tree,form,calendar,pivot + + + + + +
diff --git a/event_session/views/event_view.xml b/event_session/views/event_view.xml new file mode 100644 index 000000000..39add992e --- /dev/null +++ b/event_session/views/event_view.xml @@ -0,0 +1,70 @@ + + + + + event.registration + + + + + + + + + + + event.registration + + + + + + + + + + + event.session + form + Sessions + tree,form,calendar + {'search_default_event_id': active_id, 'default_event_id': active_id} + + + + event.event + + + + + + + {'readonly':[('sessions_count', '<', 1)]} + + + + + + + + + event.event + + + + + + + + diff --git a/event_session/wizards/__init__.py b/event_session/wizards/__init__.py new file mode 100644 index 000000000..5a6bb71ae --- /dev/null +++ b/event_session/wizards/__init__.py @@ -0,0 +1 @@ +from . import wizard_event_session diff --git a/event_session/wizards/wizard_event_session.py b/event_session/wizards/wizard_event_session.py new file mode 100644 index 000000000..312145c44 --- /dev/null +++ b/event_session/wizards/wizard_event_session.py @@ -0,0 +1,209 @@ +# Copyright 2017 David Vidal +# Copyright 2017 Tecnativa - Pedro M. Baeza +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError +from datetime import datetime, timedelta +from pytz import timezone, utc + + +class WizardEventSession(models.TransientModel): + _name = "wizard.event.session" + + name = fields.Char( + "Session info", + required=True, + help="It will be generated according to given parameters", + default='/', + ) + event_id = fields.Many2one( + comodel_name="event.event", readonly=True, on_delete="cascade", + default=lambda self: self.env.context["active_id"], required=True, + ) + event_date_begin = fields.Datetime( + related="event_id.date_begin", + readonly=True, + help="Set it up in the event configuration" + "Sessions will be generated from this date", + ) + event_date_end = fields.Datetime( + related="event_id.date_end", + readonly=True, + help="Set it up in the event configuration" + "Sessions will be generated up to this date", + ) + event_date_tz = fields.Selection( + related="event_id.date_tz", + readonly=True, + help="Set it up in the event configuration" + "Sessions will be generated up to this date", + ) + mondays = fields.Boolean( + help="Create sessions on Mondays", + ) + tuesdays = fields.Boolean( + help="Create sessions on Tuesdays", + ) + wednesdays = fields.Boolean( + help="Create sessions on Wednesdays", + ) + thursdays = fields.Boolean( + help="Create sessions on Thursdays", + ) + fridays = fields.Boolean( + help="Create sessions on Fridays", + ) + saturdays = fields.Boolean( + help="Create sessions on Saturdays", + ) + sundays = fields.Boolean( + help="Create sessions on Sundays", + ) + delete_existing_sessions = fields.Boolean( + default=True, + help="Check in order to delete every previous session for this event" + ) + session_hour_ids = fields.One2many( + comodel_name='wizard.event.session.hours', + inverse_name='wizard_event_session_id', + string='Hours', + ) + event_mail_template_id = fields.Many2one( + comodel_name='event.mail.template', + string='Mail Schedule Template', + ) + + @api.multi + @api.constrains('session_hour_ids') + def _avoid_overlapping_hours(self): + for hour_a in self.session_hour_ids: + for hour_b in self.session_hour_ids: + if hour_a != hour_b: + if hour_a.start_time == hour_b.start_time: + raise ValidationError( + _("There are overlapping hours!") + ) + elif hour_b.start_time < \ + hour_a.start_time < hour_b.end_time: + raise ValidationError( + _("There are overlapping hours!") + ) + + @api.multi + def weekdays(self): + """Generate a tuple with the values for accessing days by index.""" + return ( + self.mondays, + self.tuesdays, + self.wednesdays, + self.thursdays, + self.fridays, + self.saturdays, + self.sundays, + ) + + @api.multi + def existing_sessions(self, date): + """Return existing sessions that match some criteria.""" + # Todo: Improve match + return self.env["event.session"].search( + [("event_id", "=", self.event_id.id), + ("date_begin", "=", date), + ("start_time", "=", self.start_time)], + ) + + def _prepare_session_values(self, date_begin, date_end): + vals = { + "event_id": self.event_id.id, + "date_begin": fields.Datetime.to_string(date_begin), + "date_end": fields.Datetime.to_string(date_end), + } + mail_template = ( + self.event_mail_template_id or + self.env['ir.default'].get( + 'res.config.settings', 'event_mail_template_id')) + if mail_template: + template_values = \ + self.env['event.session']._session_mails_from_template( + self.event_id.id, mail_template) + vals['event_mail_ids'] = template_values + return vals + + @api.multi + def generate_sessions(self): + self.ensure_one() + session_obj = self.env["event.session"] + event_start = utc.localize( + fields.Datetime.from_string(self.event_date_begin) + ) + event_end = utc.localize( + fields.Datetime.from_string(self.event_date_end) + ) + weekdays = self.weekdays() + current = event_start + current = current.replace(hour=event_end.hour, minute=event_end.minute) + while current <= event_end: + if not weekdays[current.weekday()]: + current += timedelta(days=1) + continue + for hour in self.session_hour_ids: + start_time = datetime.min + timedelta(hours=hour.start_time) + end_time = datetime.min + timedelta(hours=hour.end_time) + current_start = datetime.combine( + current.date(), start_time.time(), + ) + current_end = datetime.combine(current.date(), end_time.time()) + # Convert to UTC from user TZ + local_tz = timezone(self.env.user.tz) + current_start = local_tz.localize(current_start) + current_start = current_start.astimezone(utc) + current_end = local_tz.localize(current_end) + current_end = current_end.astimezone(utc) + if current_start < event_start or current_end > event_end: + continue + # TODO: Check that no session exists with this data + session_obj.create( + self._prepare_session_values(current_start, current_end) + ) + current += timedelta(days=1) + + @api.multi + def action_generate_sessions(self): + """Here's where magic is triggered""" + weekdays = self.weekdays() + if not any(weekdays): + raise ValidationError(_("You must select at least one weekday")) + if self.delete_existing_sessions: + self.event_id.session_ids.unlink() + self.generate_sessions() + + +class WizardEventSessionHours(models.TransientModel): + _name = "wizard.event.session.hours" + + wizard_event_session_id = fields.Many2one( + comodel_name='wizard.event.session' + ) + start_time = fields.Float(required=True) + end_time = fields.Float(required=True) + + # Todo: manage multiday sessions + + @api.multi + @api.constrains('start_time', 'end_time') + def _check_zero_duration(self): + for hour in self: + if hour.start_time == hour.end_time: + raise ValidationError( + _("There are sessions with no duration!") + ) + + @api.multi + @api.constrains('start_time', 'end_time') + def _check_hour_validity(self): + for hour in self: + if hour.start_time > 23.99 or hour.end_time > 23.99: + raise ValidationError( + _("You've entered invalid hours!") + ) diff --git a/event_session/wizards/wizard_event_session_view.xml b/event_session/wizards/wizard_event_session_view.xml new file mode 100644 index 000000000..4a48085e3 --- /dev/null +++ b/event_session/wizards/wizard_event_session_view.xml @@ -0,0 +1,73 @@ + + + + + + Generate Sessions Wizard + wizard.event.session + form + form + new + + + + event.event + + + +