From dbcbd84a24bfe48dd294b7b0f4732a2d0f8a603a Mon Sep 17 00:00:00 2001
From: Jairo Llopis
Date: Fri, 5 Feb 2021 16:42:03 +0000
Subject: [PATCH 1/5] [ADD] event_sale_reservation: sell events before they
exist
This module extends the functionality of event_sale to support selling
reservations of events that still don't exist and to allow you to schedule the
creation of events based on how many reservations already exist.
Includes integration workaround to avoid test conflicts with
`event_sale_registration_multi_qty`.
@Tecnativa TT27664
[UPD] Update event_sale_reservation.pot
[UPD] README.rst
---
event_sale_reservation/README.rst | 164 ++++++
event_sale_reservation/__init__.py | 3 +
event_sale_reservation/__manifest__.py | 31 ++
event_sale_reservation/exceptions.py | 12 +
event_sale_reservation/i18n/es.po | 218 ++++++++
.../i18n/event_sale_reservation.pot | 201 +++++++
event_sale_reservation/models/__init__.py | 4 +
event_sale_reservation/models/event_type.py | 61 +++
.../models/product_template.py | 47 ++
event_sale_reservation/models/sale_order.py | 52 ++
.../models/sale_order_line.py | 32 ++
event_sale_reservation/readme/CONFIGURE.rst | 5 +
.../readme/CONTRIBUTORS.rst | 1 +
event_sale_reservation/readme/DESCRIPTION.rst | 3 +
event_sale_reservation/readme/INSTALL.rst | 4 +
event_sale_reservation/readme/USAGE.rst | 60 +++
event_sale_reservation/reports/__init__.py | 1 +
event_sale_reservation/reports/sale_report.py | 25 +
.../reports/sale_report_view.xml | 15 +
.../static/description/icon.png | Bin 0 -> 9455 bytes
.../static/description/index.html | 501 ++++++++++++++++++
event_sale_reservation/tests/__init__.py | 1 +
.../tests/test_event_sale.py | 175 ++++++
.../views/event_type_view.xml | 39 ++
.../views/product_template_view.xml | 23 +
.../views/sale_order_view.xml | 29 +
event_sale_reservation/wizards/__init__.py | 2 +
.../wizards/registration_editor.py | 71 +++
.../wizards/registration_editor_line.py | 13 +
.../wizards/registration_editor_view.xml | 52 ++
30 files changed, 1845 insertions(+)
create mode 100644 event_sale_reservation/README.rst
create mode 100644 event_sale_reservation/__init__.py
create mode 100644 event_sale_reservation/__manifest__.py
create mode 100644 event_sale_reservation/exceptions.py
create mode 100644 event_sale_reservation/i18n/es.po
create mode 100644 event_sale_reservation/i18n/event_sale_reservation.pot
create mode 100644 event_sale_reservation/models/__init__.py
create mode 100644 event_sale_reservation/models/event_type.py
create mode 100644 event_sale_reservation/models/product_template.py
create mode 100644 event_sale_reservation/models/sale_order.py
create mode 100644 event_sale_reservation/models/sale_order_line.py
create mode 100644 event_sale_reservation/readme/CONFIGURE.rst
create mode 100644 event_sale_reservation/readme/CONTRIBUTORS.rst
create mode 100644 event_sale_reservation/readme/DESCRIPTION.rst
create mode 100644 event_sale_reservation/readme/INSTALL.rst
create mode 100644 event_sale_reservation/readme/USAGE.rst
create mode 100644 event_sale_reservation/reports/__init__.py
create mode 100644 event_sale_reservation/reports/sale_report.py
create mode 100644 event_sale_reservation/reports/sale_report_view.xml
create mode 100644 event_sale_reservation/static/description/icon.png
create mode 100644 event_sale_reservation/static/description/index.html
create mode 100644 event_sale_reservation/tests/__init__.py
create mode 100644 event_sale_reservation/tests/test_event_sale.py
create mode 100644 event_sale_reservation/views/event_type_view.xml
create mode 100644 event_sale_reservation/views/product_template_view.xml
create mode 100644 event_sale_reservation/views/sale_order_view.xml
create mode 100644 event_sale_reservation/wizards/__init__.py
create mode 100644 event_sale_reservation/wizards/registration_editor.py
create mode 100644 event_sale_reservation/wizards/registration_editor_line.py
create mode 100644 event_sale_reservation/wizards/registration_editor_view.xml
diff --git a/event_sale_reservation/README.rst b/event_sale_reservation/README.rst
new file mode 100644
index 000000000..aa2af80e1
--- /dev/null
+++ b/event_sale_reservation/README.rst
@@ -0,0 +1,164 @@
+=======================
+Sell event reservations
+=======================
+
+.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! This file is generated by oca-gen-addon-readme !!
+ !! changes will be overwritten. !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
+ :target: https://odoo-community.org/page/development-status
+ :alt: Beta
+.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fevent-lightgray.png?logo=github
+ :target: https://github.com/OCA/event/tree/12.0/event_sale_reservation
+ :alt: OCA/event
+.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
+ :target: https://translation.odoo-community.org/projects/event-12-0/event-12-0-event_sale_reservation
+ :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
+ :target: https://runbot.odoo-community.org/runbot/199/12.0
+ :alt: Try me on Runbot
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
+
+This module extends the functionality of event_sale to support selling
+reservations of events that still don't exist and to allow you to schedule the
+creation of events based on how many reservations already exist.
+
+**Table of contents**
+
+.. contents::
+ :local:
+
+Installation
+============
+
+To install this module, you need to:
+
+#. Install ``web_ir_actions_act_multi`` from https://github.com/OCA/web
+#. Install ``web_ir_actions_act_view_reload`` from https://github.com/OCA/web
+
+Configuration
+=============
+
+
+To make use of this module, a user needs these minimal permissions:
+
+- Sales / User: Own Documents Only
+- Events / User
+
+Usage
+=====
+
+To know how many reservations exist for a given event type:
+
+#. Go to *Events > Configuration > Event Categories* and pick or create one.
+#. There's a new smart button called *Reserved seats* with that count.
+#. Click on it to get to the sales orders where the seats got reserved.
+
+But that counter will be probably zero when you install, so let's see how to
+increase it.
+
+To create an event reservation product:
+
+#. Go to *Sales > Products > Products*.
+#. Create one.
+#. Set its basic info (name, price...) and go to *Sales* tab.
+#. Under *Events*, tick *Is an event reservation*.
+#. Select one *Event type for reservations*.
+#. Save.
+
+From now on, you can sell event reservations for that event type. To do it:
+
+#. Go to *Sales > Orders > Quotations*.
+#. Create one.
+#. Set its basic info (customer, date...) and go to *Order lines* tab.
+#. Click *Add a product*.
+#. Select the event reservation product you created above.
+#. Set its info (quantity, price...).
+#. Save that line and the quotation.
+
+At this point, the reservation is not yet confirmed, so if you go to the event
+type, the smart button will still count zero.
+
+To confirm those reservations:
+
+#. Go to the quotation you just created (if you are not there yet).
+#. Click on *Confirm*.
+
+Now, if you go to the event type form, the smart button will indicate how many
+reserved seats exist.
+
+If you want to convert those reservations into real event registrations:
+
+#. Go to the quotation you just created (if you are not there yet).
+#. Click on *Register in event*.
+#. In the wizard you see, set the *Event* and *Event Ticket* for all the order
+ lines you want to convert into registrations.
+#. If there is any line you still don't want to convert, remove it from the
+ wizard.
+#. Click on *Next*.
+#. A new wizard will appear, where you will be able to specify the name, email
+ and phone of each one of the attendees. If you don't do it, they will get
+ that info from the sales order customer.
+#. After that's done, click on *Apply*.
+
+At this point, the sales order lines will be modified to include the ticket
+product instead of the reservation product, and the event reservations have
+been created, linked to those lines.
+
+If the ticket was free, the registrations are confirmed. Otherwise, they are
+kept as draft until an invoice is created for the sales order, and paid. But
+that is just upstream ``event_sale`` module in action.
+
+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 smashing it by providing a detailed and welcomed
+`feedback `_.
+
+Do not contact contributors directly about support or help with technical issues.
+
+Credits
+=======
+
+Authors
+~~~~~~~
+
+* Tecnativa
+
+Contributors
+~~~~~~~~~~~~
+
+* Jairo Llopis (https://www.tecnativa.com/)
+
+Maintainers
+~~~~~~~~~~~
+
+This module is maintained by the OCA.
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+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.
+
+.. |maintainer-Yajo| image:: https://github.com/Yajo.png?size=40px
+ :target: https://github.com/Yajo
+ :alt: Yajo
+
+Current `maintainer `__:
+
+|maintainer-Yajo|
+
+This module is part of the `OCA/event `_ project on GitHub.
+
+You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/event_sale_reservation/__init__.py b/event_sale_reservation/__init__.py
new file mode 100644
index 000000000..8d855c85d
--- /dev/null
+++ b/event_sale_reservation/__init__.py
@@ -0,0 +1,3 @@
+from . import models
+from . import reports
+from . import wizards
diff --git a/event_sale_reservation/__manifest__.py b/event_sale_reservation/__manifest__.py
new file mode 100644
index 000000000..dc33056ea
--- /dev/null
+++ b/event_sale_reservation/__manifest__.py
@@ -0,0 +1,31 @@
+# Copyright 2021 Tecnativa - Jairo Llopis
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+{
+ "name": "Sell event reservations",
+ "summary": "Allow selling event registrations before the event exists",
+ "version": "12.0.1.0.0",
+ "development_status": "Beta",
+ "category": "Marketing",
+ "website": "https://github.com/OCA/event",
+ "author": "Tecnativa, Odoo Community Association (OCA)",
+ "maintainers": ["Yajo"],
+ "license": "AGPL-3",
+ "application": False,
+ "installable": True,
+ "depends": [
+ "event_sale",
+ "web_ir_actions_act_multi",
+ "web_ir_actions_act_view_reload",
+ ],
+ "data": [
+ "reports/sale_report_view.xml",
+ "wizards/registration_editor_view.xml",
+ "views/event_type_view.xml",
+ "views/product_template_view.xml",
+ "views/sale_order_view.xml",
+ ],
+ # These modules makes totals wrong because they depend currently on count
+ # and not sum of qtys; integrating with them would require a glue module
+ "excludes": ["event_registration_multi_qty", "event_sale_registration_multi_qty"],
+}
diff --git a/event_sale_reservation/exceptions.py b/event_sale_reservation/exceptions.py
new file mode 100644
index 000000000..582465cd2
--- /dev/null
+++ b/event_sale_reservation/exceptions.py
@@ -0,0 +1,12 @@
+# Copyright 2021 Tecnativa - Jairo Llopis
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import exceptions
+
+
+class TicketAndReservationError(exceptions.ValidationError):
+ pass
+
+
+class ReservationWithoutEventTypeError(exceptions.ValidationError):
+ pass
diff --git a/event_sale_reservation/i18n/es.po b/event_sale_reservation/i18n/es.po
new file mode 100644
index 000000000..d8829a93f
--- /dev/null
+++ b/event_sale_reservation/i18n/es.po
@@ -0,0 +1,218 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * event_sale_reservation
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-05 16:33+0000\n"
+"PO-Revision-Date: 2021-02-05 16:37+0000\n"
+"Last-Translator: Jairo Llopis \n"
+"Language-Team: \n"
+"Language: es_ES\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.4.2\n"
+
+#. module: event_sale_reservation
+#: model:ir.actions.act_window,name:event_sale_reservation.act_event_registration_from_so
+msgid "Attendees"
+msgstr "Asistentes"
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Cancel"
+msgstr "Cancelar"
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Configure registrations"
+msgstr "Configurar registros"
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Convert pending event reservations into registrations for"
+msgstr "Convertir las reservas a eventos que estén pendientes de"
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_sale_order_line__event_registration_count
+msgid "Count of event registrations related to this sale order line"
+msgstr ""
+"Cuenta de registros a eventos relacionados con esta línea de pedido de venta"
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_registration_editor
+msgid "Edit Attendee Details on Sales Confirmation"
+msgstr "Editar detalles del asistente al confirmar la venta"
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_registration_editor_line
+msgid "Edit Attendee Line on Sales Confirmation"
+msgstr "Editar la línea del asistente al confirmar la venta"
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_event_type
+msgid "Event Category"
+msgstr "Categoría de eventos"
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_order_line__event_registration_count
+msgid "Event Registration Count"
+msgstr "Cuenta de registros a eventos"
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.view_order_product_search
+msgid "Event Reservation Type"
+msgstr "Categoría de evento de la reserva"
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_order__event_registration_count
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_order_line__event_registration_ids
+msgid "Event registrations"
+msgstr "Registros a eventos"
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_sale_order_line__event_registration_ids
+msgid "Event registrations related to this sale order line"
+msgstr "Registros a eventos relacionados con esta línea de pedido de venta"
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_report__event_reservation_type_id
+msgid "Event reservation type"
+msgstr "Categoría de evento de reserva"
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_product_product__event_reservation_type_id
+#: model:ir.model.fields,field_description:event_sale_reservation.field_product_template__event_reservation_type_id
+#: model:ir.model.fields,field_description:event_sale_reservation.field_registration_editor_line__event_reservation_type_id
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_order_line__event_reservation_type_id
+msgid "Event type for reservations"
+msgstr "Categoría de evento para las reservas"
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_product_product__event_reservation_ok
+#: model:ir.model.fields,help:event_sale_reservation.field_product_template__event_reservation_ok
+msgid ""
+"If checked, this product enables selling event reservations even before an "
+"event of the specified type has been scheduled."
+msgstr ""
+"Si se activa, este producto permite vender reservas a eventos incluso antes "
+"de que un evento de la categoría especificada se haya programado."
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid ""
+"If there is any line from that order that you still do\n"
+" not want to convert into real event registrations, "
+"you\n"
+" can remove it from the list below. You will be able "
+"to\n"
+" repeat this process later for those lines."
+msgstr ""
+"Si hay alguna línea de ese pedido que todavía\n"
+" no desee convertir en registros de evento reales,\n"
+" puede borrarla de la lista abajo. Podrá\n"
+" repetir este proceso más adelante para esas líneas."
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_sale_order__event_registration_count
+msgid "Indicates how many event registrations are linked to this order."
+msgstr ""
+"Indica cuántas reservas a eventos están vinculadas a este pedido de venta."
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_sale_order__event_reservations_pending
+msgid ""
+"Indicates how many event reservations are still not linked to any "
+"registration."
+msgstr ""
+"Indica cuántas reservas a eventos todavía no están vinculadas a ningún "
+"registro."
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_product_product__event_reservation_ok
+#: model:ir.model.fields,field_description:event_sale_reservation.field_product_template__event_reservation_ok
+msgid "Is an event reservation"
+msgstr "Es una reserva de evento"
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Next"
+msgstr "Siguiente"
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_order__event_reservations_pending
+msgid "Pending event reservations"
+msgstr "Reservas pendientes a eventos"
+
+#. module: event_sale_reservation
+#: code:addons/event_sale_reservation/models/product_template.py:38
+#, python-format
+msgid ""
+"Product %(name)s cannot be both an event ticket and an event reservation."
+msgstr ""
+"El producto %(name)s no puede ser al mismo tiempo un ticket y una reserva de "
+"eventos."
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_product_template
+msgid "Product Template"
+msgstr "Plantilla de producto"
+
+#. module: event_sale_reservation
+#: model:ir.actions.act_window,name:event_sale_reservation.action_registration_editor_reservations
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.view_sale_order_form_inherit_event
+msgid "Register in event"
+msgstr "Registrar en evento"
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Register reservations"
+msgstr "Registrar reservas"
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Registrations"
+msgstr "Registros"
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_event_type__seats_reservation_total
+msgid "Reserved seats"
+msgstr "Plazas reservadas"
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_sale_order
+msgid "Sale Order"
+msgstr "Pedido de venta"
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_sale_report
+msgid "Sales Analysis Report"
+msgstr "Informe de análisis de ventas"
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_sale_order_line
+msgid "Sales Order Line"
+msgstr "Línea de pedido de venta"
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_event_type__seats_reservation_total
+msgid "Seats reserved for events of this type."
+msgstr "Plazas reservadas para eventos de esta categoría."
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_product_product__event_reservation_type_id
+#: model:ir.model.fields,help:event_sale_reservation.field_product_template__event_reservation_type_id
+#: model:ir.model.fields,help:event_sale_reservation.field_registration_editor_line__event_reservation_type_id
+#: model:ir.model.fields,help:event_sale_reservation.field_sale_order_line__event_reservation_type_id
+msgid "Type of events that can be reserved by buying this product"
+msgstr "Categoría de eventos que se pueden reservar al comprar este producto"
+
+#. module: event_sale_reservation
+#: code:addons/event_sale_reservation/models/product_template.py:46
+#, python-format
+msgid "You must indicate event type for %(name)s."
+msgstr "Debe indicar la categoría de evento para %(name)s."
diff --git a/event_sale_reservation/i18n/event_sale_reservation.pot b/event_sale_reservation/i18n/event_sale_reservation.pot
new file mode 100644
index 000000000..2ac4cdcf7
--- /dev/null
+++ b/event_sale_reservation/i18n/event_sale_reservation.pot
@@ -0,0 +1,201 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * event_sale_reservation
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.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_sale_reservation
+#: code:addons/event_sale_reservation/models/sale_order.py:47
+#, python-format
+msgid "Attendees"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Cancel"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Configure registrations"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Convert pending event reservations into registrations for"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_sale_order_line__event_registration_count
+msgid "Count of event registrations related to this sale order line"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_registration_editor
+msgid "Edit Attendee Details on Sales Confirmation"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_registration_editor_line
+msgid "Edit Attendee Line on Sales Confirmation"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_event_type
+msgid "Event Category"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_order_line__event_registration_count
+msgid "Event Registration Count"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.view_order_product_search
+msgid "Event Reservation Type"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_order__event_registration_count
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_order_line__event_registration_ids
+msgid "Event registrations"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_sale_order_line__event_registration_ids
+msgid "Event registrations related to this sale order line"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_report__event_reservation_type_id
+msgid "Event reservation type"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_product_product__event_reservation_type_id
+#: model:ir.model.fields,field_description:event_sale_reservation.field_product_template__event_reservation_type_id
+#: model:ir.model.fields,field_description:event_sale_reservation.field_registration_editor_line__event_reservation_type_id
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_order_line__event_reservation_type_id
+msgid "Event type for reservations"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_product_product__event_reservation_ok
+#: model:ir.model.fields,help:event_sale_reservation.field_product_template__event_reservation_ok
+msgid "If checked, this product enables selling event reservations even before an event of the specified type has been scheduled."
+msgstr ""
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "If there is any line from that order that you still do\n"
+" not want to convert into real event registrations, you\n"
+" can remove it from the list below. You will be able to\n"
+" repeat this process later for those lines."
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_sale_order__event_registration_count
+msgid "Indicates how many event registrations are linked to this order."
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_sale_order__event_reservations_pending
+msgid "Indicates how many event reservations are still not linked to any registration."
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_product_product__event_reservation_ok
+#: model:ir.model.fields,field_description:event_sale_reservation.field_product_template__event_reservation_ok
+msgid "Is an event reservation"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Next"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_sale_order__event_reservations_pending
+msgid "Pending event reservations"
+msgstr ""
+
+#. module: event_sale_reservation
+#: code:addons/event_sale_reservation/models/product_template.py:38
+#, python-format
+msgid "Product %(name)s cannot be both an event ticket and an event reservation."
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_product_template
+msgid "Product Template"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.actions.act_window,name:event_sale_reservation.action_registration_editor_reservations
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.view_sale_order_form_inherit_event
+msgid "Register in event"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Register reservations"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
+msgid "Registrations"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_event_type__reserved_sale_order_line_ids
+msgid "Reserved sale order lines"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,field_description:event_sale_reservation.field_event_type__seats_reservation_total
+msgid "Reserved seats"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_sale_order
+msgid "Sale Order"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_sale_report
+msgid "Sales Analysis Report"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model,name:event_sale_reservation.model_sale_order_line
+msgid "Sales Order Line"
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_event_type__seats_reservation_total
+msgid "Seats reserved for events of this type."
+msgstr ""
+
+#. module: event_sale_reservation
+#: model:ir.model.fields,help:event_sale_reservation.field_product_product__event_reservation_type_id
+#: model:ir.model.fields,help:event_sale_reservation.field_product_template__event_reservation_type_id
+#: model:ir.model.fields,help:event_sale_reservation.field_registration_editor_line__event_reservation_type_id
+#: model:ir.model.fields,help:event_sale_reservation.field_sale_order_line__event_reservation_type_id
+msgid "Type of events that can be reserved by buying this product"
+msgstr ""
+
+#. module: event_sale_reservation
+#: code:addons/event_sale_reservation/models/product_template.py:46
+#, python-format
+msgid "You must indicate event type for %(name)s."
+msgstr ""
+
diff --git a/event_sale_reservation/models/__init__.py b/event_sale_reservation/models/__init__.py
new file mode 100644
index 000000000..f3fcd22cf
--- /dev/null
+++ b/event_sale_reservation/models/__init__.py
@@ -0,0 +1,4 @@
+from . import event_type
+from . import product_template
+from . import sale_order
+from . import sale_order_line
diff --git a/event_sale_reservation/models/event_type.py b/event_sale_reservation/models/event_type.py
new file mode 100644
index 000000000..6f8f713a0
--- /dev/null
+++ b/event_sale_reservation/models/event_type.py
@@ -0,0 +1,61 @@
+# Copyright 2021 Tecnativa - Jairo Llopis
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import api, fields, models
+
+
+class EventType(models.Model):
+ _inherit = "event.type"
+
+ reserved_sale_order_line_ids = fields.One2many(
+ string="Reserved sale order lines",
+ comodel_name="sale.order.line",
+ inverse_name="event_reservation_type_id",
+ )
+ seats_reservation_total = fields.Integer(
+ string="Reserved seats",
+ compute="_compute_reservations_total",
+ store=True,
+ help="Seats reserved for events of this type.",
+ )
+
+ def _seats_reservation_domain(self):
+ """Domain to select sale.order.line with pending reservations."""
+ return [
+ ("event_reservation_type_id", "in", self.ids),
+ ("order_id.state", "in", ("sale", "done")),
+ ("product_id.event_reservation_ok", "=", True),
+ ]
+
+ @api.depends(
+ "reserved_sale_order_line_ids.event_registration_count",
+ "reserved_sale_order_line_ids.event_reservation_type_id",
+ "reserved_sale_order_line_ids.order_id.state",
+ "reserved_sale_order_line_ids.product_id.event_reservation_ok",
+ "reserved_sale_order_line_ids.product_uom_qty",
+ )
+ def _compute_reservations_total(self):
+ """Get how many reserved seats exist."""
+ results = self.env["sale.order.line"].read_group(
+ domain=self._seats_reservation_domain(),
+ fields=["event_registration_count", "product_uom_qty"],
+ groupby="event_reservation_type_id",
+ )
+ totals = {group["event_reservation_type_id"][0]: group for group in results}
+ for one in self:
+ totals_item = totals.get(one.id, {})
+ one.seats_reservation_total = totals_item.get(
+ "product_uom_qty", 0
+ ) - totals_item.get("event_registration_count", 0)
+
+ def action_open_sale_orders(self):
+ """Display SO that include reservations."""
+ sol = self.env["sale.order.line"].search(
+ self._seats_reservation_domain(),
+ )
+ result = self.env["ir.actions.act_window"].for_xml_id(
+ "sale",
+ "action_orders",
+ )
+ result["domain"] = [("order_line", "in", sol.ids)]
+ return result
diff --git a/event_sale_reservation/models/product_template.py b/event_sale_reservation/models/product_template.py
new file mode 100644
index 000000000..fbf3c8405
--- /dev/null
+++ b/event_sale_reservation/models/product_template.py
@@ -0,0 +1,47 @@
+# Copyright 2021 Tecnativa - Jairo Llopis
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import _, api, fields, models
+from ..exceptions import TicketAndReservationError, ReservationWithoutEventTypeError
+
+
+class Product(models.Model):
+ _inherit = "product.template"
+
+ event_reservation_ok = fields.Boolean(
+ index=True,
+ string="Is an event reservation",
+ help=(
+ "If checked, this product enables selling event reservations "
+ "even before an event of the specified type has been scheduled."
+ ),
+ )
+ event_reservation_type_id = fields.Many2one(
+ comodel_name="event.type",
+ index=True,
+ string="Event type for reservations",
+ help="Type of events that can be reserved by buying this product",
+ )
+
+ @api.constrains("event_ok", "event_reservation_ok")
+ def _check_event_reservation(self):
+ """Event reservation products checks.
+
+ - A product cannot be both an event ticket and an event reservation.
+ - An event reservation must have an event type attached.
+ """
+ for one in self:
+ if not one.event_reservation_ok:
+ continue
+ if one.event_ok:
+ raise TicketAndReservationError(
+ _(
+ "Product %(name)s cannot be both an event ticket and "
+ "an event reservation."
+ )
+ % {"name": one.display_name}
+ )
+ if not one.event_reservation_type_id:
+ raise ReservationWithoutEventTypeError(
+ _("You must indicate event type for %(name)s.")
+ )
diff --git a/event_sale_reservation/models/sale_order.py b/event_sale_reservation/models/sale_order.py
new file mode 100644
index 000000000..f11acad77
--- /dev/null
+++ b/event_sale_reservation/models/sale_order.py
@@ -0,0 +1,52 @@
+# Copyright 2021 Tecnativa - Jairo Llopis
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import _, api, fields, models
+
+
+class SaleOrder(models.Model):
+ _inherit = "sale.order"
+
+ event_reservations_pending = fields.Integer(
+ compute="_compute_event_reservations_pending",
+ string="Pending event reservations",
+ help=(
+ "Indicates how many event reservations are still not linked to "
+ "any registration."
+ ),
+ )
+ event_registration_count = fields.Integer(
+ compute="_compute_event_registration_count",
+ string="Event registrations",
+ help=("Indicates how many event registrations are linked to this order."),
+ )
+
+ @api.depends("order_line.product_uom_qty", "order_line.event_registration_count")
+ def _compute_event_reservations_pending(self):
+ """Know how many pending event reservations are linked to this SO."""
+ for one in self:
+ reservation_lines = one.order_line.filtered(
+ "product_id.event_reservation_ok"
+ )
+ reserved = sum(reservation_lines.mapped("product_uom_qty"))
+ registered = sum(reservation_lines.mapped("event_registration_count"))
+ one.event_reservations_pending = reserved - registered
+
+ @api.depends("order_line.event_registration_ids")
+ def _compute_event_registration_count(self):
+ """Get registrations per SO."""
+ for one in self:
+ one.event_registration_count = len(
+ one.mapped("order_line.event_registration_ids")
+ )
+
+ def action_open_event_registrations(self):
+ """Redirect user to event registrations related to this SO."""
+ return {
+ "domain": [("sale_order_id", "in", self.ids)],
+ "name": _("Attendees"),
+ "res_model": "event.registration",
+ "type": "ir.actions.act_window",
+ "view_mode": "tree,form,calendar,graph",
+ "view_type": "form",
+ }
diff --git a/event_sale_reservation/models/sale_order_line.py b/event_sale_reservation/models/sale_order_line.py
new file mode 100644
index 000000000..62900e892
--- /dev/null
+++ b/event_sale_reservation/models/sale_order_line.py
@@ -0,0 +1,32 @@
+# Copyright 2021 Tecnativa - Jairo Llopis
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import api, fields, models
+
+
+class SaleOrderLine(models.Model):
+ _inherit = "sale.order.line"
+
+ event_registration_ids = fields.One2many(
+ comodel_name="event.registration",
+ inverse_name="sale_order_line_id",
+ string="Event registrations",
+ help="Event registrations related to this sale order line",
+ )
+ event_registration_count = fields.Integer(
+ compute="_compute_event_registration_count",
+ store=True,
+ help="Count of event registrations related to this sale order line",
+ )
+ event_reservation_type_id = fields.Many2one(
+ index=True,
+ readonly=True,
+ related="product_id.event_reservation_type_id",
+ store=True,
+ )
+
+ @api.depends("event_registration_ids")
+ def _compute_event_registration_count(self):
+ """Get count of related event registrations."""
+ for one in self:
+ one.event_registration_count = len(one.event_registration_ids)
diff --git a/event_sale_reservation/readme/CONFIGURE.rst b/event_sale_reservation/readme/CONFIGURE.rst
new file mode 100644
index 000000000..e6f8effa4
--- /dev/null
+++ b/event_sale_reservation/readme/CONFIGURE.rst
@@ -0,0 +1,5 @@
+
+To make use of this module, a user needs these minimal permissions:
+
+- Sales / User: Own Documents Only
+- Events / User
diff --git a/event_sale_reservation/readme/CONTRIBUTORS.rst b/event_sale_reservation/readme/CONTRIBUTORS.rst
new file mode 100644
index 000000000..7ee45dc9b
--- /dev/null
+++ b/event_sale_reservation/readme/CONTRIBUTORS.rst
@@ -0,0 +1 @@
+* Jairo Llopis (https://www.tecnativa.com/)
diff --git a/event_sale_reservation/readme/DESCRIPTION.rst b/event_sale_reservation/readme/DESCRIPTION.rst
new file mode 100644
index 000000000..95aced0ec
--- /dev/null
+++ b/event_sale_reservation/readme/DESCRIPTION.rst
@@ -0,0 +1,3 @@
+This module extends the functionality of event_sale to support selling
+reservations of events that still don't exist and to allow you to schedule the
+creation of events based on how many reservations already exist.
diff --git a/event_sale_reservation/readme/INSTALL.rst b/event_sale_reservation/readme/INSTALL.rst
new file mode 100644
index 000000000..8870fa25c
--- /dev/null
+++ b/event_sale_reservation/readme/INSTALL.rst
@@ -0,0 +1,4 @@
+To install this module, you need to:
+
+#. Install ``web_ir_actions_act_multi`` from https://github.com/OCA/web
+#. Install ``web_ir_actions_act_view_reload`` from https://github.com/OCA/web
diff --git a/event_sale_reservation/readme/USAGE.rst b/event_sale_reservation/readme/USAGE.rst
new file mode 100644
index 000000000..34a87759b
--- /dev/null
+++ b/event_sale_reservation/readme/USAGE.rst
@@ -0,0 +1,60 @@
+To know how many reservations exist for a given event type:
+
+#. Go to *Events > Configuration > Event Categories* and pick or create one.
+#. There's a new smart button called *Reserved seats* with that count.
+#. Click on it to get to the sales orders where the seats got reserved.
+
+But that counter will be probably zero when you install, so let's see how to
+increase it.
+
+To create an event reservation product:
+
+#. Go to *Sales > Products > Products*.
+#. Create one.
+#. Set its basic info (name, price...) and go to *Sales* tab.
+#. Under *Events*, tick *Is an event reservation*.
+#. Select one *Event type for reservations*.
+#. Save.
+
+From now on, you can sell event reservations for that event type. To do it:
+
+#. Go to *Sales > Orders > Quotations*.
+#. Create one.
+#. Set its basic info (customer, date...) and go to *Order lines* tab.
+#. Click *Add a product*.
+#. Select the event reservation product you created above.
+#. Set its info (quantity, price...).
+#. Save that line and the quotation.
+
+At this point, the reservation is not yet confirmed, so if you go to the event
+type, the smart button will still count zero.
+
+To confirm those reservations:
+
+#. Go to the quotation you just created (if you are not there yet).
+#. Click on *Confirm*.
+
+Now, if you go to the event type form, the smart button will indicate how many
+reserved seats exist.
+
+If you want to convert those reservations into real event registrations:
+
+#. Go to the quotation you just created (if you are not there yet).
+#. Click on *Register in event*.
+#. In the wizard you see, set the *Event* and *Event Ticket* for all the order
+ lines you want to convert into registrations.
+#. If there is any line you still don't want to convert, remove it from the
+ wizard.
+#. Click on *Next*.
+#. A new wizard will appear, where you will be able to specify the name, email
+ and phone of each one of the attendees. If you don't do it, they will get
+ that info from the sales order customer.
+#. After that's done, click on *Apply*.
+
+At this point, the sales order lines will be modified to include the ticket
+product instead of the reservation product, and the event reservations have
+been created, linked to those lines.
+
+If the ticket was free, the registrations are confirmed. Otherwise, they are
+kept as draft until an invoice is created for the sales order, and paid. But
+that is just upstream ``event_sale`` module in action.
diff --git a/event_sale_reservation/reports/__init__.py b/event_sale_reservation/reports/__init__.py
new file mode 100644
index 000000000..cd23411b8
--- /dev/null
+++ b/event_sale_reservation/reports/__init__.py
@@ -0,0 +1 @@
+from . import sale_report
diff --git a/event_sale_reservation/reports/sale_report.py b/event_sale_reservation/reports/sale_report.py
new file mode 100644
index 000000000..38c3302d2
--- /dev/null
+++ b/event_sale_reservation/reports/sale_report.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Tecnativa - Jairo Llopis
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import fields, models
+from odoo.tools import frozendict
+
+
+class SaleReport(models.Model):
+ _inherit = "sale.report"
+
+ event_reservation_type_id = fields.Many2one(
+ comodel_name="event.type",
+ readonly=True,
+ string="Event reservation type",
+ )
+
+ def _query(self, with_clause="", fields=frozendict(), groupby="", from_clause=""):
+ fields = dict(
+ fields,
+ event_reservation_type_id="""
+ , t.event_reservation_type_id as event_reservation_type_id
+ """,
+ )
+ groupby += ", t.event_reservation_type_id"
+ return super()._query(with_clause, fields, groupby, from_clause)
diff --git a/event_sale_reservation/reports/sale_report_view.xml b/event_sale_reservation/reports/sale_report_view.xml
new file mode 100644
index 000000000..f97d9b3d8
--- /dev/null
+++ b/event_sale_reservation/reports/sale_report_view.xml
@@ -0,0 +1,15 @@
+
+
+
+
+ Event type search
+ sale.report
+
+
+
+
+
+
+
+
diff --git a/event_sale_reservation/static/description/icon.png b/event_sale_reservation/static/description/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d
GIT binary patch
literal 9455
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
z
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
Xviia!U7SGha1wx#SCgwmn*{w2TRX*I
literal 0
HcmV?d00001
diff --git a/event_sale_reservation/static/description/index.html b/event_sale_reservation/static/description/index.html
new file mode 100644
index 000000000..061419662
--- /dev/null
+++ b/event_sale_reservation/static/description/index.html
@@ -0,0 +1,501 @@
+
+
+
+
+
+
+Sell event reservations
+
+
+
+
+
Sell event reservations
+
+
+
+
This module extends the functionality of event_sale to support selling
+reservations of events that still don’t exist and to allow you to schedule the
+creation of events based on how many reservations already exist.
To know how many reservations exist for a given event type:
+
+
Go to Events > Configuration > Event Categories and pick or create one.
+
There’s a new smart button called Reserved seats with that count.
+
Click on it to get to the sales orders where the seats got reserved.
+
+
But that counter will be probably zero when you install, so let’s see how to
+increase it.
+
To create an event reservation product:
+
+
Go to Sales > Products > Products.
+
Create one.
+
Set its basic info (name, price…) and go to Sales tab.
+
Under Events, tick Is an event reservation.
+
Select one Event type for reservations.
+
Save.
+
+
From now on, you can sell event reservations for that event type. To do it:
+
+
Go to Sales > Orders > Quotations.
+
Create one.
+
Set its basic info (customer, date…) and go to Order lines tab.
+
Click Add a product.
+
Select the event reservation product you created above.
+
Set its info (quantity, price…).
+
Save that line and the quotation.
+
+
At this point, the reservation is not yet confirmed, so if you go to the event
+type, the smart button will still count zero.
+
To confirm those reservations:
+
+
Go to the quotation you just created (if you are not there yet).
+
Click on Confirm.
+
+
Now, if you go to the event type form, the smart button will indicate how many
+reserved seats exist.
+
If you want to convert those reservations into real event registrations:
+
+
Go to the quotation you just created (if you are not there yet).
+
Click on Register in event.
+
In the wizard you see, set the Event and Event Ticket for all the order
+lines you want to convert into registrations.
+
If there is any line you still don’t want to convert, remove it from the
+wizard.
+
Click on Next.
+
A new wizard will appear, where you will be able to specify the name, email
+and phone of each one of the attendees. If you don’t do it, they will get
+that info from the sales order customer.
+
After that’s done, click on Apply.
+
+
At this point, the sales order lines will be modified to include the ticket
+product instead of the reservation product, and the event reservations have
+been created, linked to those lines.
+
If the ticket was free, the registrations are confirmed. Otherwise, they are
+kept as draft until an invoice is created for the sales order, and paid. But
+that is just upstream event_sale module in action.
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 smashing it by providing a detailed and welcomed
+feedback.
+
Do not contact contributors directly about support or help with technical issues.
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.
-
-
+
-
diff --git a/event_sale_reservation/wizards/registration_editor.py b/event_sale_reservation/wizards/registration_editor.py
index e79e379c4..44d3e5de0 100644
--- a/event_sale_reservation/wizards/registration_editor.py
+++ b/event_sale_reservation/wizards/registration_editor.py
@@ -23,8 +23,7 @@ def default_get(self, fields):
0,
{
"sale_order_line_id": sol.id,
- "event_reservation_type_id":
- sol.event_reservation_type_id.id,
+ "event_reservation_type_id": sol.event_reservation_type_id.id,
},
)
]
@@ -64,8 +63,5 @@ def action_make_registration(self):
result = super().action_make_registration()
return {
"type": "ir.actions.act_multi",
- "actions": [
- result,
- {"type": "ir.actions.act_view_reload"},
- ],
+ "actions": [result, {"type": "ir.actions.act_view_reload"},],
}
diff --git a/event_sale_reservation/wizards/registration_editor_line.py b/event_sale_reservation/wizards/registration_editor_line.py
index b661fc28e..47cae677c 100644
--- a/event_sale_reservation/wizards/registration_editor_line.py
+++ b/event_sale_reservation/wizards/registration_editor_line.py
@@ -8,6 +8,5 @@ class RegistrationEditorLine(models.TransientModel):
_inherit = "registration.editor.line"
event_reservation_type_id = fields.Many2one(
- related="sale_order_line_id.event_reservation_type_id",
- readonly=True,
+ related="sale_order_line_id.event_reservation_type_id", readonly=True,
)
diff --git a/event_sale_reservation/wizards/registration_editor_view.xml b/event_sale_reservation/wizards/registration_editor_view.xml
index d3223c4ea..408f491e9 100644
--- a/event_sale_reservation/wizards/registration_editor_view.xml
+++ b/event_sale_reservation/wizards/registration_editor_view.xml
@@ -1,9 +1,7 @@
-
+
-
-
Convert reservation into registrations
@@ -24,20 +22,33 @@
-
-
-
-
+
+
+
+
-
Register in eventir.actions.act_window
@@ -48,5 +59,4 @@
new{'registering_reservations': True}
-
From d1a6a3718097c1b1979e2b8fc1aefe248b3ba855 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?=
Date: Tue, 25 Jan 2022 13:18:50 +0100
Subject: [PATCH 3/5] [MIG] event_sale_reservation: Migration to 13.0 TT31321
[UPD] Update event_sale_reservation.pot
[UPD] README.rst
---
event_sale_reservation/README.rst | 21 +++++++---
event_sale_reservation/__manifest__.py | 5 +--
.../i18n/event_sale_reservation.pot | 35 +++++++++--------
event_sale_reservation/models/event_type.py | 2 +-
event_sale_reservation/models/sale_order.py | 1 -
.../readme/CONTRIBUTORS.rst | 4 +-
event_sale_reservation/readme/ROADMAP.rst | 3 ++
event_sale_reservation/reports/sale_report.py | 22 ++++++-----
.../static/description/index.html | 38 ++++++++++++-------
.../views/sale_order_view.xml | 2 +-
.../wizards/registration_editor.py | 16 ++++++--
.../wizards/registration_editor_view.xml | 1 -
12 files changed, 93 insertions(+), 57 deletions(-)
create mode 100644 event_sale_reservation/readme/ROADMAP.rst
diff --git a/event_sale_reservation/README.rst b/event_sale_reservation/README.rst
index aa2af80e1..f9686f7b0 100644
--- a/event_sale_reservation/README.rst
+++ b/event_sale_reservation/README.rst
@@ -14,13 +14,13 @@ Sell event reservations
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fevent-lightgray.png?logo=github
- :target: https://github.com/OCA/event/tree/12.0/event_sale_reservation
+ :target: https://github.com/OCA/event/tree/13.0/event_sale_reservation
:alt: OCA/event
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/event-12-0/event-12-0-event_sale_reservation
+ :target: https://translation.odoo-community.org/projects/event-13-0/event-13-0-event_sale_reservation
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/199/12.0
+ :target: https://runbot.odoo-community.org/runbot/199/13.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -115,13 +115,20 @@ If the ticket was free, the registrations are confirmed. Otherwise, they are
kept as draft until an invoice is created for the sales order, and paid. But
that is just upstream ``event_sale`` module in action.
+Known issues / Roadmap
+======================
+
+Some addons (event_registration_multi_qty + event_sale_registration_multi_qty)
+makes totals wrong because they depend currently on count and not sum of qtys;
+integrating with them would require a glue module.
+
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 smashing it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -136,7 +143,9 @@ Authors
Contributors
~~~~~~~~~~~~
-* Jairo Llopis (https://www.tecnativa.com/)
+* `Tecnativa `_:
+
+ * Jairo Llopis
Maintainers
~~~~~~~~~~~
@@ -159,6 +168,6 @@ Current `maintainer `__:
|maintainer-Yajo|
-This module is part of the `OCA/event `_ project on GitHub.
+This module is part of the `OCA/event `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/event_sale_reservation/__manifest__.py b/event_sale_reservation/__manifest__.py
index dc33056ea..c1d6603c3 100644
--- a/event_sale_reservation/__manifest__.py
+++ b/event_sale_reservation/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Sell event reservations",
"summary": "Allow selling event registrations before the event exists",
- "version": "12.0.1.0.0",
+ "version": "13.0.1.0.0",
"development_status": "Beta",
"category": "Marketing",
"website": "https://github.com/OCA/event",
@@ -25,7 +25,4 @@
"views/product_template_view.xml",
"views/sale_order_view.xml",
],
- # These modules makes totals wrong because they depend currently on count
- # and not sum of qtys; integrating with them would require a glue module
- "excludes": ["event_registration_multi_qty", "event_sale_registration_multi_qty"],
}
diff --git a/event_sale_reservation/i18n/event_sale_reservation.pot b/event_sale_reservation/i18n/event_sale_reservation.pot
index 2ac4cdcf7..9c318db3b 100644
--- a/event_sale_reservation/i18n/event_sale_reservation.pot
+++ b/event_sale_reservation/i18n/event_sale_reservation.pot
@@ -1,12 +1,12 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
-# * event_sale_reservation
+# * event_sale_reservation
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 12.0\n"
+"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
-"Last-Translator: <>\n"
+"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -14,7 +14,7 @@ msgstr ""
"Plural-Forms: \n"
#. module: event_sale_reservation
-#: code:addons/event_sale_reservation/models/sale_order.py:47
+#: code:addons/event_sale_reservation/models/sale_order.py:0
#, python-format
msgid "Attendees"
msgstr ""
@@ -91,12 +91,15 @@ msgstr ""
#. module: event_sale_reservation
#: model:ir.model.fields,help:event_sale_reservation.field_product_product__event_reservation_ok
#: model:ir.model.fields,help:event_sale_reservation.field_product_template__event_reservation_ok
-msgid "If checked, this product enables selling event reservations even before an event of the specified type has been scheduled."
+msgid ""
+"If checked, this product enables selling event reservations even before an "
+"event of the specified type has been scheduled."
msgstr ""
#. module: event_sale_reservation
#: model_terms:ir.ui.view,arch_db:event_sale_reservation.registration_editor_reservations_view_form
-msgid "If there is any line from that order that you still do\n"
+msgid ""
+"If there is any line from that order that you still do\n"
" not want to convert into real event registrations, you\n"
" can remove it from the list below. You will be able to\n"
" repeat this process later for those lines."
@@ -109,7 +112,9 @@ msgstr ""
#. module: event_sale_reservation
#: model:ir.model.fields,help:event_sale_reservation.field_sale_order__event_reservations_pending
-msgid "Indicates how many event reservations are still not linked to any registration."
+msgid ""
+"Indicates how many event reservations are still not linked to any "
+"registration."
msgstr ""
#. module: event_sale_reservation
@@ -129,9 +134,10 @@ msgid "Pending event reservations"
msgstr ""
#. module: event_sale_reservation
-#: code:addons/event_sale_reservation/models/product_template.py:38
+#: code:addons/event_sale_reservation/models/product_template.py:0
#, python-format
-msgid "Product %(name)s cannot be both an event ticket and an event reservation."
+msgid ""
+"Product %(name)s cannot be both an event ticket and an event reservation."
msgstr ""
#. module: event_sale_reservation
@@ -166,13 +172,13 @@ msgid "Reserved seats"
msgstr ""
#. module: event_sale_reservation
-#: model:ir.model,name:event_sale_reservation.model_sale_order
-msgid "Sale Order"
+#: model:ir.model,name:event_sale_reservation.model_sale_report
+msgid "Sales Analysis Report"
msgstr ""
#. module: event_sale_reservation
-#: model:ir.model,name:event_sale_reservation.model_sale_report
-msgid "Sales Analysis Report"
+#: model:ir.model,name:event_sale_reservation.model_sale_order
+msgid "Sales Order"
msgstr ""
#. module: event_sale_reservation
@@ -194,8 +200,7 @@ msgid "Type of events that can be reserved by buying this product"
msgstr ""
#. module: event_sale_reservation
-#: code:addons/event_sale_reservation/models/product_template.py:46
+#: code:addons/event_sale_reservation/models/product_template.py:0
#, python-format
msgid "You must indicate event type for %(name)s."
msgstr ""
-
diff --git a/event_sale_reservation/models/event_type.py b/event_sale_reservation/models/event_type.py
index 588d5bc0c..f78c1acef 100644
--- a/event_sale_reservation/models/event_type.py
+++ b/event_sale_reservation/models/event_type.py
@@ -51,6 +51,6 @@ def _compute_reservations_total(self):
def action_open_sale_orders(self):
"""Display SO that include reservations."""
sol = self.env["sale.order.line"].search(self._seats_reservation_domain(),)
- result = self.env["ir.actions.act_window"].for_xml_id("sale", "action_orders",)
+ result = self.env["ir.actions.act_window"].for_xml_id("sale", "action_orders")
result["domain"] = [("order_line", "in", sol.ids)]
return result
diff --git a/event_sale_reservation/models/sale_order.py b/event_sale_reservation/models/sale_order.py
index f11acad77..4e92b4e30 100644
--- a/event_sale_reservation/models/sale_order.py
+++ b/event_sale_reservation/models/sale_order.py
@@ -48,5 +48,4 @@ def action_open_event_registrations(self):
"res_model": "event.registration",
"type": "ir.actions.act_window",
"view_mode": "tree,form,calendar,graph",
- "view_type": "form",
}
diff --git a/event_sale_reservation/readme/CONTRIBUTORS.rst b/event_sale_reservation/readme/CONTRIBUTORS.rst
index 7ee45dc9b..8c4d96846 100644
--- a/event_sale_reservation/readme/CONTRIBUTORS.rst
+++ b/event_sale_reservation/readme/CONTRIBUTORS.rst
@@ -1 +1,3 @@
-* Jairo Llopis (https://www.tecnativa.com/)
+* `Tecnativa `_:
+
+ * Jairo Llopis
diff --git a/event_sale_reservation/readme/ROADMAP.rst b/event_sale_reservation/readme/ROADMAP.rst
new file mode 100644
index 000000000..5199b37a1
--- /dev/null
+++ b/event_sale_reservation/readme/ROADMAP.rst
@@ -0,0 +1,3 @@
+Some addons (event_registration_multi_qty + event_sale_registration_multi_qty)
+makes totals wrong because they depend currently on count and not sum of qtys;
+integrating with them would require a glue module.
diff --git a/event_sale_reservation/reports/sale_report.py b/event_sale_reservation/reports/sale_report.py
index d1328820a..7006e66ee 100644
--- a/event_sale_reservation/reports/sale_report.py
+++ b/event_sale_reservation/reports/sale_report.py
@@ -2,7 +2,6 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
-from odoo.tools import frozendict
class SaleReport(models.Model):
@@ -12,12 +11,17 @@ class SaleReport(models.Model):
comodel_name="event.type", readonly=True, string="Event reservation type",
)
- def _query(self, with_clause="", fields=frozendict(), groupby="", from_clause=""):
- fields = dict(
- fields,
- event_reservation_type_id="""
- , t.event_reservation_type_id as event_reservation_type_id
- """,
- )
+ def _query(self, with_clause="", fields=None, groupby="", from_clause=""):
+ if fields is None:
+ fields = {}
+ select_str = """ ,
+ t.event_reservation_type_id as event_reservation_type_id
+ """
+ fields.update({"event_reservation_type_id": select_str})
groupby += ", t.event_reservation_type_id"
- return super()._query(with_clause, fields, groupby, from_clause)
+ return super()._query(
+ with_clause=with_clause,
+ fields=fields,
+ groupby=groupby,
+ from_clause=from_clause,
+ )
diff --git a/event_sale_reservation/static/description/index.html b/event_sale_reservation/static/description/index.html
index 061419662..0040c60d2 100644
--- a/event_sale_reservation/static/description/index.html
+++ b/event_sale_reservation/static/description/index.html
@@ -367,7 +367,7 @@
Sell event reservations
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
+
This module extends the functionality of event_sale to support selling
reservations of events that still don’t exist and to allow you to schedule the
creation of events based on how many reservations already exist.
Some addons (event_registration_multi_qty + event_sale_registration_multi_qty)
+makes totals wrong because they depend currently on count and not sum of qtys;
+integrating with them would require a glue module.
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 smashing it by providing a detailed and welcomed
-feedback.