diff --git a/requirements.txt b/requirements.txt index a1b1b78c18..6f66e455b7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ # generated from manifests external_dependencies +linkedin-api-client requests_toolbelt +tweepy diff --git a/social_media_base/README.rst b/social_media_base/README.rst new file mode 100644 index 0000000000..3aae31bbf3 --- /dev/null +++ b/social_media_base/README.rst @@ -0,0 +1,109 @@ +================= +Social Media Base +================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:9ef0613fac59ec66dcecfb14f4bff101e89925782f08418a3cf3b64bdf731cd0 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fsocial-lightgray.png?logo=github + :target: https://github.com/OCA/social/tree/17.0/social_media_base + :alt: OCA/social +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/social-17-0/social-17-0-social_media_base + :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/social&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module provides the fundamental foundation for social media +management. It facilitates the integration of user accounts, posts, +reactions (likes), comments, and graph-based analysis. Designed to be +flexible and scalable, it allows developers and businesses to integrate +and customize social features according to their needs. + +Main features: + +- Integration of multiple user accounts. +- Basic methods that can be extended and adapted to suit the social + network. +- Basic business structure. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Generate group campaign. +------------------------ + +- Go to *Social Media* > Campaign group > New +- Fill in the required fields |CREATE_GROUP_CAMPAIGN| +- Save + +Generate campaign. +------------------ + +- Go to *Social Media* > Campaign > New +- Fill in the required fields |CREATE_CAMPAIGN| +- Save + +.. |CREATE_GROUP_CAMPAIGN| image:: https://raw.githubusercontent.com/OCA/social/17.0/social_media_base/static/img/readme/CREATE_GROUP_CAMPAIGN.png +.. |CREATE_CAMPAIGN| image:: https://raw.githubusercontent.com/OCA/social/17.0/social_media_base/static/img/readme/CREATE_CAMPAIGN.png + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* BinhexTeam + +Contributors +------------ + +- [Binhex Cloud] (https://www.binhex.cloud): + + - Edilio Escalona Almira e.escalona@binhex.cloud + +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/social `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/social_media_base/__init__.py b/social_media_base/__init__.py new file mode 100644 index 0000000000..4f82eb86b8 --- /dev/null +++ b/social_media_base/__init__.py @@ -0,0 +1,6 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import controllers +from . import models +from . import wizards diff --git a/social_media_base/__manifest__.py b/social_media_base/__manifest__.py new file mode 100644 index 0000000000..3cf926c769 --- /dev/null +++ b/social_media_base/__manifest__.py @@ -0,0 +1,48 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Social Media Base", + "summary": """Basic module for social media management.""", + "version": "17.0.1.0.0", + "license": "AGPL-3", + "author": "BinhexTeam,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/social", + "depends": ["base", "web", "mail", "utm"], + "data": [ + "security/ir.model.access.csv", + "security/social_account_security.xml", + "security/social_post_security.xml", + "security/social_post_account_security.xml", + "data/ir_cron_data.xml", + "views/social_media_views.xml", + "views/social_account_views.xml", + "views/social_post_views.xml", + "views/social_post_account_views.xml", + "views/utm_group_campaign_views.xml", + "views/utm_campaign_views.xml", + "views/social_action_client_views.xml", + "wizards/wizard_social_account.xml", + "views/social_media_base_menus.xml", + ], + "assets": { + "web.assets_backend": [ + ("include", "web.chartjs_lib"), + # GENERAL + "social_media_base/static/src/xml/**/*.xml", + "social_media_base/static/src/scss/**/*.scss", + # MIXINS + "social_media_base/static/src/js/app/**/*.js", + # SERVICES + "social_media_base/static/src/js/services/**/*.js", + # COMPONENTS + "social_media_base/static/src/components/**/*.xml", + "social_media_base/static/src/components/**/*.js", + "social_media_base/static/src/components/**/*.scss", + # VIEWS + "social_media_base/static/src/js/views/**/*.xml", + "social_media_base/static/src/js/views/**/*.scss", + "social_media_base/static/src/js/views/**/*.js", + ], + }, + "exclude": ["social"], +} diff --git a/social_media_base/controllers/__init__.py b/social_media_base/controllers/__init__.py new file mode 100644 index 0000000000..8aa4159f91 --- /dev/null +++ b/social_media_base/controllers/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import thread diff --git a/social_media_base/controllers/thread.py b/social_media_base/controllers/thread.py new file mode 100644 index 0000000000..3226cc02ac --- /dev/null +++ b/social_media_base/controllers/thread.py @@ -0,0 +1,41 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.http import request, route + +from odoo.addons.mail.controllers.thread import ThreadController +from odoo.addons.mail.models.discuss.mail_guest import add_guest_to_context + + +class ThreadControllerSocial(ThreadController): + def _prepare_result(self): + return { + "author": { + "id": request.env.user.partner_id.id, + "name": request.env.user.partner_id.name, + "is_company": request.env.user.partner_id.is_company, + "user": { + "id": request.env.uid, + "isInternalUser": request.env.user._is_internal(), + }, + "type": "partner", + } + } + + @route("/mail/message/post", methods=["POST"], type="json", auth="public") + @add_guest_to_context + def mail_message_post(self, thread_model, thread_id, post_data, context=None): + if thread_model == "social.post.account" and thread_id: + post_id = request.env[thread_model].browse(thread_id) + if post_id: + comment = post_id.create_comment(post_data, context) + request.env["bus.bus"]._sendone( + request.env.user.partner_id, "comments", comment + ) + return self._prepare_result() + else: + return None + else: + return super().mail_message_post( + thread_model, thread_id, post_data, context + ) diff --git a/social_media_base/data/ir_cron_data.xml b/social_media_base/data/ir_cron_data.xml new file mode 100644 index 0000000000..f8a88a3c52 --- /dev/null +++ b/social_media_base/data/ir_cron_data.xml @@ -0,0 +1,24 @@ + + + + Social Post: Send post schedule + + code + model._run_send_post() + 5 + minutes + -1 + 1 + + + + Social: Checking social media updates + + code + model._run_check_media_updates() + 30 + minutes + -1 + 1 + + diff --git a/social_media_base/i18n/es_ES.po b/social_media_base/i18n/es_ES.po new file mode 100644 index 0000000000..5bfe9548c4 --- /dev/null +++ b/social_media_base/i18n/es_ES.po @@ -0,0 +1,1215 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * social_media_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-07 06:01+0000\n" +"PO-Revision-Date: 2025-12-07 06:01+0000\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: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__interactions_count +msgid "" +"\n" +" Indicates the interactions with the\n" +" publication (clicks, likes, comments,shares).\n" +" " +msgstr "" +"\n" +" Indica las interacciones con la publicación (clics, 'me gusta', comentarios, veces que se ha compartido).\n" +" " + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__impression_count +msgid "" +"\n" +" Total number of views, which may include\n" +" multiple views by the same user.\n" +" " +msgstr "" +"\n" +" Número total de visualizaciones, que puede incluir\n" +" múltiples visualizaciones del mismo usuario.\n" +" " + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post.py:0 +#, python-format +msgid "" +"%(post)s: cannot be cancelled because it is published or in the process of " +"being published." +msgstr "" +"%(post)s: no se puede cancelar porque está publicado o en proceso de publicación." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/xml/app/common_templates.xml:0 +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_kanban_view +#, python-format +msgid "...see more" +msgstr "...ver más" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__access_token +msgid "Access Token" +msgstr "Token de Acceso" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__account_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__account_id +#: model:ir.model.fields,field_description:social_media_base.field_utm_campaign__account_id +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__account_id +msgid "Account" +msgstr "Cuenta" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__account_url +msgid "Account Url" +msgstr "Url de la Cuenta" + +#. module: social_media_base +#: model:ir.actions.act_window,name:social_media_base.social_account_act_window_tree +#: model:ir.ui.menu,name:social_media_base.social_account_menu +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_account_view_search +msgid "Accounts" +msgstr "Cuentas" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_needaction +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_needaction +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__active +#: model:ir.model.fields,field_description:social_media_base.field_social_post__active +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__active +msgid "Active" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_ids +msgid "Activities" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_exception_decoration +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_state +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_state +msgid "Activity State" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_type_icon +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_type_icon +msgid "Activity Type Icon" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__actor_urn +msgid "Actor Urn" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/kanban_buttons.xml:0 +#, python-format +msgid "Add Post" +msgstr "Agregar publicación" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/kanban_buttons.xml:0 +#, python-format +msgid "Add account" +msgstr "Agregar cuenta" + +#. module: social_media_base +#: model:ir.actions.client,name:social_media_base.social_ads_account_action_client +#: model:ir.ui.menu,name:social_media_base.social_ads_account_action_client_menu +msgid "Ads" +msgstr "Anuncios" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__advertising_account_id +msgid "Advertising Account" +msgstr "Cuenta de publicidad" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment_dialog/social_comment_dialog.esm.js:0 +#: code:addons/social_media_base/static/src/js/app/social_post_account_mixin.esm.js:0 +#, python-format +msgid "All Images" +msgstr "Imágenes" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__any_failed_post +msgid "Any Failed Post" +msgstr "" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "" +"Are you sure you want to delete the account? Please note that all data " +"associated with this account will be archived." +msgstr "" +"¿Seguro que desea eliminar la cuenta? Tenga en cuenta que todos los datos asociados a esta cuenta se archivarán." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#, python-format +msgid "Are you sure you want to delete this comment?" +msgstr "¿Seguro que desea eliminar este comentario?" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_account_kanban_view +msgid "Are you sure you want to delete this post?" +msgstr "¿Seguro que desea eliminar esta publicación?" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.wizard_social_account_view_form +msgid "Associate" +msgstr "Asociar" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_wizard_social_account +msgid "Associate Social Media Account" +msgstr "Asociar Cuenta de Red Social" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_media_kanban_view +msgid "Associate account" +msgstr "Asociar cuenta" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_attachment_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_attachment_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__avatar_1920 +msgid "Avatar" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__avatar_1024 +msgid "Avatar 1024" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__avatar_128 +msgid "Avatar 128" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__avatar_256 +msgid "Avatar 256" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__avatar_512 +msgid "Avatar 512" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__campaign_id +msgid "Campaign" +msgstr "Campaña" + +#. module: social_media_base +#: model:ir.actions.act_window,name:social_media_base.utm_group_campaign_act_window_tree +#: model:ir.model.fields,field_description:social_media_base.field_utm_campaign__campaign_group_id +#: model:ir.ui.menu,name:social_media_base.social_media_base_menu_utm_group_campaign_action +msgid "Campaign group" +msgstr "Grupo de Campañas" + +#. module: social_media_base +#: model:ir.ui.menu,name:social_media_base.social_media_base_menu_utm_campaign_action +msgid "Campaigns" +msgstr "Campañas" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_form_view +#: model_terms:ir.ui.view,arch_db:social_media_base.wizard_social_account_view_form +#, python-format +msgid "Cancel" +msgstr "Cancelar" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__state__cancelled +msgid "Cancelled" +msgstr "Cancelado" + +#. module: social_media_base +#: model:ir.actions.client,name:social_media_base.social_chart_account_action_client +msgid "Chart" +msgstr "Gráfico" + +#. module: social_media_base +#: model:ir.ui.menu,name:social_media_base.social_chart_account_action_client_menu +msgid "Charts" +msgstr "Gráficos" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__click_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__click_count +msgid "Click Count" +msgstr "Cantidad de clics" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_clicks +msgid "Clicks" +msgstr "Clicks" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads/social_ads.xml:0 +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_kanban_view +#, python-format +msgid "Clicks:" +msgstr "Clicks:" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.xml:0 +#: code:addons/social_media_base/static/src/xml/app/common_templates.xml:0 +#, python-format +msgid "Comment" +msgstr "Comentario" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__comment_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__comment_count +msgid "Comment Count" +msgstr "Cantidad de comentarios" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment_dialog/social_comment_dialog.esm.js:0 +#, python-format +msgid "Comment created" +msgstr "Comentario creado" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#, python-format +msgid "Comment deleted" +msgstr "Comentario eliminado" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_chart_account/social_chart_account.xml:0 +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_comments +#, python-format +msgid "Comments" +msgstr "Comentarios" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__company_id +msgid "Company" +msgstr "Compañía" + +#. module: social_media_base +#: model:ir.ui.menu,name:social_media_base.social_configuration_menu +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "Configuration" +msgstr "Configuración" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__create_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_media__create_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_post__create_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__create_uid +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__create_uid +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__create_uid +msgid "Created by" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__create_date +#: model:ir.model.fields,field_description:social_media_base.field_social_media__create_date +#: model:ir.model.fields,field_description:social_media_base.field_social_post__create_date +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__create_date +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__create_date +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__create_date +msgid "Created on" +msgstr "" + +#. module: social_media_base +#: model:ir.actions.act_window,name:social_media_base.social_post_account_act_window_kanban +#: model:ir.ui.menu,name:social_media_base.social_network_stream_post_menu +msgid "Dashboard" +msgstr "Tablero" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#: code:addons/social_media_base/static/src/xml/app/common_templates.xml:0 +#, python-format +msgid "Delete" +msgstr "Eliminar" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "Delete account" +msgstr "Eliminar cuenta" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#, python-format +msgid "Delete comment" +msgstr "Eliminar comentario" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_account_kanban_view +msgid "Delete post" +msgstr "Eliminar publicación" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "" +"Deleting the account only from the system does not delete the account on the" +" social network." +msgstr "" +"Eliminar la cuenta solo del sistema no elimina la cuenta en la red social." + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_media__description +msgid "Description" +msgstr "Descripción" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__display_name +#: model:ir.model.fields,field_description:social_media_base.field_social_media__display_name +#: model:ir.model.fields,field_description:social_media_base.field_social_post__display_name +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__display_name +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__display_name +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__display_name +msgid "Display Name" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__state__draft +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_form_view +msgid "Draft" +msgstr "Borrador" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/wizards/wizard_social_account.py:0 +#, python-format +msgid "ERROR UPDATE ACCOUNT %(account)s: %(error)s" +msgstr "ERROR ACTUALIZANDO CUENTA %(account)s: %(error)s" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__engagement +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_engagement +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__engagement +msgid "Engagement" +msgstr "" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_kanban_view +msgid "Engagement:" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__enviroment +msgid "Enviroment" +msgstr "" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post.py:0 +#, python-format +msgid "Error Post Tweet [%(media)s]: %(error)s" +msgstr "Error Post Tweet [%(media)s]: %(error)s" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment_dialog/social_comment_dialog.esm.js:0 +#, python-format +msgid "Error retrieving comments" +msgstr "Error recuperando comentarios" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__expire_access_token_date +msgid "Expire Access Token" +msgstr "Vencimiento del token de acceso" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post_account__state__failed +msgid "Failed" +msgstr "Fallido" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__failed_description +msgid "Failed Description" +msgstr "Descripción fallida" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_follower_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_follower_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_partner_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_partner_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__activity_type_icon +#: model:ir.model.fields,help:social_media_base.field_social_post__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_account/social_account.xml:0 +#, python-format +msgid "Go to account" +msgstr "Ir a la cuenta" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_account_view_search +msgid "Group By" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__has_message +#: model:ir.model.fields,field_description:social_media_base.field_social_post__has_message +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__has_message +msgid "Has Message" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__hide_post +msgid "Hide Post" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__id +#: model:ir.model.fields,field_description:social_media_base.field_social_media__id +#: model:ir.model.fields,field_description:social_media_base.field_social_post__id +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__id +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__id +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__id +msgid "ID" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_exception_icon +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_exception_icon +msgid "Icon" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__activity_exception_icon +#: model:ir.model.fields,help:social_media_base.field_social_post__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__message_needaction +#: model:ir.model.fields,help:social_media_base.field_social_post__message_needaction +#: model:ir.model.fields,help:social_media_base.field_social_post_account__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__message_has_error +#: model:ir.model.fields,help:social_media_base.field_social_post__message_has_error +#: model:ir.model.fields,help:social_media_base.field_social_post_account__message_has_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__image_1920 +#: model:ir.model.fields,field_description:social_media_base.field_social_media__image +#: model:ir.model.fields,field_description:social_media_base.field_social_post__image_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__image_ids +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__image +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_kanban_view +msgid "Image" +msgstr "Imagen" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__image_1024 +msgid "Image 1024" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__image_128 +msgid "Image 128" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__image_256 +msgid "Image 256" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__image_512 +msgid "Image 512" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__image_urls +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__image_urls +#: model:ir.model.fields,field_description:social_media_base.field_social_post_mixin__image_urls +msgid "Image Urls" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_impression +msgid "Impression" +msgstr "Impresiones" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__impression_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__impression_count +msgid "Impression Count" +msgstr "Cantidad de impresiones" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_chart_account/social_chart_account.xml:0 +#, python-format +msgid "Impressions" +msgstr "Impresiones" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads/social_ads.xml:0 +#, python-format +msgid "Impressions:" +msgstr "Impresiones:" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_interactions +msgid "Interactions" +msgstr "Interacciones" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__interactions_count +msgid "Interactions Count" +msgstr "Cantidad de interacciones" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_kanban_view +msgid "Interactions:" +msgstr "Interacciones:" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_is_follower +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_is_follower +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__is_property_account +msgid "Is Property Account" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__last_update_account +msgid "Last Update Account" +msgstr "Última actualización de la cuenta" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__write_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_media__write_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_post__write_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__write_uid +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__write_uid +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__write_date +#: model:ir.model.fields,field_description:social_media_base.field_social_media__write_date +#: model:ir.model.fields,field_description:social_media_base.field_social_post__write_date +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__write_date +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__write_date +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__write_date +msgid "Last Updated on" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__like_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__like_count +msgid "Like Count" +msgstr "Cantidad de me gusta" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_likes +msgid "Likes" +msgstr "Me gusta" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__media_id +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__media_id +#: model:ir.model.fields,field_description:social_media_base.field_utm_campaign__allow_media_ids +#: model:ir.model.fields,field_description:social_media_base.field_utm_campaign__media_id +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__media_id +msgid "Media" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__media_type +#: model:ir.model.fields,field_description:social_media_base.field_social_media__media_type +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__media_type +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__media_type +msgid "Media Type" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message +msgid "Message" +msgstr "Mensaje" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_has_error +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_has_error +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_info +msgid "Message Info" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_ids +msgid "Messages" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__my_activity_date_deadline +#: model:ir.model.fields,field_description:social_media_base.field_social_post__my_activity_date_deadline +msgid "My Activity Deadline" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__name +#: model:ir.model.fields,field_description:social_media_base.field_social_media__name +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__author +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__name +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "Name" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__need_update +msgid "Need Update" +msgstr "Necesita actualizar" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/social_kanban_controller.esm.js:0 +#, python-format +msgid "New Post" +msgstr "Nueva publicación" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_account/social_account.xml:0 +#, python-format +msgid "New updates are available, press the" +msgstr "Hay nuevas actualizaciones disponibles, presione el" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_image_dialog/social_image_dialog.xml:0 +#, python-format +msgid "Next" +msgstr "Siguiente" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_calendar_event_id +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_calendar_event_id +msgid "Next Activity Calendar Event" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_date_deadline +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_summary +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_summary +msgid "Next Activity Summary" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_type_id +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_type_id +msgid "Next Activity Type" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads_account/social_ads_account.xml:0 +#: code:addons/social_media_base/static/src/components/social_chart/social_chart.xml:0 +#, python-format +msgid "No data" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads_account/social_ads_account.xml:0 +#: code:addons/social_media_base/static/src/components/social_chart/social_chart.xml:0 +#, python-format +msgid "No data to display" +msgstr "No hay datos que mostrar" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads/social_ads.xml:0 +#, python-format +msgid "No post available" +msgstr "No hay ninguna publicación disponible" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post.py:0 +#, python-format +msgid "No preview available" +msgstr "No hay vista previa disponible" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__send_post__now +msgid "Now" +msgstr "Ahora" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_needaction_counter +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_needaction_counter +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_has_error_counter +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_has_error_counter +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__message_needaction_counter +#: model:ir.model.fields,help:social_media_base.field_social_post__message_needaction_counter +#: model:ir.model.fields,help:social_media_base.field_social_post_account__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__message_has_error_counter +#: model:ir.model.fields,help:social_media_base.field_social_post__message_has_error_counter +#: model:ir.model.fields,help:social_media_base.field_social_post_account__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads_account/social_ads_account.xml:0 +#, python-format +msgid "Once you have ads registered in your accounts, you can view them here." +msgstr "Una vez que tenga anuncios registrados en sus cuentas, podrá verlos aquí." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_chart/social_chart.xml:0 +#, python-format +msgid "Once you have recorded information, you can view it here as a graph." +msgstr "Una vez que haya registrado la información, podrá verla aquí como un gráfico." + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_wizard_social_account__update_keys +msgid "Only enable this field if your credentials have changed" +msgstr "Habilite este campo solo si sus credenciales han cambiado" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__state__planned +msgid "Planned" +msgstr "Planificado" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__post_id +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_form_view +msgid "Post" +msgstr "Publicar" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__post_account_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post__post_account_ids +msgid "Post Account" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__post_account_url +msgid "Post Account Url" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/social_kanban_record.esm.js:0 +#, python-format +msgid "Post Comment" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__post_preview +msgid "Post Preview" +msgstr "" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post_account.py:0 +#, python-format +msgid "Post deleted [%(account)s]" +msgstr "Publicación eliminada [%(account)s]" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post.py:0 +#, python-format +msgid "Post on %(posts)s" +msgstr "Publicación en %(posts)s" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post_account__state__posted +msgid "Posted" +msgstr "Publicado" + +#. module: social_media_base +#: model:ir.actions.act_window,name:social_media_base.social_post_act_window_kanban +#: model:ir.ui.menu,name:social_media_base.social_network_post_menu +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_form_view +msgid "Posts" +msgstr "Publicaciones" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_form_view +msgid "Press the publish button to retry sending failed posts." +msgstr "Presione el botón publicar para reintentar enviar las publicaciones fallidas." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_image_dialog/social_image_dialog.xml:0 +#, python-format +msgid "Prev" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_account__enviroment__production +msgid "Production" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__published +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__state__published +msgid "Published" +msgstr "Publicado" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__published_date +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__published_date +msgid "Published Date" +msgstr "Fecha publicación" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__state__publishing +msgid "Publishing" +msgstr "Publicando" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_chart_account/social_chart_account.xml:0 +#, python-format +msgid "Reactions" +msgstr "Reacciones" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post_account__state__ready +msgid "Ready" +msgstr "Listo" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.xml:0 +#: code:addons/social_media_base/static/src/xml/app/common_templates.xml:0 +#, python-format +msgid "Recommend" +msgstr "Recomendar" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__refresh_access_token +msgid "Refresh Access Token" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_user_id +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_user_id +msgid "Responsible User" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__send_post__schedule +msgid "Schedule" +msgstr "Programar" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__send_post_date +msgid "Schedule date" +msgstr "Fecha de programación" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_filter/social_filter.xml:0 +#, python-format +msgid "Search..." +msgstr "Buscar..." + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__send_post +msgid "Send Post" +msgstr "Enviar publicación" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__share_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__share_count +msgid "Share Count" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_shares +msgid "Shares" +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_social_account +msgid "Social Account" +msgstr "Cuenta de red social" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_account/social_account.xml:0 +#: model:ir.actions.act_window,name:social_media_base.social_media_act_window_kanban +#: model:ir.model,name:social_media_base.model_social_media +#: model:ir.ui.menu,name:social_media_base.social_root_menu +#, python-format +msgid "Social Media" +msgstr "" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_media_base_mixin.py:0 +#, python-format +msgid "" +"Social Media %(social_media)s [%(account)s]

%(message)s" +msgstr "" +"Red social %(social_media)s [%(account)s]

%(message)s" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_social_media_base_mixin +msgid "Social Media Base Mixin" +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_social_post_mixin +msgid "Social Network Post Mixin" +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_social_post +msgid "Social Post" +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_social_post_account +msgid "Social Post Account" +msgstr "" + +#. module: social_media_base +#: model:ir.actions.server,name:social_media_base.send_post_schedule_job_ir_actions_server +msgid "Social Post: Send post schedule" +msgstr "Red social: Enviar publicaciones programadas" + +#. module: social_media_base +#: model:ir.ui.menu,name:social_media_base.social_media_menu +msgid "Social medias" +msgstr "Red social" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_view_search +msgid "Social network" +msgstr "" + +#. module: social_media_base +#: model:ir.actions.server,name:social_media_base.webhook_schedule_job_ir_actions_server +msgid "Social: Checking social media updates" +msgstr "Red social: Verificando actualizaciones de redes sociales" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__state +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__state +msgid "State" +msgstr "Estado" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__activity_state +#: model:ir.model.fields,help:social_media_base.field_social_post__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads_account/social_ads_account.xml:0 +#, python-format +msgid "Sync ads" +msgstr "Actualizar anuncios" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_account__enviroment__test +msgid "Test" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/social_kanban_controller.esm.js:0 +#, python-format +msgid "The data was updated successfully." +msgstr "Los datos se actualizaron exitosamente." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/social_kanban_record.esm.js:0 +#, python-format +msgid "The post does not exist or has been deleted." +msgstr "La publicación no existe o ha sido eliminada." + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post_account.py:0 +#, python-format +msgid "The post was successfully deleted." +msgstr "La publicación fue eliminada exitosamente." + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__activity_exception_decoration +#: model:ir.model.fields,help:social_media_base.field_social_post__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_utm_campaign +msgid "UTM Campaign" +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_utm_group_campaign +msgid "UTM Group Campaign" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_account/social_account.xml:0 +#: code:addons/social_media_base/static/src/js/views/kanban/kanban_buttons.xml:0 +#: model_terms:ir.ui.view,arch_db:social_media_base.wizard_social_account_view_form +#, python-format +msgid "Update" +msgstr "Actualizar" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__update_keys +msgid "Update Keys" +msgstr "Actualizar claves" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__update_token +msgid "Update Token" +msgstr "Actualizar token de acceso" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "Update account" +msgstr "Actualizar cuenta" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_wizard_social_account__update_token +msgid "Update token" +msgstr "Actualizar token" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__username +msgid "Username" +msgstr "Usuario" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__video_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__video_ids +msgid "Video" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#: code:addons/social_media_base/static/src/js/app/social_post_account_mixin.esm.js:0 +#, python-format +msgid "You have liked the post." +msgstr "Te ha gustado el post." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_account/social_account.xml:0 +#, python-format +msgid "button to get them." +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/xml/app/common_templates.xml:0 +#, python-format +msgid "comments" +msgstr "comentarios" diff --git a/social_media_base/i18n/social_media_base.pot b/social_media_base/i18n/social_media_base.pot new file mode 100644 index 0000000000..5bfe9548c4 --- /dev/null +++ b/social_media_base/i18n/social_media_base.pot @@ -0,0 +1,1215 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * social_media_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-07 06:01+0000\n" +"PO-Revision-Date: 2025-12-07 06:01+0000\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: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__interactions_count +msgid "" +"\n" +" Indicates the interactions with the\n" +" publication (clicks, likes, comments,shares).\n" +" " +msgstr "" +"\n" +" Indica las interacciones con la publicación (clics, 'me gusta', comentarios, veces que se ha compartido).\n" +" " + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__impression_count +msgid "" +"\n" +" Total number of views, which may include\n" +" multiple views by the same user.\n" +" " +msgstr "" +"\n" +" Número total de visualizaciones, que puede incluir\n" +" múltiples visualizaciones del mismo usuario.\n" +" " + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post.py:0 +#, python-format +msgid "" +"%(post)s: cannot be cancelled because it is published or in the process of " +"being published." +msgstr "" +"%(post)s: no se puede cancelar porque está publicado o en proceso de publicación." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/xml/app/common_templates.xml:0 +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_kanban_view +#, python-format +msgid "...see more" +msgstr "...ver más" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__access_token +msgid "Access Token" +msgstr "Token de Acceso" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__account_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__account_id +#: model:ir.model.fields,field_description:social_media_base.field_utm_campaign__account_id +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__account_id +msgid "Account" +msgstr "Cuenta" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__account_url +msgid "Account Url" +msgstr "Url de la Cuenta" + +#. module: social_media_base +#: model:ir.actions.act_window,name:social_media_base.social_account_act_window_tree +#: model:ir.ui.menu,name:social_media_base.social_account_menu +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_account_view_search +msgid "Accounts" +msgstr "Cuentas" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_needaction +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_needaction +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__active +#: model:ir.model.fields,field_description:social_media_base.field_social_post__active +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__active +msgid "Active" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_ids +msgid "Activities" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_exception_decoration +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_state +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_state +msgid "Activity State" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_type_icon +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_type_icon +msgid "Activity Type Icon" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__actor_urn +msgid "Actor Urn" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/kanban_buttons.xml:0 +#, python-format +msgid "Add Post" +msgstr "Agregar publicación" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/kanban_buttons.xml:0 +#, python-format +msgid "Add account" +msgstr "Agregar cuenta" + +#. module: social_media_base +#: model:ir.actions.client,name:social_media_base.social_ads_account_action_client +#: model:ir.ui.menu,name:social_media_base.social_ads_account_action_client_menu +msgid "Ads" +msgstr "Anuncios" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__advertising_account_id +msgid "Advertising Account" +msgstr "Cuenta de publicidad" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment_dialog/social_comment_dialog.esm.js:0 +#: code:addons/social_media_base/static/src/js/app/social_post_account_mixin.esm.js:0 +#, python-format +msgid "All Images" +msgstr "Imágenes" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__any_failed_post +msgid "Any Failed Post" +msgstr "" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "" +"Are you sure you want to delete the account? Please note that all data " +"associated with this account will be archived." +msgstr "" +"¿Seguro que desea eliminar la cuenta? Tenga en cuenta que todos los datos asociados a esta cuenta se archivarán." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#, python-format +msgid "Are you sure you want to delete this comment?" +msgstr "¿Seguro que desea eliminar este comentario?" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_account_kanban_view +msgid "Are you sure you want to delete this post?" +msgstr "¿Seguro que desea eliminar esta publicación?" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.wizard_social_account_view_form +msgid "Associate" +msgstr "Asociar" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_wizard_social_account +msgid "Associate Social Media Account" +msgstr "Asociar Cuenta de Red Social" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_media_kanban_view +msgid "Associate account" +msgstr "Asociar cuenta" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_attachment_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_attachment_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__avatar_1920 +msgid "Avatar" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__avatar_1024 +msgid "Avatar 1024" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__avatar_128 +msgid "Avatar 128" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__avatar_256 +msgid "Avatar 256" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__avatar_512 +msgid "Avatar 512" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__campaign_id +msgid "Campaign" +msgstr "Campaña" + +#. module: social_media_base +#: model:ir.actions.act_window,name:social_media_base.utm_group_campaign_act_window_tree +#: model:ir.model.fields,field_description:social_media_base.field_utm_campaign__campaign_group_id +#: model:ir.ui.menu,name:social_media_base.social_media_base_menu_utm_group_campaign_action +msgid "Campaign group" +msgstr "Grupo de Campañas" + +#. module: social_media_base +#: model:ir.ui.menu,name:social_media_base.social_media_base_menu_utm_campaign_action +msgid "Campaigns" +msgstr "Campañas" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_form_view +#: model_terms:ir.ui.view,arch_db:social_media_base.wizard_social_account_view_form +#, python-format +msgid "Cancel" +msgstr "Cancelar" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__state__cancelled +msgid "Cancelled" +msgstr "Cancelado" + +#. module: social_media_base +#: model:ir.actions.client,name:social_media_base.social_chart_account_action_client +msgid "Chart" +msgstr "Gráfico" + +#. module: social_media_base +#: model:ir.ui.menu,name:social_media_base.social_chart_account_action_client_menu +msgid "Charts" +msgstr "Gráficos" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__click_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__click_count +msgid "Click Count" +msgstr "Cantidad de clics" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_clicks +msgid "Clicks" +msgstr "Clicks" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads/social_ads.xml:0 +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_kanban_view +#, python-format +msgid "Clicks:" +msgstr "Clicks:" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.xml:0 +#: code:addons/social_media_base/static/src/xml/app/common_templates.xml:0 +#, python-format +msgid "Comment" +msgstr "Comentario" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__comment_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__comment_count +msgid "Comment Count" +msgstr "Cantidad de comentarios" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment_dialog/social_comment_dialog.esm.js:0 +#, python-format +msgid "Comment created" +msgstr "Comentario creado" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#, python-format +msgid "Comment deleted" +msgstr "Comentario eliminado" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_chart_account/social_chart_account.xml:0 +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_comments +#, python-format +msgid "Comments" +msgstr "Comentarios" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__company_id +msgid "Company" +msgstr "Compañía" + +#. module: social_media_base +#: model:ir.ui.menu,name:social_media_base.social_configuration_menu +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "Configuration" +msgstr "Configuración" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__create_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_media__create_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_post__create_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__create_uid +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__create_uid +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__create_uid +msgid "Created by" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__create_date +#: model:ir.model.fields,field_description:social_media_base.field_social_media__create_date +#: model:ir.model.fields,field_description:social_media_base.field_social_post__create_date +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__create_date +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__create_date +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__create_date +msgid "Created on" +msgstr "" + +#. module: social_media_base +#: model:ir.actions.act_window,name:social_media_base.social_post_account_act_window_kanban +#: model:ir.ui.menu,name:social_media_base.social_network_stream_post_menu +msgid "Dashboard" +msgstr "Tablero" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#: code:addons/social_media_base/static/src/xml/app/common_templates.xml:0 +#, python-format +msgid "Delete" +msgstr "Eliminar" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "Delete account" +msgstr "Eliminar cuenta" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#, python-format +msgid "Delete comment" +msgstr "Eliminar comentario" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_account_kanban_view +msgid "Delete post" +msgstr "Eliminar publicación" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "" +"Deleting the account only from the system does not delete the account on the" +" social network." +msgstr "" +"Eliminar la cuenta solo del sistema no elimina la cuenta en la red social." + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_media__description +msgid "Description" +msgstr "Descripción" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__display_name +#: model:ir.model.fields,field_description:social_media_base.field_social_media__display_name +#: model:ir.model.fields,field_description:social_media_base.field_social_post__display_name +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__display_name +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__display_name +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__display_name +msgid "Display Name" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__state__draft +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_form_view +msgid "Draft" +msgstr "Borrador" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/wizards/wizard_social_account.py:0 +#, python-format +msgid "ERROR UPDATE ACCOUNT %(account)s: %(error)s" +msgstr "ERROR ACTUALIZANDO CUENTA %(account)s: %(error)s" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__engagement +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_engagement +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__engagement +msgid "Engagement" +msgstr "" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_kanban_view +msgid "Engagement:" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__enviroment +msgid "Enviroment" +msgstr "" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post.py:0 +#, python-format +msgid "Error Post Tweet [%(media)s]: %(error)s" +msgstr "Error Post Tweet [%(media)s]: %(error)s" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment_dialog/social_comment_dialog.esm.js:0 +#, python-format +msgid "Error retrieving comments" +msgstr "Error recuperando comentarios" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__expire_access_token_date +msgid "Expire Access Token" +msgstr "Vencimiento del token de acceso" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post_account__state__failed +msgid "Failed" +msgstr "Fallido" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__failed_description +msgid "Failed Description" +msgstr "Descripción fallida" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_follower_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_follower_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_partner_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_partner_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__activity_type_icon +#: model:ir.model.fields,help:social_media_base.field_social_post__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_account/social_account.xml:0 +#, python-format +msgid "Go to account" +msgstr "Ir a la cuenta" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_account_view_search +msgid "Group By" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__has_message +#: model:ir.model.fields,field_description:social_media_base.field_social_post__has_message +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__has_message +msgid "Has Message" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__hide_post +msgid "Hide Post" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__id +#: model:ir.model.fields,field_description:social_media_base.field_social_media__id +#: model:ir.model.fields,field_description:social_media_base.field_social_post__id +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__id +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__id +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__id +msgid "ID" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_exception_icon +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_exception_icon +msgid "Icon" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__activity_exception_icon +#: model:ir.model.fields,help:social_media_base.field_social_post__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__message_needaction +#: model:ir.model.fields,help:social_media_base.field_social_post__message_needaction +#: model:ir.model.fields,help:social_media_base.field_social_post_account__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__message_has_error +#: model:ir.model.fields,help:social_media_base.field_social_post__message_has_error +#: model:ir.model.fields,help:social_media_base.field_social_post_account__message_has_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__image_1920 +#: model:ir.model.fields,field_description:social_media_base.field_social_media__image +#: model:ir.model.fields,field_description:social_media_base.field_social_post__image_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__image_ids +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__image +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_kanban_view +msgid "Image" +msgstr "Imagen" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__image_1024 +msgid "Image 1024" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__image_128 +msgid "Image 128" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__image_256 +msgid "Image 256" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__image_512 +msgid "Image 512" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__image_urls +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__image_urls +#: model:ir.model.fields,field_description:social_media_base.field_social_post_mixin__image_urls +msgid "Image Urls" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_impression +msgid "Impression" +msgstr "Impresiones" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__impression_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__impression_count +msgid "Impression Count" +msgstr "Cantidad de impresiones" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_chart_account/social_chart_account.xml:0 +#, python-format +msgid "Impressions" +msgstr "Impresiones" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads/social_ads.xml:0 +#, python-format +msgid "Impressions:" +msgstr "Impresiones:" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_interactions +msgid "Interactions" +msgstr "Interacciones" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__interactions_count +msgid "Interactions Count" +msgstr "Cantidad de interacciones" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_kanban_view +msgid "Interactions:" +msgstr "Interacciones:" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_is_follower +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_is_follower +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__is_property_account +msgid "Is Property Account" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__last_update_account +msgid "Last Update Account" +msgstr "Última actualización de la cuenta" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__write_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_media__write_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_post__write_uid +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__write_uid +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__write_uid +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__write_date +#: model:ir.model.fields,field_description:social_media_base.field_social_media__write_date +#: model:ir.model.fields,field_description:social_media_base.field_social_post__write_date +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__write_date +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__write_date +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__write_date +msgid "Last Updated on" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__like_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__like_count +msgid "Like Count" +msgstr "Cantidad de me gusta" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_likes +msgid "Likes" +msgstr "Me gusta" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__media_id +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__media_id +#: model:ir.model.fields,field_description:social_media_base.field_utm_campaign__allow_media_ids +#: model:ir.model.fields,field_description:social_media_base.field_utm_campaign__media_id +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__media_id +msgid "Media" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__media_type +#: model:ir.model.fields,field_description:social_media_base.field_social_media__media_type +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__media_type +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__media_type +msgid "Media Type" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message +msgid "Message" +msgstr "Mensaje" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_has_error +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_has_error +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_info +msgid "Message Info" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_ids +msgid "Messages" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__my_activity_date_deadline +#: model:ir.model.fields,field_description:social_media_base.field_social_post__my_activity_date_deadline +msgid "My Activity Deadline" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__name +#: model:ir.model.fields,field_description:social_media_base.field_social_media__name +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__author +#: model:ir.model.fields,field_description:social_media_base.field_utm_group_campaign__name +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "Name" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__need_update +msgid "Need Update" +msgstr "Necesita actualizar" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/social_kanban_controller.esm.js:0 +#, python-format +msgid "New Post" +msgstr "Nueva publicación" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_account/social_account.xml:0 +#, python-format +msgid "New updates are available, press the" +msgstr "Hay nuevas actualizaciones disponibles, presione el" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_image_dialog/social_image_dialog.xml:0 +#, python-format +msgid "Next" +msgstr "Siguiente" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_calendar_event_id +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_calendar_event_id +msgid "Next Activity Calendar Event" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_date_deadline +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_summary +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_summary +msgid "Next Activity Summary" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_type_id +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_type_id +msgid "Next Activity Type" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads_account/social_ads_account.xml:0 +#: code:addons/social_media_base/static/src/components/social_chart/social_chart.xml:0 +#, python-format +msgid "No data" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads_account/social_ads_account.xml:0 +#: code:addons/social_media_base/static/src/components/social_chart/social_chart.xml:0 +#, python-format +msgid "No data to display" +msgstr "No hay datos que mostrar" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads/social_ads.xml:0 +#, python-format +msgid "No post available" +msgstr "No hay ninguna publicación disponible" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post.py:0 +#, python-format +msgid "No preview available" +msgstr "No hay vista previa disponible" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__send_post__now +msgid "Now" +msgstr "Ahora" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_needaction_counter +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_needaction_counter +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__message_has_error_counter +#: model:ir.model.fields,field_description:social_media_base.field_social_post__message_has_error_counter +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__message_needaction_counter +#: model:ir.model.fields,help:social_media_base.field_social_post__message_needaction_counter +#: model:ir.model.fields,help:social_media_base.field_social_post_account__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__message_has_error_counter +#: model:ir.model.fields,help:social_media_base.field_social_post__message_has_error_counter +#: model:ir.model.fields,help:social_media_base.field_social_post_account__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads_account/social_ads_account.xml:0 +#, python-format +msgid "Once you have ads registered in your accounts, you can view them here." +msgstr "Una vez que tenga anuncios registrados en sus cuentas, podrá verlos aquí." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_chart/social_chart.xml:0 +#, python-format +msgid "Once you have recorded information, you can view it here as a graph." +msgstr "Una vez que haya registrado la información, podrá verla aquí como un gráfico." + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_wizard_social_account__update_keys +msgid "Only enable this field if your credentials have changed" +msgstr "Habilite este campo solo si sus credenciales han cambiado" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__state__planned +msgid "Planned" +msgstr "Planificado" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__post_id +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_form_view +msgid "Post" +msgstr "Publicar" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__post_account_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post__post_account_ids +msgid "Post Account" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__post_account_url +msgid "Post Account Url" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/social_kanban_record.esm.js:0 +#, python-format +msgid "Post Comment" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__post_preview +msgid "Post Preview" +msgstr "" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post_account.py:0 +#, python-format +msgid "Post deleted [%(account)s]" +msgstr "Publicación eliminada [%(account)s]" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post.py:0 +#, python-format +msgid "Post on %(posts)s" +msgstr "Publicación en %(posts)s" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post_account__state__posted +msgid "Posted" +msgstr "Publicado" + +#. module: social_media_base +#: model:ir.actions.act_window,name:social_media_base.social_post_act_window_kanban +#: model:ir.ui.menu,name:social_media_base.social_network_post_menu +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_form_view +msgid "Posts" +msgstr "Publicaciones" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_form_view +msgid "Press the publish button to retry sending failed posts." +msgstr "Presione el botón publicar para reintentar enviar las publicaciones fallidas." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_image_dialog/social_image_dialog.xml:0 +#, python-format +msgid "Prev" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_account__enviroment__production +msgid "Production" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__published +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__state__published +msgid "Published" +msgstr "Publicado" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__published_date +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__published_date +msgid "Published Date" +msgstr "Fecha publicación" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__state__publishing +msgid "Publishing" +msgstr "Publicando" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_chart_account/social_chart_account.xml:0 +#, python-format +msgid "Reactions" +msgstr "Reacciones" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post_account__state__ready +msgid "Ready" +msgstr "Listo" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.xml:0 +#: code:addons/social_media_base/static/src/xml/app/common_templates.xml:0 +#, python-format +msgid "Recommend" +msgstr "Recomendar" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__refresh_access_token +msgid "Refresh Access Token" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__activity_user_id +#: model:ir.model.fields,field_description:social_media_base.field_social_post__activity_user_id +msgid "Responsible User" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_post__send_post__schedule +msgid "Schedule" +msgstr "Programar" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__send_post_date +msgid "Schedule date" +msgstr "Fecha de programación" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_filter/social_filter.xml:0 +#, python-format +msgid "Search..." +msgstr "Buscar..." + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__send_post +msgid "Send Post" +msgstr "Enviar publicación" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__share_count +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__share_count +msgid "Share Count" +msgstr "" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__count_post_shares +msgid "Shares" +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_social_account +msgid "Social Account" +msgstr "Cuenta de red social" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_account/social_account.xml:0 +#: model:ir.actions.act_window,name:social_media_base.social_media_act_window_kanban +#: model:ir.model,name:social_media_base.model_social_media +#: model:ir.ui.menu,name:social_media_base.social_root_menu +#, python-format +msgid "Social Media" +msgstr "" + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_media_base_mixin.py:0 +#, python-format +msgid "" +"Social Media %(social_media)s [%(account)s]

%(message)s" +msgstr "" +"Red social %(social_media)s [%(account)s]

%(message)s" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_social_media_base_mixin +msgid "Social Media Base Mixin" +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_social_post_mixin +msgid "Social Network Post Mixin" +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_social_post +msgid "Social Post" +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_social_post_account +msgid "Social Post Account" +msgstr "" + +#. module: social_media_base +#: model:ir.actions.server,name:social_media_base.send_post_schedule_job_ir_actions_server +msgid "Social Post: Send post schedule" +msgstr "Red social: Enviar publicaciones programadas" + +#. module: social_media_base +#: model:ir.ui.menu,name:social_media_base.social_media_menu +msgid "Social medias" +msgstr "Red social" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_post_view_search +msgid "Social network" +msgstr "" + +#. module: social_media_base +#: model:ir.actions.server,name:social_media_base.webhook_schedule_job_ir_actions_server +msgid "Social: Checking social media updates" +msgstr "Red social: Verificando actualizaciones de redes sociales" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__state +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__state +msgid "State" +msgstr "Estado" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__activity_state +#: model:ir.model.fields,help:social_media_base.field_social_post__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_ads_account/social_ads_account.xml:0 +#, python-format +msgid "Sync ads" +msgstr "Actualizar anuncios" + +#. module: social_media_base +#: model:ir.model.fields.selection,name:social_media_base.selection__social_account__enviroment__test +msgid "Test" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/social_kanban_controller.esm.js:0 +#, python-format +msgid "The data was updated successfully." +msgstr "Los datos se actualizaron exitosamente." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/js/views/kanban/social_kanban_record.esm.js:0 +#, python-format +msgid "The post does not exist or has been deleted." +msgstr "La publicación no existe o ha sido eliminada." + +#. module: social_media_base +#. odoo-python +#: code:addons/social_media_base/models/social_post_account.py:0 +#, python-format +msgid "The post was successfully deleted." +msgstr "La publicación fue eliminada exitosamente." + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_social_account__activity_exception_decoration +#: model:ir.model.fields,help:social_media_base.field_social_post__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_utm_campaign +msgid "UTM Campaign" +msgstr "" + +#. module: social_media_base +#: model:ir.model,name:social_media_base.model_utm_group_campaign +msgid "UTM Group Campaign" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_account/social_account.xml:0 +#: code:addons/social_media_base/static/src/js/views/kanban/kanban_buttons.xml:0 +#: model_terms:ir.ui.view,arch_db:social_media_base.wizard_social_account_view_form +#, python-format +msgid "Update" +msgstr "Actualizar" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__update_keys +msgid "Update Keys" +msgstr "Actualizar claves" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_wizard_social_account__update_token +msgid "Update Token" +msgstr "Actualizar token de acceso" + +#. module: social_media_base +#: model_terms:ir.ui.view,arch_db:social_media_base.social_account_form_view +msgid "Update account" +msgstr "Actualizar cuenta" + +#. module: social_media_base +#: model:ir.model.fields,help:social_media_base.field_wizard_social_account__update_token +msgid "Update token" +msgstr "Actualizar token" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_account__username +msgid "Username" +msgstr "Usuario" + +#. module: social_media_base +#: model:ir.model.fields,field_description:social_media_base.field_social_post__video_ids +#: model:ir.model.fields,field_description:social_media_base.field_social_post_account__video_ids +msgid "Video" +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_comment/social_comment.esm.js:0 +#: code:addons/social_media_base/static/src/js/app/social_post_account_mixin.esm.js:0 +#, python-format +msgid "You have liked the post." +msgstr "Te ha gustado el post." + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/components/social_account/social_account.xml:0 +#, python-format +msgid "button to get them." +msgstr "" + +#. module: social_media_base +#. odoo-javascript +#: code:addons/social_media_base/static/src/xml/app/common_templates.xml:0 +#, python-format +msgid "comments" +msgstr "comentarios" diff --git a/social_media_base/models/__init__.py b/social_media_base/models/__init__.py new file mode 100644 index 0000000000..8557cea7ee --- /dev/null +++ b/social_media_base/models/__init__.py @@ -0,0 +1,11 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import social_media_base_mixin +from . import social_post_mixin +from . import social_account +from . import social_media +from . import social_post +from . import social_post_account +from . import utm_group_campaign +from . import utm_campaign diff --git a/social_media_base/models/social_account.py b/social_media_base/models/social_account.py new file mode 100644 index 0000000000..c5dd360c63 --- /dev/null +++ b/social_media_base/models/social_account.py @@ -0,0 +1,344 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import base64 +import json +from datetime import datetime + +from dateutil.relativedelta import relativedelta + +from odoo import _, api, fields, models +from odoo.tools import file_open + +from ..social_utils import _generate_timestamps, get_weeks + + +class SocialAccount(models.Model): + _name = "social.account" + _inherit = [ + "mail.thread", + "mail.activity.mixin", + "avatar.mixin", + "social.media.base.mixin", + ] + _description = "Social Account" + + """ + This model defines the accounts associated with the different social medias. + """ + + name = fields.Char() + active = fields.Boolean(default=True) + username = fields.Char() + media_id = fields.Many2one("social.media", ondelete="restrict") + media_type = fields.Selection(related="media_id.media_type") + company_id = fields.Many2one( + "res.company", "Company", default=lambda self: self.env.company + ) + advertising_account_id = fields.Char() + last_update_account = fields.Datetime() + post_account_ids = fields.One2many("social.post.account", "account_id") + + @api.model + def _default_image(self): + return base64.b64encode(file_open("base/static/img/avatar.png", "rb").read()) + + image_1920 = fields.Image(default=_default_image) + + # STATISTICS + comment_count = fields.Integer(default=0) + like_count = fields.Integer(default=0) + click_count = fields.Integer(default=0) + share_count = fields.Integer(default=0) + interactions_count = fields.Integer( + compute="_compute_interactions_count", + store=True, + default=0, + help=""" + Indicates the interactions with the + publication (clicks, likes, comments,shares). + """, + ) + impression_count = fields.Integer( + default=0, + help=""" + Total number of views, which may include + multiple views by the same user. + """, + ) + engagement = fields.Float(default=0, digits=(16, 2)) + + account_url = fields.Char(compute="_compute_account_url") + enviroment = fields.Selection( + [("test", "Test"), ("production", "Production")], default="test" + ) + need_update = fields.Boolean(default=False) + + # SECURITY + access_token = fields.Char() + refresh_access_token = fields.Char() + expire_access_token_date = fields.Date(string="Expire Access Token") + is_property_account = fields.Boolean( + default=False, compute="_compute_is_property_account" + ) + + @api.depends_context("uid") + def _compute_is_property_account(self): + for account in self: + account.is_property_account = self.env.user == account.create_uid + + def update_account(self): + return { + "res_model": "wizard.social.account", + "views": [[False, "form"]], + "target": "new", + "type": "ir.actions.act_window", + "context": { + "default_account_id": self.id, + "default_media_id": self.media_id.id, + "social_update_account": True, + }, + } + + def delete_account(self): + """ + Archive social media account. + + This method is used to delete the social account, + as well as all its associated posts and campaigns. + It also marks all the associated posts and campaigns + as inactive. + """ + SocialPostAccount = self.env["social.post.account"] + SocialPost = self.env["social.post"] + UtmCampaign = self.env["utm.campaign"] + for account in self: + SocialPostAccount.search([("account_id", "=", account.id)]).write( + { + "active": False, + } + ) + UtmCampaign.search([("account_id", "=", account.id)]).write( + { + "active": False, + } + ) + post_ids = SocialPost.search([("account_ids", "in", account.id)]) + for post in post_ids: + if len(post.account_ids) == 1: + post.write( + { + "active": False, + } + ) + account.write( + { + "active": False, + } + ) + + def _compute_display_name(self): + for account in self: + account.display_name = ( + f"[{account.media_type.upper()}] {account.name}" + if account.media_type + else account.name + ) + + def _fields_account_url(self): + return [] + + @api.depends(lambda self: [val[0] for val in self._fields_account_url()]) + def _compute_account_url(self): + for account in self: + for val_url in account._fields_account_url(): + if len(val_url) < 2: + account.account_url = "" + continue + if account.media_type and val_url[0].find(account.media_type) > -1: + account.account_url = val_url[1] + break + account.account_url = "" + + @api.depends("click_count", "like_count", "share_count", "comment_count") + def _compute_interactions_count(self): + for account in self: + account.interactions_count = ( + account.click_count + + account.like_count + + account.share_count + + account.comment_count + ) + + def _filter_statistics(self, entity_statistics): + post_statistics = { + "click_count": 0, + "like_count": 0, + "comment_count": 0, + "share_count": 0, + "engagement": 0, + "impression_count": 0, + } + for __, statistics in entity_statistics.items(): + post_statistics["click_count"] += statistics[0] + post_statistics["like_count"] += statistics[1] + post_statistics["comment_count"] += statistics[2] + post_statistics["share_count"] += statistics[3] + post_statistics["engagement"] += statistics[4] + post_statistics["impression_count"] += statistics[5] + return post_statistics + + def _get_chart_account_statistics(self, start_date, end_date, granularity): + """ + Returns a list of dictionaries containing statistics + for the specified social media account, formatted correctly + for display in the chart view. + + :param start_date: Start date and time of the period + :param end_date: End date and time of the period + :param granularity: Level of granularity for the statistics + (e.g., WEEK, MONTH, YEAR) + :return: List of dictionaries + :rtype: dict + """ + return [] + + def get_chart_account_statistics( + self, start_date=None, end_date=None, granularity="WEEK" + ): + return self._get_chart_account_statistics(start_date, end_date, granularity) + + def _update_posts_statistics(self, post_id, domain): + """ + Update posts and statistics. + + :param post_id: ID of the post + :param domain: Domain of the post + :return: List of dictionaries + :rtype: list + """ + return [] + + def update_posts_statistics(self, post_id=None, domain=None): + statistics = self._update_posts_statistics(post_id, domain) + return json.dumps(statistics) + + def validate_access_token(self): + """ + Validates the access token for the social media account. + """ + pass + + def _load_ads_accounts(self): + """ + Returns a dictionary containing the ads accounts of the social media account. + + :return: Dictionary containing ads accounts + :rtype: dict + """ + return {} + + def load_ads_accounts(self): + return self._load_ads_accounts() + + def _run_check_media_updates(self): + """ + Checks for social media updates. + This method is used to check for any new social media updates. + + :return: True if new updates are found, otherwise False + :rtype: bool + """ + return False + + def _need_update(self, need_update=True): + self.env["bus.bus"]._sendone( + self.env.user.partner_id, + "social_need_update", + {"need_update": need_update}, + ) + + def _get_default_filter_date(self, start_date, end_date, time_date=False, months=1): + start = start_date or (datetime.now() - relativedelta(months=months)) + end = end_date or (datetime.now()) + if time_date: + return _generate_timestamps(date_start=start, date_end=end) + return start, end + + def _map_chart_statistics(self, account_statistics, **values): + data_chart = [] + statistics_values = ( + account_statistics.values() + if isinstance(account_statistics, dict) + else account_statistics + ) + if statistics_values and self.media_type: + chart_weeks = get_weeks( + values.get( + "start_date", + ), + values.get( + "end_date", + ), + freq=values.get("freq", "W-MON"), + ) + + def map_chart_data(chart_statistics, label, key_data=0): + dataset = { + "pointStyle": "circle", + "pointRadius": 10, + "pointHoverRadius": 15, + "label": _(label), + "data": [ + statistics[key_data] + for statistics in chart_statistics + if len(statistics) > key_data + ], + } + return dataset + + impression_count = sum( + [ + statistics[5] + for statistics in statistics_values + if len(statistics) > 5 + ] + ) + comment_count = sum( + [ + statistics[2] + for statistics in statistics_values + if len(statistics) > 2 + ] + ) + reaction_count = sum( + [ + statistics[1] + statistics[3] + for statistics in statistics_values + if len(statistics) > 1 and len(statistics) > 3 + ] + ) + data_chart.append( + { + "id": self.id, + "name": _(f"[{self.media_type.upper()}] {self.name}"), + "impressionCount": impression_count, + "commentCount": comment_count, + "reactionCount": reaction_count, + "chartLabel": _("Statistics"), + "labels": [week for week in chart_weeks], + "datasets": [ + map_chart_data(statistics_values, "Clicks", 0), + map_chart_data(statistics_values, "Shares", 3), + map_chart_data(statistics_values, "Likes", 1), + map_chart_data(statistics_values, "Comments", 2), + map_chart_data( + statistics_values, + "Impressions", + 5, + ), + map_chart_data(statistics_values, "Engagement", 4), + ], + } + ) + return data_chart diff --git a/social_media_base/models/social_media.py b/social_media_base/models/social_media.py new file mode 100644 index 0000000000..ad58602918 --- /dev/null +++ b/social_media_base/models/social_media.py @@ -0,0 +1,28 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class SocialMedia(models.Model): + _name = "social.media" + _inherit = "social.media.base.mixin" + _description = "Social Media" + + """ + This model defines social medias. + """ + + name = fields.Char() + description = fields.Text() + media_type = fields.Selection( + [], + readonly=True, + ) + image = fields.Binary() + + def open_action_account(self): + """ + Show wizard for creating a new social media account + """ + pass diff --git a/social_media_base/models/social_media_base_mixin.py b/social_media_base/models/social_media_base_mixin.py new file mode 100644 index 0000000000..2118a947ea --- /dev/null +++ b/social_media_base/models/social_media_base_mixin.py @@ -0,0 +1,66 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from markupsafe import Markup + +from odoo import _, models + + +class SocialMediaBaseMixin(models.AbstractModel): + _name = "social.media.base.mixin" + _description = "Social Media Base Mixin" + + def _notify_user_client( + self, + target=None, + notif_type=None, + notif_message=None, + media=False, + social_name=False, + account_name=False, + ): + """ + Notify the user of an event. + + :param target: The target of the notification. + If not provided, the current user will be notified. + :param notif_type: The type of the notification. + If not provided, it will be set to "danger". + :param notif_message: The message to be displayed to the user. + :param media: If True, the notification will be about a social media. + :param social_name: If True, the name of the social media will + be included in the notification. + :param account_name: If True, the name of the account will + be included in the notification. + """ + message_type = ( + notif_type.split("_")[-1] if len(notif_type.split("_")) > 0 else "danger" + ) + message = "" + if media: + social_media_name = ( + media.upper() + " " + social_name if social_name else media.upper() + ) + message = Markup( + _( + "Social Media %(social_media)s " + "[%(account)s]

%(message)s" + ) + % { + "social_media": social_media_name, + "account": social_media_name if not account_name else account_name, + "message": f"{'ERROR:' if message_type == 'danger' else ''}" + f" {notif_message}", + } + ) + + # Notifying the user + if message: + self.env["bus.bus"]._sendone( + target or self.env.user.partner_id, + notif_type, + { + "message_type": message_type, + "message": message, + }, + ) diff --git a/social_media_base/models/social_post.py b/social_media_base/models/social_post.py new file mode 100644 index 0000000000..91d9bdc9c4 --- /dev/null +++ b/social_media_base/models/social_post.py @@ -0,0 +1,330 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import logging +from datetime import datetime, timedelta + +from odoo import Command, _, api, fields, models +from odoo.exceptions import ValidationError + +_logger = logging.getLogger(__name__) + + +class SocialPost(models.Model): + _name = "social.post" + _inherit = ["mail.thread", "mail.activity.mixin", "social.post.mixin"] + _description = "Social Post" + + account_ids = fields.Many2many("social.account", required=True, ondelete="restrict") + active = fields.Boolean(default=True) + message = fields.Text(required=True, tracking=True) + campaign_id = fields.Many2one("utm.campaign") + send_post = fields.Selection( + [("now", "Now"), ("schedule", "Schedule")], + required=True, + default="now", + tracking=True, + ) + send_post_date = fields.Datetime( + string="Schedule date", compute="_compute_send_post_date", store=True + ) + published_date = fields.Datetime(tracking=True) + state = fields.Selection( + [ + ("draft", "Draft"), + ("planned", "Planned"), + ("publishing", "Publishing"), + ("published", "Published"), + ("cancelled", "Cancelled"), + ], + default="draft", + tracking=True, + ) + post_account_ids = fields.One2many("social.post.account", "post_id") + count_post_likes = fields.Integer( + compute="_compute_post_statistics", default=0, string="Likes" + ) + count_post_comments = fields.Integer( + compute="_compute_post_statistics", default=0, string="Comments" + ) + count_post_clicks = fields.Integer( + compute="_compute_post_statistics", default=0, string="Clicks" + ) + count_post_shares = fields.Integer( + compute="_compute_post_statistics", default=0, string="Shares" + ) + count_post_impression = fields.Integer( + compute="_compute_post_statistics", default=0, string="Impression" + ) + count_post_engagement = fields.Float( + compute="_compute_post_statistics", default=0, string="Engagement" + ) + count_post_interactions = fields.Float( + compute="_compute_post_statistics", default=0, string="Interactions" + ) + image_ids = fields.Many2many( + "ir.attachment", + column1="post_id", + column2="image_id", + ondelete="restrict", + relation="social_network_post_image_rel", + ) + video_ids = fields.Many2many( + "ir.attachment", + relation="social_network_post_video_rel", + column1="post_id", + column2="video_id", + ondelete="restrict", + ) + post_preview = fields.Html(compute="_compute_post_preview", store=True) + message_info = fields.Text(compute="_compute_message_info") + any_failed_post = fields.Boolean(compute="_compute_any_failed_post") + hide_post = fields.Boolean(compute="_compute_hide_post") + + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + if vals.get("send_post", False) == "schedule": + vals["state"] = "planned" + return super().create(vals_list) + + def write(self, vals): + res = super().write(vals) + for post in self: + if ("send_post" in vals and vals["send_post"] == "schedule") or ( + "send_post_date" in vals and post.send_post == "schedule" + ): + post.state = "planned" + return res + + @api.depends("state", "any_failed_post", "send_post", "message", "account_ids") + def _compute_hide_post(self): + for post in self: + post.hide_post = ( + ( + post.state in ("planned", "publishing", "published", "cancelled") + and not post.any_failed_post + ) + or not post.message + or not post.account_ids + ) + + @api.depends("post_account_ids") + def _compute_any_failed_post(self): + for post in self: + post.any_failed_post = any( + post_account.state == "failed" for post_account in post.post_account_ids + ) or (post.state == "publishing" and not post.post_account_ids) + + @api.depends("account_ids") + def _compute_message_info(self): + pass + + @api.depends("account_ids.media_id") + def _compute_display_name(self): + for acc in self: + acc.display_name = _("Post on %(posts)s") % { + "posts": ", ".join(acc.account_ids.mapped("media_id.name")) + } + + @api.depends("send_post") + def _compute_send_post_date(self): + for post in self: + if post.send_post == "schedule": + post.send_post_date = datetime.now() + timedelta(hours=1) + else: + post.send_post_date = None + + @api.depends( + "post_account_ids.like_count", + "post_account_ids.comment_count", + "post_account_ids.click_count", + "post_account_ids.share_count", + "post_account_ids.engagement", + "post_account_ids.impression_count", + ) + def _compute_post_statistics(self): + for post in self: + post.count_post_clicks = sum(post.mapped("post_account_ids.click_count")) + post.count_post_shares = sum(post.mapped("post_account_ids.share_count")) + post.count_post_likes = sum(post.mapped("post_account_ids.like_count")) + post.count_post_engagement = sum(post.mapped("post_account_ids.engagement")) + post.count_post_impression = sum(post.mapped("post_account_ids.engagement")) + post.count_post_comments = sum( + post.mapped("post_account_ids.comment_count") + ) + post.count_post_interactions = ( + post.count_post_clicks + + post.count_post_likes + + post.count_post_comments + + post.count_post_shares + ) + + def filter_by_media_types(self, media_types, add_domain=None): + domain = [ + ("media_type", "in", media_types), + ("post_id", "=", self.id), + ("state", "in", ("ready", "failed")), + ] + if add_domain: + domain += add_domain + return self.env["social.post.account"].search(domain) + + def action_draft(self): + for post in self: + post.state = "draft" + + def action_cancel(self): + for post in self: + if post.state in ("publishing", "published"): + raise ValidationError( + _( + "%(post)s: cannot be cancelled because it " + "is published or in the process of being published." + ) + % {"post": post.display_name} + ) + post.state = "cancelled" + + def _render_values_preview(self): + """ + Add extra values dictionary for preview view, if necessary. + :rtype: dict + """ + return {} + + def _render_template_preview(self): + """ + Render the template for the preview view of the post. + + :return: A string containing the rendered templates. + :rtype: str + """ + render_template = "" + IrQweb = self.env["ir.qweb"] + for account in self.account_ids: + values = { + "media_id": account.media_id, + "author": account.name, + "message": self.message, + "image_ids": self.image_ids[0:2], + } + try: + render_template += """\n\n""" + IrQweb._render( + "social_media_{}.social_media_post_preview".format( + account.media_id.media_type + ), + values | self._render_values_preview(), + ) + except ValueError: + render_template += """\n\n""" + IrQweb._render( + "social_media_base.social_media_post_preview", + values | self._render_values_preview(), + ) + return render_template if render_template else _("No preview available") + + @api.depends("account_ids", "message", "image_ids", "video_ids") + def _compute_post_preview(self): + """ + This method is responsible for obtaining the templates + to preview the posts when they are created. + + Template ID format: + * social_media_{media_type}.social_media_post_preview + Example: + * social_media_linkedin.social_media_post_preview + + As many templates as there are media according to the accounts selected in + the post will be rendered. + + If the template does not exist, a default one is rendered. + """ + for post in self: + post.post_preview = post._render_template_preview() + + def _default_account_ids(self): + """ + Returns a list of default account IDs to use when creating a post. + By default, this method returns an empty list. + + :rtype: list[int] + """ + return [] + + @api.model + def default_get(self, fields): + res = super().default_get(fields) + account_ids = self._default_account_ids() + if account_ids: + res["account_ids"] = [(6, 0, account_ids)] + return res + + def action_create_post_account(self): + """ + Publishes the post on all the + associated social media accounts. + """ + self._action_create_post_account() + + def _prepare_post_account_values(self): + """ + Prepare the posting values for each account. + """ + posts_account = [] + for account in self.account_ids: + if account.id not in self.post_account_ids.mapped("account_id").ids: + posts_account.append( + Command.create( + { + "post_id": self.id, + "account_id": account.id, + "state": "ready", + "message": self.message, + } + ) + ) + return posts_account + + def _action_create_post_account(self): + """ + The posts are sent to social media. + """ + SocialPostAccount = self.env["social.post.account"] + for post in self: + post.write( + { + "state": "publishing", + "post_account_ids": post._prepare_post_account_values(), + } + ) + SocialPostAccount._action_post(post_id=post) + if all(post_acc.state == "posted" for post_acc in post.post_account_ids): + post.write({"state": "published"}) + elif all(post_acc.state == "failed" for post_acc in post.post_account_ids): + post.write({"state": "draft"}) + + def _message_error_post(self, message, media_id): + self.message_post( + body=_("Error Post Tweet [%(media)s]: %(error)s") + % {"error": message, "media": media_id}, + ) + + def _run_send_post(self): + """ + Runs the scheduled posts. + + It looks for all the posts that are scheduled to be sent + and sends them to social media. + """ + posts = self.env["social.post"].search( + [ + ("state", "in", ("planned", "publishing")), + ("send_post", "=", "schedule"), + ("send_post_date", "<=", datetime.now()), + ] + ) + posts.with_context( + **{ + "social_post_cron": True, + } + )._action_create_post_account() diff --git a/social_media_base/models/social_post_account.py b/social_media_base/models/social_post_account.py new file mode 100644 index 0000000000..0623833d95 --- /dev/null +++ b/social_media_base/models/social_post_account.py @@ -0,0 +1,174 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import base64 + +import requests + +from odoo import Command, _, fields, models + + +class SocialPostAccount(models.Model): + _name = "social.post.account" + _inherit = ["mail.thread", "social.post.mixin"] + _description = "Social Post Account" + _rec_name = "message" + + post_id = fields.Many2one("social.post", ondelete="restrict") + active = fields.Boolean(default=True) + account_id = fields.Many2one("social.account", ondelete="restrict", required=True) + media_id = fields.Many2one( + "social.media", related="account_id.media_id", required=True + ) + media_type = fields.Selection(related="media_id.media_type") + + state = fields.Selection( + [ + ("ready", "Ready"), + ("posted", "Posted"), + ("failed", "Failed"), + ], + default="ready", + ) + published_date = fields.Datetime() + published = fields.Boolean(default=True) + message = fields.Text(required=True) + + comment_count = fields.Integer() + like_count = fields.Integer() + click_count = fields.Integer() + share_count = fields.Integer() + impression_count = fields.Float() + engagement = fields.Float() + video_ids = fields.Many2many( + "ir.attachment", + relation="social_post_account_video_rel", + column1="post_id", + column2="video_id", + ondelete="restrict", + ) + + image_ids = fields.Many2many( + "ir.attachment", + column1="post_id", + column2="image_id", + ondelete="restrict", + relation="social_post_account_image_rel", + ) + failed_description = fields.Html() + post_account_url = fields.Char() + author = fields.Char(related="account_id.name", store=True) + actor_urn = fields.Char() + + def action_like_post(self, author_urn=None): + """ + Likes the post on social media. + + :param author_urn: The actor urn of the user who is performing the like action. + :type author_urn: str + :return: A dictionary containing the success and message of the like action. + :rtype: dict + """ + return {"success": True, "message": ""} + + def action_like_comment(self, author_urn=None): + return {"success": True, "message": ""} + + def _action_post(self, post_id): + """ + Post on social media + """ + pass + + def _action_campaign_post(self, post_id): + """ + Publishes the campaign post on social media. + + :param post_id: The post ID of the campaign. + :type post_id: int + :return: A dictionary containing the success and message of the post action. + :rtype: dict + """ + pass + + def _delete_post_account(self): + """ + Deletes the post account from social media. + + It should be overridden in the child classes to provide + the specific implementation for each social media platform. + + :return: A dictionary containing the success and message of the deletion action. + :rtype: dict + """ + pass + + def delete_post_account(self): + self.ensure_one() + self._delete_post_account() + account_id = self.account_id + post_id = self.post_id + self.unlink() + if not post_id.post_account_ids: + post_id.unlink() + return { + "type": "ir.actions.client", + "tag": "display_notification", + "params": { + "title": _("Post deleted [%(account)s]") % {"account": account_id.name}, + "type": "success", + "message": _("The post was successfully deleted."), + "next": {"type": "ir.actions.client", "tag": "reload"}, + }, + } + + def get_comments(self): + """ + Retrieves the comments of the post on social media. + + :return: A dictionary containing the success and data of the comments action. + :rtype: dict + """ + return {"success": False, "data": []} + + def create_comment(self, post_data, context=None): + """ + Creates a comment on social media. + + :param post_data: A dictionary containing the message and other post data. + :type post_data: dict + :param context: Optional context to use for rendering the comment. + :type context: dict + :return: A dictionary containing the success and data of the comment action. + :rtype: dict + """ + pass + + def _get_medias_account(self, medias): + return ( + self.env["ir.attachment"] + .search( + [ + ("name", "in", medias), + ] + ) + .mapped("name") + ) + + def _map_medias_account(self, **values): + attach_values = values or {} + media_content = ( + requests.get(values["url"], timeout=10) + if values.get("url", False) + else None + ) + if media_content and media_content.status_code == 200: + attach_values.update( + { + "type": "binary", + "res_model": self._name, + "res_id": self.id, + "datas": base64.b64encode(media_content.content), + } + ) + return Command.create(attach_values) diff --git a/social_media_base/models/social_post_mixin.py b/social_media_base/models/social_post_mixin.py new file mode 100644 index 0000000000..4ea0b6cbf3 --- /dev/null +++ b/social_media_base/models/social_post_mixin.py @@ -0,0 +1,20 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import json + +from odoo import api, fields, models + + +class SocialPostMixin(models.AbstractModel): + _name = "social.post.mixin" + _description = "Social Network Post Mixin" + + image_urls = fields.Char(compute="_compute_image_urls", store=True) + + @api.depends(lambda self: ["image_ids"]) + def _compute_image_urls(self): + for post in self: + post.image_urls = json.dumps( + [f"/web/image/{image_id}" for image_id in post.image_ids.ids] + ) diff --git a/social_media_base/models/utm_campaign.py b/social_media_base/models/utm_campaign.py new file mode 100644 index 0000000000..9eedebee50 --- /dev/null +++ b/social_media_base/models/utm_campaign.py @@ -0,0 +1,43 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import Command, api, fields, models + + +class UtmCampaign(models.Model): + _inherit = "utm.campaign" + + campaign_group_id = fields.Many2one("utm.group.campaign", string="Campaign group") + allow_media_ids = fields.Many2many( + "social.media", string="Media", compute="_compute_media_id" + ) + media_id = fields.Many2one( + "social.media", string="Media", domain="[('id','in',allow_media_ids)]" + ) + account_id = fields.Many2one( + "social.account", string="Account", domain="[('media_id','in',allow_media_ids)]" + ) + + @api.depends("media_id", "account_id") + def _compute_media_id(self): + SocialMedia = self.env["social.media"] + for campaign in self: + campaign.allow_media_ids = [ + Command.set( + SocialMedia.search( + [("media_type", "in", campaign._available_campaign())] + ).ids + ) + ] + + def _available_campaign(self): + """ + Returns a list of available campaign media types. + + It is used to filter the available media types + for a campaign. + + :return: A list of available campaign media types. + :rtype: list + """ + return [] diff --git a/social_media_base/models/utm_group_campaign.py b/social_media_base/models/utm_group_campaign.py new file mode 100644 index 0000000000..b8e75d5048 --- /dev/null +++ b/social_media_base/models/utm_group_campaign.py @@ -0,0 +1,11 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class UtmGroupCampaign(models.Model): + _name = "utm.group.campaign" + _description = "UTM Group Campaign" + + name = fields.Char() diff --git a/social_media_base/pyproject.toml b/social_media_base/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/social_media_base/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/social_media_base/readme/CONTRIBUTORS.md b/social_media_base/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..0bfe91dd47 --- /dev/null +++ b/social_media_base/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- [Binhex Cloud] (https://www.binhex.cloud): + - Edilio Escalona Almira diff --git a/social_media_base/readme/DESCRIPTION.md b/social_media_base/readme/DESCRIPTION.md new file mode 100644 index 0000000000..9c7420d438 --- /dev/null +++ b/social_media_base/readme/DESCRIPTION.md @@ -0,0 +1,11 @@ +This module provides the fundamental foundation for social media management. +It facilitates the integration of user accounts, posts, reactions (likes), +comments, and graph-based analysis. Designed to be flexible and scalable, +it allows developers and businesses to integrate and customize social features +according to their needs. + +Main features: + +- Integration of multiple user accounts. +- Basic methods that can be extended and adapted to suit the social network. +- Basic business structure. diff --git a/social_media_base/readme/USAGE.md b/social_media_base/readme/USAGE.md new file mode 100644 index 0000000000..a104b816e3 --- /dev/null +++ b/social_media_base/readme/USAGE.md @@ -0,0 +1,15 @@ +Generate group campaign. +--------------- + +- Go to *Social Media* > Campaign group > New +- Fill in the required fields + ![CREATE_GROUP_CAMPAIGN](../static/img/readme/CREATE_GROUP_CAMPAIGN.png) +- Save + +Generate campaign. +--------------- + +- Go to *Social Media* > Campaign > New +- Fill in the required fields + ![CREATE_CAMPAIGN](../static/img/readme/CREATE_CAMPAIGN.png) +- Save diff --git a/social_media_base/security/ir.model.access.csv b/social_media_base/security/ir.model.access.csv new file mode 100644 index 0000000000..b377fd6af8 --- /dev/null +++ b/social_media_base/security/ir.model.access.csv @@ -0,0 +1,7 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_social_media_admin,social_media_base_social_media,model_social_media,base.group_user,1,1,1,1 +access_social_account_admin,social_media_base_social_account,model_social_account,base.group_user,1,1,1,1 +access_social_network_post_admin,social_media_base_social_post,model_social_post,base.group_user,1,1,1,1 +access_social_post_account_admin,social_media_base_social_account,model_social_post_account,base.group_user,1,1,1,1 +access_utm_group_campaign_admin,social_media_base_utm_group_campaign,model_utm_group_campaign,base.group_user,1,1,1,1 +access_wizard_social_account_admin,social_media_base_wizard_social_account,model_wizard_social_account,base.group_user,1,1,1,1 diff --git a/social_media_base/security/social_account_security.xml b/social_media_base/security/social_account_security.xml new file mode 100644 index 0000000000..ec7b53e01a --- /dev/null +++ b/social_media_base/security/social_account_security.xml @@ -0,0 +1,14 @@ + + + + + + Social media accounts, the one who created it is the logged-in user. + + [('create_uid', '=', user.id)] + + + diff --git a/social_media_base/security/social_post_account_security.xml b/social_media_base/security/social_post_account_security.xml new file mode 100644 index 0000000000..850adc6c07 --- /dev/null +++ b/social_media_base/security/social_post_account_security.xml @@ -0,0 +1,14 @@ + + + + + + Social media post accounts, the one who created it is the logged-in user. + + [('account_id.create_uid', '=', user.id)] + + + diff --git a/social_media_base/security/social_post_security.xml b/social_media_base/security/social_post_security.xml new file mode 100644 index 0000000000..3ac146e006 --- /dev/null +++ b/social_media_base/security/social_post_security.xml @@ -0,0 +1,14 @@ + + + + + + Social media post, the one who created it is the logged-in user. + + [('create_uid', '=', user.id)] + + + diff --git a/social_media_base/social_utils.py b/social_media_base/social_utils.py new file mode 100644 index 0000000000..81ba9f81a7 --- /dev/null +++ b/social_media_base/social_utils.py @@ -0,0 +1,192 @@ +# Copyright 2025 Binhex +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import re +from datetime import date, datetime, timedelta +from urllib.parse import quote + +import pytz +from werkzeug.urls import url_encode, url_quote + +from odoo.exceptions import ValidationError +from odoo.tools import DEFAULT_SERVER_DATE_FORMAT +from odoo.tools.date_utils import add + + +def convert_to_days(seconds=None, miliseconds=None): + """ + Converts the given duration in seconds or miliseconds into days. + + :param int seconds: duration in seconds + :param int miliseconds: duration in miliseconds + :return: duration in days + :rtype: int + """ + if seconds: + return seconds / 60 / 60 / 24 + elif miliseconds: + return miliseconds / 1000 / 60 / 60 / 24 + return 0 + + +def convert_to_date( + date_add=None, + seconds=None, + miliseconds=None, + expire_date=True, + time_zone=None, + format_date=None, +): + if time_zone and isinstance(time_zone, str): + time_zone = pytz.timezone(time_zone) + if expire_date: + if not date_add: + date_add = date.today() + return_date = add( + date_add + timedelta(days=convert_to_days(seconds, miliseconds)) + ) + else: + return_date = datetime.fromtimestamp(miliseconds / 1000, tz=time_zone) + if format_date: + return_date = return_date.strftime(format_date) + return return_date + + +def convert_date_in_time(miliseconds, timezone=None): + timezone = timezone if timezone else pytz.utc + if isinstance(timezone, str): + timezone = pytz.timezone(timezone) + val_date = convert_to_date( + miliseconds=miliseconds, expire_date=False, time_zone=timezone + ) + current_date = datetime.now(timezone) + diff_date = current_date - val_date + seconds = diff_date.total_seconds() + minutes = seconds / 60 # Convert seconds to minutes + hours = minutes / 60 # Convert minutes to hours + days = hours / 24 # Convert hours to days + months = days / 30 # Convert days to months (months 30 days) + years = months / 12 # Convert months to years + + if seconds < 60: + date_in_time = f"{int(seconds)} seconds" + elif minutes < 60: + date_in_time = f"{int(minutes)} minutes" + elif hours < 24: + date_in_time = f"{int(hours)} hours" + elif days < 30: + date_in_time = f"{int(days)} days" + elif months < 12: + date_in_time = f"{int(months)} months" + else: + years_exacts = int(years) + months_exacts = int(months % 12) + date_in_time = f"{years_exacts} years y {months_exacts} months" + return date_in_time + + +def replace_repetitions(text, character_replace, character_new, repetitions): + positions = [m.start() for m in re.finditer(re.escape(character_replace), text)] + # Convert string to list to modify it + text_result = list(text) + # Replace only the indicated repetitions + count = 0 + for repetition in repetitions: + if int(repetition) - 1 < len(positions): # Check if the occurrence exists + if count == 0: + start = positions[int(repetition) - 1] + count += 1 + else: + start = positions[int(repetition) - 1] - ( + (len(character_replace) - 1) * count + ) + count += 1 + fin = start + len(character_replace) + text_result[start:fin] = character_new + return "".join(text_result) # We convert the list back to string + + +def social_url_encode( + param_field, params_values, params_values_char_ignore, format_quote=False +): + values = {param_field: params_values[param_field]} + if isinstance(params_values[param_field], list): + values = ( + "List(" + + ",".join( + quote(param_value, safe=",") + for param_value in params_values[param_field] + ) + + ")" + ) + url_format = f"{param_field}={url_quote(values, safe='()%,')}".replace("+", "") + elif format_quote: + url_format = ( + f"{param_field}={url_quote(params_values[param_field], safe='()%,')}" + ) + else: + url_format = url_encode(values) + if params_values_char_ignore and params_values_char_ignore.get(param_field, False): + for params_values_char in params_values_char_ignore[param_field]: + for key, character in params_values_char.items(): + if quote(character) in url_format and key == "all": + url_format = url_format.replace(quote(character), character) + else: + url_format = replace_repetitions( + url_format, quote(character), character, key.split(",") + ) + return url_format + + +def _generate_timestamps(date_start=None, date_end=None): + if isinstance(date_start, str): + date_start = datetime.strptime(date_start, DEFAULT_SERVER_DATE_FORMAT) + if isinstance(date_end, str): + date_end = datetime.strptime(date_end, DEFAULT_SERVER_DATE_FORMAT) + + if date_start: + date_start_time = date_start.timestamp() * 1000 + else: + date_start_time = datetime.now().timestamp() * 1000 + + if date_end: + date_end_time = date_start_time + date_end.timestamp() * 1000 + else: + date_end_time = date_start_time + (30 * 86400000) + return int(date_start_time), int(date_end_time) + + +def get_weeks(start_date, end_date, freq="W-MON"): + if isinstance(start_date, str): + start_date = datetime.fromisoformat(start_date) + if isinstance(end_date, str): + end_date = datetime.fromisoformat(end_date) + + result = [] + + if freq == "D": + current = start_date + while current <= end_date: + result.append(current.strftime("%d/%m/%Y")) + current += timedelta(days=1) + + elif freq == "ME": # Month End + current = start_date.replace(day=1) + while current <= end_date: + next_month = (current.replace(day=28) + timedelta(days=4)).replace(day=1) + last_day = next_month - timedelta(days=1) + if last_day <= end_date: + result.append(last_day.strftime("%m/%Y")) + current = next_month + + elif freq == "W-MON": + # Align start_date to the next Monday + days_ahead = (0 - start_date.weekday()) % 7 + current = start_date + timedelta(days=days_ahead) + while current <= end_date: + result.append(current.strftime("%W/%Y")) + current += timedelta(weeks=1) + + else: + raise ValidationError(f"Unsupported frequency: {freq}") + + return result diff --git a/social_media_base/static/description/icon.png b/social_media_base/static/description/icon.png new file mode 100644 index 0000000000..f10b3a7b31 Binary files /dev/null and b/social_media_base/static/description/icon.png differ diff --git a/social_media_base/static/description/icon.svg b/social_media_base/static/description/icon.svg new file mode 100644 index 0000000000..c77511d417 --- /dev/null +++ b/social_media_base/static/description/icon.svg @@ -0,0 +1,83 @@ + + diff --git a/social_media_base/static/description/index.html b/social_media_base/static/description/index.html new file mode 100644 index 0000000000..b1bb90d1a6 --- /dev/null +++ b/social_media_base/static/description/index.html @@ -0,0 +1,461 @@ + + + + + +Social Media Base + + + +
+

Social Media Base

+ + +

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runboat

+

This module provides the fundamental foundation for social media +management. It facilitates the integration of user accounts, posts, +reactions (likes), comments, and graph-based analysis. Designed to be +flexible and scalable, it allows developers and businesses to integrate +and customize social features according to their needs.

+

Main features:

+
    +
  • Integration of multiple user accounts.
  • +
  • Basic methods that can be extended and adapted to suit the social +network.
  • +
  • Basic business structure.
  • +
+

Table of contents

+ +
+

Usage

+
+

Generate group campaign.

+
    +
  • Go to Social Media > Campaign group > New
  • +
  • Fill in the required fields CREATE_GROUP_CAMPAIGN
  • +
  • Save
  • +
+
+
+

Generate campaign.

+
    +
  • Go to Social Media > Campaign > New
  • +
  • Fill in the required fields CREATE_CAMPAIGN
  • +
  • Save
  • +
+
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • BinhexTeam
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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/social project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/social_media_base/static/img/readme/CREATE_CAMPAIGN.png b/social_media_base/static/img/readme/CREATE_CAMPAIGN.png new file mode 100644 index 0000000000..a9028b0c02 Binary files /dev/null and b/social_media_base/static/img/readme/CREATE_CAMPAIGN.png differ diff --git a/social_media_base/static/img/readme/CREATE_GROUP_CAMPAIGN.png b/social_media_base/static/img/readme/CREATE_GROUP_CAMPAIGN.png new file mode 100644 index 0000000000..ea007c2f8f Binary files /dev/null and b/social_media_base/static/img/readme/CREATE_GROUP_CAMPAIGN.png differ diff --git a/social_media_base/static/src/components/social_account/social_account.esm.js b/social_media_base/static/src/components/social_account/social_account.esm.js new file mode 100644 index 0000000000..a35c49f616 --- /dev/null +++ b/social_media_base/static/src/components/social_account/social_account.esm.js @@ -0,0 +1,26 @@ +/** @odoo-module **/ + +import {Component, onWillStart, useState} from "@odoo/owl"; +import {useBus, useService} from "@web/core/utils/hooks"; + +export class SocialAccount extends Component { + static template = "social_media_base.SocialAccount"; + static props = { + socialAccounts: {type: Array}, + }; + + setup() { + super.setup(); + this.orm = useService("dialog"); + this.state = useState({ + needUpdate: false, + }); + onWillStart(async () => { + this.state.needUpdate = + this.props.socialAccounts.filter((item) => item.need_update).length > 0; + }); + useBus(this.env.bus, "SOCIAL:NEED-UPDATE", async ({detail: data}) => { + this.state.needUpdate = data.needUpdate; + }); + } +} diff --git a/social_media_base/static/src/components/social_account/social_account.scss b/social_media_base/static/src/components/social_account/social_account.scss new file mode 100644 index 0000000000..41a574c70e --- /dev/null +++ b/social_media_base/static/src/components/social_account/social_account.scss @@ -0,0 +1,5 @@ +div.social-account-oca { + > div { + margin: 0 0 5px 0 !important; + } +} diff --git a/social_media_base/static/src/components/social_account/social_account.xml b/social_media_base/static/src/components/social_account/social_account.xml new file mode 100644 index 0000000000..21d8a0ef6f --- /dev/null +++ b/social_media_base/static/src/components/social_account/social_account.xml @@ -0,0 +1,69 @@ + + + + +
+ + +
+
+
+ Social Media +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ +
diff --git a/social_media_base/static/src/components/social_ads/social_ads.esm.js b/social_media_base/static/src/components/social_ads/social_ads.esm.js new file mode 100644 index 0000000000..4dcbb6b38a --- /dev/null +++ b/social_media_base/static/src/components/social_ads/social_ads.esm.js @@ -0,0 +1,56 @@ +/** @odoo-module **/ + +import {Component} from "@odoo/owl"; +import {browser} from "@web/core/browser/browser"; + +export class SocialAds extends Component { + static template = "social_media_base.SocialAds"; + static props = { + socialAds: {type: Object, required: true}, + }; + + /** + * Gets the list of ads. + * + * @returns {Object[]} - The list of ads. + */ + get ads() { + return this.props.socialAds; + } + + /** + * Gets the statistic object of the ads. + * + * @returns {Object} - The statistic object of the ads. + */ + get statistic() { + return this.props.socialAds.statistic; + } + + /** + * Gets the campaign object from the social ads. + * + * @returns {Object} - The campaign object of the ads. + */ + get campaign() { + return this.props.socialAds.campaign; + } + + /** + * Gets the post object from the social ads. + * + * @returns {Object} - The post object of the ads. + */ + get post() { + return this.props.socialAds.post; + } + + /** + * Opens the ad link in a new tab. + * + * @returns {void} + */ + onAdsClick() { + browser.open(this.ads.url); + } +} diff --git a/social_media_base/static/src/components/social_ads/social_ads.scss b/social_media_base/static/src/components/social_ads/social_ads.scss new file mode 100644 index 0000000000..76f84aae7c --- /dev/null +++ b/social_media_base/static/src/components/social_ads/social_ads.scss @@ -0,0 +1,4 @@ +div.social-network-ads { + border: 1px solid var(--border-color, #dee2e6); + background-color: white; +} diff --git a/social_media_base/static/src/components/social_ads/social_ads.xml b/social_media_base/static/src/components/social_ads/social_ads.xml new file mode 100644 index 0000000000..5c24f5db61 --- /dev/null +++ b/social_media_base/static/src/components/social_ads/social_ads.xml @@ -0,0 +1,48 @@ + + + + + + diff --git a/social_media_base/static/src/components/social_ads_account/social_ads_account.esm.js b/social_media_base/static/src/components/social_ads_account/social_ads_account.esm.js new file mode 100644 index 0000000000..b05d729643 --- /dev/null +++ b/social_media_base/static/src/components/social_ads_account/social_ads_account.esm.js @@ -0,0 +1,128 @@ +/** @odoo-module **/ + +import {Component, onWillStart, useState} from "@odoo/owl"; +import {ControlPanel} from "@web/search/control_panel/control_panel"; +import {SocialAds} from "../social_ads/social_ads.esm"; +import {SocialFilter} from "../social_filter/social_filter.esm"; +import {registry} from "@web/core/registry"; +import {useService} from "@web/core/utils/hooks"; + +const {DateTime} = luxon; + +export class SocialAdsAccount extends Component { + static template = "social_media_base.SocialAdsAccount"; + static components = { + ControlPanel, + SocialAds, + SocialFilter, + }; + + /** + * Initializes the component by setting up services and initializing state. + * + * This method sets up the ORM and notification services, and initializes + * the state variables for social ads, campaigns, and posts. It also + * triggers the loading of ad accounts before the component starts. + */ + setup() { + this.ormService = useService("orm"); + this.notification = useService("notification"); + this.socialAdsAccount = []; + this.campaigns = []; + this.posts = []; + this.social_state = useState({ + socialAds: [], + loaderAds: false, + }); + onWillStart(async () => { + await this._loadAdsAccount(); + }); + } + + filter_ads(item, startDate, endDate, val_search) { + const created = DateTime.fromFormat(item.created, "dd/MM/yyyy"); + const start_date = DateTime.fromFormat(startDate, "yyyy-MM-dd"); + const end_date = DateTime.fromFormat(endDate, "yyyy-MM-dd"); + return ( + (start_date ? created >= start_date : false) && + (end_date ? created <= end_date : false) && + (val_search + ? (item.campaign.name + ? item.campaign.name.includes(val_search) + : false) || + (item.post.name ? item.post.name.includes(val_search) : false) || + item.status.includes(val_search) + : true) + ); + } + + onFilterAds({startDate, endDate, val_search}) { + if (val_search || startDate || endDate) { + this.social_state.socialAds = this.socialAdsAccount.ads.filter((item) => { + return this.filter_ads(item, startDate, endDate, val_search); + }); + } else { + this.clearFilter(); + } + } + + /** + * Clears the filter and displays all ads again. + * + * When called, this method resets the `socialAds` state to the original + * list of ads retrieved from the server, effectively clearing any + * filtering criteria. + */ + clearFilter() { + this.social_state.socialAds = this.socialAdsAccount.ads; + } + + /** + * Gets the ads after applying the filter criteria. + * + * @returns {Object[]} - The ads after applying the filter criteria. + */ + get ads() { + return this.social_state.socialAds; + } + + /** + * Loads all ads again from the server. + * + * This method is triggered by the "Sync ads" button and is used to + * reload all ads from the server. It will clear any filtering criteria + * and display all ads again. + * + * @returns {Promise} + */ + async onUpdateAllAds() { + await this._loadAdsAccount(); + } + + /** + * Loads all ads from the server. + * + * This method is called when the user clicks on the "Sync ads" button. + * It will clear any filtering criteria, set the `loaderAds` state to + * `true`, and load all ads from the server. After loading the ads, + * it sets the `loaderAds` state to `false` and updates the component's + * state with the retrieved ads. + * + * @returns {Promise} + */ + async _loadAdsAccount() { + this.social_state.loaderAds = true; + const adsAccount = await this.ormService.call( + "social.account", + "load_ads_accounts", + [[]] + ); + this.socialAdsAccount = adsAccount; + this.social_state.socialAds = adsAccount.ads; + this.campaigns = adsAccount.campaigns; + this.posts = adsAccount.posts; + this.social_state.loaderAds = false; + } +} + +registry.category("actions").add("social_ads_account", SocialAdsAccount); diff --git a/social_media_base/static/src/components/social_ads_account/social_ads_account.scss b/social_media_base/static/src/components/social_ads_account/social_ads_account.scss new file mode 100644 index 0000000000..4c6d182540 --- /dev/null +++ b/social_media_base/static/src/components/social_ads_account/social_ads_account.scss @@ -0,0 +1,9 @@ +div.social-network-ads-account { + min-height: 100% !important; + height: 100% !important; + overflow: auto; + + div.social-ads { + margin: 0 !important; + } +} diff --git a/social_media_base/static/src/components/social_ads_account/social_ads_account.xml b/social_media_base/static/src/components/social_ads_account/social_ads_account.xml new file mode 100644 index 0000000000..077c8aa58a --- /dev/null +++ b/social_media_base/static/src/components/social_ads_account/social_ads_account.xml @@ -0,0 +1,55 @@ + + + +