[IMP] base, *: use a many2one for the company report layout
Before this rev. one could set the report layout on the company using a hardcoded list (background, clean, standard, etc.). Other modules (typically accounting modules) could add options in this list. The used template was built on the layout key. Now, the layout is a many2one field to a newly created model `report.layout`, which is linked to a view with the layout architecture. This gives more control to customize reports and create a new layout (without creating a python module that extend the layout selection).
@@ -39,8 +39,8 @@ class ResConfigSettings(models.TransientModel):
|
||||
group_multi_currency = fields.Boolean(string='Multi-Currencies',
|
||||
implied_group='base.group_multi_currency',
|
||||
help="Allows to work in a multi currency environment")
|
||||
paperformat_id = fields.Many2one(related="company_id.paperformat_id", string='Paper Format')
|
||||
external_report_layout = fields.Selection(related="company_id.external_report_layout")
|
||||
paperformat_id = fields.Many2one(related="company_id.paperformat_id", string='Paper format')
|
||||
external_report_layout_id = fields.Many2one(related="company_id.external_report_layout_id")
|
||||
show_effect = fields.Boolean(string="Show Effect", config_parameter='base_setup.show_effect')
|
||||
|
||||
@api.model
|
||||
@@ -87,9 +87,9 @@ class ResConfigSettings(models.TransientModel):
|
||||
|
||||
@api.multi
|
||||
def edit_external_header(self):
|
||||
if not self.external_report_layout:
|
||||
if not self.external_report_layout_id:
|
||||
return False
|
||||
return self._prepare_report_view_action('web.external_layout_' + self.external_report_layout)
|
||||
return self._prepare_report_view_action(self.external_report_layout_id.key)
|
||||
|
||||
@api.multi
|
||||
def change_report_template(self):
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
</div>
|
||||
<div class="content-group">
|
||||
<div class="mt16" groups="base.group_no_one">
|
||||
<label for="external_report_layout" string="Template" class="col-3 col-lg-3 o_light_label"/>
|
||||
<field name="external_report_layout" class="oe_inline"/>
|
||||
<label for="external_report_layout_id" string="Template" class="col-3 col-lg-3 o_light_label"/>
|
||||
<field name="external_report_layout_id" class="oe_inline"/>
|
||||
</div>
|
||||
<div class="mt16">
|
||||
<button name="change_report_template" string="Change Document Template" type="object" class="oe_link" icon="fa-arrow-right"/>
|
||||
|
||||
@@ -22,6 +22,7 @@ German accounting chart and localization.
|
||||
'data/res.country.state.csv',
|
||||
'data/menuitem_data.xml',
|
||||
'views/account_view.xml',
|
||||
'data/report_layout.xml',
|
||||
'report/din5008_report.xml',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="report_layout_din5008" model="report.layout">
|
||||
<field name="view_id" ref="l10n_de.external_layout_din5008"/>
|
||||
<field name="image">/l10n_de/static/img/preview_din.png</field>
|
||||
<field name="pdf">/l10n_de/static/pdf/preview_din.pdf</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import api, fields, models
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class AccountChartTemplate(models.Model):
|
||||
@@ -18,10 +18,6 @@ class AccountChartTemplate(models.Model):
|
||||
res = super(AccountChartTemplate, self).load_for_current_company(sale_tax_rate, purchase_tax_rate)
|
||||
company = self.env.user.company_id
|
||||
if company.country_id.code == 'DE':
|
||||
company.write({'external_report_layout': 'din5008', 'paperformat_id': self.env.ref('l10n_de.paperformat_euro_din').id})
|
||||
company.write({'external_report_layout': self.env.ref('l10n_de.external_layout_din5008').id,
|
||||
'paperformat_id': self.env.ref('l10n_de.paperformat_euro_din').id})
|
||||
return res
|
||||
|
||||
class Company(models.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
external_report_layout = fields.Selection(selection_add=[('din5008', 'Din 5008')])
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</template>
|
||||
|
||||
<!-- New report layout for din5008 format -->
|
||||
<template id="web.external_layout_din5008">
|
||||
<template id="external_layout_din5008">
|
||||
<t t-if="not o and doc">
|
||||
<t t-set="o" t-value="doc"/>
|
||||
</t>
|
||||
|
||||
@@ -10,71 +10,4 @@
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_company_report_form" model="ir.ui.view">
|
||||
<field name="name">res.company.l10nde.report.form</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="inherit_id" ref="base.view_company_report_form"></field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="external_report_layout" position="attributes">
|
||||
<attribute name="options">{
|
||||
'background': {
|
||||
'image_link': '/base/static/img/preview_background.png',
|
||||
'preview_link': '/base/static/pdf/preview_background.pdf'
|
||||
},
|
||||
'boxed': {
|
||||
'image_link': '/base/static/img/preview_boxed.png',
|
||||
'preview_link': '/base/static/pdf/preview_boxed.pdf'
|
||||
},
|
||||
'clean': {
|
||||
'image_link': '/base/static/img/preview_clean.png',
|
||||
'preview_link': '/base/static/pdf/preview_clean.pdf'
|
||||
},
|
||||
'standard': {
|
||||
'image_link': '/base/static/img/preview_standard.png',
|
||||
'preview_link': '/base/static/pdf/preview_standard.pdf'
|
||||
},
|
||||
'din5008': {
|
||||
'image_link': '/l10n_de/static/img/preview_din.png',
|
||||
'preview_link': '/l10n_de/static/pdf/preview_din.pdf'
|
||||
}
|
||||
}
|
||||
</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Template use in community -->
|
||||
<record id="view_company_document_template_form" model="ir.ui.view">
|
||||
<field name="name">res.company.l10nde.template.report.form</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="inherit_id" ref="base.view_company_document_template_form"></field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="external_report_layout" position="attributes">
|
||||
<attribute name="options">{
|
||||
'background': {
|
||||
'image_link': '/base/static/img/preview_background.png',
|
||||
'preview_link': '/base/static/pdf/preview_background.pdf'
|
||||
},
|
||||
'boxed': {
|
||||
'image_link': '/base/static/img/preview_boxed.png',
|
||||
'preview_link': '/base/static/pdf/preview_boxed.pdf'
|
||||
},
|
||||
'clean': {
|
||||
'image_link': '/base/static/img/preview_clean.png',
|
||||
'preview_link': '/base/static/pdf/preview_clean.pdf'
|
||||
},
|
||||
'standard': {
|
||||
'image_link': '/base/static/img/preview_standard.png',
|
||||
'preview_link': '/base/static/pdf/preview_standard.pdf'
|
||||
},
|
||||
'din5008': {
|
||||
'image_link': '/l10n_de/static/img/preview_din.png',
|
||||
'preview_link': '/l10n_de/static/pdf/preview_din.pdf'
|
||||
}
|
||||
}
|
||||
</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -46,7 +46,7 @@ class PosDetails(models.TransientModel):
|
||||
def generate_report(self):
|
||||
if (not self.env.user.company_id.logo):
|
||||
raise UserError(_("You have to set a logo or a layout for your company."))
|
||||
elif (not self.env.user.company_id.external_report_layout):
|
||||
elif (not self.env.user.company_id.external_report_layout_id):
|
||||
raise UserError(_("You have to set your reports's header and footer layout."))
|
||||
data = {'date_start': self.start_date, 'date_stop': self.end_date, 'config_ids': self.pos_config_ids.ids}
|
||||
return self.env.ref('point_of_sale.sale_details_report').report_action([], data=data)
|
||||
|
||||
@@ -24,7 +24,7 @@ class product_price_list(models.TransientModel):
|
||||
"""
|
||||
if (not self.env.user.company_id.logo):
|
||||
raise UserError(_("You have to set a logo or a layout for your company."))
|
||||
elif (not self.env.user.company_id.external_report_layout):
|
||||
elif (not self.env.user.company_id.external_report_layout_id):
|
||||
raise UserError(_("You have to set your reports's header and footer layout."))
|
||||
|
||||
datas = {'ids': self.env.context.get('active_ids', [])}
|
||||
|
||||
@@ -15,8 +15,11 @@ This module provides the core of the Odoo Web Client.
|
||||
'depends': ['base'],
|
||||
'auto_install': True,
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'views/webclient_templates.xml',
|
||||
'views/report_templates.xml',
|
||||
'data/res_company.xml',
|
||||
'data/report_layout.xml',
|
||||
],
|
||||
'qweb': [
|
||||
"static/src/xml/base.xml",
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="report_layout_background" model="report.layout">
|
||||
<field name="view_id" ref="web.external_layout_background"/>
|
||||
<field name="image">/web/static/img/preview_background.png</field>
|
||||
<field name="pdf">/web/static/pdf/preview_background.pdf</field>
|
||||
</record>
|
||||
<record id="report_layout_boxed" model="report.layout">
|
||||
<field name="view_id" ref="web.external_layout_boxed"/>
|
||||
<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="view_id" ref="web.external_layout_clean"/>
|
||||
<field name="image">/web/static/img/preview_clean.png</field>
|
||||
<field name="pdf">/web/static/pdf/preview_clean.pdf</field>
|
||||
</record>
|
||||
<record id="report_layout_standard" model="report.layout">
|
||||
<field name="view_id" ref="web.external_layout_standard"/>
|
||||
<field name="image">/web/static/img/preview_standard.png</field>
|
||||
<field name="pdf">/web/static/pdf/preview_standard.pdf</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="base.main_company" model="res.company">
|
||||
<field name="external_report_layout_id" ref="web.external_layout_standard"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -4,3 +4,4 @@
|
||||
from . import ir_qweb
|
||||
from . import ir_http
|
||||
from . import models
|
||||
from . import report_layout
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- coding: ascii -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class View(models.Model):
|
||||
|
||||
_name = "report.layout"
|
||||
|
||||
view_id = fields.Many2one('ir.ui.view', 'Document Template', required=True)
|
||||
image = fields.Char(string="Preview image src")
|
||||
pdf = fields.Char(string="Preview pdf src")
|
||||
@@ -0,0 +1,2 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_report_layout,access_report_layout,model_report_layout,,1,1,1,1
|
||||
|
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
@@ -2826,56 +2826,6 @@ var AceEditor = DebouncedField.extend({
|
||||
},
|
||||
});
|
||||
|
||||
var ImageSelection = AbstractField.extend({
|
||||
supportedFieldTypes: ['selection'],
|
||||
events: _.extend({}, AbstractField.prototype.events, {
|
||||
'click img': '_onImgClicked',
|
||||
}),
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @private
|
||||
*/
|
||||
_render: function () {
|
||||
var self = this;
|
||||
this.$el.empty();
|
||||
_.each(this.nodeOptions, function (val, key) {
|
||||
var $container = $('<div>').addClass('col-3 text-center');
|
||||
var $img = $('<img>')
|
||||
.addClass('img img-fluid img-thumbnail ml16')
|
||||
.toggleClass('btn-info', key === self.value)
|
||||
.attr('src', val.image_link)
|
||||
.data('key', key);
|
||||
$container.append($img);
|
||||
if (val.preview_link) {
|
||||
var $previewLink = $('<a>')
|
||||
.text('Preview')
|
||||
.attr('href', val.preview_link)
|
||||
.attr('target', '_blank');
|
||||
$container.append($previewLink);
|
||||
}
|
||||
self.$el.append($container);
|
||||
});
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @private
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
_onImgClicked: function (event) {
|
||||
this._setValue($(event.currentTarget).data('key'));
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
TranslatableFieldMixin: TranslatableFieldMixin,
|
||||
DebouncedField: DebouncedField,
|
||||
@@ -2906,7 +2856,6 @@ return {
|
||||
HandleWidget: HandleWidget,
|
||||
InputField: InputField,
|
||||
AttachmentImage: AttachmentImage,
|
||||
ImageSelection: ImageSelection,
|
||||
LabelSelection: LabelSelection,
|
||||
StateSelectionWidget: StateSelectionWidget,
|
||||
FavoriteWidget: FavoriteWidget,
|
||||
|
||||
@@ -43,7 +43,6 @@ registry
|
||||
.add('percentage', basic_fields.FieldPercentage)
|
||||
.add('priority', basic_fields.PriorityWidget)
|
||||
.add('attachment_image', basic_fields.AttachmentImage)
|
||||
.add('image_selection', basic_fields.ImageSelection)
|
||||
.add('label_selection', basic_fields.LabelSelection)
|
||||
.add('state_selection', basic_fields.StateSelectionWidget)
|
||||
.add('kanban_state_selection', basic_fields.StateSelectionWidget)
|
||||
@@ -81,5 +80,6 @@ registry
|
||||
|
||||
// Special fields
|
||||
registry
|
||||
.add('timezone_mismatch', special_fields.FieldTimezoneMismatch);
|
||||
.add('timezone_mismatch', special_fields.FieldTimezoneMismatch)
|
||||
.add('report_layout', special_fields.FieldReportLayout);
|
||||
});
|
||||
|
||||
@@ -102,8 +102,75 @@ var FieldTimezoneMismatch = FieldSelection.extend({
|
||||
},
|
||||
});
|
||||
|
||||
var FieldReportLayout = relational_fields.FieldMany2One.extend({
|
||||
supportedFieldTypes: ['many2one', 'selection'],
|
||||
events: _.extend({}, relational_fields.FieldMany2One.prototype.events, {
|
||||
'click img': '_onImgClicked',
|
||||
}),
|
||||
|
||||
willStart: function () {
|
||||
var self = this;
|
||||
this.previews = {};
|
||||
return this._super()
|
||||
.then(function () {
|
||||
return self._rpc({
|
||||
model: 'report.layout',
|
||||
method: "search_read"
|
||||
}).then(function (values) {
|
||||
self.previews = values;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @private
|
||||
*/
|
||||
_render: function () {
|
||||
var self = this;
|
||||
this.$el.empty();
|
||||
var value = _.isObject(this.value) ? this.value.data.id : this.value;
|
||||
_.each(this.previews, function (val) {
|
||||
var $container = $('<div>').addClass('col-3 text-center');
|
||||
var $img = $('<img>')
|
||||
.addClass('img img-fluid img-thumbnail ml16')
|
||||
.toggleClass('btn-info', val.view_id[0] === value)
|
||||
.attr('src', val.image)
|
||||
.data('key', val.view_id[0]);
|
||||
$container.append($img);
|
||||
if (val.pdf) {
|
||||
var $previewLink = $('<a>')
|
||||
.text('Preview')
|
||||
.attr('href', val.pdf)
|
||||
.attr('target', '_blank');
|
||||
$container.append($previewLink);
|
||||
}
|
||||
self.$el.append($container);
|
||||
});
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @private
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
_onImgClicked: function (event) {
|
||||
this._setValue($(event.currentTarget).data('key'));
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
return {
|
||||
FieldTimezoneMismatch: FieldTimezoneMismatch,
|
||||
FieldReportLayout: FieldReportLayout,
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
@@ -606,7 +606,8 @@
|
||||
}
|
||||
}
|
||||
&.o_company_document_layout {
|
||||
.image_selection_container {
|
||||
.report_layout_container {
|
||||
display: inline-block;
|
||||
div {
|
||||
display: inline-block;
|
||||
img {
|
||||
|
||||
@@ -40,8 +40,6 @@ QUnit.module('basic_fields', {
|
||||
selection: {string: "Selection", type: "selection", searchable:true,
|
||||
selection: [['normal', 'Normal'],['blocked', 'Blocked'],['done', 'Done']]},
|
||||
document: {string: "Binary", type: "binary"},
|
||||
image_selection: {string: "Image Selection", type: "selection", searchable:true,
|
||||
selection: [['background', 'Background'],['boxed', 'Boxed'],['clean', 'Clean'],['standard', 'Standard']]},
|
||||
},
|
||||
records: [{
|
||||
id: 1,
|
||||
@@ -4828,45 +4826,6 @@ QUnit.module('basic_fields', {
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.module('FieldImageSelection');
|
||||
|
||||
QUnit.test('image selection widget in form view', function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
var nodeOptions = {
|
||||
background: {
|
||||
image_link: '/base/static/img/preview_background.png',
|
||||
preview_link: '/base/static/pdf/preview_background.pdf',
|
||||
},
|
||||
boxed: {
|
||||
image_link: '/base/static/img/preview_boxed.png',
|
||||
preview_link: '/base/static/pdf/preview_boxed.pdf',
|
||||
},
|
||||
};
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form>' +
|
||||
'<field name="image_selection" widget="image_selection"' +
|
||||
' options=\'' + JSON.stringify(nodeOptions) + '\'/> '+
|
||||
'</form>',
|
||||
res_id: 2,
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.img.img-fluid').length, 2,
|
||||
"Two images should be rendered");
|
||||
assert.strictEqual(form.$('.img.btn-info').length, 0,
|
||||
"No image should be selected");
|
||||
|
||||
// select first image
|
||||
form.$(".img.img-fluid:first").click();
|
||||
assert.ok(form.$(".img.img-fluid:first").hasClass('btn-info'),
|
||||
"First image should be selected");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -213,6 +213,53 @@ QUnit.module('special_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.module('FieldReportLayout');
|
||||
|
||||
QUnit.test('report_layout widget in form view', function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
this.data['report.layout'] = {
|
||||
fields: {
|
||||
view_id: {string: "Document Template", type: "many2one", relation: "product"},
|
||||
image: {string: "Preview image src", type: "char"},
|
||||
pdf: {string: "Preview pdf src", type: "char"}
|
||||
},
|
||||
records: [{
|
||||
id: 1,
|
||||
view_id: 37,
|
||||
image: "/web/static/toto.png",
|
||||
pdf: "/web/static/toto.pdf",
|
||||
}, {
|
||||
id: 2,
|
||||
view_id: 41,
|
||||
image: "/web/static/tata.png",
|
||||
pdf: "/web/static/tata.pdf",
|
||||
}]
|
||||
};
|
||||
this.data.partner.records[1].product_id = false;
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form>' +
|
||||
'<field name="product_id" widget="report_layout"/> '+
|
||||
'</form>',
|
||||
res_id: 2,
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.img.img-fluid').length, 2,
|
||||
"Two images should be rendered");
|
||||
assert.strictEqual(form.$('.img.btn-info').length, 0,
|
||||
"No image should be selected");
|
||||
|
||||
// select first image
|
||||
form.$(".img.img-fluid:first").click();
|
||||
assert.ok(form.$(".img.img-fluid:first").hasClass('btn-info'),
|
||||
"First image should be selected");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
t-att-data-report-landscape="data_report_landscape"
|
||||
t-att-web-base-url="web_base_url">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="initial-scale=1"/>
|
||||
<title><t t-esc="title or 'Odoo Report'"/></title>
|
||||
<t t-call-assets="web.assets_common" t-js="false"/>
|
||||
@@ -179,8 +179,8 @@
|
||||
</div>
|
||||
|
||||
<div class="article o_report_layout_background" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id">
|
||||
<t t-call="web.address_layout" />
|
||||
<t t-raw="0" />
|
||||
<t t-call="web.address_layout"/>
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
|
||||
<div class="footer o_background_footer">
|
||||
@@ -219,8 +219,8 @@
|
||||
</div>
|
||||
|
||||
<div class="article o_report_layout_boxed" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id">
|
||||
<t t-call="web.address_layout" />
|
||||
<t t-raw="0" />
|
||||
<t t-call="web.address_layout"/>
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
|
||||
<div class="footer o_boxed_footer">
|
||||
@@ -258,8 +258,8 @@
|
||||
</div>
|
||||
|
||||
<div class="article o_report_layout_clean" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id">
|
||||
<t t-call="web.address_layout" />
|
||||
<t t-raw="0" />
|
||||
<t t-call="web.address_layout"/>
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
|
||||
<div class="footer o_clean_footer">
|
||||
@@ -306,8 +306,8 @@
|
||||
</div>
|
||||
|
||||
<div class="article o_report_layout_standard" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id">
|
||||
<t t-call="web.address_layout" />
|
||||
<t t-raw="0" />
|
||||
<t t-call="web.address_layout"/>
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
|
||||
<div class="footer o_standard_footer">
|
||||
@@ -333,32 +333,40 @@
|
||||
<!-- Public api: layout to t-call from reports -->
|
||||
|
||||
<template id="external_layout">
|
||||
<!-- Multicompany -->
|
||||
<t t-if="not o and doc">
|
||||
<t t-set="o" t-value="doc"/>
|
||||
<t t-if="not o" t-set="o" t-value="doc"/>
|
||||
|
||||
<t t-if="not company">
|
||||
<!-- Multicompany -->
|
||||
<t t-if="company_id">
|
||||
<t t-set="company" t-value="company_id"/>
|
||||
</t>
|
||||
<t t-elif="o and 'company_id' in o">
|
||||
<t t-set="company" t-value="o.company_id.sudo()"/>
|
||||
</t>
|
||||
<t t-else="else">
|
||||
<t t-set="company" t-value="res_company"/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-if="o and 'company_id' in o">
|
||||
<t t-set="company" t-value="o.company_id.sudo()"/>
|
||||
</t>
|
||||
<t t-if="not o or not 'company_id' in o">
|
||||
<t t-set="company" t-value="res_company"/>
|
||||
</t>
|
||||
<t t-if="company.external_report_layout_id" t-call="{{company.external_report_layout_id.key}}"><t t-raw="0"/></t>
|
||||
<t t-else="else" t-raw="0"/>
|
||||
|
||||
<t t-call="web.external_layout_{{company.external_report_layout or 'standard'}}"><t t-raw="0"/></t>
|
||||
</template>
|
||||
|
||||
<template id="internal_layout">
|
||||
<!-- Multicompany -->
|
||||
<t t-if="company_id">
|
||||
<t t-set="company" t-value="company_id"/>
|
||||
<t t-set="res_company" t-value="company_id"/>
|
||||
</t>
|
||||
<t t-if="not company_id">
|
||||
<t t-set="company" t-value="res_company"/>
|
||||
</t>
|
||||
<t t-if="not o and doc">
|
||||
<t t-set="o" t-value="doc"/>
|
||||
<t t-if="not o" t-set="o" t-value="doc"/>
|
||||
|
||||
<t t-if="not company">
|
||||
<!-- Multicompany -->
|
||||
<t t-if="company_id">
|
||||
<t t-set="company" t-value="company_id"/>
|
||||
</t>
|
||||
<t t-elif="o and 'company_id' in o">
|
||||
<t t-set="company" t-value="o.company_id.sudo()"/>
|
||||
</t>
|
||||
<t t-else="else">
|
||||
<t t-set="company" t-value="res_company"/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<div class="header">
|
||||
@@ -379,18 +387,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="article" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id">
|
||||
<t t-raw="0" />
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="basic_layout">
|
||||
<t t-if="not o and doc">
|
||||
<t t-set="o" t-value="doc"/>
|
||||
</t>
|
||||
<t t-if="not o" t-set="o" t-value="doc"/>
|
||||
|
||||
<t t-call="web.html_container">
|
||||
<div class="article" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id">
|
||||
<t t-raw="0" />
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
@@ -399,6 +405,7 @@
|
||||
<!-- Demo reports definition -->
|
||||
<template id="preview_internalreport">
|
||||
<t t-call="web.html_container">
|
||||
<t t-set="o" t-value="res_company"/>
|
||||
<t t-call="web.internal_layout">
|
||||
<div class="page">
|
||||
<p>This is a sample of an internal report.</p>
|
||||
@@ -408,6 +415,7 @@
|
||||
</template>
|
||||
<template id="preview_externalreport">
|
||||
<t t-call="web.html_container">
|
||||
<t t-set="o" t-value="res_company"/>
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<p>This is a sample of an external report.</p>
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<data noupdate="1">
|
||||
<record id="main_company" model="res.company">
|
||||
<field name="name">ProBike Inc</field>
|
||||
<field name="external_report_layout">standard</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -710,7 +710,7 @@ class IrActionsReport(models.Model):
|
||||
:param report_name: Name of the template to generate an action for
|
||||
"""
|
||||
discard_logo_check = self.env.context.get('discard_logo_check')
|
||||
if (self.env.uid == SUPERUSER_ID) and ((not self.env.user.company_id.external_report_layout) or (not discard_logo_check and not self.env.user.company_id.logo)) and config:
|
||||
if (self.env.uid == SUPERUSER_ID) and ((not self.env.user.company_id.external_report_layout_id) or (not discard_logo_check and not self.env.user.company_id.logo)) and config:
|
||||
template = self.env.ref('base.view_company_report_form_with_print') if self.env.context.get('from_transient_model', False) else self.env.ref('base.view_company_report_form')
|
||||
return {
|
||||
'name': _('Choose Your Document Layout'),
|
||||
|
||||
@@ -655,6 +655,4 @@ class QwebView(models.AbstractModel):
|
||||
_logger.warning("%s.%s must be a 'ir.ui.view' model." % (record, field_name))
|
||||
return None
|
||||
|
||||
view = view.with_context(object=record)
|
||||
|
||||
return pycompat.to_text(view.render(view._context, engine='ir.qweb'))
|
||||
return pycompat.to_text(view.render(options.get('values', {}), engine='ir.qweb'))
|
||||
|
||||
@@ -55,14 +55,8 @@ class Company(models.Model):
|
||||
website = fields.Char(related='partner_id.website')
|
||||
vat = fields.Char(related='partner_id.vat', string="Tax ID")
|
||||
company_registry = fields.Char()
|
||||
paperformat_id = fields.Many2one('report.paperformat', 'Paper Format', default=lambda self: self.env.ref('base.paperformat_euro', raise_if_not_found=False))
|
||||
external_report_layout = fields.Selection([
|
||||
('background', 'Background'),
|
||||
('boxed', 'Boxed'),
|
||||
('clean', 'Clean'),
|
||||
('standard', 'Standard'),
|
||||
], string='Document Template')
|
||||
|
||||
paperformat_id = fields.Many2one('report.paperformat', 'Paper format', default=lambda self: self.env.ref('base.paperformat_euro', raise_if_not_found=False))
|
||||
external_report_layout_id = fields.Many2one('ir.ui.view', 'Document Template')
|
||||
_sql_constraints = [
|
||||
('name_uniq', 'unique (name)', 'The company name must be unique !')
|
||||
]
|
||||
|
||||
@@ -141,23 +141,9 @@
|
||||
<xpath expr="//sheet" position="inside">
|
||||
<hr />
|
||||
<div class="row mt16">
|
||||
<field style="margin-right: 40px;" name="external_report_layout" widget="image_selection" options="{
|
||||
'background': {
|
||||
'image_link': '/base/static/img/preview_background.png',
|
||||
'preview_link': '/base/static/pdf/preview_background.pdf'
|
||||
},
|
||||
'boxed': {
|
||||
'image_link': '/base/static/img/preview_boxed.png',
|
||||
'preview_link': '/base/static/pdf/preview_boxed.pdf'
|
||||
},
|
||||
'clean': {
|
||||
'image_link': '/base/static/img/preview_clean.png',
|
||||
'preview_link': '/base/static/pdf/preview_clean.pdf'
|
||||
},
|
||||
'standard': {
|
||||
'image_link': '/base/static/img/preview_standard.png',
|
||||
'preview_link': '/base/static/pdf/preview_standard.pdf'
|
||||
}
|
||||
<field style="margin-right: 40px;" name="external_report_layout_id" widget="report_layout" options="{
|
||||
'field_image': 'preview_image',
|
||||
'field_binary': 'preview_pdf'
|
||||
}"/>
|
||||
</div>
|
||||
<footer>
|
||||
@@ -187,32 +173,21 @@
|
||||
<field name="priority">2048</field>
|
||||
<field name="arch" type="xml">
|
||||
<form class="o_company_document_layout">
|
||||
<group>
|
||||
<label for="external_report_layout_id" string="Template" colspan="2" />
|
||||
<field name="external_report_layout_id" colspan="2" nolabel="1"
|
||||
class="report_layout_container"
|
||||
widget="report_layout" options="{
|
||||
'field_image': 'preview_image',
|
||||
'field_binary': 'preview_pdf'
|
||||
}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="logo" widget="image" />
|
||||
<field name="external_report_layout" string="Layout"
|
||||
class="image_selection_container"
|
||||
widget="image_selection" options="{
|
||||
'background': {
|
||||
'image_link': '/base/static/img/preview_background.png',
|
||||
'preview_link': '/base/static/pdf/preview_background.pdf'
|
||||
},
|
||||
'boxed': {
|
||||
'image_link': '/base/static/img/preview_boxed.png',
|
||||
'preview_link': '/base/static/pdf/preview_boxed.pdf'
|
||||
},
|
||||
'clean': {
|
||||
'image_link': '/base/static/img/preview_clean.png',
|
||||
'preview_link': '/base/static/pdf/preview_clean.pdf'
|
||||
},
|
||||
'standard': {
|
||||
'image_link': '/base/static/img/preview_standard.png',
|
||||
'preview_link': '/base/static/pdf/preview_standard.pdf'
|
||||
}
|
||||
}" />
|
||||
<field name="report_header" widget="char"
|
||||
placeholder="e.g. Global Business Solutions" />
|
||||
placeholder="e.g. Global Business Solutions" />
|
||||
<field name="report_footer" string="Footer"
|
||||
placeholder="e.g. Opening hours, bank accounts (one per line)" />
|
||||
placeholder="e.g. Opening hours, bank accounts (one per line)" />
|
||||
<field name="paperformat_id" widget="selection" />
|
||||
</group>
|
||||
<footer>
|
||||
|
||||