[IMP] base: base layout designer improvements
This commit implements improvements in the layout designer, such as addition of a new custom background, adds custom report footer and company details. task-2355704 closes odoo/odoo#66860 Related: odoo/upgrade#2275 Signed-off-by: Arnaud Joset <arj-odoo@users.noreply.github.com>
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
}
|
||||
|
||||
/* ISR is intended for pre-printed paper, we don't want stylistic background */
|
||||
.o_report_layout_background {
|
||||
.o_report_layout_striped {
|
||||
background: none;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ body.l10n_ch_qr {
|
||||
padding:0;
|
||||
|
||||
/* Disable custom bakground */
|
||||
.o_report_layout_background {
|
||||
.o_report_layout_striped {
|
||||
background: none;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="external_layout_clean" inherit_id="web.external_layout_clean" >
|
||||
<template id="external_layout_bold" inherit_id="web.external_layout_bold" >
|
||||
<!-- support for custom header -->
|
||||
<div t-attf-class="header o_company_#{company.id}_layout" position="attributes">
|
||||
<attribute name="t-if">not custom_header</attribute>
|
||||
@@ -72,7 +72,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="external_layout_background" inherit_id="web.external_layout_background" >
|
||||
<template id="external_layout_striped" inherit_id="web.external_layout_striped" >
|
||||
<!-- support for custom header -->
|
||||
<div t-attf-class="o_company_#{company.id}_layout header" position="attributes">
|
||||
<attribute name="t-if">not custom_header</attribute>
|
||||
|
||||
@@ -76,6 +76,6 @@ class TestPingenSend(HttpCase):
|
||||
|
||||
def test_pingen_send_invoice(self):
|
||||
self.render_and_send('external_layout_standard')
|
||||
self.render_and_send('external_layout_background')
|
||||
self.render_and_send('external_layout_striped')
|
||||
self.render_and_send('external_layout_boxed')
|
||||
self.render_and_send('external_layout_clean')
|
||||
self.render_and_send('external_layout_bold')
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="report_layout_background" model="report.layout">
|
||||
<field name="name">Background</field>
|
||||
<record id="report_layout_striped" model="report.layout">
|
||||
<field name="name">Striped</field>
|
||||
<field name="sequence">5</field>
|
||||
<field name="view_id" ref="web.external_layout_background"/>
|
||||
<field name="view_id" ref="web.external_layout_striped"/>
|
||||
<field name="image">/web/static/img/preview_background.png</field>
|
||||
<field name="pdf">/web/static/pdf/preview_background.pdf</field>
|
||||
</record>
|
||||
@@ -25,10 +25,10 @@
|
||||
<field name="image">/web/static/img/preview_boxed.png</field>
|
||||
<field name="pdf">/web/static/pdf/preview_boxed.pdf</field>
|
||||
</record>
|
||||
<record id="report_layout_clean" model="report.layout">
|
||||
<field name="name">Clean</field>
|
||||
<record id="report_layout_bold" model="report.layout">
|
||||
<field name="name">Bold</field>
|
||||
<field name="sequence">4</field>
|
||||
<field name="view_id" ref="web.external_layout_clean"/>
|
||||
<field name="view_id" ref="web.external_layout_bold"/>
|
||||
<field name="image">/web/static/img/preview_clean.png</field>
|
||||
<field name="pdf">/web/static/pdf/preview_clean.pdf</field>
|
||||
</record>
|
||||
|
||||
@@ -24,13 +24,30 @@ class BaseDocumentLayout(models.TransientModel):
|
||||
_name = 'base.document.layout'
|
||||
_description = 'Company Document Layout'
|
||||
|
||||
@api.model
|
||||
def _default_report_footer(self):
|
||||
company = self.env.company
|
||||
footer_fields = filter(None, [company.phone, company.email, company.website, company.vat])
|
||||
return ' '.join(footer_fields)
|
||||
|
||||
@api.model
|
||||
def _default_company_details(self):
|
||||
company = self.env.company
|
||||
return (
|
||||
f'{company.name}\n'
|
||||
f'{company.street}\n'
|
||||
f'{company.city} {company.state_id.name} {company.zip}\n'
|
||||
f'{company.country_id.name}\n'
|
||||
)
|
||||
|
||||
company_id = fields.Many2one(
|
||||
'res.company', default=lambda self: self.env.company, required=True)
|
||||
|
||||
logo = fields.Binary(related='company_id.logo', readonly=False)
|
||||
preview_logo = fields.Binary(related='logo', string="Preview logo")
|
||||
report_header = fields.Html(related='company_id.report_header', readonly=False)
|
||||
report_footer = fields.Html(related='company_id.report_footer', readonly=False)
|
||||
report_footer = fields.Html(related='company_id.report_footer', readonly=False, default=_default_report_footer)
|
||||
company_details = fields.Html(related='company_id.company_details', readonly=False, default=_default_company_details)
|
||||
|
||||
# The paper format changes won't be reflected in the preview.
|
||||
paperformat_id = fields.Many2one(related='company_id.paperformat_id', readonly=False)
|
||||
@@ -45,6 +62,9 @@ class BaseDocumentLayout(models.TransientModel):
|
||||
logo_primary_color = fields.Char(compute="_compute_logo_colors")
|
||||
logo_secondary_color = fields.Char(compute="_compute_logo_colors")
|
||||
|
||||
layout_background = fields.Selection(related='company_id.layout_background', readonly=False)
|
||||
layout_background_image = fields.Binary(related='company_id.layout_background_image', readonly=False)
|
||||
|
||||
report_layout_id = fields.Many2one('report.layout')
|
||||
|
||||
# All the sanitization get disabled as we want true raw html to be passed to an iframe.
|
||||
@@ -82,17 +102,22 @@ class BaseDocumentLayout(models.TransientModel):
|
||||
wizard_for_image = wizard
|
||||
wizard.logo_primary_color, wizard.logo_secondary_color = wizard.extract_image_primary_secondary_colors(wizard_for_image.logo)
|
||||
|
||||
@api.depends('report_layout_id', 'logo', 'font', 'primary_color', 'secondary_color', 'report_header', 'report_footer')
|
||||
@api.depends('report_layout_id', 'logo', 'font', 'primary_color', 'secondary_color', 'report_header', 'report_footer', 'layout_background', 'layout_background_image', 'company_details')
|
||||
def _compute_preview(self):
|
||||
""" compute a qweb based preview to display on the wizard """
|
||||
|
||||
styles = self._get_asset_style()
|
||||
|
||||
for wizard in self:
|
||||
if wizard.report_layout_id:
|
||||
preview_css = self._get_css_for_preview(styles, wizard.id)
|
||||
ir_ui_view = wizard.env['ir.ui.view']
|
||||
wizard.preview = ir_ui_view._render_template('web.report_invoice_wizard_preview', {'company': wizard, 'preview_css': preview_css})
|
||||
# guarantees that bin_size is always set to False,
|
||||
# so the logo always contains the bin data instead of the binary size
|
||||
if wizard.env.context.get('bin_size'):
|
||||
wizard_with_logo = wizard.with_context(bin_size=False)
|
||||
else:
|
||||
wizard_with_logo = wizard
|
||||
preview_css = self._get_css_for_preview(styles, wizard_with_logo.id)
|
||||
ir_ui_view = wizard_with_logo.env['ir.ui.view']
|
||||
wizard.preview = ir_ui_view._render_template('web.report_invoice_wizard_preview', {'company': wizard_with_logo, 'preview_css': preview_css})
|
||||
else:
|
||||
wizard.preview = False
|
||||
|
||||
@@ -101,7 +126,9 @@ class BaseDocumentLayout(models.TransientModel):
|
||||
for wizard in self:
|
||||
wizard.logo = wizard.company_id.logo
|
||||
wizard.report_header = wizard.company_id.report_header
|
||||
wizard.report_footer = wizard.company_id.report_footer
|
||||
# company_details and report_footer can store empty strings (set by the user) or false (meaning the user didn't set a value). Since both are falsy values, we use isinstance of string to differentiate them
|
||||
wizard.report_footer = wizard.company_id.report_footer if isinstance(wizard.company_id.report_footer, str) else wizard.report_footer
|
||||
wizard.company_details = wizard.company_id.company_details if isinstance(wizard.company_id.company_details, str) else wizard.company_details
|
||||
wizard.paperformat_id = wizard.company_id.paperformat_id
|
||||
wizard.external_report_layout_id = wizard.company_id.external_report_layout_id
|
||||
wizard.font = wizard.company_id.font
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
.o_background_footer, .o_background_header, .o_report_layout_background {
|
||||
.o_background_footer, .o_background_header, .o_report_layout_striped {
|
||||
color: gray('700');
|
||||
}
|
||||
.o_background_header {
|
||||
@@ -31,13 +31,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.o_report_layout_background {
|
||||
background-image: url(/base/static/img/bg_background_template.jpg);
|
||||
.o_layout_background {
|
||||
background-size: cover;
|
||||
background-position: bottom center;
|
||||
background-repeat: no-repeat;
|
||||
min-height: 620px;
|
||||
|
||||
min-height: 620px
|
||||
}
|
||||
.o_report_layout_striped {
|
||||
strong {
|
||||
color: $o-default-report-secondary-color;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.o_clean_footer, .o_clean_header, .o_report_layout_clean {
|
||||
.o_clean_footer, .o_clean_header, .o_report_layout_bold {
|
||||
color: #000;
|
||||
}
|
||||
.o_clean_header img {
|
||||
@@ -21,7 +21,7 @@
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.o_report_layout_clean {
|
||||
.o_report_layout_bold {
|
||||
h1, h2, h3 {
|
||||
color: $o-default-report-primary-color;
|
||||
font-weight: bolder;
|
||||
|
||||
@@ -1800,7 +1800,7 @@
|
||||
|
||||
<t t-name="web.IframeWrapper">
|
||||
<div class="o_preview_iframe_wrapper">
|
||||
<i class="o_iframe_wrapper_spinner fa fa-circle-o-notch fa-spin fa-4x" style="color: #875a7b; z-index: 2"/>
|
||||
<i class="o_iframe_wrapper_spinner fa fa-circle-o-notch fa-spin fa-4x" style="color: black; z-index: 2"/>
|
||||
<!--suppress CheckTagEmptyBody -->
|
||||
<iframe src="about:blank" class="o_preview_iframe" style="display:none"></iframe>
|
||||
</div>
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
<field name="external_report_layout_id" invisible="1" />
|
||||
<field name="logo_primary_color" invisible="1" />
|
||||
<field name="logo_secondary_color" invisible="1" />
|
||||
<field name="report_layout_id" widget="radio" string="Layout"/>
|
||||
<field name="logo" widget="image"/>
|
||||
<field name="report_layout_id" widget="radio" string="Layout" required="1"/>
|
||||
<field name="font" widget="selection" required="1"/>
|
||||
<field name="logo" widget="image" options="{'size': [0, 50]}"/>
|
||||
<label for="primary_color" string="Colors" />
|
||||
<div class="o_document_layout_colors">
|
||||
<field name="primary_color" widget="color"/>
|
||||
@@ -23,13 +24,16 @@
|
||||
<label for="custom_colors" class="fa fa-refresh" string="" />
|
||||
</button>
|
||||
</div>
|
||||
<field name="font" widget="font"/>
|
||||
<field name="report_header" placeholder="e.g. Global Business Solutions" />
|
||||
<field name="report_footer" string="Footer" placeholder="e.g. Opening hours, bank accounts (one per line)" />
|
||||
<field name="paperformat_id" required="1" />
|
||||
<field name="layout_background" widget="selection" required="1"/>
|
||||
<field name="layout_background_image" options="{'accepted_file_extensions': 'image/*'}" attrs="{'invisible': [('layout_background', '!=', 'Custom')], 'required': [('layout_background', '=', 'Custom')]}">Upload your file</field>
|
||||
<field name="report_header" placeholder="e.g. Global Business Solutions" options="{'resizable': false}"/>
|
||||
<field name="company_details" string="Company Details" options="{'resizable': false}"/>
|
||||
<field name="report_footer" string="Footer" options="{'resizable': false}"/>
|
||||
<field name="paperformat_id" widget="selection" required="1" domain="[('report_ids', '=', False)]"/>
|
||||
</group>
|
||||
<div>
|
||||
<field name="preview" widget="iframe_wrapper" />
|
||||
<button name="web.action_report_layout_preview" string="Download PDF Preview" type="action" class="oe_link" icon="fa-arrow-right"/>
|
||||
</div>
|
||||
</group>
|
||||
<footer>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<t t-call-assets="web.assets_common" t-css="false"/>
|
||||
<t t-call-assets="web.report_assets_common" t-css="false"/>
|
||||
</head>
|
||||
<body t-att-class="'container' if not full_width else 'container-fluid'">
|
||||
<body t-att-class="'container' if not full_width else 'container-fluid'" style="overflow:hidden">
|
||||
<div id="wrapwrap">
|
||||
<main>
|
||||
<t t-out="0"/>
|
||||
@@ -60,16 +60,20 @@
|
||||
|
||||
/** The footers are not at the bottom of the page, so we push them down. **/
|
||||
.o_background_footer {
|
||||
margin-top: 270px !important;
|
||||
margin-top: 295px !important;
|
||||
font-size: 0.8rem
|
||||
}
|
||||
.o_standard_footer {
|
||||
margin-top: 190px !important;
|
||||
margin-top: 200px !important;
|
||||
font-size: 0.8rem
|
||||
}
|
||||
.o_boxed_footer {
|
||||
margin-top: 270px !important;
|
||||
font-size: 0.8rem
|
||||
}
|
||||
.o_clean_footer {
|
||||
margin-top: 160px !important;
|
||||
margin-top: 175px !important;
|
||||
font-size: 0.8rem
|
||||
}
|
||||
|
||||
/** Avoid image overflowing and creating a scrollbar **/
|
||||
@@ -89,7 +93,7 @@
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body t-att-class="'container' if not full_width else 'container-fluid'">
|
||||
<body t-att-class="'container' if not full_width else 'container-fluid'" style="overflow:hidden">
|
||||
<div id="wrapwrap">
|
||||
<t t-out="0"/>
|
||||
</div>
|
||||
@@ -117,7 +121,7 @@
|
||||
<t t-call="web.external_layout">
|
||||
<div class="pt-5">
|
||||
<div class="address row">
|
||||
<div name="address" class="col-md-5 ml-auto">
|
||||
<div name="address" class="col-5" style="margin-left: auto">
|
||||
<address>
|
||||
<address class="mb-0" itemscope="itemscope"
|
||||
itemtype="http://schema.org/Organization">
|
||||
@@ -200,8 +204,8 @@
|
||||
</table>
|
||||
<div class="clearfix">
|
||||
<div id="total" class="row">
|
||||
<div class="col-sm-7 col-md-6 ml-auto">
|
||||
<table class="table table-sm" style="page-break-inside: avoid;">
|
||||
<div class="col-7 ml-auto">
|
||||
<table class="table table-sm" style="page-break-inside: avoid; position:relative;">
|
||||
<tbody><tr class="border-black o_subtotal" style="">
|
||||
<td><strong>Subtotal</strong></td>
|
||||
<td class="text-right">
|
||||
@@ -278,7 +282,7 @@
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="container" t-att-onload="subst and 'subst()'">
|
||||
<body class="container" t-att-onload="subst and 'subst()'" style="overflow:hidden">
|
||||
<t t-out="body"/>
|
||||
</body>
|
||||
</html>
|
||||
@@ -287,7 +291,7 @@
|
||||
<!-- External layouts styles -->
|
||||
|
||||
<template id="address_layout">
|
||||
<t t-set="colclass" t-value="('col-md-5' if report_type == 'html' else 'col-5') + ' ml-auto'"/>
|
||||
<t t-set="colclass" t-value="('col-sm-5' if report_type == 'html' else 'col-5') + ' ml-auto'"/>
|
||||
<t t-if="address">
|
||||
<div class="address row">
|
||||
<t t-if="information_block">
|
||||
@@ -303,7 +307,7 @@
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="external_layout_background">
|
||||
<template id="external_layout_striped">
|
||||
<div t-attf-class="o_company_#{company.id}_layout header" t-att-style="report_header_style">
|
||||
<div class="o_background_header">
|
||||
<div class="float-right">
|
||||
@@ -311,17 +315,13 @@
|
||||
</div>
|
||||
<img t-if="company.logo" t-att-src="image_data_uri(company.logo)" class="float-left" alt="Logo"/>
|
||||
<div class="float-left company_address">
|
||||
<div>
|
||||
<strong t-field="company.partner_id.name"/>
|
||||
</div>
|
||||
<span t-field="company.partner_id"
|
||||
t-options='{"widget": "contact", "fields": ["address"], "no_marker": true}'/>
|
||||
<span t-if="company.company_details" t-field="company.company_details"></span>
|
||||
</div>
|
||||
<div class="clearfix mb8"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-attf-class="o_company_#{company.id}_layout article o_report_layout_background" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')">
|
||||
<div t-attf-class="o_company_#{company.id}_layout article o_report_layout_striped {{ 'o_layout_background' if company.layout_background in ['Geometric', 'Custom'] else '' }}" t-attf-style="background-image: url({{ 'data:image/png;base64,%s' % company.layout_background_image.decode('utf-8') if company.layout_background_image and company.layout_background == 'Custom' else '/base/static/img/bg_background_template.jpg' }});" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')">
|
||||
<t t-call="web.address_layout"/>
|
||||
<t t-out="0"/>
|
||||
</div>
|
||||
@@ -329,17 +329,8 @@
|
||||
<div t-attf-class="o_company_#{company.id}_layout footer o_background_footer">
|
||||
<div class="text-center">
|
||||
<ul class="list-inline">
|
||||
<li t-if="company.phone" class="list-inline-item"><i class="fa fa-phone" role="img" aria-label="Phone" title="Phone"/> <span class="o_force_ltr" t-field="company.phone"/></li>
|
||||
<li t-if="company.email" class="list-inline-item"><i class="fa fa-at" role="img" aria-label="Email" title="Email"/> <span t-field="company.email"/></li>
|
||||
<li t-if="company.website" class="list-inline-item"><i class="fa fa-globe" role="img" aria-label="Website" title="Website"/> <span t-field="company.website"/></li>
|
||||
<li t-if="forced_vat or company.vat" class="list-inline-item">
|
||||
<i class="fa fa-building-o" role="img" aria-label="Fiscal number"/>
|
||||
<t t-esc="company.country_id.vat_label or 'Tax ID'"/>:
|
||||
<span t-if="forced_vat" t-esc="forced_vat"/>
|
||||
<span t-else="" t-field="company.vat"/>
|
||||
</li>
|
||||
<div t-field="company.report_footer"/>
|
||||
</ul>
|
||||
<div t-field="company.report_footer"/>
|
||||
<div t-if="report_type == 'pdf'" class="text-muted">
|
||||
Page:
|
||||
<span class="page"/>
|
||||
@@ -360,15 +351,14 @@
|
||||
<div class="col-6 text-right mb4">
|
||||
<h4 class="mt0" t-field="company.report_header"/>
|
||||
<div name="company_address" class="float-right mb4">
|
||||
<span class="company_address" t-field="company.partner_id"
|
||||
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'/>
|
||||
<span t-if="company.company_details" t-field="company.company_details"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-attf-class="article o_report_layout_boxed o_company_#{company.id}_layout" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')">
|
||||
<div t-attf-class="article o_report_layout_boxed o_company_#{company.id}_layout {{ 'o_layout_background' if company.layout_background in ['Geometric', 'Custom'] else '' }}" t-attf-style="background-image: url({{ 'data:image/png;base64,%s' % company.layout_background_image.decode('utf-8') if company.layout_background_image and company.layout_background == 'Custom' else '/base/static/img/bg_background_template.jpg' }});" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')">
|
||||
<div class="pt-5">
|
||||
<!-- This div ensures that the address is not cropped by the header. -->
|
||||
<t t-call="web.address_layout"/>
|
||||
@@ -378,16 +368,6 @@
|
||||
|
||||
<div t-attf-class="footer o_boxed_footer o_company_#{company.id}_layout">
|
||||
<div class="text-center">
|
||||
<ul class="list-inline">
|
||||
<li t-if="company.phone" class="list-inline-item"><span class="o_force_ltr" t-field="company.phone"/></li>
|
||||
<li t-if="company.email" class="list-inline-item"><span t-field="company.email"/></li>
|
||||
<li t-if="company.website" class="list-inline-item"><span t-field="company.website"/></li>
|
||||
<li t-if="forced_vat or company.vat" class="list-inline-item">
|
||||
<t t-esc="company.country_id.vat_label or 'Tax ID'"/>:
|
||||
<span t-if="forced_vat" t-esc="forced_vat"/>
|
||||
<span t-else="" t-field="company.vat"/>
|
||||
</li>
|
||||
</ul>
|
||||
<div t-field="company.report_footer"/>
|
||||
<div t-if="report_type == 'pdf'">
|
||||
Page: <span class="page"/> / <span class="topage"/>
|
||||
@@ -396,7 +376,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="external_layout_clean">
|
||||
<template id="external_layout_bold">
|
||||
<div t-attf-class="header o_company_#{company.id}_layout" t-att-style="report_header_style">
|
||||
<div class="o_clean_header">
|
||||
<div class="row">
|
||||
@@ -420,22 +400,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-attf-class="article o_report_layout_clean o_company_#{company.id}_layout" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')">
|
||||
<div t-attf-class="article o_report_layout_bold o_company_#{company.id}_layout {{ 'o_layout_background' if company.layout_background in ['Geometric', 'Custom'] else '' }}" t-attf-style="background-image: url({{ 'data:image/png;base64,%s' % company.layout_background_image.decode('utf-8') if company.layout_background_image and company.layout_background == 'Custom' else '/base/static/img/bg_background_template.jpg' }});" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')">
|
||||
<t t-call="web.address_layout"/>
|
||||
<t t-out="0"/>
|
||||
</div>
|
||||
|
||||
<div t-attf-class="footer o_clean_footer o_company_#{company.id}_layout">
|
||||
<div class="row mt8">
|
||||
<div class="col-3">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<span t-field="company.report_footer"/>
|
||||
</div>
|
||||
<div class="col-4 text-right">
|
||||
<span class="company_address" t-field="company.partner_id"
|
||||
t-options='{"widget": "contact", "fields": ["address"], "no_marker": true}'/>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<h4 class="mt0 mb0 text-uppercase" t-field="company.report_header"/>
|
||||
<span t-if="company.company_details" t-field="company.company_details"/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<h5 class="mt0 mb0" t-field="company.report_header"/>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<ul t-if="report_type == 'pdf'" class="list-inline pagenumber float-right text-center">
|
||||
@@ -461,14 +440,12 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6" name="company_address">
|
||||
<div t-field="company.partner_id"
|
||||
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'
|
||||
/>
|
||||
<span t-if="company.company_details" t-field="company.company_details"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-attf-class="article o_report_layout_standard o_company_#{company.id}_layout" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')">
|
||||
<div t-attf-class="article o_report_layout_standard o_company_#{company.id}_layout {{ 'o_layout_background' if company.layout_background in ['Geometric', 'Custom'] else '' }}" t-attf-style="background-image: url({{ 'data:image/png;base64,%s' % company.layout_background_image.decode('utf-8') if company.layout_background_image and company.layout_background == 'Custom' else '/base/static/img/bg_background_template.jpg' if company.layout_background == 'Geometric' else ''}});" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')">
|
||||
<div class="pt-5">
|
||||
<!-- This div ensures that the address is not cropped by the header. -->
|
||||
<t t-call="web.address_layout"/>
|
||||
@@ -479,22 +456,9 @@
|
||||
<div t-attf-class="footer o_standard_footer o_company_#{company.id}_layout">
|
||||
<div class="text-center" style="border-top: 1px solid black;">
|
||||
<ul class="list-inline mb4">
|
||||
<!-- using the list-inline-item class from bootstrap causes weird behaviours in pdf report
|
||||
adding d-inline class fixes the problem-->
|
||||
<li t-if="company.phone" class="list-inline-item d-inline"><span class="o_force_ltr" t-field="company.phone"/></li>
|
||||
<li t-if="company.email" class="list-inline-item d-inline"><span t-field="company.email"/></li>
|
||||
<li t-if="company.website" class="list-inline-item d-inline"><span t-field="company.website"/></li>
|
||||
<li t-if="forced_vat or company.vat" class="list-inline-item d-inline">
|
||||
<t t-esc="company.country_id.vat_label or 'Tax ID'"/>:
|
||||
<span t-if="forced_vat" t-esc="forced_vat"/>
|
||||
<span t-else="" t-field="company.vat"/>
|
||||
</li>
|
||||
<div t-field="company.report_footer"/>
|
||||
</ul>
|
||||
|
||||
<div name="financial_infos">
|
||||
<span t-field="company.report_footer"/>
|
||||
</div>
|
||||
|
||||
<div t-if="report_type == 'pdf'" class="text-muted">
|
||||
Page: <span class="page"/> / <span class="topage"/>
|
||||
</div>
|
||||
@@ -597,6 +561,14 @@
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="preview_layout_report">
|
||||
<t t-set="company" t-value="env.company"/>
|
||||
<t t-call="web.html_container">
|
||||
<t t-set="o" t-value="res_company"/>
|
||||
<t t-call="web.report_invoice_wizard_preview"/>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="styles_company_report">
|
||||
<t t-foreach="company_ids" t-as="company" t-translation="off">
|
||||
<t t-set="font" t-value="company.font or 'Lato'" />
|
||||
@@ -604,22 +576,9 @@
|
||||
<t t-set="secondary" t-value="company.secondary_color or 'black'" />
|
||||
<t t-set="layout" t-value="company.external_report_layout_id.key or 'web.external_layout_standard'" />
|
||||
.o_company_<t t-esc='company.id'/>_layout {
|
||||
font-family: '<t t-esc="font" />';
|
||||
|
||||
<t t-if="layout == 'web.external_layout_background'">
|
||||
.o_background_header {
|
||||
h3 {
|
||||
color: <t t-esc='primary'/>;
|
||||
}
|
||||
}
|
||||
&.o_background_footer {
|
||||
ul {
|
||||
li {
|
||||
color: <t t-esc='secondary'/>;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.o_report_layout_background {
|
||||
font-family: <t t-esc="font" />;
|
||||
<t t-if="layout == 'web.external_layout_striped'">
|
||||
&.o_report_layout_striped {
|
||||
strong {
|
||||
color: <t t-esc='secondary'/>;
|
||||
}
|
||||
@@ -679,7 +638,7 @@
|
||||
}
|
||||
}
|
||||
</t>
|
||||
<t t-elif="layout == 'web.external_layout_clean'" >
|
||||
<t t-elif="layout == 'web.external_layout_bold'" >
|
||||
&.o_clean_footer {
|
||||
border-top: 3px solid <t t-esc='secondary'/>;
|
||||
h4 {
|
||||
@@ -690,7 +649,7 @@
|
||||
background-color: <t t-esc='secondary'/>;
|
||||
}
|
||||
}
|
||||
&.o_report_layout_clean {
|
||||
&.o_report_layout_bold {
|
||||
h1, h2, h3 {
|
||||
color: <t t-esc='primary'/>;
|
||||
}
|
||||
@@ -757,4 +716,13 @@
|
||||
<field name="binding_model_id" ref="model_res_company"/>
|
||||
<field name="binding_type">report</field>
|
||||
</record>
|
||||
<record id="action_report_layout_preview" model="ir.actions.report">
|
||||
<field name="name">Report Layout Preview</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">web.preview_layout_report</field>
|
||||
<field name="report_file">web.preview_layout_report</field>
|
||||
<field name="binding_model_id" ref="model_res_company"/>
|
||||
<field name="binding_type">report</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
<field name="page_width">0</field>
|
||||
<field name="orientation">Portrait</field>
|
||||
<field name="margin_top">15</field>
|
||||
<field name="margin_bottom">10</field>
|
||||
<field name="margin_bottom">30</field>
|
||||
<field name="margin_left">10</field>
|
||||
<field name="margin_right">10</field>
|
||||
<field name="header_line" eval="False" />
|
||||
<field name="header_spacing">0</field>
|
||||
<field name="header_spacing">15</field>
|
||||
<field name="dpi">90</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
@@ -63,6 +63,7 @@ class Company(models.Model):
|
||||
partner_id = fields.Many2one('res.partner', string='Partner', required=True)
|
||||
report_header = fields.Html(string='Company Tagline', help="Appears by default on the top right corner of your printed documents (report header).")
|
||||
report_footer = fields.Html(string='Report Footer', translate=True, help="Footer text displayed at the bottom of all reports.")
|
||||
company_details = fields.Html(string='Company Details', help="Header text displayed at the top of all reports.")
|
||||
logo = fields.Binary(related='partner_id.image_1920', default=_get_logo, string="Company Logo", readonly=False)
|
||||
# logo_web: do not store in attachments, since the image is retrieved in SQL for
|
||||
# performance reasons (see addons/web/controllers/main.py, Binary.company_logo)
|
||||
@@ -93,6 +94,8 @@ class Company(models.Model):
|
||||
font = fields.Selection([("Lato", "Lato"), ("Roboto", "Roboto"), ("Open_Sans", "Open Sans"), ("Montserrat", "Montserrat"), ("Oswald", "Oswald"), ("Raleway", "Raleway")], default="Lato")
|
||||
primary_color = fields.Char()
|
||||
secondary_color = fields.Char()
|
||||
layout_background = fields.Selection([('Blank', 'Blank'), ('Geometric', 'Geometric'), ('Custom', 'Custom')], default="Blank", required=True)
|
||||
layout_background_image = fields.Binary("Background Image")
|
||||
_sql_constraints = [
|
||||
('name_uniq', 'unique (name)', 'The company name must be unique !')
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user