mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2025-02-25 18:55:21 -06:00
Merge branch 'master-upstream-patch-18082023' into 'master'
[PATCH] Upstream patch - 18082023 See merge request flectra-hq/flectra!1110
This commit is contained in:
@@ -25,3 +25,12 @@ def migrate(cr, version):
|
||||
rename_tag(cr, "tag_de_liabilities_bs_D_8", "tag_de_liabilities_bs_C_8")
|
||||
rename_tag(cr, "tag_de_liabilities_bs_E", "tag_de_liabilities_bs_D")
|
||||
rename_tag(cr, "tag_de_liabilities_bs_F", "tag_de_liabilities_bs_E")
|
||||
|
||||
# By deleting tag B from ir_model_data we ensure that the ORM won't try to remove this record.
|
||||
# This is done because the tag might be already used as a FK somewhere else.
|
||||
cr.execute(
|
||||
"""DELETE FROM ir_model_data
|
||||
WHERE module='l10n_de'
|
||||
AND name='tag_de_liabilities_bs_B'
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ class ChannelPartner(models.Model):
|
||||
|
||||
custom_channel_name = fields.Char('Custom channel name')
|
||||
partner_id = fields.Many2one('res.partner', string='Recipient', ondelete='cascade')
|
||||
partner_email = fields.Char('Email', related='partner_id.email', depends=['partner_id'], readonly=False)
|
||||
partner_email = fields.Char('Email', related='partner_id.email', depends=['partner_id'], related_sudo=False)
|
||||
channel_id = fields.Many2one('mail.channel', string='Channel', ondelete='cascade')
|
||||
fetched_message_id = fields.Many2one('mail.message', string='Last Fetched')
|
||||
seen_message_id = fields.Many2one('mail.message', string='Last Seen')
|
||||
|
||||
@@ -1275,6 +1275,9 @@ class MailThread(models.AbstractModel):
|
||||
if message.get_content_type() == 'text/plain':
|
||||
# text/plain -> <pre/>
|
||||
body = tools.append_content_to_html(u'', body, preserve=True)
|
||||
elif message.get_content_type() == 'text/html':
|
||||
# we only strip_classes here everything else will be done in by html field of mail.message
|
||||
body = tools.html_sanitize(body, sanitize_tags=False, strip_classes=True)
|
||||
else:
|
||||
alternative = False
|
||||
mixed = False
|
||||
|
||||
@@ -27,3 +27,7 @@ class StockMove(models.Model):
|
||||
res = super(StockMove, self)._filter_anglo_saxon_moves(product)
|
||||
res += self.filtered(lambda m: m.bom_line_id.bom_id.product_tmpl_id.id == product.product_tmpl_id.id)
|
||||
return res
|
||||
|
||||
def _should_force_price_unit(self):
|
||||
self.ensure_one()
|
||||
return self.picking_type_id.code == 'mrp_operation' or super()._should_force_price_unit()
|
||||
|
||||
@@ -198,9 +198,22 @@ class TestMrpValuationStandard(TestMrpValuationCommon):
|
||||
self.assertEqual(self.product1.value_svl, 8.8 * 2)
|
||||
self.assertEqual(self.component.quantity_svl, 0)
|
||||
self.assertEqual(self.product1.quantity_svl, 2)
|
||||
self.assertEqual(self.product1.standard_price, 8.8)
|
||||
|
||||
self._make_out_move(self.product1, 1)
|
||||
self.assertEqual(self.product1.value_svl, 8.8)
|
||||
|
||||
# Update component price
|
||||
self.component.standard_price = 0
|
||||
|
||||
self._make_in_move(self.component, 3)
|
||||
mo = self._make_mo(self.bom, 3)
|
||||
self._produce(mo)
|
||||
mo.button_mark_done()
|
||||
self.assertEqual(self.product1.value_svl, 8.8)
|
||||
self.assertEqual(self.product1.quantity_svl, 4)
|
||||
self.assertEqual(self.product1.standard_price, 2.2)
|
||||
|
||||
def test_std_std_1(self):
|
||||
self.component.product_tmpl_id.categ_id.property_cost_method = 'standard'
|
||||
self.product1.product_tmpl_id.categ_id.property_cost_method = 'standard'
|
||||
|
||||
@@ -25,7 +25,7 @@ flectra.define('point_of_sale.AbstractReceiptScreen', function (require) {
|
||||
} else {
|
||||
const { confirmed } = await this.showPopup('ConfirmPopup', {
|
||||
title: printResult.message.title,
|
||||
body: 'Do you want to print using the web printer?',
|
||||
body: this.env._t('Do you want to print using the web printer?'),
|
||||
});
|
||||
if (confirmed) {
|
||||
// We want to call the _printWeb when the popup is fully gone
|
||||
|
||||
@@ -105,6 +105,36 @@ Please call me as soon as possible this afternoon!
|
||||
Sylvie
|
||||
"""
|
||||
|
||||
MAIL_TEMPLATE_HTML = """Return-Path: {return_path}
|
||||
To: {to}
|
||||
cc: {cc}
|
||||
Received: by mail1.openerp.com (Postfix, from userid 10002)
|
||||
id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST)
|
||||
From: {email_from}
|
||||
Subject: {subject}
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
Date: Fri, 10 Aug 2012 14:16:26 +0000
|
||||
Message-ID: {msg_id}
|
||||
{extra}
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>=20
|
||||
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8" />
|
||||
</head>=20
|
||||
<body style=3D"margin: 0; padding: 0; background: #ffffff;-webkit-text-size-adjust: 100%;">=20
|
||||
|
||||
<p>Please call me as soon as possible this afternoon!</p>
|
||||
|
||||
<p>--<br/>
|
||||
Sylvie
|
||||
<p>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
MAIL_MULTIPART_MIXED = """Return-Path: <ignasse.carambar@gmail.com>
|
||||
X-Original-To: raoul@grosbedon.fr
|
||||
Delivered-To: raoul@grosbedon.fr
|
||||
|
||||
@@ -42,6 +42,12 @@ class TestEmailParsing(TestMailCommon):
|
||||
res = self.env['mail.thread'].message_parse(self.from_string(plaintext))
|
||||
self.assertIn('Please call me as soon as possible this afternoon!', res['body'])
|
||||
|
||||
# test pure html
|
||||
html = self.format(test_mail_data.MAIL_TEMPLATE_HTML, email_from='"Sylvie Lelitre" <test.sylvie.lelitre@agrolait.com>')
|
||||
res = self.env['mail.thread'].message_parse(self.from_string(html))
|
||||
self.assertIn('<p>Please call me as soon as possible this afternoon!</p>', res['body'])
|
||||
self.assertNotIn('<!DOCTYPE', res['body'])
|
||||
|
||||
# test multipart / text and html -> html has priority
|
||||
multipart = self.format(MAIL_TEMPLATE, email_from='"Sylvie Lelitre" <test.sylvie.lelitre@agrolait.com>')
|
||||
res = self.env['mail.thread'].message_parse(self.from_string(multipart))
|
||||
|
||||
@@ -85,10 +85,12 @@ class WebsiteRewrite(models.Model):
|
||||
if rewrite.redirect_type in ['301', '302', '308']:
|
||||
if not rewrite.url_to:
|
||||
raise ValidationError(_('"URL to" can not be empty.'))
|
||||
elif not rewrite.url_to.startswith('/'):
|
||||
raise ValidationError(_('"URL to" must start with a leading slash.'))
|
||||
if not rewrite.url_from:
|
||||
raise ValidationError(_('"URL from" can not be empty.'))
|
||||
|
||||
if rewrite.redirect_type == '308':
|
||||
if not rewrite.url_to.startswith('/'):
|
||||
raise ValidationError(_('"URL to" must start with a leading slash.'))
|
||||
for param in re.findall('/<.*?>', rewrite.url_from):
|
||||
if param not in rewrite.url_to:
|
||||
raise ValidationError(_('"URL to" must contain parameter %s used in "URL from".') % param)
|
||||
|
||||
@@ -72,6 +72,11 @@ if (!$('.website_blog').length) {
|
||||
|
||||
const NEW_TAG_PREFIX = 'new-blog-tag-';
|
||||
|
||||
// TODO Remove in master.
|
||||
for (const el of document.querySelectorAll(".o_wblog_social_links")) {
|
||||
el.classList.add("o_not_editable");
|
||||
}
|
||||
|
||||
WysiwygMultizone.include({
|
||||
custom_events: Object.assign({}, WysiwygMultizone.prototype.custom_events, {
|
||||
'set_blog_post_updated_tags': '_onSetBlogPostUpdatedTags',
|
||||
|
||||
@@ -126,7 +126,7 @@ Options:
|
||||
<xpath expr="//div[@id='o_wblog_sidebar']" position="inside">
|
||||
<div class="o_wblog_sidebar_block pb-5">
|
||||
<h6 class="text-uppercase pb-2 mb-4 border-bottom font-weight-bold">Follow Us</h6>
|
||||
<div class="o_wblog_social_links d-flex flex-wrap mx-n1">
|
||||
<div class="o_wblog_social_links d-flex flex-wrap mx-n1 o_not_editable">
|
||||
<t t-set="classes" t-translation="off">bg-100 border mx-1 mb-2 rounded-circle d-flex align-items-center justify-content-center text-decoration-none</t>
|
||||
<a t-if="website.social_facebook" t-att-href="website.social_facebook" aria-label="Facebook" title="Facebook" t-att-class="classes"><i class="fa fa-facebook-square text-facebook"/></a>
|
||||
<a t-if="website.social_twitter" t-att-href="website.social_twitter" t-att-class="classes"><i class="fa fa-twitter text-twitter" aria-label="Twitter" title="Twitter"/></a>
|
||||
@@ -218,7 +218,7 @@ Display a sidebar beside the post content.
|
||||
<div class="o_wblog_sidebar_block pb-5">
|
||||
<h6 class="text-uppercase pb-3 mb-4 border-bottom font-weight-bold">Share this post</h6>
|
||||
|
||||
<div class="o_wblog_social_links d-flex flex-wrap mx-n1">
|
||||
<div class="o_wblog_social_links d-flex flex-wrap mx-n1 o_not_editable">
|
||||
<t t-set="classes" t-translation="off">bg-100 border mx-1 mb-2 rounded-circle d-flex align-items-center justify-content-center text-decoration-none</t>
|
||||
<a href="#" aria-label="Facebook" title="Share on Facebook" t-attf-class="o_facebook #{classes}"><i class="fa fa-facebook-square text-facebook"/></a>
|
||||
<a href="#" aria-label="Twitter" title="Share on Twitter" t-attf-class="o_twitter #{classes}"><i class="fa fa-twitter text-twitter" aria-label="Twitter" title="Twitter"/></a>
|
||||
|
||||
@@ -6,4 +6,4 @@ furniture_certification_answer_1_p1_q2_3,furniture_certification_answer_1,furnit
|
||||
furniture_certification_answer_1_p1_q3,furniture_certification_answer_1,furniture_certification_page_1_question_3,False,text_box,,,,"I really liked the videos, you are awesome!",,
|
||||
furniture_certification_answer_2_p1_q1,furniture_certification_answer_2,furniture_certification_page_1_question_1,False,suggestion,,,,,furniture_certification_page_1_question_1_choice_3,
|
||||
furniture_certification_answer_2_p1_q2,furniture_certification_answer_2,furniture_certification_page_1_question_2,False,suggestion,,,,,furniture_certification_page_1_question_2_choice_4,
|
||||
furniture_certification_answer_2_p1_q3,furniture_certification_answer_2,furniture_certification_page_1_question_3,true,,,,,,,
|
||||
furniture_certification_answer_2_p1_q3,furniture_certification_answer_2,furniture_certification_page_1_question_3,true,,,,,,,
|
||||
|
Reference in New Issue
Block a user