Skip to content
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
6 changes: 6 additions & 0 deletions setup/web_concurrent_edit_global_warning/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,
)
94 changes: 94 additions & 0 deletions web_concurrent_edit_global_warning/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

==================================
Web Concurrent Edit Global Warning
==================================

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

.. |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/license-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%2Fweb-lightgray.png?logo=github
:target: https://github.com/OCA/web/tree/16.0/web_concurrent_edit_global_warning
:alt: OCA/web
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/web-16-0/web-16-0-web_concurrent_edit_global_warning
: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/web&target_branch=16.0
:alt: Try me on Runboat

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

This module provides a mechanism to warn users about concurrent edits
from multiple users on the same record.

When a user starts editing a record, the module tracks changes made to
that record. If the same record is being edited by another user, the
module detects this and shows a warning icon in the form view's status
indicator, and a popover with details about the concurrent edits.

**Table of contents**

.. contents::
:local:

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

Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/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/web/issues/new?body=module:%20web_concurrent_edit_global_warning%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
-------

* Akretion

Contributors
------------

- Florian Mounier florian.mounier@akretion.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-paradoxxxzero| image:: https://github.com/paradoxxxzero.png?size=40px
:target: https://github.com/paradoxxxzero
:alt: paradoxxxzero

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-paradoxxxzero|

This module is part of the `OCA/web <https://github.com/OCA/web/tree/16.0/web_concurrent_edit_global_warning>`_ 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 web_concurrent_edit_global_warning/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import controllers
23 changes: 23 additions & 0 deletions web_concurrent_edit_global_warning/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2026 Akretion (http://www.akretion.com).
# @author Florian Mounier <florian.mounier@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "Web Concurrent Edit Global Warning",
"summary": """
Adds a warning when a record is edited by multiple users at the same time.
""",
"version": "16.0.1.0.0",
"author": "Akretion, Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/web",
"depends": ["web"],
"data": [],
"assets": {
"web.assets_backend": [
"web_concurrent_edit_global_warning/static/src/**/*",
],
},
"maintainers": ["paradoxxxzero"],
"installable": True,
}
1 change: 1 addition & 0 deletions web_concurrent_edit_global_warning/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import broadcast_channel
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2026 Akretion (http://www.akretion.com).
# @author Florian Mounier <florian.mounier@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import logging
import threading
from weakref import WeakSet

from odoo import http

from odoo.addons.bus.websocket import WebsocketConnectionHandler


class BroadcastChannelWebsocketConnectionHandler(WebsocketConnectionHandler):
_broadcast_websocket = WeakSet()

@classmethod
def _serve_forever(cls, websocket, db, httprequest):
current_thread = threading.current_thread()
current_thread.type = "websocket"
cls._broadcast_websocket.add(websocket)

for message in websocket.get_messages():
for ws in set(cls._broadcast_websocket):
if ws != websocket:
try:
ws._send(message)
except Exception as e:
logging.warning(f"Error sending message: {e}")
try:
ws.close()
except Exception:
logging.warning(f"Error closing websocket: {e}")
cls._broadcast_websocket.remove(ws)

cls._broadcast_websocket.remove(websocket)


class BroadcastChannel(http.Controller):
"""Broadcast Channel for concurrent edit warning"""

@http.route(
"/websocket/broadcast_channel",
type="http",
auth="public",
csrf=False,
websocket=True,
)
def broadcast_channel(self, **kwargs):
"""Websocket route to handle broadcast channel connections."""
return BroadcastChannelWebsocketConnectionHandler.open_connection(http.request)
129 changes: 129 additions & 0 deletions web_concurrent_edit_global_warning/i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * web_concurrent_edit_global_warning
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: Florian Mounier <florian.mounier@akretion.com>\n"
"Language-Team: \n"
"Language: fr\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"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "Close"
msgstr "Fermer"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "Concurrent Edit Detected"
msgstr "Modification concurrente détectée"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "Concurrent Edit Detected!"
msgstr "Modification concurrente détectée !"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "Concurrent Save Detected"
msgstr "Enregistrement concurrent détecté"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "Concurrent Save Detected!"
msgstr "Enregistrement concurrent détecté !"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "Discard Local Changes"
msgstr "Abandonner les modifications locales"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid ""
"It is recommended to reload the record to see the latest changes before "
"making changes."
msgstr ""
"Il est recommandé de recharger l'enregistrement pour voir les dernières "
"modifications avant d'apporter de nouvelles modifications."

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid ""
"It is recommended to wait for the other user to finish editing before making"
" changes."
msgstr ""
"Il est recommandé d'attendre que l'autre utilisateur ait terminé de modifier "
"l'enregistrement avant d'apporter de nouvelles modifications."

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "Refresh"
msgstr "Actualiser"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "Reload record"
msgstr "Recharger l'enregistrement"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "This record has been modified by another user"
msgstr "Cet enregistrement a été modifié par un autre utilisateur"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "This record is already being edited by"
msgstr "Cet enregistrement est déjà en cours de modification par"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "This record is being edited by another user"
msgstr "Cet enregistrement est en cours de modification par un autre utilisateur"

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "This record seems to have changed."
msgstr "Cet enregistrement semble avoir été modifié."

#. module: web_concurrent_edit_global_warning
#. odoo-javascript
#: code:addons/web_concurrent_edit_global_warning/static/src/views/form/form_status_indicator/form_status_indicator.xml:0
#, python-format
msgid "other user"
msgstr "autre utilisateur"
Loading
Loading