Merge branch '17.0' of git.bemade.org:bemade/bemade-addons into 17.0

This commit is contained in:
xtremxpert 2024-12-09 09:36:06 -05:00
commit 5b18adb083
13 changed files with 1160 additions and 0 deletions

View file

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

View file

@ -0,0 +1,39 @@
#
# Bemade Inc.
#
# Copyright (C) 2023-June Bemade Inc. (<https://www.bemade.org>).
# 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,
}

View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="mail_template_price_update" model="mail.template">
<field name="name">Product Price Update</field>
<field name="model_id"
ref="price_update_notifications.model_price_notice_mailing"/>
<field name="subject">
{{ object.partner_id.company_id.name }} Price Update
Notification -
Effective {{ object.effective_date.strftime("%Y-%m-%d") }}
</field>
<field name="description">Sent using the send price update letter action on partners.</field>
<field name="email_from">
{{ object.partner_id.company_id.email}}
</field>
<field name="email_to">{{ object.email }}</field>
<field name="lang">{{ object.partner_id.lang }}</field>
<field name="body_html" type="html">
<div style="margin: 0px; padding: 0px" id="intro">
<p>Dear <span t-field="object.partner_id.name"/>,</p>
<p>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
<span t-out="object.effective_date.strftime('%Y-%m-%d')"/>.
</p>
</div>
<t t-set="company"
t-value="object.partner_id.company_id or object.env.company"/>
<div id="table">
<table class="table" style="width: 100%; border-collapse: collapse; font-family: Arial, sans-serif;">
<thead style="background-color: #f2f2f2; text-align: left;">
<tr>
<th style="padding: 8px; border-bottom: 2px solid #ddd;">Product</th>
<th style="padding: 8px; border-bottom: 2px solid #ddd;">Unit</th>
<th style="padding: 8px; border-bottom: 2px solid #ddd; text-align: right;">Unit Price</th>
<th style="padding: 8px; border-bottom: 2px solid #ddd;">Currency</th>
</tr>
</thead>
<tbody>
<tr t-foreach="object.line_ids" t-as="line" t-attf-style="background-color: {{ line_index % 2 == 0 and '#f9f9f9' or '#ffffff' }};">
<td style="padding: 8px; border-bottom: 1px solid #ddd;">
<span t-field="line.product_id.display_name"/>
</td>
<td style="padding: 8px; border-bottom: 1px solid #ddd;">
<span t-field="line.product_id.uom_id.display_name"/>
</td>
<td style="padding: 8px; border-bottom: 1px solid #ddd; text-align: right;">
<span t-field="line.price" t-options="{'widget': 'monetary', 'display_currency': line.currency_id}"/>
</td>
<td style="padding: 8px; border-bottom: 1px solid #ddd;">
<span t-field="line.currency_id.name"/>
</td>
</tr>
</tbody>
</table>
<p>Best regards,</p>
<p>The <span t-out="company.name"/> team.</p>
</div>
</field>
</record>
</odoo>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="send_pricing_update_mails" model="ir.cron">
<field name="name">Price Update Notifications: Send
Notifications</field>
<field name="model_id"
ref="price_update_notifications.model_price_notice_mailing"/>
<field name="state">code</field>
<field name="code">model.action_send_all()</field>
<field name="active" eval="True"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="nextcall"
eval="(DateTime.now() + timedelta(days=1))"/>
</record>
</odoo>

View file

@ -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 ""
"<div style=\"margin: 0px; padding: 0px\" id=\"intro\">\n"
" <p>Dear <span t-field=\"object.partner_id.name\"></span>,</p>\n"
" <p>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"
" <span t-out=\"object.effective_date.strftime('%Y-%m-%d')\"></span>.\n"
" </p>\n"
" </div>\n"
" <t t-set=\"company\" t-value=\"object.partner_id.company_id or object.env.company\"></t>\n"
" <div id=\"table\">\n"
" <table class=\"table\" style=\"width: 100%; border-collapse: collapse; font-family: Arial, sans-serif;\">\n"
" <thead style=\"background-color: #f2f2f2; text-align: left;\">\n"
" <tr>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd;\">Product</th>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd;\">Unit</th>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd; text-align: right;\">Unit Price</th>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd;\">Currency</th>\n"
" </tr>\n"
" </thead>\n"
" <tbody>\n"
" <tr t-foreach=\"object.line_ids\" t-as=\"line\" t-attf-style=\"background-color: {{ line_index % 2 == 0 and '#f9f9f9' or '#ffffff' }};\">\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd;\">\n"
" <span t-field=\"line.product_id.display_name\"></span>\n"
" </td>\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd;\">\n"
" <span t-field=\"line.product_id.uom_id.display_name\"></span>\n"
" </td>\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd; text-align: right;\">\n"
" <span t-field=\"line.price\" t-options=\"{'widget': 'monetary', 'display_currency': line.currency_id}\"></span>\n"
" </td>\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd;\">\n"
" <span t-field=\"line.currency_id.name\"></span>\n"
" </td>\n"
" </tr>\n"
" </tbody>\n"
" </table>\n"
" <p>Best regards,</p>\n"
" <p>The <span t-out=\"company.name\"></span> team.</p>\n"
" </div>\n"
" "
msgstr ""
"<div style=\"margin: 0px; padding: 0px\" id=\"intro\">\n"
" <p>Bonjour <span t-field=\"object.partner_id.name\"></span>,</p>\n"
" <p>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 "
" <span t-out=\"object.effective_date.strftime('%Y-%m-%d')\"></span>"
" </p>\n"
" </div>\n"
" <t t-set=\"company\" t-value=\"object.partner_id.company_id or object.env.company\"></t>\n"
" <div id=\"table\">\n"
" <table class=\"table\" style=\"width: 100%; border-collapse: collapse; font-family: Arial, sans-serif;\">\n"
" <thead style=\"background-color: #f2f2f2; text-align: left;\">\n"
" <tr>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd;\">Produit</th>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd;\">Unité de mesure</th>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd; text-align: right;\">Prix unitaire</th>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd;\">Devise</th>\n"
" </tr>\n"
" </thead>\n"
" <tbody>\n"
" <tr t-foreach=\"object.line_ids\" t-as=\"line\" t-attf-style=\"background-color: {{ line_index % 2 == 0 and '#f9f9f9' or '#ffffff' }};\">\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd;\">\n"
" <span t-field=\"line.product_id.display_name\"></span>\n"
" </td>\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd;\">\n"
" <span t-field=\"line.product_id.uom_id.display_name\"></span>\n"
" </td>\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd; text-align: right;\">\n"
" <span t-field=\"line.price\" t-options=\"{'widget': 'monetary', 'display_currency': line.currency_id}\"></span>\n"
" </td>\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd;\">\n"
" <span t-field=\"line.currency_id.name\"></span>\n"
" </td>\n"
" </tr>\n"
" </tbody>\n"
" </table>\n"
" <p>Cordialement,</p>\n"
" <p>L'équipe <span t-out=\"company.name\"></span></p>\n"
" </div>\n"
" "
#. module: price_update_notifications
#. odoo-python
#: code:addons/price_update_notifications/wizard/send_price_update_notice.py:0
#, python-format
msgid "<p>The following partners do not have emails configured:</p>"
msgstr "<p>Les partenaires suivants n'ont pas d'adresse courriel définie.</p>"
#. 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"

View file

@ -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 ""
"<div style=\"margin: 0px; padding: 0px\" id=\"intro\">\n"
" <p>Dear <span t-field=\"object.partner_id.name\"></span>,</p>\n"
" <p>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"
" <span t-out=\"object.effective_date.strftime('%Y-%m-%d')\"></span>.\n"
" </p>\n"
" </div>\n"
" <t t-set=\"company\" t-value=\"object.partner_id.company_id or object.env.company\"></t>\n"
" <div id=\"table\">\n"
" <table class=\"table\" style=\"width: 100%; border-collapse: collapse; font-family: Arial, sans-serif;\">\n"
" <thead style=\"background-color: #f2f2f2; text-align: left;\">\n"
" <tr>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd;\">Product</th>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd;\">Unit</th>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd; text-align: right;\">Unit Price</th>\n"
" <th style=\"padding: 8px; border-bottom: 2px solid #ddd;\">Currency</th>\n"
" </tr>\n"
" </thead>\n"
" <tbody>\n"
" <tr t-foreach=\"object.line_ids\" t-as=\"line\" t-attf-style=\"background-color: {{ line_index % 2 == 0 and '#f9f9f9' or '#ffffff' }};\">\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd;\">\n"
" <span t-field=\"line.product_id.display_name\"></span>\n"
" </td>\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd;\">\n"
" <span t-field=\"line.product_id.uom_id.display_name\"></span>\n"
" </td>\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd; text-align: right;\">\n"
" <span t-field=\"line.price\" t-options=\"{'widget': 'monetary', 'display_currency': line.currency_id}\"></span>\n"
" </td>\n"
" <td style=\"padding: 8px; border-bottom: 1px solid #ddd;\">\n"
" <span t-field=\"line.currency_id.name\"></span>\n"
" </td>\n"
" </tr>\n"
" </tbody>\n"
" </table>\n"
" <p>Best regards,</p>\n"
" <p>The <span t-out=\"company.name\"></span> team.</p>\n"
" </div>\n"
" "
msgstr ""
#. module: price_update_notifications
#. odoo-python
#: code:addons/price_update_notifications/wizard/send_price_update_notice.py:0
#, python-format
msgid "<p>The following partners do not have emails configured:</p>"
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 ""

View file

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

View file

@ -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)

View file

@ -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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 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
3 access_price_notice_mailing_manager access_price_notice_mailing_manager model_price_notice_mailing sales_team.group_sale_manager 1 1 1 1
4 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
5 access_wizard_price_update_notice_user access_wizard_price_update_notice_user model_wizard_price_update_notice base.group_user 1 0 0 0
6 access_price_notice_mailing_user access_price_notice_mailing_user model_price_notice_mailing base.group_user 1 0 0 0
7 access_price_notice_mailing_line_user access_price_notice_mailing_line_user model_price_notice_mailing_line base.group_user 1 0 0 0

View file

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="price_notice_mailing_view_form" model="ir.ui.view">
<field name="name">price.notice.mailing.view.form</field>
<field name="model">price.notice.mailing</field>
<field name="arch" type="xml">
<form>
<sheet>
<group colspan="2">
<field name="partner_id"/>
<field name="send_date"/>
<field name="effective_date"/>
<field name="sent"/>
</group>
<notebook>
<page string="Notification Lines">
<field name="line_ids">
<tree>
<field name="product_id"/>
<field name="price"/>
<field name="currency_id"/>
</tree>
</field>
</page>
<page string="Applicable Products">
<field name="product_template_ids">
<tree>
<field name="name"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<record id="price_notice_mailing_view_list" model="ir.ui.view">
<field name="name">price.notice.mailing.view.list</field>
<field name="model">price.notice.mailing</field>
<field name="arch" type="xml">
<tree>
<field name="send_date"/>
<field name="partner_id"/>
<field name="effective_date"/>
<field name="send_date"/>
<field name="sent"/>
</tree>
</field>
</record>
<record id="action_view_price_notice_mailings" model="ir.actions.act_window">
<field name="name">Price Notice Mailings</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">price.notice.mailing</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No mailings yet. Create one!
</p>
</field>
</record>
<record id="action_send_price_update_notice_wizard" model="ir.actions.act_window">
<field name="name">Send Price Update Notice</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">wizard.price.update.notice</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<record id="partner_action_send_price_update_notice" model="ir.actions.server">
<field name="name">Send Price Update Notice(s)</field>
<field name="model_id" ref="base.model_res_partner"/>
<field name="binding_model_id" ref="base.model_res_partner"/>
<field name="binding_type">action</field>
<field name="state">code</field>
<field name="code">
action = {
'type': 'ir.actions.act_window',
'name': 'Send Price Update Notice',
'res_model': 'wizard.price.update.notice',
'view_mode': 'form',
'target': 'new',
}
</field>
</record>
<menuitem id="sale_menu_price_notice_mailing"
parent="sale.sale_menu_root"
action="action_view_price_notice_mailings"
sequence="20"
name="Price Update Notices"/>
</odoo>

View file

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

View file

@ -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 = _("<p>The following partners do not have emails configured:</p>")
msg += "<ul>"
for partner in partner_ids:
msg += f"<li>{partner.display_name}</li>"
msg += "</ul>"
return msg

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="send_price_update_notice_view_form" model="ir.ui.view">
<field name="name">send.price.update.notice.view.form</field>
<field name="model">wizard.price.update.notice</field>
<field name="arch" type="xml">
<form>
<sheet>
<div invisible="not warning_msg" class="alert alert-warning"
role="alert">
<field name="warning_msg" readonly="True"/>
</div>
<group>
<group>
<field name="partner_ids" invisible="True"/>
<field name="pricing_date"/>
<field name="send_date"/>
</group>
</group>
<notebook>
<page string="Applicable Products">
<field name="product_template_ids"/>
</page>
</notebook>
<footer>
<button special="cancel" string="Cancel"
class="btn btn-secondary"/>
<button type="object" name="action_create"
string="Create Notifications"
class="btn btn-primary"/>
</footer>
</sheet>
</form>
</field>
</record>
</odoo>