diff --git a/price_update_notifications/__init__.py b/price_update_notifications/__init__.py new file mode 100644 index 0000000..9b42961 --- /dev/null +++ b/price_update_notifications/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/price_update_notifications/__manifest__.py b/price_update_notifications/__manifest__.py new file mode 100644 index 0000000..84b7f04 --- /dev/null +++ b/price_update_notifications/__manifest__.py @@ -0,0 +1,39 @@ +# +# Bemade Inc. +# +# Copyright (C) 2023-June Bemade Inc. (). +# Author: Marc Durepos (Contact : marc@bemade.org) +# +# This program is under the terms of the GNU Lesser General Public License, +# version 3. +# +# For full license details, see https://www.gnu.org/licenses/lgpl-3.0.en.html. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +{ + "name": "Price Update Notifications", + "version": "17.0.1.0.0", + "summary": "Send a price update notification to clients", + "category": "Sale", + "author": "Bemade Inc.", + "website": "http://www.bemade.org", + "license": "LGPL-3", + "depends": ["sale_management", "sales_team", "mail"], + "data": [ + "security/ir.model.access.csv", + "data/ir_cron_data.xml", + "data/email_templates.xml", + "views/price_notice_mailing_views.xml", + "wizard/send_price_update_notice_views.xml", + ], + "assets": {}, + "installable": True, + "auto_install": False, +} diff --git a/price_update_notifications/data/email_templates.xml b/price_update_notifications/data/email_templates.xml new file mode 100644 index 0000000..dc8bf8b --- /dev/null +++ b/price_update_notifications/data/email_templates.xml @@ -0,0 +1,61 @@ + + + + Product Price Update + + + {{ object.partner_id.company_id.name }} Price Update + Notification - + Effective {{ object.effective_date.strftime("%Y-%m-%d") }} + + Sent using the send price update letter action on partners. + + {{ object.partner_id.company_id.email}} + + {{ object.email }} + {{ object.partner_id.lang }} + +
+

Dear ,

+

We have recently updated the pricing for the following + products you have purchased or requested pricing for in the past + year. Please take note that these prices will be effective as of + . +

+
+ +
+ + + + + + + + + + + + + + + + + +
ProductUnitUnit PriceCurrency
+ + + + + + + +
+

Best regards,

+

The team.

+
+
+
+
\ No newline at end of file diff --git a/price_update_notifications/data/ir_cron_data.xml b/price_update_notifications/data/ir_cron_data.xml new file mode 100644 index 0000000..38b94ab --- /dev/null +++ b/price_update_notifications/data/ir_cron_data.xml @@ -0,0 +1,18 @@ + + + + Price Update Notifications: Send + Notifications + + code + model.action_send_all() + + 1 + days + -1 + + + + \ No newline at end of file diff --git a/price_update_notifications/i18n/fr.po b/price_update_notifications/i18n/fr.po new file mode 100644 index 0000000..6b060e2 --- /dev/null +++ b/price_update_notifications/i18n/fr.po @@ -0,0 +1,309 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * price_update_notifications +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-12-05 18:30+0000\n" +"PO-Revision-Date: 2024-12-05 18:30+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: price_update_notifications +#: model:mail.template,subject:price_update_notifications.mail_template_price_update +msgid "" +"\n" +" {{ object.partner_id.company_id.name }} Price Update\n" +" Notification -\n" +" Effective {{ object.effective_date.strftime(\"%Y-%m-%d\") }}\n" +" " +msgstr "" + +#. module: price_update_notifications +#: model:mail.template,body_html:price_update_notifications.mail_template_price_update +msgid "" +"
\n" +"

Dear ,

\n" +"

We have recently updated the pricing for the following\n" +" products you have purchased or requested pricing for in the past\n" +" year. Please take note that these prices will be effective as of\n" +" .\n" +"

\n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
ProductUnitUnit PriceCurrency
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

Best regards,

\n" +"

The team.

\n" +"
\n" +" " +msgstr "" +"
\n" +"

Bonjour ,

\n" +"

Nous avons récemment mis à jour les prix pour les produits " +" suivants, que vous avez demandé en soumission ou" +" commandés dans la dernière année. Veuillez noter " +" que ces prix entreront en vigueur le " +" " +"

\n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
ProduitUnité de mesurePrix unitaireDevise
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

Cordialement,

\n" +"

L'équipe

\n" +"
\n" +" " +#. module: price_update_notifications +#. odoo-python +#: code:addons/price_update_notifications/wizard/send_price_update_notice.py:0 +#, python-format +msgid "

The following partners do not have emails configured:

" +msgstr "

Les partenaires suivants n'ont pas d'adresse courriel définie.

" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_needaction +msgid "Action Needed" +msgstr "Action requise" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__active +msgid "Active" +msgstr "Actif" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__product_template_ids +#: model_terms:ir.ui.view,arch_db:price_update_notifications.price_notice_mailing_view_form +#: model_terms:ir.ui.view,arch_db:price_update_notifications.send_price_update_notice_view_form +msgid "Applicable Products" +msgstr "Produits applicables" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_attachment_count +msgid "Attachment Count" +msgstr "Nombre de pièces jointes" + +#. module: price_update_notifications +#: model_terms:ir.ui.view,arch_db:price_update_notifications.send_price_update_notice_view_form +msgid "Cancel" +msgstr "Annuler" + +#. module: price_update_notifications +#: model_terms:ir.ui.view,arch_db:price_update_notifications.send_price_update_notice_view_form +msgid "Create Notifications" +msgstr "Créer les envois" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__create_uid +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__create_uid +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__create_date +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__create_date +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__currency_id +msgid "Currency" +msgstr "Devise" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__effective_date +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__pricing_date +msgid "Effective Pricing Date" +msgstr "Date d'entrée en vigueur des prix" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__email +msgid "Email" +msgstr "Courriel" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__line_ids +msgid "Line" +msgstr "Ligne" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__mailing_id +msgid "Mailing" +msgstr "Envoi" + +#. module: price_update_notifications +#: model_terms:ir.actions.act_window,help:price_update_notifications.action_view_price_notice_mailings +msgid "No mailings yet. Create one!" +msgstr "Il n'existe aucun envoi. Créez-en un!" + +#. module: price_update_notifications +#. odoo-python +#: code:addons/price_update_notifications/wizard/send_price_update_notice.py:0 +#, python-format +msgid "" +"No valid partners were selected. Partners must have an email address set." +msgstr "" +"Aucun partenaire valide n'a été sélectionné. Les partenaires doivent avoir un courriel défini." + +#. module: price_update_notifications +#: model_terms:ir.ui.view,arch_db:price_update_notifications.price_notice_mailing_view_form +msgid "Notification Lines" +msgstr "Lignes de notification" + + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__partner_id +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__partner_ids +msgid "Partner" +msgstr "Partenaire" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__price +msgid "Price" +msgstr "Prix" + +#. module: price_update_notifications +#: model:ir.model,name:price_update_notifications.model_price_notice_mailing +msgid "Price Notice Mailing" +msgstr "Mise à jour des prix" + +#. module: price_update_notifications +#: model:ir.model,name:price_update_notifications.model_price_notice_mailing_line +msgid "Price Notice Mailing Line" +msgstr "Ligne de mise à jour des prix" + +#. module: price_update_notifications +#: model:ir.actions.act_window,name:price_update_notifications.action_view_price_notice_mailings +msgid "Price Notice Mailings" +msgstr "Mise à jour des prix" + +#. module: price_update_notifications +#: model:ir.model,name:price_update_notifications.model_wizard_price_update_notice +msgid "Price Update Notice Wizard" +msgstr "" + +#. module: price_update_notifications +#: model:ir.ui.menu,name:price_update_notifications.sale_menu_price_notice_mailing +msgid "Price Update Notices" +msgstr "Mises à jour des prix" + +#. module: price_update_notifications +#: model:ir.actions.server,name:price_update_notifications.send_pricing_update_mails_ir_actions_server +msgid "" +"Price Update Notifications: Send\n" +" Notifications" +msgstr "" +"Mise à jour des prix: envoyer\n" +" notifications" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__product_id +msgid "Product" +msgstr "Produit" + +#. module: price_update_notifications +#: model:mail.template,name:price_update_notifications.mail_template_price_update +msgid "Product Price Update" +msgstr "Mise à jour du prix des produits" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__product_template_ids +msgid "Product Template" +msgstr "Gabarit de produit" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__send_date +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__send_date +msgid "Send Date" +msgstr "Date d'envoi" + +#. module: price_update_notifications +#: model:ir.actions.act_window,name:price_update_notifications.action_send_price_update_notice_wizard +msgid "Send Price Update Notice" +msgstr "Envoyer mises à jour des prix" + +#. module: price_update_notifications +#: model:ir.actions.server,name:price_update_notifications.partner_action_send_price_update_notice +msgid "Send Price Update Notice(s)" +msgstr "Envoyer mise(s) à jour des prix" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__sent +msgid "Sent" +msgstr "Envoyé" + +#. module: price_update_notifications +#: model:mail.template,description:price_update_notifications.mail_template_price_update +msgid "" +"Sent using the send price update letter action on partners." +" " +msgstr "" +"Envoyé en utilisant l'action d'envoi des mises à jour des prix sur les partenaires." + +#. module: price_update_notifications +#: model:ir.model.fields,help:price_update_notifications.field_wizard_price_update_notice__pricing_date +msgid "The date at which the prices are valid." +msgstr "La date à laquelle les prix sont valides." + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__warning_msg +msgid "Warning Msg" +msgstr "Avertissement" \ No newline at end of file diff --git a/price_update_notifications/i18n/price_update_notifications.pot b/price_update_notifications/i18n/price_update_notifications.pot new file mode 100644 index 0000000..e4496ad --- /dev/null +++ b/price_update_notifications/i18n/price_update_notifications.pot @@ -0,0 +1,374 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * price_update_notifications +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-12-05 18:30+0000\n" +"PO-Revision-Date: 2024-12-05 18:30+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: price_update_notifications +#: model:mail.template,subject:price_update_notifications.mail_template_price_update +msgid "" +"\n" +" {{ object.partner_id.company_id.name }} Price Update\n" +" Notification -\n" +" Effective {{ object.effective_date.strftime(\"%Y-%m-%d\") }}\n" +" " +msgstr "" + +#. module: price_update_notifications +#: model:mail.template,body_html:price_update_notifications.mail_template_price_update +msgid "" +"
\n" +"

Dear ,

\n" +"

We have recently updated the pricing for the following\n" +" products you have purchased or requested pricing for in the past\n" +" year. Please take note that these prices will be effective as of\n" +" .\n" +"

\n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
ProductUnitUnit PriceCurrency
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

Best regards,

\n" +"

The team.

\n" +"
\n" +" " +msgstr "" + +#. module: price_update_notifications +#. odoo-python +#: code:addons/price_update_notifications/wizard/send_price_update_notice.py:0 +#, python-format +msgid "

The following partners do not have emails configured:

" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__active +msgid "Active" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__product_template_ids +#: model_terms:ir.ui.view,arch_db:price_update_notifications.price_notice_mailing_view_form +#: model_terms:ir.ui.view,arch_db:price_update_notifications.send_price_update_notice_view_form +msgid "Applicable Products" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: price_update_notifications +#: model_terms:ir.ui.view,arch_db:price_update_notifications.send_price_update_notice_view_form +msgid "Cancel" +msgstr "" + +#. module: price_update_notifications +#: model_terms:ir.ui.view,arch_db:price_update_notifications.send_price_update_notice_view_form +msgid "Create Notifications" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__create_uid +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__create_uid +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__create_uid +msgid "Created by" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__create_date +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__create_date +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__create_date +msgid "Created on" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__currency_id +msgid "Currency" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__display_name +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__display_name +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__display_name +msgid "Display Name" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__effective_date +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__pricing_date +msgid "Effective Pricing Date" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__email +msgid "Email" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__has_message +msgid "Has Message" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__id +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__id +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__id +msgid "ID" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,help:price_update_notifications.field_price_notice_mailing__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,help:price_update_notifications.field_price_notice_mailing__message_has_error +#: model:ir.model.fields,help:price_update_notifications.field_price_notice_mailing__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__write_uid +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__write_uid +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__write_date +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__write_date +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__write_date +msgid "Last Updated on" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__line_ids +msgid "Line" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__mailing_id +msgid "Mailing" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_ids +msgid "Messages" +msgstr "" + +#. module: price_update_notifications +#: model_terms:ir.actions.act_window,help:price_update_notifications.action_view_price_notice_mailings +msgid "No mailings yet. Create one!" +msgstr "" + +#. module: price_update_notifications +#. odoo-python +#: code:addons/price_update_notifications/wizard/send_price_update_notice.py:0 +#, python-format +msgid "" +"No valid partners were selected. Partners must have an email address set." +msgstr "" + +#. module: price_update_notifications +#: model_terms:ir.ui.view,arch_db:price_update_notifications.price_notice_mailing_view_form +msgid "Notification Lines" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,help:price_update_notifications.field_price_notice_mailing__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,help:price_update_notifications.field_price_notice_mailing__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__partner_id +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__partner_ids +msgid "Partner" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__price +msgid "Price" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model,name:price_update_notifications.model_price_notice_mailing +msgid "Price Notice Mailing" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model,name:price_update_notifications.model_price_notice_mailing_line +msgid "Price Notice Mailing Line" +msgstr "" + +#. module: price_update_notifications +#: model:ir.actions.act_window,name:price_update_notifications.action_view_price_notice_mailings +msgid "Price Notice Mailings" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model,name:price_update_notifications.model_wizard_price_update_notice +msgid "Price Update Notice Wizard" +msgstr "" + +#. module: price_update_notifications +#: model:ir.ui.menu,name:price_update_notifications.sale_menu_price_notice_mailing +msgid "Price Update Notices" +msgstr "" + +#. module: price_update_notifications +#: model:ir.actions.server,name:price_update_notifications.send_pricing_update_mails_ir_actions_server +msgid "" +"Price Update Notifications: Send\n" +" Notifications" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing_line__product_id +msgid "Product" +msgstr "" + +#. module: price_update_notifications +#: model:mail.template,name:price_update_notifications.mail_template_price_update +msgid "Product Price Update" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__product_template_ids +msgid "Product Template" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__rating_ids +msgid "Ratings" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__send_date +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__send_date +msgid "Send Date" +msgstr "" + +#. module: price_update_notifications +#: model:ir.actions.act_window,name:price_update_notifications.action_send_price_update_notice_wizard +msgid "Send Price Update Notice" +msgstr "" + +#. module: price_update_notifications +#: model:ir.actions.server,name:price_update_notifications.partner_action_send_price_update_notice +msgid "Send Price Update Notice(s)" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__sent +msgid "Sent" +msgstr "" + +#. module: price_update_notifications +#: model:mail.template,description:price_update_notifications.mail_template_price_update +msgid "" +"Sent using the send price update\n" +" letter action on partners.\n" +" " +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,help:price_update_notifications.field_wizard_price_update_notice__pricing_date +msgid "The date at which the prices are valid." +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_wizard_price_update_notice__warning_msg +msgid "Warning Msg" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,field_description:price_update_notifications.field_price_notice_mailing__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: price_update_notifications +#: model:ir.model.fields,help:price_update_notifications.field_price_notice_mailing__website_message_ids +msgid "Website communication history" +msgstr "" diff --git a/price_update_notifications/models/__init__.py b/price_update_notifications/models/__init__.py new file mode 100644 index 0000000..0c775fd --- /dev/null +++ b/price_update_notifications/models/__init__.py @@ -0,0 +1 @@ +from . import price_notice_mailing diff --git a/price_update_notifications/models/price_notice_mailing.py b/price_update_notifications/models/price_notice_mailing.py new file mode 100644 index 0000000..f953302 --- /dev/null +++ b/price_update_notifications/models/price_notice_mailing.py @@ -0,0 +1,132 @@ +from odoo import models, fields, api +from odoo.exceptions import ValidationError +from datetime import timedelta + + +class PriceNoticeMailing(models.Model): + _name = "price.notice.mailing" + _description = "Price Notice Mailing" + _inherit = ["mail.thread"] + + partner_id = fields.Many2one("res.partner", required=True, readonly=True) + email = fields.Char(readonly=True) + product_template_ids = fields.Many2many("product.template") + line_ids = fields.One2many( + comodel_name="price.notice.mailing.line", + inverse_name="mailing_id", + ) + effective_date = fields.Date( + required=True, + string="Effective Pricing Date", + ) + send_date = fields.Date(required=True) + sent = fields.Boolean(default=False, readonly=True) + active = fields.Boolean(default=True) + + def _compute_display_name(self): + for rec in self: + rec.display_name = f"{rec.send_date} - {rec.partner_id.name}" + + def create(self, vals_list): + res = super().create(vals_list) + for mailing in res: + email = mailing.partner_id.email + if not email: + raise ValidationError( + f"Partner email not found for price " + f"notice " + "mailing to {partner.display_name}." + ) + mailing.email = mailing.partner_id.email + mailing._create_lines() + if not mailing.line_ids: + mailing.active = False + return res + + def _create_lines(self): + line_vals = [] + for mailing in self: + products = mailing._get_purchased_products() + for product in products: + pricelist = mailing.partner_id.property_product_pricelist + price = pricelist._get_product_price( + product, + quantity=1.0, + date=mailing.effective_date, + ) + currency = ( + pricelist.currency_id + or mailing.partner_id.company_id.currency_id + or self.env.company.currency_id + ) + line_vals.append( + { + "mailing_id": mailing.id, + "product_id": product.id, + "currency_id": currency.id, + "price": price, + } + ) + self.env["price.notice.mailing.line"].create(line_vals) + + def _get_purchased_products(self): + self.ensure_one() + # Retrieve partner purchase history + so_domain = [ + ("date_order", ">=", fields.Date.today() - timedelta(days=365)), + "|", + "|", + ("partner_id", "=", self.partner_id.id), + ("partner_id", "=", self.partner_id.commercial_partner_id.id), + ( + "partner_id.commercial_partner_id", + "=", + self.partner_id.commercial_partner_id.id, + ), + ] + if self.product_template_ids: + so_domain = [ + "order_line.product_tmpl_id", + "in", + self.product_template_ids.ids, + ] + so_domain + sale_ids = self.env["sale.order"].search(so_domain) + + # Retrieve purchased products and limit to the selected product + # templates + product_domain = [ + ("id", "in", sale_ids.order_line.mapped("product_id").ids), + ] + if self.product_template_ids: + product_domain = product_domain + [ + ("product_tmpl_id", "in", self.product_template_ids.ids) + ] + product_ids = self.env["product.product"].search(product_domain) + return product_ids + + @api.model + def action_send_all(self): + due_mailings = self.search( + [("sent", "=", False), ("send_date", "<=", fields.Date.today())] + ) + due_mailings._action_send() + + def _action_send(self): + template = self.env.ref("price_update_notifications.mail_template_price_update") + for mailing in self: + template.send_mail(mailing.id) + mailing.sent = True + + +class PriceNoticeMailingLine(models.Model): + _name = "price.notice.mailing.line" + _description = "Price Notice Mailing Line" + + mailing_id = fields.Many2one( + "price.notice.mailing", + required=True, + ondelete="cascade", + ) + product_id = fields.Many2one("product.product", required=True) + currency_id = fields.Many2one("res.currency", required=True) + price = fields.Monetary(required=True) diff --git a/price_update_notifications/security/ir.model.access.csv b/price_update_notifications/security/ir.model.access.csv new file mode 100644 index 0000000..2f5226c --- /dev/null +++ b/price_update_notifications/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_wizard_price_update_notice_manager,access_wizard_price_update_notice_manager,model_wizard_price_update_notice,sales_team.group_sale_manager,1,1,1,1 +access_price_notice_mailing_manager,access_price_notice_mailing_manager,model_price_notice_mailing,sales_team.group_sale_manager,1,1,1,1 +access_price_notice_mailing_line_manager,access_price_notice_mailing_line_manager,model_price_notice_mailing_line,sales_team.group_sale_manager,1,1,1,1 +access_wizard_price_update_notice_user,access_wizard_price_update_notice_user,model_wizard_price_update_notice,base.group_user,1,0,0,0 +access_price_notice_mailing_user,access_price_notice_mailing_user,model_price_notice_mailing,base.group_user,1,0,0,0 +access_price_notice_mailing_line_user,access_price_notice_mailing_line_user,model_price_notice_mailing_line,base.group_user,1,0,0,0 \ No newline at end of file diff --git a/price_update_notifications/views/price_notice_mailing_views.xml b/price_update_notifications/views/price_notice_mailing_views.xml new file mode 100644 index 0000000..aaa97dd --- /dev/null +++ b/price_update_notifications/views/price_notice_mailing_views.xml @@ -0,0 +1,97 @@ + + + + price.notice.mailing.view.form + price.notice.mailing + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+
+ + price.notice.mailing.view.list + price.notice.mailing + + + + + + + + + + + + Price Notice Mailings + ir.actions.act_window + price.notice.mailing + tree,form + +

+ No mailings yet. Create one! +

+
+
+ + + Send Price Update Notice + ir.actions.act_window + wizard.price.update.notice + form + new + + + + Send Price Update Notice(s) + + + action + code + + action = { + 'type': 'ir.actions.act_window', + 'name': 'Send Price Update Notice', + 'res_model': 'wizard.price.update.notice', + 'view_mode': 'form', + 'target': 'new', + } + + + + +
\ No newline at end of file diff --git a/price_update_notifications/wizard/__init__.py b/price_update_notifications/wizard/__init__.py new file mode 100644 index 0000000..5448d5c --- /dev/null +++ b/price_update_notifications/wizard/__init__.py @@ -0,0 +1 @@ +from . import send_price_update_notice diff --git a/price_update_notifications/wizard/send_price_update_notice.py b/price_update_notifications/wizard/send_price_update_notice.py new file mode 100644 index 0000000..df6a1cf --- /dev/null +++ b/price_update_notifications/wizard/send_price_update_notice.py @@ -0,0 +1,83 @@ +""" Send a price update notice to selected partners """ + +from odoo import models, fields, api, _ +from odoo.exceptions import UserError +from datetime import timedelta + + +class SendPriceUpdateNotice(models.TransientModel): + _name = "wizard.price.update.notice" + _description = "Price Update Notice Wizard" + + partner_ids = fields.Many2many(comodel_name="res.partner") + product_template_ids = fields.Many2many( + string="Applicable Products", + comodel_name="product.template", + ) + pricing_date = fields.Date( + string="Effective Pricing Date", + help="The date at which the prices are valid.", + ) + send_date = fields.Date( + default=fields.Date.today() + timedelta(days=1), + ) + warning_msg = fields.Html() + + @api.depends_context("active_ids") + def default_get(self, fields): + vals = {} + if "partner_ids" in fields: + active_ids = self.env.context.get("active_ids") or [ + self.env.context.get("active_id") + ] + partners = self.env["res.partner"].search([("id", "in", active_ids)]) + if no_email_partners := partners.filtered(lambda p: not p.email): + warning_msg = self._get_warning_message(no_email_partners) + else: + warning_msg = None + valid_partners = partners.filtered("email") + if not valid_partners: + raise UserError( + _( + "No valid partners were selected. Partners must have an email address set." + ) + ) + vals.update( + partner_ids=partners.filtered("email").ids, + warning_msg=warning_msg, + ) + if "product_template_ids" in fields: + vals.update(product_template_ids=[]) + return vals + + def action_create(self): + self.ensure_one() + vals_list = [] + for partner in self.partner_ids: + vals_list.append( + { + "partner_id": partner.id, + "product_template_ids": self.product_template_ids.ids, + "effective_date": self.pricing_date, + "send_date": self.send_date, + } + ) + mailings = self.env["price.notice.mailing"].create(vals_list) + return { + "name": "Price Notice Mailings", + "type": "ir.actions.act_window", + "view_mode": "tree,form", + "res_model": "price.notice.mailing", + "res_id": False, + "domain": [["id", "in", mailings.ids]], + "target": "current", + } + + @api.model + def _get_warning_message(self, partner_ids): + msg = _("

The following partners do not have emails configured:

") + msg += "" + return msg diff --git a/price_update_notifications/wizard/send_price_update_notice_views.xml b/price_update_notifications/wizard/send_price_update_notice_views.xml new file mode 100644 index 0000000..04cbe41 --- /dev/null +++ b/price_update_notifications/wizard/send_price_update_notice_views.xml @@ -0,0 +1,36 @@ + + + + send.price.update.notice.view.form + wizard.price.update.notice + +
+ + + + + + + + + + + + + + + + +
+
+
+
\ No newline at end of file