PURPOSE
Clean organization of templates in odoo apps: mail.template records in data,
qweb templates (views) used directly in code, notably using post with view.
Purpose is to ease future improvements in posting based on templates.
SPECIFICATIONS
* move those templates in their own file to ease their discovering and
maintenance;
* put them into data (as those are not views even if it contains qweb)
* guidelines are now :
-> Qweb templates should be in data/mail_templates.xml;
-> mail.template records should be in data/mail_template_data.xml;
* put their declaration in no update when not done if template has no
technical code or complex dependency on underlying code;
* move found mail data (mail.message.subtype or mail.activity.type) records
in a mail_data file that should contain only "core" records linked to mail;
LINKS
Task ID-2375767
COM PR odoo/odoo#61814
ENT PR odoo/enterprise#14775
UPG PR odoo/upgrade#1936
225 lines
11 KiB
XML
225 lines
11 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<odoo>
|
|
<data noupdate="1">
|
|
<record id="email_template_edi_sale" model="mail.template">
|
|
<field name="name">Sales Order: Send by email</field>
|
|
<field name="model_id" ref="sale.model_sale_order"/>
|
|
<field name="subject">${object.company_id.name} ${object.state in ('draft', 'sent') and (ctx.get('proforma') and 'Proforma' or 'Quotation') or 'Order'} (Ref ${object.name or 'n/a' })</field>
|
|
<field name="email_from">${(object.user_id.email_formatted or user.email_formatted) | safe}</field>
|
|
<field name="partner_to">${object.partner_id.id}</field>
|
|
<field name="body_html" type="html">
|
|
<div style="margin: 0px; padding: 0px;">
|
|
<p style="margin: 0px; padding: 0px; font-size: 13px;">
|
|
% set doc_name = 'quotation' if object.state in ('draft', 'sent') else 'order'
|
|
Hello,
|
|
<br/><br/>
|
|
Your
|
|
% if ctx.get('proforma'):
|
|
Pro forma invoice for ${doc_name} <strong>${object.name}</strong>
|
|
% if object.origin:
|
|
(with reference: ${object.origin} )
|
|
% endif
|
|
amounting in <strong>${format_amount(object.amount_total, object.pricelist_id.currency_id)}</strong> is available.
|
|
% else:
|
|
${doc_name} <strong>${object.name}</strong>
|
|
% if object.origin:
|
|
(with reference: ${object.origin} )
|
|
% endif
|
|
amounting in <strong>${format_amount(object.amount_total, object.pricelist_id.currency_id)}</strong> is ready for review.
|
|
% endif
|
|
<br/><br/>
|
|
Do not hesitate to contact us if you have any questions.
|
|
<br/>
|
|
</p>
|
|
</div>
|
|
</field>
|
|
<field name="report_template" ref="action_report_saleorder"/>
|
|
<field name="report_name">${(object.name or '').replace('/','_')}</field>
|
|
<field name="lang">${object.partner_id.lang}</field>
|
|
<field name="auto_delete" eval="True"/>
|
|
</record>
|
|
|
|
<record id="mail_template_sale_confirmation" model="mail.template">
|
|
<field name="name">Sales Order: Confirmation Email</field>
|
|
<field name="model_id" ref="sale.model_sale_order"/>
|
|
<field name="subject">${object.company_id.name} ${(object.get_portal_last_transaction().state == 'pending') and 'Pending Order' or 'Order'} (Ref ${object.name or 'n/a' })</field>
|
|
<field name="email_from">${(object.user_id.email_formatted or user.email_formatted) | safe}</field>
|
|
<field name="partner_to">${object.partner_id.id}</field>
|
|
<field name="body_html" type="html">
|
|
<div style="margin: 0px; padding: 0px;">
|
|
<p style="margin: 0px; padding: 0px; font-size: 12px;">
|
|
Hello,
|
|
<br/><br/>
|
|
% set transaction = object.get_portal_last_transaction()
|
|
Your order <strong>${object.name}</strong> amounting in <strong>${format_amount(object.amount_total, object.currency_id)}</strong>
|
|
% if object.state == 'sale' or (transaction and transaction.state in ('done', 'authorized')) :
|
|
has been confirmed.<br/>
|
|
Thank you for your trust!
|
|
% elif transaction and transaction.state == 'pending' :
|
|
is pending. It will be confirmed when the payment is received.
|
|
% if object.reference:
|
|
Your payment reference is <strong>${object.reference}</strong>.
|
|
% endif
|
|
% endif
|
|
<br/><br/>
|
|
Do not hesitate to contact us if you have any questions.
|
|
<br/><br/>
|
|
</p>
|
|
% if object.website_id:
|
|
<div style="margin: 0px; padding: 0px;">
|
|
<table width="100%" style="color: #454748; font-size: 12px; border-collapse: collapse;">
|
|
<tr style="border-bottom: 2px solid #dee2e6;">
|
|
<td style="width: 150px;"><strong>Products</strong></td>
|
|
<td></td>
|
|
<td width="15%" align="center"><strong>Quantity</strong></td>
|
|
<td width="20%" align="right"><strong>
|
|
% if object.user_id.has_group('account.group_show_line_subtotals_tax_excluded'):
|
|
VAT Excl.
|
|
% else
|
|
VAT Incl.
|
|
% endif
|
|
</strong></td>
|
|
</tr>
|
|
</table>
|
|
% for line in object.order_line:
|
|
% if not line.is_delivery and line.display_type in ['line_section', 'line_note']:
|
|
<table width="100%" style="color: #454748; font-size: 12px; border-collapse: collapse;">
|
|
<tr style="${loop.cycle('background-color: #f2f2f2', 'background-color: #ffffff')}">
|
|
<td colspan="4">
|
|
% if line.display_type == 'line_section':
|
|
<strong>${line.name}</strong>
|
|
% elif line.display_type == 'line_note':
|
|
<i>${line.name}</i>
|
|
% endif
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
% elif not line.is_delivery
|
|
<table width="100%" style="color: #454748; font-size: 12px; border-collapse: collapse;">
|
|
<tr style="${loop.cycle('background-color: #f2f2f2', 'background-color: #ffffff')}">
|
|
<td style="width: 150px;">
|
|
<img src="/web/image/product.product/${line.product_id.id}/image_128" style="width: 64px; height: 64px; object-fit: contain;" alt="Product image"></img>
|
|
</td>
|
|
<td align="left">${line.product_id.name}</td>
|
|
<td width="15%" align="center">${line.product_uom_qty}</td>
|
|
<td width="20%" align="right"><strong>
|
|
% if object.user_id.has_group('account.group_show_line_subtotals_tax_excluded'):
|
|
${format_amount(line.price_reduce_taxexcl, object.currency_id)}
|
|
% else
|
|
${format_amount(line.price_reduce_taxinc, object.currency_id)}
|
|
% endif
|
|
</strong></td>
|
|
</tr>
|
|
</table>
|
|
% endif
|
|
% endfor
|
|
</div>
|
|
% if object.carrier_id:
|
|
<div style="margin: 0px; padding: 0px;">
|
|
<table width="100%" style="color: #454748; font-size: 12px; border-spacing: 0px 4px;" align="right">
|
|
<tr>
|
|
<td style="width: 60%"/>
|
|
<td style="width: 30%; border-top: 1px solid #dee2e6;" align="right"><strong>Delivery:</strong></td>
|
|
<td style="width: 10%; border-top: 1px solid #dee2e6;" align="right">${format_amount(object.amount_delivery, object.currency_id)}</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width: 60%"/>
|
|
<td style="width: 30%;" align="right"><strong>SubTotal:</strong></td>
|
|
<td style="width: 10%;" align="right">${format_amount(object.amount_untaxed, object.currency_id)}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
% else:
|
|
<div style="margin: 0px; padding: 0px;">
|
|
<table width="100%" style="color: #454748; font-size: 12px; border-spacing: 0px 4px;" align="right">
|
|
<tr>
|
|
<td style="width: 60%"/>
|
|
<td style="width: 30%; border-top: 1px solid #dee2e6;" align="right"><strong>SubTotal:</strong></td>
|
|
<td style="width: 10%; border-top: 1px solid #dee2e6;" align="right">${format_amount(object.amount_untaxed, object.currency_id)}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
% endif
|
|
<div style="margin: 0px; padding: 0px;">
|
|
<table width="100%" style="color: #454748; font-size: 12px; border-spacing: 0px 4px;" align="right">
|
|
<tr>
|
|
<td style="width: 60%"/>
|
|
<td style="width: 30%;" align="right"><strong>Taxes:</strong></td>
|
|
<td style="width: 10%;" align="right">${format_amount(object.amount_tax, object.currency_id)}</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width: 60%"/>
|
|
<td style="width: 30%; border-top: 1px solid #dee2e6;" align="right"><strong>Total:</strong></td>
|
|
<td style="width: 10%; border-top: 1px solid #dee2e6;" align="right">${format_amount(object.amount_total, object.currency_id)}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
% if object.partner_invoice_id:
|
|
<div style="margin: 0px; padding: 0px;">
|
|
<table width="100%" style="color: #454748; font-size: 12px;">
|
|
<tr>
|
|
<td style="padding-top: 10px;">
|
|
<strong>Bill to:</strong>
|
|
${object.partner_invoice_id.street or ''}
|
|
${object.partner_invoice_id.city or ''}
|
|
${object.partner_invoice_id.state_id.name or ''}
|
|
${object.partner_invoice_id.zip or ''}
|
|
${object.partner_invoice_id.country_id.name or ''}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<strong>Payment Method:</strong>
|
|
% if transaction.payment_token_id:
|
|
${transaction.payment_token_id.name}
|
|
% else:
|
|
${transaction.acquirer_id.name}
|
|
% endif
|
|
(${format_amount(transaction.amount, object.currency_id)})
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
% endif
|
|
% if object.partner_shipping_id and not object.only_services:
|
|
<div style="margin: 0px; padding: 0px;">
|
|
<table width="100%" style="color: #454748; font-size: 12px;">
|
|
<tr>
|
|
<td>
|
|
<br/>
|
|
<strong>Ship to:</strong>
|
|
${object.partner_shipping_id.street or ''}
|
|
${object.partner_shipping_id.city or ''}
|
|
${object.partner_shipping_id.state_id.name or ''}
|
|
${object.partner_shipping_id.zip or ''}
|
|
${object.partner_shipping_id.country_id.name or ''}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
% if object.carrier_id:
|
|
<table width="100%" style="color: #454748; font-size: 12px;">
|
|
<tr>
|
|
<td>
|
|
<strong>Shipping Method:</strong>
|
|
${object.carrier_id.name}
|
|
% if object.carrier_id.fixed_price == 0.0:
|
|
(Free)
|
|
% else:
|
|
(${format_amount(object.carrier_id.fixed_price, object.currency_id)})
|
|
% endif
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
% endif
|
|
</div>
|
|
% endif
|
|
% endif
|
|
</div></field>
|
|
<field name="report_template" ref="action_report_saleorder"/>
|
|
<field name="report_name">${(object.name or '').replace('/','_')}</field>
|
|
<field name="lang">${object.partner_id.lang}</field>
|
|
<field name="auto_delete" eval="True"/>
|
|
</record>
|
|
</data>
|
|
</odoo>
|