Initial commit: OCA Technical packages (595 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:03 +02:00
commit 2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# Announcement
Odoo addon: announcement
## Installation
```bash
pip install odoo-bringout-oca-server-ux-announcement
```
## Dependencies
This addon depends on:
- mail
## Manifest Information
- **Name**: Announcement
- **Version**: 16.0.1.0.1
- **Category**: Server UX
- **License**: AGPL-3
- **Installable**: False
## Source
Based on [OCA/server-ux](https://github.com/OCA/server-ux) branch 16.0, addon `announcement`.
## License
This package maintains the original AGPL-3 license from the upstream Odoo project.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Reports: doc/REPORTS.md
- Security: doc/SECURITY.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -0,0 +1,125 @@
============
Announcement
============
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:784e888a875fb1f37b9d3a48ca5c5c63bdec23a06cce24e648a5910f4907891d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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%2Fserver--ux-lightgray.png?logo=github
:target: https://github.com/OCA/server-ux/tree/16.0/announcement
:alt: OCA/server-ux
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-ux-16-0/server-ux-16-0-announcement
: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/server-ux&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module adds popup announcements in the backend for targeted internal users. Those
announcements can contain rich format and a user read log is kept for everyone.
**Table of contents**
.. contents::
:local:
Configuration
=============
To create new announcements a user should be in the *Announcements Managers* group.
When your user has such permissions, this is the way to create an announcement:
#. Go to *Discuss > Announcements*
#. Create a new one and define a title. This title will be shown in the announcement
header.
#. Define the announcement scope:
- Specific users: manually select which users will see the announcement.
- User groups: users from the selected groups will be the ones to see the
announcement.
#. Define the announcement body. You can use rich formatting and event paste your
own html (editor in debug mode).
#. By default, the announcement will be archived. This is to prevent the announcement
to show up before time.
#. Once the announcement is ready, unarchive it going to the *Actions* menu an choosing
the *Unarchive* option.
#. Optionally you can set an announcement date to schedule the announcement. The
announcement won't show up until that date.
#. If the announcement doesn't make sense once a date is passed, you can set a due date.
From that date, the announcement won't be shown to anyone.
Usage
=====
When a user in the scope of active announcements logs in, those will popup. The user
has to mark them as read to continue working. If the announcement is set during the
user session, the announcement will be eventually prompted in the top bar on the right
part. The user click on the unread announcements icon (a speaker) and the announcements
will popup for the user to check them.
Users can go *Discuss > Announcements* to check current and past announcements.
Announcement managers can also track which users have read the announcement.
Known issues / Roadmap
======================
* It could be integrated in Discuss app to review past announcements.
* Log other information like geolocation, IP, browser agent, etc when marking
announcement as read.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-ux/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/server-ux/issues/new?body=module:%20announcement%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
~~~~~~~
* Tecnativa
Contributors
~~~~~~~~~~~~
* `Tecnativa <https://www.tecnativa.com>`__:
* Pedro M. Baeza
* David Vidal
* Carlos Roca
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/server-ux <https://github.com/OCA/server-ux/tree/16.0/announcement>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -0,0 +1,2 @@
from . import models
from . import wizards

View file

@ -0,0 +1,30 @@
# Copyright 2022 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Announcement",
"version": "16.0.1.0.1",
"summary": "Notify internal users about relevant organization stuff",
"author": "Tecnativa, Odoo Community Association (OCA)",
"license": "AGPL-3",
"category": "Server UX",
"website": "https://github.com/OCA/server-ux",
"depends": ["mail"],
"data": [
"security/announcement_security.xml",
"security/ir.model.access.csv",
"views/announcement_views.xml",
"views/announcement_tag_views.xml",
"wizards/read_announcement_wizard.xml",
],
"demo": [
"demo/announcement_tag_demo.xml",
],
"assets": {
"web.assets_backend": [
"announcement/static/src/js/announcement_dialog/**/*",
"announcement/static/src/js/announcement_menu/**/*",
"announcement/static/src/js/announcement_service/**/*",
],
},
}

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="announcement_tag_1" model="announcement.tag">
<field name="name">Company information</field>
<field name="color" eval="1" />
</record>
<record id="announcement_tag_2" model="announcement.tag">
<field name="name">Employees</field>
<field name="color" eval="2" />
</record>
<record id="announcement_tag_3" model="announcement.tag">
<field name="name">Accounting</field>
<field name="color" eval="3" />
</record>
<record id="announcement_tag_4" model="announcement.tag">
<field name="name">Sales</field>
<field name="color" eval="4" />
</record>
<record id="announcement_tag_5" model="announcement.tag">
<field name="name">Manufacturing</field>
<field name="color" eval="5" />
</record>
</odoo>

View file

@ -0,0 +1,447 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * announcement
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.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: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "<span class=\"o_stat_text\">Read(s)</span>"
msgstr ""
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_3
msgid "Accounting"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__active
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Active"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__allowed_user_ids
msgid "Allowed User"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__allowed_users_count
msgid "Allowed Users Count"
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Announce at"
msgstr ""
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: model:ir.model.fields,field_description:announcement.field_announcement_log__announcement_id
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__announcement_id
#: model:ir.module.category,name:announcement.category_announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
#, python-format
msgid "Announcement"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__announcement_log_ids
msgid "Announcement Log"
msgstr ""
#. module: announcement
#: model:ir.actions.act_window,name:announcement.action_announcement_log
msgid "Announcement Logs"
msgstr ""
#. module: announcement
#: model:res.groups,name:announcement.announcemenent_manager
msgid "Announcement Manager"
msgstr ""
#. module: announcement
#: model:ir.actions.act_window,name:announcement.announcement_tag_action
#: model:ir.model,name:announcement.model_announcement_tag
#: model:ir.ui.menu,name:announcement.menu_announcement_tag_management
msgid "Announcement Tags"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__announcement_type
msgid "Announcement Type"
msgstr ""
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: model:ir.actions.act_window,name:announcement.announcement_action
#: model:ir.ui.menu,name:announcement.menu_announcement_management
#, python-format
msgid "Announcements"
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Archived"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__attachment_ids
msgid "Attachments"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__color
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__color
msgid "Color"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__company_id
msgid "Company"
msgstr ""
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_1
msgid "Company information"
msgstr ""
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement_tag__company_id
msgid "Company related to this tag"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__content
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Content"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__create_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_log__create_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__create_uid
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__create_uid
msgid "Created by"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__create_date
#: model:ir.model.fields,field_description:announcement.field_announcement_log__create_date
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__create_date
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__create_date
msgid "Created on"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__display_name
#: model:ir.model.fields,field_description:announcement.field_announcement_log__display_name
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__display_name
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__display_name
msgid "Display Name"
msgstr ""
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_2
msgid "Employees"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__full_name
msgid "Full Name"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__is_general_announcement
msgid "General Announcement"
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "Groups"
msgstr ""
#. module: announcement
#: model:ir.model,name:announcement.model_ir_http
msgid "HTTP Routing"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__id
#: model:ir.model.fields,field_description:announcement.field_announcement_log__id
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__id
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__id
msgid "ID"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__in_date
msgid "In Date"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement____last_update
#: model:ir.model.fields,field_description:announcement.field_announcement_log____last_update
#: model:ir.model.fields,field_description:announcement.field_announcement_tag____last_update
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard____last_update
msgid "Last Modified on"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__write_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_log__write_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__write_uid
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__write_uid
msgid "Last Updated by"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__write_date
#: model:ir.model.fields,field_description:announcement.field_announcement_log__write_date
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__write_date
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__write_date
msgid "Last Updated on"
msgstr ""
#. module: announcement
#: model:ir.model,name:announcement.model_announcement_log
msgid "Log user reads"
msgstr ""
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_5
msgid "Manufacturing"
msgstr ""
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.esm.js:0
#, python-format
msgid "Mark as read"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__name
msgid "Name"
msgstr ""
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#, python-format
msgid "No announcements."
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_date
msgid "Notification Date"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_end_date
msgid "Notification End Date"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_expiry_date
msgid "Notification Expiry Date"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_start_date
msgid "Notification Start Date"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__parent_id
msgid "Parent Tag"
msgstr ""
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__read_announcement_wizard__read_state__read
msgid "Read"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_res_users__read_announcement_ids
msgid "Read Announcement"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__read_announcement_count
msgid "Read Announcement Count"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__date
msgid "Read Date"
msgstr ""
#. module: announcement
#. odoo-python
#: code:addons/announcement/models/announcement.py:0
#, python-format
msgid "Read Logs"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__read_state
msgid "Read State"
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_tree
msgid "Reads"
msgstr ""
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_4
msgid "Sales"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__sequence
msgid "Sequence"
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Set here the content of the announcement."
msgstr ""
#. module: announcement
#: model:ir.model,name:announcement.model_read_announcement_wizard
msgid "Show altogether users who read and users who didn't"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__specific_user_ids
msgid "Specific User"
msgstr ""
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__announcement__announcement_type__specific_users
msgid "Specific users"
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Tag"
msgstr ""
#. module: announcement
#: model:ir.model.constraint,message:announcement.constraint_announcement_tag_name_uniq
msgid "Tag name already exists!"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__tag_ids
msgid "Tags"
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Tags..."
msgstr ""
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__notification_end_date
#: model:ir.model.fields,help:announcement.field_announcement__notification_start_date
msgid "Technical field to display announcements in the calendar view"
msgstr ""
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__color
msgid "Technical field to display items by color in the calendar"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__name
msgid "Title"
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_tree
msgid "Total users"
msgstr ""
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__read_announcement_wizard__read_state__unread
msgid "Unread"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_res_users__unread_announcement_ids
msgid "Unread Announcement"
msgstr ""
#. module: announcement
#: model:ir.model,name:announcement.model_res_users
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__user_id
msgid "User"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__user_group_ids
msgid "User Group"
msgstr ""
#. module: announcement
#: model:ir.model,name:announcement.model_announcement
msgid "User announcements"
msgstr ""
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__announcement__announcement_type__user_group
msgid "User groups"
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "Users"
msgstr ""
#. module: announcement
#: model:res.groups,comment:announcement.announcemenent_manager
msgid "Users allowed to manage and configure announcements."
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Valid up to"
msgstr ""
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__attachment_ids
msgid "You can attach the copy of your Letter"
msgstr ""
#. module: announcement
#. odoo-python
#: code:addons/announcement/models/announcement_tag.py:0
#, python-format
msgid "You cannot create recursive tags."
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "e.g. Announcement description..."
msgstr ""
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_calendar
msgid "name"
msgstr ""

View file

@ -0,0 +1,447 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * announcement
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.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: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "<span class=\"o_stat_text\">Read(s)</span>"
msgstr "<span class=\"o_stat_text\">Čitanje</span>"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_3
msgid "Accounting"
msgstr "Računovodstvo"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__active
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Active"
msgstr "Aktivan"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__allowed_user_ids
msgid "Allowed User"
msgstr "Dozvoljeni korisnik"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__allowed_users_count
msgid "Allowed Users Count"
msgstr "Broj dozvoljenih korisnika"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Announce at"
msgstr "Objavi u"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: model:ir.model.fields,field_description:announcement.field_announcement_log__announcement_id
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__announcement_id
#: model:ir.module.category,name:announcement.category_announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
#, python-format
msgid "Announcement"
msgstr "Obaveštenje"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__announcement_log_ids
msgid "Announcement Log"
msgstr "Zapis obaveštenja"
#. module: announcement
#: model:ir.actions.act_window,name:announcement.action_announcement_log
msgid "Announcement Logs"
msgstr "Zapisi obaveštenja"
#. module: announcement
#: model:res.groups,name:announcement.announcemenent_manager
msgid "Announcement Manager"
msgstr "Menadžer obaveštenja"
#. module: announcement
#: model:ir.actions.act_window,name:announcement.announcement_tag_action
#: model:ir.model,name:announcement.model_announcement_tag
#: model:ir.ui.menu,name:announcement.menu_announcement_tag_management
msgid "Announcement Tags"
msgstr "Oznake obaveštenja"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__announcement_type
msgid "Announcement Type"
msgstr "Tip obaveštenja"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: model:ir.actions.act_window,name:announcement.announcement_action
#: model:ir.ui.menu,name:announcement.menu_announcement_management
#, python-format
msgid "Announcements"
msgstr "Obaveštenja"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Archived"
msgstr "Arhivirano"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__attachment_ids
msgid "Attachments"
msgstr "Prilozi"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__color
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__color
msgid "Color"
msgstr "Boja"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__company_id
msgid "Company"
msgstr "Preduzeće"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_1
msgid "Company information"
msgstr "Informacije o kompaniji"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement_tag__company_id
msgid "Company related to this tag"
msgstr "Kompanija povezana sa ovom oznakom"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__content
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Content"
msgstr "Sadržaj"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__create_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_log__create_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__create_uid
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__create_uid
msgid "Created by"
msgstr "Kreirao"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__create_date
#: model:ir.model.fields,field_description:announcement.field_announcement_log__create_date
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__create_date
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__create_date
msgid "Created on"
msgstr "Kreirano"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__display_name
#: model:ir.model.fields,field_description:announcement.field_announcement_log__display_name
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__display_name
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__display_name
msgid "Display Name"
msgstr "Prikazani naziv"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_2
msgid "Employees"
msgstr "Zaposleni"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__full_name
msgid "Full Name"
msgstr "Puni naziv"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__is_general_announcement
msgid "General Announcement"
msgstr "Opšte obaveštenje"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "Groups"
msgstr "Grupe"
#. module: announcement
#: model:ir.model,name:announcement.model_ir_http
msgid "HTTP Routing"
msgstr "HTTP usmjeravanje"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__id
#: model:ir.model.fields,field_description:announcement.field_announcement_log__id
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__id
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__id
msgid "ID"
msgstr "ID"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__in_date
msgid "In Date"
msgstr "U datumu"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement____last_update
#: model:ir.model.fields,field_description:announcement.field_announcement_log____last_update
#: model:ir.model.fields,field_description:announcement.field_announcement_tag____last_update
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard____last_update
msgid "Last Modified on"
msgstr "Zadnje mijenjano"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__write_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_log__write_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__write_uid
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__write_uid
msgid "Last Updated by"
msgstr "Zadnji ažurirao"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__write_date
#: model:ir.model.fields,field_description:announcement.field_announcement_log__write_date
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__write_date
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__write_date
msgid "Last Updated on"
msgstr "Zadnje ažurirano"
#. module: announcement
#: model:ir.model,name:announcement.model_announcement_log
msgid "Log user reads"
msgstr "Evidentiraj čitanja korisnika"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_5
msgid "Manufacturing"
msgstr "Proizvodnja"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.esm.js:0
#, python-format
msgid "Mark as read"
msgstr "Označi kao pročitano"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__name
msgid "Name"
msgstr "Naziv:"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#, python-format
msgid "No announcements."
msgstr "Nema obaveštenja."
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_date
msgid "Notification Date"
msgstr "Datum obaveštenja"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_end_date
msgid "Notification End Date"
msgstr "Datum završetka obaveštenja"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_expiry_date
msgid "Notification Expiry Date"
msgstr "Datum isteka obaveštenja"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_start_date
msgid "Notification Start Date"
msgstr "Datum početka obaveštenja"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__parent_id
msgid "Parent Tag"
msgstr "Roditeljska oznaka"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__read_announcement_wizard__read_state__read
msgid "Read"
msgstr "Pročitano"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_res_users__read_announcement_ids
msgid "Read Announcement"
msgstr "Pročitano obaveštenje"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__read_announcement_count
msgid "Read Announcement Count"
msgstr "Broj pročitanih obaveštenja"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__date
msgid "Read Date"
msgstr "Datum čitanja"
#. module: announcement
#. odoo-python
#: code:addons/announcement/models/announcement.py:0
#, python-format
msgid "Read Logs"
msgstr "Zapisi čitanja"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__read_state
msgid "Read State"
msgstr "Status čitanja"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_tree
msgid "Reads"
msgstr "Čitanja"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_4
msgid "Sales"
msgstr "Prodaja"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__sequence
msgid "Sequence"
msgstr "Sekvenca"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Set here the content of the announcement."
msgstr "Ovde postavite sadržaj obaveštenja."
#. module: announcement
#: model:ir.model,name:announcement.model_read_announcement_wizard
msgid "Show altogether users who read and users who didn't"
msgstr "Prikaži zajedno korisnike koji su pročitali i korisnike koji nisu"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__specific_user_ids
msgid "Specific User"
msgstr "Određen korisnik"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__announcement__announcement_type__specific_users
msgid "Specific users"
msgstr "Određeni korisnici"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Tag"
msgstr "Oznaka"
#. module: announcement
#: model:ir.model.constraint,message:announcement.constraint_announcement_tag_name_uniq
msgid "Tag name already exists!"
msgstr "Naziv oznake već postoji !"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__tag_ids
msgid "Tags"
msgstr "Oznake"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Tags..."
msgstr "Oznake..."
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__notification_end_date
#: model:ir.model.fields,help:announcement.field_announcement__notification_start_date
msgid "Technical field to display announcements in the calendar view"
msgstr "Tehničko polje za prikazivanje obaveštenja u kalendaru"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__color
msgid "Technical field to display items by color in the calendar"
msgstr "Tehničko polje za prikazivanje stavki po boji u kalendaru"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__name
msgid "Title"
msgstr "Naslov"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_tree
msgid "Total users"
msgstr "Ukupno korisnika"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__read_announcement_wizard__read_state__unread
msgid "Unread"
msgstr "Nepročitano"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_res_users__unread_announcement_ids
msgid "Unread Announcement"
msgstr "Nepročitano obaveštenje"
#. module: announcement
#: model:ir.model,name:announcement.model_res_users
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__user_id
msgid "User"
msgstr "Korisnik"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__user_group_ids
msgid "User Group"
msgstr "Korisnička grupa"
#. module: announcement
#: model:ir.model,name:announcement.model_announcement
msgid "User announcements"
msgstr "Korisnička obaveštenja"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__announcement__announcement_type__user_group
msgid "User groups"
msgstr "Korisničke grupe"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "Users"
msgstr "Korisnici"
#. module: announcement
#: model:res.groups,comment:announcement.announcemenent_manager
msgid "Users allowed to manage and configure announcements."
msgstr "Korisnici kojima je dozvoljeno upravljanje i konfigurisanje obaveštenja."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Valid up to"
msgstr "Važi do"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__attachment_ids
msgid "You can attach the copy of your Letter"
msgstr "Možete priložiti kopiju vašeg pisma"
#. module: announcement
#. odoo-python
#: code:addons/announcement/models/announcement_tag.py:0
#, python-format
msgid "You cannot create recursive tags."
msgstr "Ne možete kreirati rekurzivne oznake."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "e.g. Announcement description..."
msgstr "npr. Opis obaveštenja..."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_calendar
msgid "name"
msgstr "naziv"

View file

@ -0,0 +1,450 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * announcement
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-12 14:41+0000\n"
"PO-Revision-Date: 2024-04-12 16:45+0200\n"
"Last-Translator: Víctor Martínez <victor.martinez@tecnativa.com>\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: nplurals=2; plural=n != 1;\n"
"X-Generator: Poedit 3.4.2\n"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "<span class=\"o_stat_text\">Read(s)</span>"
msgstr "<span class=\"o_stat_text\">Leído(s)</span>"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_3
msgid "Accounting"
msgstr "Contabilidad"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__active
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Active"
msgstr "Activo"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__allowed_user_ids
msgid "Allowed User"
msgstr "Usuario permitido"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__allowed_users_count
msgid "Allowed Users Count"
msgstr "Número de usuarios permitidos"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Announce at"
msgstr "Anunciar a"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: model:ir.model.fields,field_description:announcement.field_announcement_log__announcement_id
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__announcement_id
#: model:ir.module.category,name:announcement.category_announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
#, python-format
msgid "Announcement"
msgstr "Anuncio"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__announcement_log_ids
msgid "Announcement Log"
msgstr "Registro del anuncio"
#. module: announcement
#: model:ir.actions.act_window,name:announcement.action_announcement_log
msgid "Announcement Logs"
msgstr "Registro del anuncio"
#. module: announcement
#: model:res.groups,name:announcement.announcemenent_manager
msgid "Announcement Manager"
msgstr "Responsable de anuncios"
#. module: announcement
#: model:ir.actions.act_window,name:announcement.announcement_tag_action
#: model:ir.model,name:announcement.model_announcement_tag
#: model:ir.ui.menu,name:announcement.menu_announcement_tag_management
msgid "Announcement Tags"
msgstr "Etiquetas de anuncios"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__announcement_type
msgid "Announcement Type"
msgstr "Tipo de anuncio"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: model:ir.actions.act_window,name:announcement.announcement_action
#: model:ir.ui.menu,name:announcement.menu_announcement_management
#, python-format
msgid "Announcements"
msgstr "Anuncios"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Archived"
msgstr "Archivado"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__attachment_ids
msgid "Attachments"
msgstr "Adjuntos"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__color
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__color
msgid "Color"
msgstr "Color"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__company_id
msgid "Company"
msgstr "Compañía"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_1
msgid "Company information"
msgstr "Información de la compañía"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement_tag__company_id
msgid "Company related to this tag"
msgstr "Compañía relacionado con esta etiqueta"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__content
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Content"
msgstr "Contenido"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__create_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_log__create_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__create_uid
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__create_uid
msgid "Created by"
msgstr "Creado por"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__create_date
#: model:ir.model.fields,field_description:announcement.field_announcement_log__create_date
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__create_date
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__create_date
msgid "Created on"
msgstr "Creado en"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__display_name
#: model:ir.model.fields,field_description:announcement.field_announcement_log__display_name
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__display_name
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__display_name
msgid "Display Name"
msgstr "Nombre mostrado"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_2
msgid "Employees"
msgstr "Empleados"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__full_name
msgid "Full Name"
msgstr "Nombre completo"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__is_general_announcement
msgid "General Announcement"
msgstr "Anuncio general"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "Groups"
msgstr "Grupos"
#. module: announcement
#: model:ir.model,name:announcement.model_ir_http
msgid "HTTP Routing"
msgstr ""
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__id
#: model:ir.model.fields,field_description:announcement.field_announcement_log__id
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__id
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__id
msgid "ID"
msgstr "ID (identificación)"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__in_date
msgid "In Date"
msgstr "En fecha"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement____last_update
#: model:ir.model.fields,field_description:announcement.field_announcement_log____last_update
#: model:ir.model.fields,field_description:announcement.field_announcement_tag____last_update
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard____last_update
msgid "Last Modified on"
msgstr "Última modificación en"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__write_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_log__write_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__write_uid
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__write_uid
msgid "Last Updated by"
msgstr "Última actualización de"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__write_date
#: model:ir.model.fields,field_description:announcement.field_announcement_log__write_date
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__write_date
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__write_date
msgid "Last Updated on"
msgstr "Última actualización en"
#. module: announcement
#: model:ir.model,name:announcement.model_announcement_log
msgid "Log user reads"
msgstr "Registrar lecturas de usuario"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_5
msgid "Manufacturing"
msgstr "Fabricación"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.esm.js:0
#, python-format
msgid "Mark as read"
msgstr "Marcar como leído"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__name
msgid "Name"
msgstr "Nombre"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#, python-format
msgid "No announcements."
msgstr "No hay anuncios."
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_date
msgid "Notification Date"
msgstr "Fecha de notificación"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_end_date
msgid "Notification End Date"
msgstr "Fecha fin de notificación"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_expiry_date
msgid "Notification Expiry Date"
msgstr "Fecha de caducidad de la notificación"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_start_date
msgid "Notification Start Date"
msgstr "Fecha inicio de notificación"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__parent_id
msgid "Parent Tag"
msgstr "Etiqueta padre"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__read_announcement_wizard__read_state__read
msgid "Read"
msgstr "Leídos"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_res_users__read_announcement_ids
msgid "Read Announcement"
msgstr "Anuncio leído"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__read_announcement_count
msgid "Read Announcement Count"
msgstr "Número de anuncios leídos"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__date
msgid "Read Date"
msgstr "Fecha de lectura"
#. module: announcement
#. odoo-python
#: code:addons/announcement/models/announcement.py:0
#, python-format
msgid "Read Logs"
msgstr "Registros de lectura"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__read_state
msgid "Read State"
msgstr "Estado de lectura"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_tree
msgid "Reads"
msgstr "Lecturas"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_4
msgid "Sales"
msgstr "Ventas"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__sequence
msgid "Sequence"
msgstr "Secuencia"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Set here the content of the announcement."
msgstr "Inserta aquí el contenido del anuncio."
#. module: announcement
#: model:ir.model,name:announcement.model_read_announcement_wizard
msgid "Show altogether users who read and users who didn't"
msgstr "Muestra juntos los usuarios que han leído un anuncio y los que no"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__specific_user_ids
msgid "Specific User"
msgstr "Usuarios específico"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__announcement__announcement_type__specific_users
msgid "Specific users"
msgstr "Usuarios específicos"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Tag"
msgstr "Etiqueta"
#. module: announcement
#: model:ir.model.constraint,message:announcement.constraint_announcement_tag_name_uniq
msgid "Tag name already exists!"
msgstr "¡El nombre de etiqueta ya existe!"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__tag_ids
msgid "Tags"
msgstr "Etiquetas"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Tags..."
msgstr "Etiquetas..."
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__notification_end_date
#: model:ir.model.fields,help:announcement.field_announcement__notification_start_date
msgid "Technical field to display announcements in the calendar view"
msgstr "Campo técnico para mostrar los anuncios en la vista calendario"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__color
msgid "Technical field to display items by color in the calendar"
msgstr "Campo técnico para mostrar items por color en el calendario"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__name
msgid "Title"
msgstr "Título"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_tree
msgid "Total users"
msgstr "Total usuarios"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__read_announcement_wizard__read_state__unread
msgid "Unread"
msgstr "Pendientes"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_res_users__unread_announcement_ids
msgid "Unread Announcement"
msgstr "Anuncio pendiente"
#. module: announcement
#: model:ir.model,name:announcement.model_res_users
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__user_id
msgid "User"
msgstr "Usuario"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__user_group_ids
msgid "User Group"
msgstr "Grupo de usuarios"
#. module: announcement
#: model:ir.model,name:announcement.model_announcement
msgid "User announcements"
msgstr "Anuncios del usuario"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__announcement__announcement_type__user_group
msgid "User groups"
msgstr "Grupos de usuarios"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "Users"
msgstr "Usuarios"
#. module: announcement
#: model:res.groups,comment:announcement.announcemenent_manager
msgid "Users allowed to manage and configure announcements."
msgstr "Usuarios autorizados a administrar y configurar anuncios."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Valid up to"
msgstr "Válido hasta"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__attachment_ids
msgid "You can attach the copy of your Letter"
msgstr "Puedes adjuntar la copia de tu correo"
#. module: announcement
#. odoo-python
#: code:addons/announcement/models/announcement_tag.py:0
#, python-format
msgid "You cannot create recursive tags."
msgstr "No puedes crear etiquetas recursivas."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "e.g. Announcement description..."
msgstr "p.e. Descripción del anuncio..."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_calendar
msgid "name"
msgstr "nombre"

View file

@ -0,0 +1,450 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * announcement
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-10-21 10:06+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\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 5.6.2\n"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "<span class=\"o_stat_text\">Read(s)</span>"
msgstr "<span class=\"o_stat_text\">Lettura(e)</span>"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_3
msgid "Accounting"
msgstr "Contabilità"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__active
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Active"
msgstr "Attivo"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__allowed_user_ids
msgid "Allowed User"
msgstr "Utente autorizzato"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__allowed_users_count
msgid "Allowed Users Count"
msgstr "Conteggio utenti autorizzati"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Announce at"
msgstr "Notifica il"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: model:ir.model.fields,field_description:announcement.field_announcement_log__announcement_id
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__announcement_id
#: model:ir.module.category,name:announcement.category_announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
#, python-format
msgid "Announcement"
msgstr "Notifiche"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__announcement_log_ids
msgid "Announcement Log"
msgstr "Registro notifica"
#. module: announcement
#: model:ir.actions.act_window,name:announcement.action_announcement_log
msgid "Announcement Logs"
msgstr "Registri notifica"
#. module: announcement
#: model:res.groups,name:announcement.announcemenent_manager
msgid "Announcement Manager"
msgstr "Gestore notifica"
#. module: announcement
#: model:ir.actions.act_window,name:announcement.announcement_tag_action
#: model:ir.model,name:announcement.model_announcement_tag
#: model:ir.ui.menu,name:announcement.menu_announcement_tag_management
msgid "Announcement Tags"
msgstr "Etichette notifica"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__announcement_type
msgid "Announcement Type"
msgstr "Tipo notifica"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: model:ir.actions.act_window,name:announcement.announcement_action
#: model:ir.ui.menu,name:announcement.menu_announcement_management
#, python-format
msgid "Announcements"
msgstr "Notifiche"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Archived"
msgstr "In archivio"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__attachment_ids
msgid "Attachments"
msgstr "Allegati"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__color
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__color
msgid "Color"
msgstr "Colore"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__company_id
msgid "Company"
msgstr "Azienda"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_1
msgid "Company information"
msgstr "Informazioni azienda"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement_tag__company_id
msgid "Company related to this tag"
msgstr "Azienda collegata a questa etichetta"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__content
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Content"
msgstr "Contenuto"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__create_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_log__create_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__create_uid
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__create_uid
msgid "Created by"
msgstr "Creato da"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__create_date
#: model:ir.model.fields,field_description:announcement.field_announcement_log__create_date
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__create_date
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__create_date
msgid "Created on"
msgstr "Creato il"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__display_name
#: model:ir.model.fields,field_description:announcement.field_announcement_log__display_name
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__display_name
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__display_name
msgid "Display Name"
msgstr "Nome visualizzato"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_2
msgid "Employees"
msgstr "Dipendenti"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__full_name
msgid "Full Name"
msgstr "Nome completo"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__is_general_announcement
msgid "General Announcement"
msgstr "Notifica generale"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "Groups"
msgstr "Gruppi"
#. module: announcement
#: model:ir.model,name:announcement.model_ir_http
msgid "HTTP Routing"
msgstr "Instradamento HTTP"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__id
#: model:ir.model.fields,field_description:announcement.field_announcement_log__id
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__id
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__id
msgid "ID"
msgstr "ID"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__in_date
msgid "In Date"
msgstr "In data"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement____last_update
#: model:ir.model.fields,field_description:announcement.field_announcement_log____last_update
#: model:ir.model.fields,field_description:announcement.field_announcement_tag____last_update
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard____last_update
msgid "Last Modified on"
msgstr "Ultima modifica il"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__write_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_log__write_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__write_uid
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__write_uid
msgid "Last Updated by"
msgstr "Ultimo aggiornamento di"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__write_date
#: model:ir.model.fields,field_description:announcement.field_announcement_log__write_date
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__write_date
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__write_date
msgid "Last Updated on"
msgstr "Ultimo aggiornamento il"
#. module: announcement
#: model:ir.model,name:announcement.model_announcement_log
msgid "Log user reads"
msgstr "Registro letture utente"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_5
msgid "Manufacturing"
msgstr "Produzione"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.esm.js:0
#, python-format
msgid "Mark as read"
msgstr "Segna come letto"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__name
msgid "Name"
msgstr "Nome"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#, python-format
msgid "No announcements."
msgstr "Nessuna notifica."
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_date
msgid "Notification Date"
msgstr "Data notifica"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_end_date
msgid "Notification End Date"
msgstr "Data fine notifica"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_expiry_date
msgid "Notification Expiry Date"
msgstr "Data scadenza notifica"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_start_date
msgid "Notification Start Date"
msgstr "Data inizio notifica"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__parent_id
msgid "Parent Tag"
msgstr "Etichetta padre"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__read_announcement_wizard__read_state__read
msgid "Read"
msgstr "Lettura"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_res_users__read_announcement_ids
msgid "Read Announcement"
msgstr "Lettura notifica"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__read_announcement_count
msgid "Read Announcement Count"
msgstr "Conteggio lettura notifica"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__date
msgid "Read Date"
msgstr "Data lettura"
#. module: announcement
#. odoo-python
#: code:addons/announcement/models/announcement.py:0
#, python-format
msgid "Read Logs"
msgstr "Registri lettura"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__read_state
msgid "Read State"
msgstr "Stato lettura"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_tree
msgid "Reads"
msgstr "Letture"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_4
msgid "Sales"
msgstr "Vendite"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__sequence
msgid "Sequence"
msgstr "Sequenza"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Set here the content of the announcement."
msgstr "Impostare qui il contenuto della notifica."
#. module: announcement
#: model:ir.model,name:announcement.model_read_announcement_wizard
msgid "Show altogether users who read and users who didn't"
msgstr "Visualizza insieme utenti che leggono o meno"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__specific_user_ids
msgid "Specific User"
msgstr "Utente specifico"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__announcement__announcement_type__specific_users
msgid "Specific users"
msgstr "Utenti specifici"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Tag"
msgstr "Etichetta"
#. module: announcement
#: model:ir.model.constraint,message:announcement.constraint_announcement_tag_name_uniq
msgid "Tag name already exists!"
msgstr "Il nome dell'etichetta esiste già!"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__tag_ids
msgid "Tags"
msgstr "Etichette"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Tags..."
msgstr "Etichette..."
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__notification_end_date
#: model:ir.model.fields,help:announcement.field_announcement__notification_start_date
msgid "Technical field to display announcements in the calendar view"
msgstr "Campo tecnico per visualizzare le notifiche nella vista calendario"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__color
msgid "Technical field to display items by color in the calendar"
msgstr "Campo tecnico per visualizzare elementi per colore nel calendario"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__name
msgid "Title"
msgstr "Titolo"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_tree
msgid "Total users"
msgstr "Utenti totali"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__read_announcement_wizard__read_state__unread
msgid "Unread"
msgstr "Non letto"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_res_users__unread_announcement_ids
msgid "Unread Announcement"
msgstr "Notifica non letta"
#. module: announcement
#: model:ir.model,name:announcement.model_res_users
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__user_id
msgid "User"
msgstr "Utente"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__user_group_ids
msgid "User Group"
msgstr "Gruppo utente"
#. module: announcement
#: model:ir.model,name:announcement.model_announcement
msgid "User announcements"
msgstr "Notifiche utente"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__announcement__announcement_type__user_group
msgid "User groups"
msgstr "Gruppi utente"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "Users"
msgstr "Utenti"
#. module: announcement
#: model:res.groups,comment:announcement.announcemenent_manager
msgid "Users allowed to manage and configure announcements."
msgstr "Utenti abilitati a gestire e configurare notifiche."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Valid up to"
msgstr "Valida fino al"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__attachment_ids
msgid "You can attach the copy of your Letter"
msgstr "Si può allegare la copia della lettera"
#. module: announcement
#. odoo-python
#: code:addons/announcement/models/announcement_tag.py:0
#, python-format
msgid "You cannot create recursive tags."
msgstr "Non si possono creare etichette ricorsive."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "e.g. Announcement description..."
msgstr "es. Descrizione notifica..."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_calendar
msgid "name"
msgstr "nome"

View file

@ -0,0 +1,450 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * announcement
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-02-25 15:52+0000\n"
"Last-Translator: İsmail Çağan Yılmaz <ismail.cagan.yilmaz@gmail.com>\n"
"Language-Team: none\n"
"Language: tr\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 5.6.2\n"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "<span class=\"o_stat_text\">Read(s)</span>"
msgstr "<span class=\"o_stat_text\">Okuma(lar)</span>"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_3
msgid "Accounting"
msgstr "Muhasebe"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__active
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Active"
msgstr "Aktif"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__allowed_user_ids
msgid "Allowed User"
msgstr "Izin Verilen Kullanıcı"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__allowed_users_count
msgid "Allowed Users Count"
msgstr "Izin Verilen Kullanıcıların Sayısı"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Announce at"
msgstr "Şu tarihte duyurulsun"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: model:ir.model.fields,field_description:announcement.field_announcement_log__announcement_id
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__announcement_id
#: model:ir.module.category,name:announcement.category_announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
#, python-format
msgid "Announcement"
msgstr "Duyuru"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__announcement_log_ids
msgid "Announcement Log"
msgstr "Duyuru Kaydı"
#. module: announcement
#: model:ir.actions.act_window,name:announcement.action_announcement_log
msgid "Announcement Logs"
msgstr "Duyuru Kayıtları"
#. module: announcement
#: model:res.groups,name:announcement.announcemenent_manager
msgid "Announcement Manager"
msgstr "Duyuru Yöneticisi"
#. module: announcement
#: model:ir.actions.act_window,name:announcement.announcement_tag_action
#: model:ir.model,name:announcement.model_announcement_tag
#: model:ir.ui.menu,name:announcement.menu_announcement_tag_management
msgid "Announcement Tags"
msgstr "Duyuru Etiketleri"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__announcement_type
msgid "Announcement Type"
msgstr "Duyuru Tipi"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#: model:ir.actions.act_window,name:announcement.announcement_action
#: model:ir.ui.menu,name:announcement.menu_announcement_management
#, python-format
msgid "Announcements"
msgstr "Duyurular"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Archived"
msgstr "Arşivlenmiş"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__attachment_ids
msgid "Attachments"
msgstr "Ekler"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__color
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__color
msgid "Color"
msgstr "Renk"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__company_id
msgid "Company"
msgstr "Şirket"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_1
msgid "Company information"
msgstr "Şirket bilgileri"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement_tag__company_id
msgid "Company related to this tag"
msgstr "Bu etiketle ilişkili şirket"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__content
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Content"
msgstr "Içerik"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__create_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_log__create_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__create_uid
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__create_uid
msgid "Created by"
msgstr "Tarafından oluşturuldu"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__create_date
#: model:ir.model.fields,field_description:announcement.field_announcement_log__create_date
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__create_date
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__create_date
msgid "Created on"
msgstr "Tarihinde oluşturuldu"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__display_name
#: model:ir.model.fields,field_description:announcement.field_announcement_log__display_name
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__display_name
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__display_name
msgid "Display Name"
msgstr "Görünür Isim"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_2
msgid "Employees"
msgstr "Çalışanlar"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__full_name
msgid "Full Name"
msgstr "Tam Isim"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__is_general_announcement
msgid "General Announcement"
msgstr "Genel Duyuru"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "Groups"
msgstr "Gruplar"
#. module: announcement
#: model:ir.model,name:announcement.model_ir_http
msgid "HTTP Routing"
msgstr "HTTP Yönlendirme"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__id
#: model:ir.model.fields,field_description:announcement.field_announcement_log__id
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__id
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__id
msgid "ID"
msgstr "ID"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__in_date
msgid "In Date"
msgstr "Tarihte"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement____last_update
#: model:ir.model.fields,field_description:announcement.field_announcement_log____last_update
#: model:ir.model.fields,field_description:announcement.field_announcement_tag____last_update
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard____last_update
msgid "Last Modified on"
msgstr "Son Değiştirilme tarihi"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__write_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_log__write_uid
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__write_uid
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__write_uid
msgid "Last Updated by"
msgstr "Son Güncelleyen"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__write_date
#: model:ir.model.fields,field_description:announcement.field_announcement_log__write_date
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__write_date
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__write_date
msgid "Last Updated on"
msgstr "Son Güncelleme tarihi"
#. module: announcement
#: model:ir.model,name:announcement.model_announcement_log
msgid "Log user reads"
msgstr "Kullanıcı okumalarını kaydet"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_5
msgid "Manufacturing"
msgstr "Üretim"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.esm.js:0
#, python-format
msgid "Mark as read"
msgstr "Okundu olarak işaretle"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__name
msgid "Name"
msgstr "Isim"
#. module: announcement
#. odoo-javascript
#: code:addons/announcement/static/src/js/announcement_menu/announcement_menu.xml:0
#, python-format
msgid "No announcements."
msgstr "Duyuru bulunamadı."
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_date
msgid "Notification Date"
msgstr "Bildirim Tarihi"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_end_date
msgid "Notification End Date"
msgstr "Bildirim Bitiş Tarihi"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_expiry_date
msgid "Notification Expiry Date"
msgstr "Bildirim Süresi Geçme Tarihi"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__notification_start_date
msgid "Notification Start Date"
msgstr "Bildirim Başlama Tarihi"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement_tag__parent_id
msgid "Parent Tag"
msgstr "Üst Etiket"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__read_announcement_wizard__read_state__read
msgid "Read"
msgstr "Okundu"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_res_users__read_announcement_ids
msgid "Read Announcement"
msgstr "Okunmuş Duyuru"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__read_announcement_count
msgid "Read Announcement Count"
msgstr "Duyuru Okunma Sayısı"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__date
msgid "Read Date"
msgstr "Okunma Tarihi"
#. module: announcement
#. odoo-python
#: code:addons/announcement/models/announcement.py:0
#, python-format
msgid "Read Logs"
msgstr "Okunma Kayıtları"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__read_state
msgid "Read State"
msgstr "Okunma Durumu"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_tree
msgid "Reads"
msgstr "Okunmalar"
#. module: announcement
#: model:announcement.tag,name:announcement.announcement_tag_4
msgid "Sales"
msgstr "Satış"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__sequence
msgid "Sequence"
msgstr "Dizi"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Set here the content of the announcement."
msgstr "Duyuru içeriğini buradan ayarlayın."
#. module: announcement
#: model:ir.model,name:announcement.model_read_announcement_wizard
msgid "Show altogether users who read and users who didn't"
msgstr "Okuyan ve okumayan kullanıcıları bir arada göster"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__specific_user_ids
msgid "Specific User"
msgstr "Belirli Kullanıcı"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__announcement__announcement_type__specific_users
msgid "Specific users"
msgstr "Belirli kullanıcılar"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_search
msgid "Tag"
msgstr "Etiket"
#. module: announcement
#: model:ir.model.constraint,message:announcement.constraint_announcement_tag_name_uniq
msgid "Tag name already exists!"
msgstr "Etiket adı zaten mevcut!"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__tag_ids
msgid "Tags"
msgstr "Etiketler"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Tags..."
msgstr "Etiketler..."
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__notification_end_date
#: model:ir.model.fields,help:announcement.field_announcement__notification_start_date
msgid "Technical field to display announcements in the calendar view"
msgstr "Duyuruları takvim görünümünde görüntülemek için teknik alan"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__color
msgid "Technical field to display items by color in the calendar"
msgstr "Takvimdeki öğeleri renge göre görüntülemek için teknik alan"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__name
msgid "Title"
msgstr "Başlık"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_tree
msgid "Total users"
msgstr "Toplam kullanıcı"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__read_announcement_wizard__read_state__unread
msgid "Unread"
msgstr "Okunmadı"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_res_users__unread_announcement_ids
msgid "Unread Announcement"
msgstr "Okunmamış Duyuru"
#. module: announcement
#: model:ir.model,name:announcement.model_res_users
#: model:ir.model.fields,field_description:announcement.field_read_announcement_wizard__user_id
msgid "User"
msgstr "Kullanıcı"
#. module: announcement
#: model:ir.model.fields,field_description:announcement.field_announcement__user_group_ids
msgid "User Group"
msgstr "Kullanıcı Grubu"
#. module: announcement
#: model:ir.model,name:announcement.model_announcement
msgid "User announcements"
msgstr "Kullanıcı duyuruları"
#. module: announcement
#: model:ir.model.fields.selection,name:announcement.selection__announcement__announcement_type__user_group
msgid "User groups"
msgstr "Kullanıcı grubu"
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_management_view_form
msgid "Users"
msgstr "Kullanıcılar"
#. module: announcement
#: model:res.groups,comment:announcement.announcemenent_manager
msgid "Users allowed to manage and configure announcements."
msgstr "Duyuruları yönetmesine ve yapılandırmasına izin verilen kullanıcılar."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "Valid up to"
msgstr "Şu tarihe kadar geçerli"
#. module: announcement
#: model:ir.model.fields,help:announcement.field_announcement__attachment_ids
msgid "You can attach the copy of your Letter"
msgstr "Mektubunuzun kopyasını ekleyebilirsiniz"
#. module: announcement
#. odoo-python
#: code:addons/announcement/models/announcement_tag.py:0
#, python-format
msgid "You cannot create recursive tags."
msgstr "Tekrar eden etiketler oluşturamazsınız."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_form
msgid "e.g. Announcement description..."
msgstr "örneğin Duyuru açıklaması..."
#. module: announcement
#: model_terms:ir.ui.view,arch_db:announcement.announcement_view_calendar
msgid "name"
msgstr "isim"

View file

@ -0,0 +1,4 @@
from . import announcement
from . import announcement_tag
from . import res_users
from . import ir_http

View file

@ -0,0 +1,274 @@
# Copyright 2022 Tecnativa - David Vidal
# Copyright 2022 Tecnativa - Pilar Vargas
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
class AnnouncementLog(models.Model):
_name = "announcement.log"
_description = "Log user reads"
_order = "create_date desc"
announcement_id = fields.Many2one(comodel_name="announcement")
class Announcement(models.Model):
_name = "announcement"
_description = "User announcements"
_order = "notification_date, sequence asc, id"
active = fields.Boolean(copy=False)
sequence = fields.Integer()
name = fields.Char(string="Title", required=True)
content = fields.Html()
tag_ids = fields.Many2many(
comodel_name="announcement.tag",
column1="announcement_id",
column2="tag_id",
string="Tags",
)
is_general_announcement = fields.Boolean("General Announcement")
attachment_ids = fields.Many2many(
comodel_name="ir.attachment",
string="Attachments",
help="You can attach the copy of your Letter",
)
announcement_type = fields.Selection(
selection=[
("specific_users", "Specific users"),
("user_group", "User groups"),
],
default="specific_users",
required=True,
)
specific_user_ids = fields.Many2many(
comodel_name="res.users",
context={"active_test": False},
domain=[("share", "=", False)],
inverse="_inverse_specific_user_ids",
)
user_group_ids = fields.Many2many(
comodel_name="res.groups",
compute="_compute_user_group_ids",
store=True,
readonly=False,
)
allowed_user_ids = fields.Many2many(
comodel_name="res.users",
relation="announcement_res_users_allowed_rel",
compute="_compute_allowed_user_ids",
compute_sudo=True,
store=True,
)
allowed_users_count = fields.Integer(
compute="_compute_allowed_user_ids",
compute_sudo=True,
store=True,
)
read_announcement_count = fields.Integer(
compute="_compute_read_announcement_count",
store=True,
)
notification_date = fields.Datetime()
notification_expiry_date = fields.Datetime()
notification_start_date = fields.Datetime(
compute="_compute_notification_start_date",
help="Technical field to display announcements in the calendar view",
)
notification_end_date = fields.Datetime(
compute="_compute_notification_end_date",
help="Technical field to display announcements in the calendar view",
)
color = fields.Integer(
compute="_compute_color",
help="Technical field to display items by color in the calendar",
)
in_date = fields.Boolean(
compute="_compute_in_date", search="_search_in_date", compute_sudo=True
)
announcement_log_ids = fields.One2many(
comodel_name="announcement.log",
inverse_name="announcement_id",
)
def _inverse_specific_user_ids(self):
"""Used to set users unread announcements when they're set in the announcement
itself"""
for announcement in self:
for user in announcement.specific_user_ids.filtered(
lambda x: announcement
not in (x.read_announcement_ids + x.unread_announcement_ids)
):
user.unread_announcement_ids |= announcement
@api.depends("specific_user_ids", "user_group_ids")
def _compute_allowed_user_ids(self):
self.allowed_user_ids = False
self.allowed_users_count = False
specific_user_announcements = self.filtered(
lambda x: x.announcement_type == "specific_users"
)
for announcement in specific_user_announcements:
announcement.allowed_user_ids = announcement.specific_user_ids
announcement.allowed_users_count = len(announcement.specific_user_ids)
for announcement in self - specific_user_announcements:
announcement.allowed_user_ids = announcement.user_group_ids.users
announcement.allowed_users_count = len(announcement.user_group_ids.users)
@api.depends("is_general_announcement")
def _compute_user_group_ids(self):
for announcement in self:
if announcement.is_general_announcement:
announcement.announcement_type = "user_group"
announcement.user_group_ids = self.env.ref("base.group_user")
else:
announcement.user_group_ids = False
@api.depends("announcement_log_ids")
def _compute_read_announcement_count(self):
logs = self.env["announcement.log"].read_group(
[("announcement_id", "in", self.ids)],
["announcement_id"],
["announcement_id"],
)
result = {
data["announcement_id"][0]: (data["announcement_id_count"]) for data in logs
}
for announcement in self:
announcement.read_announcement_count = result.get(announcement.id, 0)
@api.depends("notification_date")
def _compute_notification_start_date(self):
"""This is a technical field that we'll use so we're able to render
announcements with no defined start date. Otherwise they don't show up"""
for announcement in self:
announcement.notification_start_date = (
announcement.notification_date or announcement.create_date
)
@api.depends("notification_expiry_date", "notification_date")
def _compute_notification_end_date(self):
"""This is a technical field that we'll use so we're able to render no end
announcements in the calendar"""
for announcement in self:
announcement.notification_end_date = (
announcement.notification_expiry_date
# We don't want undefined end announment appearing forever in the
# calendar just because one user didn't read them. So we just
# show them in the date they start
or announcement.notification_start_date
)
@api.depends("tag_ids")
def _compute_color(self):
"""Get the first tag color if any. Used in the calendar"""
self.color = False
for announcement in self.filtered("tag_ids"):
announcement.color = announcement.tag_ids[0].color
def _compute_in_date(self):
"""The announcement is publishable according to date criterias"""
self.in_date = False
now = fields.Datetime.now()
for record in self:
date_passed = (
not record.notification_date or record.notification_date <= now
)
date_unexpired = (
not record.notification_expiry_date
or record.notification_expiry_date >= now
)
record.in_date = date_passed and date_unexpired
def _search_in_date(self, operator, value):
"""Used mainly for record rules as time module values will be cached"""
now = fields.Datetime.now()
return [
"|",
("notification_date", "=", False),
("notification_date", "<=", now),
"|",
("notification_expiry_date", "=", False),
("notification_expiry_date", ">=", now),
]
def _process_attachments(self, vals):
"""Assign attachments owner (if not yet set) or create a copy of the added
attachments for making sure that they are accessible to the users that read
the announcement.
"""
if self.env.context.get("bypass_attachment_process"):
return
for command in vals.get("attachment_ids", []):
to_process = []
if command[0] == 4:
to_process.append(command[1])
elif command[0] == 6:
to_process += command[2]
for attachment_id in to_process:
attachment = self.env["ir.attachment"].browse(attachment_id)
for record in self:
if not attachment.res_id:
attachment.res_id = record.id
attachment.res_model = record._name
else:
new_attachment = attachment.copy(
{"res_id": record.id, "res_model": record._name}
)
record.with_context(
bypass_attachment_process=True
).attachment_ids = [(3, attachment_id), (4, new_attachment.id)]
@api.model_create_multi
def create(self, vals_list):
"""Adjust attachments for being accesible to receivers of the announcement."""
records = super().create(vals_list)
for vals in vals_list:
records._process_attachments(vals)
return records
def write(self, vals):
"""Adjust attachments for being accesible to receivers of the announcement."""
res = super().write(vals)
self._process_attachments(vals)
return res
@api.onchange("announcement_type")
def _onchange_announcement_type(self):
"""We want to reset the values on screen"""
if self.announcement_type == "specific_users":
self.user_group_ids = False
elif self.announcement_type == "user_group":
self.specific_user_ids = False
def action_announcement_log(self):
"""See altogether read logs and unread users"""
self.ensure_one()
read_logs = self.env["announcement.log"].search(
[("announcement_id", "in", self.ids)]
)
unread_users = self.allowed_user_ids.filtered(
lambda x: x not in read_logs.create_uid
)
read_unread_log = self.env["read.announcement.wizard"].create(
[
{
"user_id": log.create_uid.id,
"date": log.create_date,
"announcement_id": self.id,
"read_state": "read",
}
for log in read_logs
]
)
read_unread_log += self.env["read.announcement.wizard"].create(
[{"user_id": user.id, "read_state": "unread"} for user in unread_users]
)
return {
"type": "ir.actions.act_window",
"res_model": "read.announcement.wizard",
"views": [[False, "tree"]],
"domain": [("id", "in", read_unread_log.ids)],
"context": dict(self.env.context, create=False, group_by=["read_state"]),
"name": _("Read Logs"),
}

View file

@ -0,0 +1,45 @@
# Copyright 2023 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class AnnouncementTag(models.Model):
_name = "announcement.tag"
_description = "Announcement Tags"
name = fields.Char(required=True, translate=True)
color = fields.Integer()
parent_id = fields.Many2one(
comodel_name="announcement.tag",
string="Parent Tag",
index=True,
ondelete="cascade",
)
full_name = fields.Char(compute="_compute_full_name")
company_id = fields.Many2one(
comodel_name="res.company",
string="Company",
index=True,
help="Company related to this tag",
)
_sql_constraints = [("name_uniq", "unique (name)", "Tag name already exists!")]
@api.constrains("parent_id")
def _check_parent_id(self):
if not self._check_recursion():
raise ValidationError(_("You cannot create recursive tags."))
@api.depends("parent_id", "name")
def _compute_full_name(self):
for item in self:
item.full_name = (
item.parent_id.name + " / " + item.name if item.parent_id else item.name
)
def name_get(self):
res = []
for item in self:
res.append((item.id, item.full_name))
return res

View file

@ -0,0 +1,12 @@
# Copyright 2024 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import models
class IrHttp(models.AbstractModel):
_inherit = "ir.http"
def session_info(self):
res = super(IrHttp, self).session_info()
res["announcements"] = self.env["res.users"].get_announcements()
return res

View file

@ -0,0 +1,93 @@
# Copyright 2022 Tecnativa - David Vidal
# Copyright 2022 Tecnativa - Pilar Vargas
# Copyright 2022 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from markupsafe import Markup
from odoo import api, fields, models
class ResUsers(models.Model):
_inherit = "res.users"
unread_announcement_ids = fields.Many2many(
comodel_name="announcement",
relation="unread_announcement_user_rel",
)
read_announcement_ids = fields.Many2many(
comodel_name="announcement",
relation="read_announcement_user_rel",
)
@api.model
def announcement_user_count(self):
"""The js widget gathers the announcements from this method"""
# It would be better to rely on record rules, but then announcement managers
# would see every announcement, which would be annoying.
group_announcements = self.env["announcement"].search_read(
[
("announcement_type", "=", "user_group"),
("in_date", "=", True),
("id", "not in", self.env.user.read_announcement_ids.ids),
],
["user_group_ids"],
)
announcements = self.env["announcement"].browse(
{
x["id"]
for x in group_announcements
if any(
[g for g in x["user_group_ids"] if g in self.env.user.groups_id.ids]
)
}
)
# Unread announcements are directly linked to the user. Normally, only a
# handful of records will be evaluated at best.
announcements |= self.env.user.unread_announcement_ids.filtered("in_date")
return [
{
"id": announcement.id,
"name": announcement.name,
"content": self._add_attachment_links(announcement),
}
for announcement in announcements.sorted(lambda k: k.sequence)
]
@api.model
def get_announcements(self):
announcements = self.announcement_user_count()
return {
"data": announcements,
"count": len(announcements),
}
def _add_attachment_links(self, announcement):
"""In case the announcement has attachments, show the list below the
modal content"""
content = announcement.content or Markup("")
attachment_links = ""
if announcement.attachment_ids:
attachment_links += "<div class='list-group'>"
for attachment in announcement.attachment_ids:
attachment_url = "/web/content/%s?download=false" % attachment.id
attachment_link = """<a href="%s" class="list-group-item list-group-item-action"
target="_blank"><i class="fa fa-download" /> %s</a>""" % (
attachment_url,
attachment.name,
)
attachment_links += attachment_link
attachment_links += "</div>"
if attachment_links:
content += Markup("<br/>") + Markup(attachment_links)
return content
@api.model
def mark_announcement_as_read(self, announcement_id):
"""Used as a controller for the widget"""
announcement = self.env["announcement"].browse(int(announcement_id))
self.env.user.unread_announcement_ids -= announcement
# Log only the first time. Users with the announcement in multiple windows would
# log multiple reads. We're only interested in the first one.
if announcement not in self.env.user.read_announcement_ids:
self.env.user.read_announcement_ids += announcement
self.env["announcement.log"].create({"announcement_id": announcement.id})

View file

@ -0,0 +1,21 @@
To create new announcements a user should be in the *Announcements Managers* group.
When your user has such permissions, this is the way to create an announcement:
#. Go to *Discuss > Announcements*
#. Create a new one and define a title. This title will be shown in the announcement
header.
#. Define the announcement scope:
- Specific users: manually select which users will see the announcement.
- User groups: users from the selected groups will be the ones to see the
announcement.
#. Define the announcement body. You can use rich formatting and event paste your
own html (editor in debug mode).
#. By default, the announcement will be archived. This is to prevent the announcement
to show up before time.
#. Once the announcement is ready, unarchive it going to the *Actions* menu an choosing
the *Unarchive* option.
#. Optionally you can set an announcement date to schedule the announcement. The
announcement won't show up until that date.
#. If the announcement doesn't make sense once a date is passed, you can set a due date.
From that date, the announcement won't be shown to anyone.

View file

@ -0,0 +1,5 @@
* `Tecnativa <https://www.tecnativa.com>`__:
* Pedro M. Baeza
* David Vidal
* Carlos Roca

View file

@ -0,0 +1,2 @@
This module adds popup announcements in the backend for targeted internal users. Those
announcements can contain rich format and a user read log is kept for everyone.

View file

@ -0,0 +1,3 @@
* It could be integrated in Discuss app to review past announcements.
* Log other information like geolocation, IP, browser agent, etc when marking
announcement as read.

View file

@ -0,0 +1,8 @@
When a user in the scope of active announcements logs in, those will popup. The user
has to mark them as read to continue working. If the announcement is set during the
user session, the announcement will be eventually prompted in the top bar on the right
part. The user click on the unread announcements icon (a speaker) and the announcements
will popup for the user to check them.
Users can go *Discuss > Announcements* to check current and past announcements.
Announcement managers can also track which users have read the announcement.

View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="category_announcement" model="ir.module.category">
<field name="name">Announcement</field>
</record>
<record id="announcemenent_manager" model="res.groups">
<field name="name">Announcement Manager</field>
<field name="category_id" ref="category_announcement" />
<field name="implied_ids" eval="[(4, ref('base.group_user'))]" />
<field
name="comment"
>Users allowed to manage and configure announcements.</field>
<field
name="users"
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"
/>
</record>
<data noupdate="1">
<record model="ir.rule" id="announcement_log_rule">
<field name="name">Announcement log per user</field>
<field name="model_id" ref="model_announcement_log" />
<field name="domain_force">[('create_uid','=', user.id)]</field>
<field name="perm_read" eval="False" />
</record>
<record model="ir.rule" id="announcement_log_manager_rule">
<field name="name">Announcement log manager</field>
<field name="model_id" ref="model_announcement_log" />
<field name="domain_force">[(1, '=', 1)]</field>
<field
name="groups"
eval="[(4, ref('announcement.announcemenent_manager'))]"
/>
</record>
<record id="announcement_user_rule" model="ir.rule">
<field name="name">User announcements</field>
<field ref="model_announcement" name="model_id" />
<field
name="domain_force"
>[('active', '=', True), ('allowed_user_ids', 'in', user.id), ('in_date', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]" />
</record>
<record id="announcement_manager_rule" model="ir.rule">
<field name="name">Announcement managers</field>
<field ref="model_announcement" name="model_id" />
<field name="domain_force">[(1, '=', 1)]</field>
<field
name="groups"
eval="[(4, ref('announcement.announcemenent_manager'))]"
/>
</record>
</data>
<!-- Company Rules !-->
<record id="rule_multi_company_announcement_tag" model="ir.rule">
<field name="name">Announcement Tag multi-company</field>
<field name="model_id" ref="model_announcement_tag" />
<field name="domain_force">[('company_id', 'in', [False] + company_ids)]</field>
</record>
</odoo>

View file

@ -0,0 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_announcement_management,announcement.manager,model_announcement,announcement.announcemenent_manager,1,1,1,1
access_announcement_user,announcement.user,model_announcement,base.group_user,1,0,0,0
access_announcement_log_all,announcement_log_all,model_announcement_log,base.group_user,1,0,1,0
access_read_announcement_wizard,access_read_announcement_wizard,model_read_announcement_wizard,announcemenent_manager,1,1,1,1
access_announcement_tag_management,announcement.tag.manager,model_announcement_tag,announcement.announcemenent_manager,1,1,1,1
access_announcement_tag_user,announcement.tag.user,model_announcement_tag,base.group_user,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_announcement_management announcement.manager model_announcement announcement.announcemenent_manager 1 1 1 1
3 access_announcement_user announcement.user model_announcement base.group_user 1 0 0 0
4 access_announcement_log_all announcement_log_all model_announcement_log base.group_user 1 0 1 0
5 access_read_announcement_wizard access_read_announcement_wizard model_read_announcement_wizard announcemenent_manager 1 1 1 1
6 access_announcement_tag_management announcement.tag.manager model_announcement_tag announcement.announcemenent_manager 1 1 1 1
7 access_announcement_tag_user announcement.tag.user model_announcement_tag base.group_user 1 0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

@ -0,0 +1,476 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Announcement</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="announcement">
<h1 class="title">Announcement</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:784e888a875fb1f37b9d3a48ca5c5c63bdec23a06cce24e648a5910f4907891d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/server-ux/tree/16.0/announcement"><img alt="OCA/server-ux" src="https://img.shields.io/badge/github-OCA%2Fserver--ux-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/server-ux-16-0/server-ux-16-0-announcement"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/server-ux&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module adds popup announcements in the backend for targeted internal users. Those
announcements can contain rich format and a user read log is kept for everyone.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="toc-entry-1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-3">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-4">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-7">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-8">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
<p>To create new announcements a user should be in the <em>Announcements Managers</em> group.
When your user has such permissions, this is the way to create an announcement:</p>
<ol class="arabic simple">
<li>Go to <em>Discuss &gt; Announcements</em></li>
<li>Create a new one and define a title. This title will be shown in the announcement
header.</li>
<li>Define the announcement scope:<ul>
<li>Specific users: manually select which users will see the announcement.</li>
<li>User groups: users from the selected groups will be the ones to see the
announcement.</li>
</ul>
</li>
<li>Define the announcement body. You can use rich formatting and event paste your
own html (editor in debug mode).</li>
<li>By default, the announcement will be archived. This is to prevent the announcement
to show up before time.</li>
<li>Once the announcement is ready, unarchive it going to the <em>Actions</em> menu an choosing
the <em>Unarchive</em> option.</li>
<li>Optionally you can set an announcement date to schedule the announcement. The
announcement wont show up until that date.</li>
<li>If the announcement doesnt make sense once a date is passed, you can set a due date.
From that date, the announcement wont be shown to anyone.</li>
</ol>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
<p>When a user in the scope of active announcements logs in, those will popup. The user
has to mark them as read to continue working. If the announcement is set during the
user session, the announcement will be eventually prompted in the top bar on the right
part. The user click on the unread announcements icon (a speaker) and the announcements
will popup for the user to check them.</p>
<p>Users can go <em>Discuss &gt; Announcements</em> to check current and past announcements.
Announcement managers can also track which users have read the announcement.</p>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>It could be integrated in Discuss app to review past announcements.</li>
<li>Log other information like geolocation, IP, browser agent, etc when marking
announcement as read.</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/server-ux/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/server-ux/issues/new?body=module:%20announcement%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-5">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-6">Authors</a></h2>
<ul class="simple">
<li>Tecnativa</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
<ul class="simple">
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>Pedro M. Baeza</li>
<li>David Vidal</li>
<li>Carlos Roca</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>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.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/server-ux/tree/16.0/announcement">OCA/server-ux</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,8 @@
/* @odoo-module */
/* Copyright 2024 Tecnativa - Carlos Roca
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
import {ConfirmationDialog} from "@web/core/confirmation_dialog/confirmation_dialog";
// Defined AnnouncementDialog to allow make possible changes in other modules
// like announcement_dialog_size
export class AnnouncementDialog extends ConfirmationDialog {}

View file

@ -0,0 +1,124 @@
/* @odoo-module */
/* Copyright 2024 Tecnativa - David Vidal
* Copyright 2024 Tecnativa - Carlos Roca
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
import {Component, markup, onMounted, useState} from "@odoo/owl";
import {_lt} from "@web/core/l10n/translation";
import {Dropdown} from "@web/core/dropdown/dropdown";
import {DropdownItem} from "@web/core/dropdown/dropdown_item";
import {session} from "@web/session";
import {registry} from "@web/core/registry";
import {useService} from "@web/core/utils/hooks";
import {AnnouncementDialog} from "../announcement_dialog/announcement_dialog.esm";
export class AnnouncementMenu extends Component {
setup() {
this.orm = useService("orm");
this.dialogService = useService("dialog");
const announcements_service = useService("announcementService");
this.announcements = useState(announcements_service.announcements);
this.announcementMenuView = useState({isOpen: false});
// When the user logs in we show him his unread announcements
onMounted(async () => {
document.addEventListener(
"click",
this._onClickCaptureGlobal.bind(this),
true
);
// Let's check if the user just logged in and to decide if we popup the
// announcements. This delay is hardcoded to 5 minutes, although we could
// allow to configure it in the future.
const user = await this.orm.call("res.users", "read", [
session.uid,
["login_date"],
]);
const login_date = !_.isEmpty(user) && user[0].login_date;
const minutes_since_last_login =
(moment.utc(new Date()).valueOf() - moment.utc(login_date).valueOf()) /
1000 /
60;
const popup_announcement = Boolean(minutes_since_last_login < 5);
const launchPopUp = () => {
if (odoo.isReady) {
if (popup_announcement && this.announcements.count > 0) {
this.openAnnouncement(this.announcements.data[0]);
}
} else {
setTimeout(launchPopUp, 500);
}
};
setTimeout(launchPopUp, 500);
});
}
async getDialogAnnouncementProps(announcement) {
return {
title: announcement.name,
body: markup(announcement.content || ""),
confirm: async () => {
await this.orm.call(
"res.users",
"mark_announcement_as_read",
[announcement.id],
{context: session.user_context}
);
this.announcements.data = this.announcements.data.filter(
(el) => el.id !== announcement.id
);
this.announcements.count--;
if (this.announcements.count > 0) {
this.openAnnouncement(this.announcements.data[0]);
}
},
confirmLabel: _lt("Mark as read"),
};
}
// ------------------------------------------------------------
// Handlers
// ------------------------------------------------------------
/**
* Toggle dropdown when clicking it
* @private
*/
onClickDropdownToggle() {
this.announcementMenuView.isOpen = !this.announcementMenuView.isOpen;
}
/**
* Hide dropdown when clicking outside
* @private
* @param {MouseEvent} ev
*/
_onClickCaptureGlobal(ev) {
if (this.__owl__.refs.root.contains(ev.target)) {
return;
}
this.announcementMenuView.isOpen = false;
}
/**
* Show announcement popup
* @private
* @param {MouseEvent} event
*/
async openAnnouncement(announcement) {
this.dialogService.add(
AnnouncementDialog,
await this.getDialogAnnouncementProps(announcement)
);
}
}
AnnouncementMenu.components = {Dropdown, DropdownItem};
AnnouncementMenu.props = [];
AnnouncementMenu.template = "announcement.AnnouncementMenu";
export const systrayAnnouncement = {
Component: AnnouncementMenu,
};
registry
.category("systray")
.add("announcement.announcement_menu", systrayAnnouncement, {sequence: 100});

View file

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates>
<t t-name="announcement.AnnouncementMenu" owl="1">
<div class="o_ActivityMenuView dropdown" t-ref="root">
<a
class="o_ActivityMenuView_dropdownToggle dropdown-toggle o-no-caret o-dropdown--narrow"
t-att-aria-expanded="announcementMenuView.isOpen ? 'true' : 'false'"
title="Announcements"
href="#"
role="button"
t-on-click="onClickDropdownToggle"
>
<i
class="fa fa-lg fa-bullhorn"
role="img"
aria-label="Announcements"
/> <span
t-if="announcements.count > 0"
class="badge bg-warning"
t-out="announcements.count"
/>
</a>
<div
t-if="announcementMenuView.isOpen"
class="o_ActivityMenuView_dropdownMenu o-dropdown-menu dropdown-menu-end show bg-view"
role="menu"
>
<div class="o_ActivityMenuView_activityGroups">
<t t-if="announcements.count > 0">
<t
t-foreach="announcements.data"
t-as="announcement"
t-key="announcement.id"
>
<div
class="o_ActivityMenuView_activityGroup"
t-on-click="() => this.openAnnouncement(announcement)"
>
<div
class="o_ActivityMenuView_activityGroupIconContainer"
>
<img
src="/announcement/static/description/icon.png"
alt="Announcement"
/>
</div>
<div class="o_ActivityMenuView_activityGroupInfo">
<div class="o_ActivityMenuView_activityGroupTitle">
<span
class="o_ActivityMenuView_activityGroupName"
>
<t t-esc="announcement.name" />
</span>
</div>
</div>
</div>
</t>
</t>
<t t-else="">
<div
class="o_ActivityMenuView_noActivity dropdown-item-text text-center d-flex justify-content-center"
>
<span>No announcements.</span>
</div>
</t>
</div>
</div>
</div>
</t>
</templates>
<!-- -->

View file

@ -0,0 +1,38 @@
/** @odoo-module */
/* Copyright 2024 Tecnativa - David Vidal
* Copyright 2024 Tecnativa - Carlos Roca
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
import {registry} from "@web/core/registry";
import {session} from "@web/session";
const {reactive} = owl;
export const announcementService = {
dependencies: ["orm"],
async start(env, {orm}) {
const announcements = reactive({});
if (session.announcements) {
Object.assign(announcements, session.announcements);
} else {
Object.assign(
announcements,
await orm.call("res.users", "get_announcements", [], {
context: session.user_context,
})
);
}
setInterval(async () => {
Object.assign(
announcements,
await orm.call("res.users", "get_announcements", [], {
context: session.user_context,
})
);
}, 60000);
return {
announcements,
};
},
};
registry.category("services").add("announcementService", announcementService);

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2023 Tecnativa - Víctor Martínez
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="announcement_tag_view_tree" model="ir.ui.view">
<field name="model">announcement.tag</field>
<field name="arch" type="xml">
<tree>
<field name="display_name" />
<field name="color" widget="color_picker" />
<field name="company_id" groups="base.group_multi_company" />
</tree>
</field>
</record>
<record id="announcement_tag_view_form" model="ir.ui.view">
<field name="model">announcement.tag</field>
<field name="arch" type="xml">
<form>
<sheet>
<group name="main_group">
<group name="left_group">
<field name="name" />
<field name="parent_id" />
<field
name="company_id"
groups="base.group_multi_company"
/>
</group>
<group name="right_group">
<field name="color" widget="color_picker" />
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="announcement_tag_action" model="ir.actions.act_window">
<field name="name">Announcement Tags</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">announcement.tag</field>
<field name="view_mode">tree,form</field>
<field name="context">{}</field>
</record>
<menuitem
id="menu_announcement_tag_management"
parent="mail.mail_menu_technical"
action="announcement_tag_action"
/>
</odoo>

View file

@ -0,0 +1,242 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2022 Tecnativa - David Vidal
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="announcement_log_view_tree" model="ir.ui.view">
<field name="model">announcement.log</field>
<field name="arch" type="xml">
<tree>
<field name="create_date" />
<field name="create_uid" />
</tree>
</field>
</record>
<record id="action_announcement_log" model="ir.actions.act_window">
<field name="name">Announcement Logs</field>
<field name="res_model">announcement.log</field>
<field name="context">{}</field>
<field name="domain">[('announcement_id', '=', active_id)]</field>
<field name="view_mode">tree</field>
</record>
<record id="announcement_view_tree" model="ir.ui.view">
<field name="model">announcement</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="notification_date" />
<field name="notification_expiry_date" />
<field
name="tag_ids"
optional="hide"
widget="many2many_tags"
options="{'color_field': 'color'}"
/>
</tree>
</field>
</record>
<record id="announcement_management_view_tree" model="ir.ui.view">
<field name="model">announcement</field>
<field name="inherit_id" ref="announcement_view_tree" />
<!-- <field
name="groups_id"
eval="[(4, ref('announcement.announcemenent_manager'))]"
/> -->
<field name="arch" type="xml">
<field name="name" position="before">
<field name="sequence" widget="handle" />
</field>
<field name="notification_expiry_date" position="after">
<field name="read_announcement_count" string="Reads" />
<field name="allowed_users_count" string="Total users" />
</field>
</field>
</record>
<record id="announcement_view_form" model="ir.ui.view">
<field name="model">announcement</field>
<field name="arch" type="xml">
<form string="Announcement">
<sheet>
<div class="oe_button_box" name="button_box" />
<widget
name="web_ribbon"
title="Archived"
bg_color="bg-danger"
attrs="{'invisible': [('active', '=', True)]}"
/>
<div class="oe_title">
<h1>
<field
name="name"
required="1"
placeholder="e.g. Announcement description..."
/>
</h1>
</div>
<group>
<field name="is_general_announcement" />
</group>
<group>
<field name="active" invisible="1" />
<group name="announcement_validity">
<field name="notification_date" string="Announce at" />
<field
name="notification_expiry_date"
string="Valid up to"
/>
<field
name="tag_ids"
widget="many2many_tags"
options="{'color_field': 'color'}"
placeholder="Tags..."
/>
</group>
</group>
<group>
<field name="attachment_ids" widget="many2many_binary" />
</group>
<notebook>
<page name="content" string="Content">
<group>
<!-- TIP: We could use website widgets in the same way website.mass_mailing.popup does.
A compatibility module should be made thou -->
<field
name="content"
nolabel="1"
colspan="2"
placeholder="Set here the content of the announcement."
/>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="announcement_management_view_form" model="ir.ui.view">
<field name="model">announcement</field>
<field name="inherit_id" ref="announcement_view_form" />
<!-- <field
name="groups_id"
eval="[(4, ref('announcement.announcemenent_manager'))]"
/> -->
<field name="arch" type="xml">
<xpath expr="//div[@name='button_box']" position="inside">
<button
type="object"
name="action_announcement_log"
icon="fa-book"
class="oe_stat_button"
>
<div class="o_stat_info">
<span class="o_stat_value">
<field name="read_announcement_count" /> / <field
name="allowed_users_count"
/>
</span>
<span class="o_stat_text">Read(s)</span>
</div>
</button>
</xpath>
<group name="announcement_validity" position="before">
<group
name="announcement_scope"
attrs="{'invisible': [('is_general_announcement', '=', True)]}"
>
<field name="announcement_type" />
<field
name="specific_user_ids"
string="Users"
options="{'no_create': True}"
attrs="{'invisible': [('announcement_type', '!=', 'specific_users')], 'required': [('announcement_type', '=', 'specific_users')]}"
widget="many2many_tags"
/>
<field
name="user_group_ids"
string="Groups"
options="{'no_create': True}"
attrs="{'invisible': [('announcement_type', '!=', 'user_group')], 'required': [('announcement_type', '=', 'user_group')]}"
widget="many2many_tags"
/>
</group>
</group>
</field>
</record>
<record id="announcement_view_kanban" model="ir.ui.view">
<field name="model">announcement</field>
<field name="arch" type="xml">
<kanban class="o_kanban_mobile">
<field name="name" />
<field name="content" />
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
<div class="row mb4">
<div class="col-12">
<t t-esc="record.name.value" />
<t t-out="record.content.raw_value" />
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="announcement_view_calendar" model="ir.ui.view">
<field name="model">announcement</field>
<field name="arch" type="xml">
<calendar
date_start="notification_start_date"
date_stop="notification_end_date"
string="name"
mode="month"
color="color"
hide_time="true"
>
<field name="notification_date" />
<field name="notification_expiry_date" />
<field name="tag_ids" />
</calendar>
</field>
</record>
<record id="announcement_view_search" model="ir.ui.view">
<field name="model">announcement</field>
<field name="arch" type="xml">
<search>
<field name="notification_date" />
<field name="notification_expiry_date" />
<field name="specific_user_ids" />
<field name="content" />
<field name="active" />
<field
name="tag_ids"
string="Tag"
filter_domain="[('tag_ids', 'child_of', self)]"
/>
<separator />
<filter
string="Active"
name="current"
domain="[('active', '=', True)]"
/>
<filter
string="Archived"
name="archived"
domain="[('active', '=', False)]"
/>
</search>
</field>
</record>
<record id="announcement_action" model="ir.actions.act_window">
<field name="name">Announcements</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">announcement</field>
<field name="view_mode">tree,kanban,calendar,form</field>
<field name="context">{}</field>
</record>
<menuitem
id="menu_announcement_management"
parent="mail.menu_root_discuss"
action="announcement_action"
/>
</odoo>

View file

@ -0,0 +1 @@
from . import read_announcement_wizard

View file

@ -0,0 +1,14 @@
# Copyright 2022 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ReadAnnouncementWizard(models.TransientModel):
_name = "read.announcement.wizard"
_description = "Show altogether users who read and users who didn't"
_order = "date desc"
date = fields.Datetime(string="Read Date")
user_id = fields.Many2one(comodel_name="res.users")
announcement_id = fields.Many2one(comodel_name="announcement")
read_state = fields.Selection(selection=[("read", "Read"), ("unread", "Unread")])

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2022 Tecnativa - David Vidal
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="read_announcement_wizard_view_tree" model="ir.ui.view">
<field name="model">read.announcement.wizard</field>
<field name="arch" type="xml">
<tree>
<field name="date" />
<field name="user_id" />
</tree>
</field>
</record>
</odoo>

View file

@ -0,0 +1,32 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Announcement Module - announcement
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for announcement. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,3 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -0,0 +1,5 @@
# Dependencies
This addon depends on:
- [mail](../../odoo-bringout-oca-ocb-mail)

View file

@ -0,0 +1,4 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon announcement or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-oca-server-ux-announcement"
# or
uv pip install odoo-bringout-oca-server-ux-announcement"
```

View file

@ -0,0 +1,16 @@
# Models
Detected core models and extensions in announcement.
```mermaid
classDiagram
class announcement
class announcement_log
class announcement_tag
class ir_http
class res_users
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: announcement. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon announcement
- License: LGPL-3

View file

@ -0,0 +1,3 @@
# Reports
This module does not define custom reports.

View file

@ -0,0 +1,42 @@
# Security
Access control and security definitions in announcement.
## Access Control Lists (ACLs)
Model access permissions defined in:
- **[ir.model.access.csv](../announcement/security/ir.model.access.csv)**
- 6 model access rules
## Record Rules
Row-level security rules defined in:
## Security Groups & Configuration
Security groups and permissions defined in:
- **[announcement_security.xml](../announcement/security/announcement_security.xml)**
- 1 security groups defined
```mermaid
graph TB
subgraph "Security Layers"
A[Users] --> B[Groups]
B --> C[Access Control Lists]
C --> D[Models]
B --> E[Record Rules]
E --> F[Individual Records]
end
```
Security files overview:
- **[announcement_security.xml](../announcement/security/announcement_security.xml)**
- Security groups, categories, and XML-based rules
- **[ir.model.access.csv](../announcement/security/ir.model.access.csv)**
- Model access permissions (CRUD rights)
Notes
- Access Control Lists define which groups can access which models
- Record Rules provide row-level security (filter records by user/group)
- Security groups organize users and define permission sets
- All security is enforced at the ORM level by Odoo

View file

@ -0,0 +1,5 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -0,0 +1,7 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon announcement
```

View file

@ -0,0 +1,3 @@
# Wizards
This module does not include UI wizards.

View file

@ -0,0 +1,42 @@
[project]
name = "odoo-bringout-oca-server-ux-announcement"
version = "16.0.0"
description = "Announcement - Notify internal users about relevant organization stuff"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-ocb-mail>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["announcement"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]