Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][ADD] Website event copy #356

Open
wants to merge 3 commits into
base: 16.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mock==5.1.0
1 change: 1 addition & 0 deletions setup/website_event_copy/odoo/addons/website_event_copy
6 changes: 6 additions & 0 deletions setup/website_event_copy/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
25 changes: 25 additions & 0 deletions website_event_copy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Le Filament - Website event copy

## Description

This module is used to copy the website associated to an event when the last is copied.

## Exemple

A golf tournament event has a website A. Click on "copy with website" button and you now
have another golf tournament event with a website A'

## Credits

## Contributors

- Thibaud <[email protected]>

## Maintainer

[![Le Filament](https://le-filament.com/img/logo-lefilament.png)](https://le-filament.com)
This module is maintained by Le Filament

## Licenses

This repository is licensed under [AGPL-3.0](LICENSE).
85 changes: 85 additions & 0 deletions website_event_copy/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
==================
Website event copy
==================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:bbbf237134bdcb6e52a3f32ae4efa8ae73c097c5506fe5e2cf42e1daa23f6266
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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/16.0/website_event_copy
:alt: OCA/event
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/event-16-0/event-16-0-website_event_copy
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/event&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module is used to copy the website associated to an event when the last is copied.

**Table of contents**

.. contents::
:local:

Usage
=====

A golf tournament event has a custom website menu (website_menu=True) A.
In case of an odoo copy this website menu will not be copied to the new event.

Clicking on "copy with website" button creates another golf tournament event with
a website A' having the same website_menu as A from the first event.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/event/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/event/issues/new?body=module:%20website_event_copy%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Le Filament

Contributors
~~~~~~~~~~~~

* Thibaud <[email protected]>

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.

This module is part of the `OCA/event <https://github.com/OCA/event/tree/16.0/website_event_copy>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions website_event_copy/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
30 changes: 30 additions & 0 deletions website_event_copy/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "Website event copy",
"summary": "Allow website linked to an event to be copied "
"when the event is duplicated",
"author": "Le Filament, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/event",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"depends": [
"event_session",
"website_event",
],
"data": [
"security/ir.model.access.csv",
# datas
# views
"views/event_views.xml",
# views menu
# wizard
],
"assets": {
"web._assets_primary_variables": [],
"web._assets_frontend_helpers": [],
"web.assets_frontend": [],
"web.assets_tests": [],
"web.assets_qweb": [],
},
"installable": True,
"auto_install": False,
}
26 changes: 26 additions & 0 deletions website_event_copy/i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * website_event_copy
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-12-18 10:32+0000\n"
"PO-Revision-Date: 2023-12-18 10:32+0000\n"
"Last-Translator: Thibaud Bruge\n"
"Language-Team: Le Filament\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: website_event_copy
#: model_terms:ir.ui.view,arch_db:website_event_copy.view_restrict_event_session_form
msgid "Duplicate with website"
msgstr "Dupliquer avec site web"

#. module: website_event_copy
#: model:ir.model,name:website_event_copy.model_event_event
msgid "Event"
msgstr "Event"
26 changes: 26 additions & 0 deletions website_event_copy/i18n/website_event_copy.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * website_event_copy
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-12-18 10:32+0000\n"
"PO-Revision-Date: 2023-12-18 10:32+0000\n"
"Last-Translator: Thibaud Bruge\n"
"Language-Team: Le Filament\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: website_event_copy
#: model_terms:ir.ui.view,arch_db:website_event_copy.view_restrict_event_session_form
msgid "Dupliquer avec site web"
msgstr "Duplicate with website"

#. module: website_event_copy
#: model:ir.model,name:website_event_copy.model_event_event
msgid "Event"
msgstr "Event"
1 change: 1 addition & 0 deletions website_event_copy/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import event_event, ir_ui_view
181 changes: 181 additions & 0 deletions website_event_copy/models/event_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import re

from odoo import api, models

from odoo.addons.http_routing.models.ir_http import slug


class Event(models.Model):
_inherit = "event.event"

# ------------------------------------------------------
# Action button
# ------------------------------------------------------

def action_dup_event_and_web(self):
new_event = self.duplicate_event_and_website({"new_name": self.name})
return {

Check warning on line 17 in website_event_copy/models/event_event.py

View check run for this annotation

Codecov / codecov/patch

website_event_copy/models/event_event.py#L16-L17

Added lines #L16 - L17 were not covered by tests
"view_type": "form",
"view_mode": "form",
"res_model": "event.event",
"type": "ir.actions.act_window",
"res_id": new_event.id,
}

def duplicate_event_and_website(self, default_dict: dict = None):
"""
Create a new event along with its website pages
One view as an inheritance there other one might not if only the title has been
changed
If the structure of the view hasn't been changed, the view with inherit_id won't
be created therefore the copy won't happen even if the title only has been
changed.
:param default_dict: A dict of default value that will be used as new event
properties use the key "new_name" to give a specific name to the new event
:return: The new event
"""
self.ensure_one()
new_event = None
if self.website_menu:
# If the name is not provided for the copy then the new event take the
# same name as the original event
new_event = self.copy(default=default_dict) # Copy current event
key_part = f"{slug(self)}"

views_to_copy = self.env["ir.ui.view"].search(
[("key", "like", key_part), ("inherit_id", "!=", False)]
)

for view in views_to_copy:
# Order of creation matter for the later delete
new_inherited_view = view.inherit_id.copy()
new_view = view.copy()

# Replace ids in keys for each view
new_view.update(
{
"key": self.replace_key_id(new_view.key, new_event.id),
"inherit_id": new_inherited_view.id,
}
)
new_inherited_view.update(
{"key": self.replace_key_id(new_inherited_view.key, new_event.id)}
)
else:
new_event = self.copy()

return new_event

def replace_key_id(self, key: str, replace_id: int) -> str:
"""
This method is used to replace the id that has been added
in the key. During the copy process the view will keep the
old reference id, therefore it needs to be changed to the new
one
:param key (str): the key you want to change the id in
:param replace_id (int): the id you wish the change for
:return (str): the new key
"""
# regex = r"(?<=-)[0-9]+"
# new_key = re.sub(regex, str(replace_id), key, count=0, flags=re.MULTILINE)
# return new_key

regex = r"(?<=-)([0-9]+-*)+"
result = re.sub(regex, str(replace_id), key, count=0, flags=re.MULTILINE)

return result

# ------------------------------------------------------
# Default functions
# ------------------------------------------------------

# ------------------------------------------------------
# CRUD methods (ORM overrides)
# ------------------------------------------------------

@api.returns("self", lambda value: value.id)
def copy_data(self, default: dict = None) -> [dict]:
"""
Inheritance of copy_data() from models module in order to counter the spread of
the string 'copy' in the new event name.
:param default: The default dict containing fields and their value for the copy
:return: A list of dictionnary (default) that key will be used as fields during
the copy process
"""
self.ensure_one()
if default.get("new_name"):
default["name"] = default["new_name"]
default.pop("new_name")
return super().copy_data(default)

@api.ondelete(at_uninstall=True)
def _flush_website_event_menus_and_views(self):
"""
Make sure both associated views and menus of an event are deleted when the last
is deleted.
"""
for event in self:
if event.website_menu:
website_menu_events = self.env["website.event.menu"].search(
[("event_id", "=", event.id)]
)

menus = []
key = None
for website_menu_event in website_menu_events:
menus.append(website_menu_event.menu_id)
if key is None and website_menu_event.view_id.key:
view = website_menu_event.view_id
# The key we are looking for is not the same as the menu one,
# we separate the menu name from the key to be able to identify
# all views regardless of the menu. The later views will be
# deleted
key = view.get_website_event_view_key()

menu_parents = {menu.parent_id for menu in menus}
for parent in menu_parents:
parent.unlink()

if key:
views = self.env["ir.ui.view"].search(
[("key", "like", key)], order="id"
)
view_list = [view for view in views]
view_list.reverse()

for view in view_list:
view.unlink()

def _create_menu(self, sequence, name, url, xml_id, menu_type):
"""
Ensure the menu is created with the right view. Before this override the menus
were referencing a wrong view. For 2 website events with the same name for
instance "golf-tournament", two views were created, golf-tournament and
golf-tournament-1
The second view whould never be called because the menu of the second
website_event would refer to the view of the first website_event and
not of the second
This behaviour has been identified of use of key which has no unicity constraint
"""
website_menu = super()._create_menu(sequence, name, url, xml_id, menu_type)

website_event_menu = (
self.env["website.event.menu"]
.sudo()
.search([("menu_id", "=", website_menu.id)])
)
view_id = website_event_menu.view_id
if view_id:
view_id.update({"key": f"{view_id.key}-{self.id}"})
key = view_id.get_website_event_menu_key()
url_splitted = website_menu.url.split("/")
url_splitted[-1] = key

website_menu.update({"url": "/".join(url_splitted)})
return website_menu
Loading
Loading