[MERGE] event_*: refactor and improve badge reporting

PURPOSE

Rework the existing badge report to ease its override and make it look better
and introduce a new ticket report that contains more detailed information.

SPECS

Improve the existing badge report
Change the event badge report to create a proper action report so that it
shows accordingly on form (and other) views.
Remove the duplicate template for event badges and unify into one template
The "event badges" report can be printed from 2 different sources, from the
event.event itself as a preview and from the event.registration as an actual
badge for a specific attendee.
Improve the general layout of the report and remove unnecessary fields.
Introduce a new badge report with the A4 format.

This report is meant to be printed for the attendee and contains more
detailed information that the existing "badge report", which is only meant to
be folded and used as a badge.

We also introduce a new field that allows easily customizing these reports by
adding "extra instructions".

See underlying commits for more details.

LINKS

ENT PR odoo/enterprise#19349
UPG PR odoo/upgrade#2599
Task-2120259

closes odoo/odoo#72935

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Odoo's Mergebot
2021-07-30 14:50:25 +02:00
committed by GitHub
27 changed files with 559 additions and 160 deletions
+7
View File
@@ -55,6 +55,13 @@ Key Features
'web.assets_qweb': [
'event/static/src/xml/**/*',
],
'web.report_assets_common': [
'/event/static/src/scss/event_foldable_badge_report.scss',
'/event/static/src/scss/event_full_page_ticket_report.scss',
],
'web.report_assets_pdf': [
'/event/static/src/scss/event_full_page_ticket_report_pdf.scss',
],
},
'license': 'LGPL-3',
}
+8
View File
@@ -14,6 +14,14 @@
<field name="event_type_id" ref="event_type_0"/>
<field name="stage_id" ref="event_stage_booked"/>
<field name="tag_ids" eval="[(4, ref('event.event_tag_category_1_tag_1')), (4, ref('event.event_tag_category_2_tag_1'))]"/>
<field name="ticket_instructions" type="html">
<div class="text-center font-weight-bold py-3">Important ticket information</div>
<ul>
<li>Please come <b>at least</b> 30 minutes before the beginning of the event.</li>
<li>Tickets can be printed or scanned directly from your phone.</li>
<li>If you don't have this ticket, you will <b>not</b> be allowed entry!</li>
</ul>
</field>
</record>
<record id="event_0_ticket_0" model="event.event.ticket">
<field name="name">Free</field>
@@ -149,6 +149,7 @@
<function model="event.registration"
name="action_confirm"
context="{'install_mode' : True}"
eval="[[ref('event_registration_0_0'), ref('event_registration_0_1'),
ref('event_registration_1_0'), ref('event_registration_1_1'), ref('event_registration_1_2'),
ref('event_registration_2_0'), ref('event_registration_2_1'), ref('event_registration_2_2'), ref('event_registration_2_3'),
+4 -2
View File
@@ -21,8 +21,8 @@
${object.event_id.user_id.signature | safe}
% endif
</div></field>
<field name="report_template" ref="report_event_registration_badge"/>
<field name="report_name">badge_of_${(object.event_id.name or '').replace('/','_')}</field>
<field name="report_template" ref="action_report_event_registration_foldable_badge"/>
<field name="report_name">Foldable Badge - ${(object.event_id.name or 'Event').replace('/','')}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="auto_delete" eval="True"/>
</record>
@@ -248,6 +248,8 @@
</td></tr>
</table>
</field>
<field name="report_template" ref="action_report_event_registration_full_page_ticket"/>
<field name="report_name">Full Page Ticket - ${(object.event_id.name or 'Event').replace('/','')}</field>
<field name="lang">${object.partner_id.lang}</field>
</record>
+14 -6
View File
@@ -44,6 +44,9 @@ class EventType(models.Model):
_tz_get, string='Timezone', default=lambda self: self.env.user.tz or 'UTC')
# communication
event_type_mail_ids = fields.One2many('event.type.mail', 'event_type_id', string='Mail Schedule')
# ticket reports
ticket_instructions = fields.Html('Ticket Instructions', translate=True,
help="This information will be printed on your tickets.")
@api.depends('has_seats_limitation')
def _compute_default_registration(self):
@@ -162,12 +165,10 @@ class EventEvent(models.Model):
tracking=True, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]")
country_id = fields.Many2one(
'res.country', 'Country', related='address_id.country_id', readonly=False, store=True)
# badge fields
badge_front = fields.Html(string='Badge Front')
badge_back = fields.Html(string='Badge Back')
badge_innerleft = fields.Html(string='Badge Inner Left')
badge_innerright = fields.Html(string='Badge Inner Right')
event_logo = fields.Html(string='Event Logo')
# ticket reports
ticket_instructions = fields.Html('Ticket Instructions', translate=True,
compute='_compute_ticket_instructions', store=True, readonly=False,
help="This information will be printed on your tickets.")
@api.depends('stage_id', 'kanban_state')
def _compute_kanban_state_label(self):
@@ -434,6 +435,13 @@ class EventEvent(models.Model):
if event.event_type_id and not is_html_empty(event.event_type_id.note):
event.note = event.event_type_id.note
@api.depends('event_type_id')
def _compute_ticket_instructions(self):
for event in self:
if is_html_empty(event.ticket_instructions) and not \
is_html_empty(event.event_type_id.ticket_instructions):
event.ticket_instructions = event.event_type_id.ticket_instructions
@api.constrains('seats_max', 'seats_available', 'seats_limited')
def _check_seats_limit(self):
if any(event.seats_limited and event.seats_max and event.seats_available < 0 for event in self):
+2 -3
View File
@@ -235,9 +235,8 @@ You receive this email because you are:
for scheduler in schedulers:
try:
with self.env.cr.savepoint():
# Prevent a mega prefetch of the registration ids of all the events of all the schedulers
self.browse(scheduler.id).execute()
# Prevent a mega prefetch of the registration ids of all the events of all the schedulers
self.browse(scheduler.id).execute()
except Exception as e:
_logger.exception(e)
self.invalidate_cache()
+10 -2
View File
@@ -155,7 +155,11 @@ class EventRegistration(models.Model):
# some were created already open
if registrations._check_auto_confirmation():
registrations.sudo().action_confirm()
else:
elif not self.env.context.get('install_mode', False):
# running the scheduler for demo data can cause an issue where wkhtmltopdf runs during
# server start and hangs indefinitely, leading to serious crashes
# we currently avoid this by not running the scheduler, would be best to find the actual
# reason for this issue and fix it so we can remove this check
registrations._update_mail_schedulers()
return registrations
@@ -167,7 +171,11 @@ class EventRegistration(models.Model):
ret = super(EventRegistration, self).write(vals)
if vals.get('state') == 'open':
if vals.get('state') == 'open' and not self.env.context.get('install_mode', False):
# running the scheduler for demo data can cause an issue where wkhtmltopdf runs during
# server start and hangs indefinitely, leading to serious crashes
# we currently avoid this by not running the scheduler, would be best to find the actual
# reason for this issue and fix it so we can remove this check
pre_draft._update_mail_schedulers()
return ret
+72 -24
View File
@@ -1,41 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="paperformat_euro_lowmargin" model="report.paperformat">
<field name="name">European A4 low margin</field>
<field name="default" eval="True"/>
<record id="paperformat_event_foldable_badge" model="report.paperformat">
<field name="name">Custom Paperformat for the Event Foldable Badge report</field>
<field name="default" eval="False"/>
<field name="disable_shrinking" eval="True"/>
<field name="format">A4</field>
<field name="page_height">0</field>
<field name="page_width">0</field>
<field name="orientation">Portrait</field>
<field name="margin_top">5</field>
<field name="margin_bottom">5</field>
<field name="margin_left">5</field>
<field name="margin_right">5</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">0</field>
<field name="dpi">80</field>
<field name="margin_top">0</field>
<field name="margin_bottom">0</field>
<field name="margin_left">0</field>
<field name="margin_right">0</field>
<field name="dpi">96</field>
</record>
<record id="report_event_registration_badge" model="ir.actions.report">
<field name="name">Registration Badge</field>
<record id="paperformat_event_full_page_ticket" model="report.paperformat">
<field name="name">Custom Paperformat for the Event Full Page Ticket report</field>
<field name="default" eval="False"/>
<field name="disable_shrinking" eval="True"/>
<field name="format">A4</field>
<field name="page_height">0</field>
<field name="page_width">0</field>
<field name="orientation">Portrait</field>
<field name="margin_top">0</field>
<field name="margin_bottom">8</field>
<field name="margin_left">0</field>
<field name="margin_right">0</field>
<field name="dpi">96</field>
</record>
<!-- The "Full Page Ticket", as opposed to the foldable badge that is meant to be folded and
only contains the bare minimum (attendee name + barcode), gives all the information of the
ticket in a portrait A4 format.
It allows to add some information in the ticket_instructions field and, when printed, functions
as an "official" ticket that the attendee can show to the registration desk where all
the information are available (event name, organizer, SO reference, barcode, footer with
sponsors, ...). -->
<record id="action_report_event_registration_full_page_ticket" model="ir.actions.report">
<field name="name">Full Page Ticket</field>
<field name="model">event.registration</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">event.event_registration_report_template_badge</field>
<field name="report_file">event.event_registration_report_template_badge</field>
<field name="print_report_name">'Registration Event - %s' % (object.name or 'Attendee').replace('/','')</field>
<field name="paperformat_id" ref="event.paperformat_euro_lowmargin"/>
<field name="report_name">event.event_registration_report_template_full_page_ticket</field>
<field name="report_file">event.event_registration_report_template_full_page_ticket</field>
<field name="print_report_name">'Full Page Ticket - %s - %s' % ((object.event_id.name or 'Event').replace('/',''), object.name.replace('/',''))</field>
<field name="binding_model_id" ref="model_event_registration"/>
<field name="binding_type">report</field>
<field name="paperformat_id" ref="paperformat_event_full_page_ticket"/>
</record>
<record id="report_event_event_badge" model="ir.actions.report">
<field name="name">Event Badge</field>
<field name="model">event.event</field>
<field name="report_type">qweb-html</field>
<field name="report_name">event.event_event_report_template_badge</field>
<field name="report_file">event.event_event_report_template_badge</field>
<field name="paperformat_id" ref="event.paperformat_euro_lowmargin"/>
</record>
<record id="action_report_event_event_full_page_ticket" model="ir.actions.report">
<field name="name">Full Page Ticket Example</field>
<field name="model">event.event</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">event.event_event_report_template_full_page_ticket</field>
<field name="report_file">event.event_event_report_template_full_page_ticket</field>
<field name="print_report_name">'Full Page Ticket - %s' % (object.name or 'Event').replace('/','')</field>
<field name="binding_model_id" ref="model_event_event"/>
<field name="binding_type">report</field>
<field name="paperformat_id" ref="paperformat_event_full_page_ticket"/>
</record>
<record id="action_report_event_registration_foldable_badge" model="ir.actions.report">
<field name="name">Foldable Badge</field>
<field name="model">event.registration</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">event.event_registration_report_template_foldable_badge</field>
<field name="report_file">event.event_registration_report_template_foldable_badge</field>
<field name="print_report_name">'Foldable Badge - %s - %s' % ((object.event_id.name or 'Event').replace('/',''), object.name.replace('/',''))</field>
<field name="binding_model_id" ref="model_event_registration"/>
<field name="binding_type">report</field>
<field name="paperformat_id" ref="paperformat_event_foldable_badge"/>
</record>
<record id="action_report_event_event_foldable_badge" model="ir.actions.report">
<field name="name">Foldable Badge Example</field>
<field name="model">event.event</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">event.event_event_report_template_foldable_badge</field>
<field name="report_file">event.event_event_report_template_foldable_badge</field>
<field name="print_report_name">'Foldable Badge - %s' % (object.name or 'Event').replace('/','')</field>
<field name="binding_model_id" ref="model_event_event"/>
<field name="binding_type">report</field>
<field name="paperformat_id" ref="paperformat_event_foldable_badge"/>
</record>
</odoo>
+228 -89
View File
@@ -1,104 +1,243 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- template use to render a Registration Badge -->
<template id="event_registration_report_template_badge">
<t t-call="web.basic_layout">
<t t-foreach="docs" t-as="o">
<div class="page">
<div class="row">
<!-- Front -->
<div class="col-6 text-center" style="padding-left:7mm; border-left:1px dashed black; height: 149mm; -webkit-transform:rotate(180deg); padding-top: 7mm">
<div>
<div class="col-12">
<t t-if="o.event_id.event_logo">
<div t-field="o.event_id.event_logo"/>
</t>
<span t-if="not o.event_id.event_logo and o.event_id.organizer_id.company_id.logo_web and o.event_id.organizer_id.is_company">
<img t-att-src="image_data_uri(o.event_id.organizer_id.company_id.logo_web)" style="max-height:1cm; max-width:4cm;" alt="Logo"/>
</span>
<h5 t-field="o.event_id.name"/>
<h5>( <i class="fa fa-clock-o" aria-label="Period" role="img" title="Period"></i> <span itemprop="startDate" t-field="o.event_id.with_context(tz=o.event_id.date_tz).date_begin" t-options='{"hide_seconds": True}'> </span> <i>to</i> <span itemprop="endDate" t-field="o.event_id.with_context(tz=o.event_id.date_tz).date_end" t-options='{"hide_seconds": True}'> </span> )</h5>
</div>
<div>
<div class="col-12 text-center" id="o_event_name">
<small>
<h3 t-field="o.name"/>
</small>
</div>
</div>
<div>
<div t-field="o.event_id.badge_front"></div>
</div>
</div>
<!-- EVENT FOLDABLE BADGE -->
<template id="event_report_template_foldable_badge">
<div class="o_event_foldable_badge_container">
<div class="row">
<!-- Front -->
<div class="page p-1 col-6 o_event_foldable_badge_top">
<div class="oe_structure"/>
</div>
<!-- Back -->
<div class="page col-6 o_event_foldable_badge_top o_event_foldable_badge_ticket pt-4">
<div class="oe_structure"/>
<div class="o_event_foldable_badge_ticket_wrapper p-2">
<div class="o_event_foldable_badge_ticket_wrapper_top page">
<h5 class="o_event_foldable_badge_event_name font-weight-bold text-center" t-field="event.name"/>
<div class="text-center o_event_foldable_badge_font_small">
<span itemprop="startDate" t-esc="event.date_begin.date()"
class="font-weight-bold"/>
<span itemprop="startDateTime" t-esc="event.date_begin"
class="font-weight-bold"
t-options='{"widget": "datetime", "time_only": True, "hide_seconds": True}'/>
<span class="fa fa-arrow-right o_event_foldable_badge_font_faded"/>
<span t-if="not event.is_one_day"
itemprop="endDate" t-esc="event.date_end.date()"
class="font-weight-bold"/>
<span itemprop="endDateTime" t-esc="event.date_end"
class="font-weight-bold"
t-options='{"widget": "datetime", "time_only": True, "hide_seconds": True}'/>
</div>
<!-- Back -->
<div class="col-6" style="padding-right:7mm; height: 149mm; -webkit-transform:rotate(180deg); padding-top: 2mm;">
<span t-field="o.event_id.badge_back"/>
<div t-if="event.address_id" class="o_event_foldable_badge_font_faded o_event_foldable_badge_font_small text-center">
<t t-call="event.event_report_template_formatted_event_address"/>
</div>
<div class="text-center mt-5 pt-2">
<h2 t-if="attendee" t-field="attendee.name"/>
<h2 t-elif="not attendee"><span>John Doe</span></h2>
<t t-set="first_ticket" t-value="event.event_ticket_ids[0] if event.event_ticket_ids else None"/>
<div t-if="attendee" class="o_event_foldable_badge_font_faded" t-field="attendee.event_ticket_id"/>
<div t-elif="first_ticket" t-esc="first_ticket.name"
class="o_event_foldable_badge_font_faded"/>
</div>
</div>
<div class="row">
<!-- Inner left -->
<div class="col-6 text-center" style="padding-right:7mm; border-top:1px dashed black; height: 148mm;">
<span t-field="o.event_id.badge_innerleft"/>
</div>
<!-- Inner right -->
<div class="col-6 text-center" style="border-left:1px dashed black; border-top:1px dashed black; height: 148mm; text-center">
<span t-field="o.event_id.badge_innerright"/>
<div class="o_event_foldable_badge_barcode mt-2">
<div class="o_event_foldable_badge_barcode_container">
</div>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Inner left -->
<div class="page o_event_foldable_badge_bottom o_event_foldable_badge_left p-1 px-2 col-6 overflow-hidden">
<div class="oe_structure"/>
<div t-field="event.ticket_instructions" class="p-4"></div>
</div>
<!-- Inner right -->
<div class="page o_event_foldable_badge_bottom o_event_foldable_badge_right col-6 text-center">
<div class="oe_structure"/>
<div class="h-50 col-12 row m-0">
<div class="col-6 h-100 p-0">
<div class="o_event_foldable_badge_step font-weight-bold">1</div>
<img src="/event/static/src/img/how_to_fold_1.png" class="w-100 h-100" alt="How to Fold (1)"/>
</div>
<div class="col-6 h-100 p-0">
<div class="o_event_foldable_badge_step font-weight-bold">2</div>
<img src="/event/static/src/img/how_to_fold_2.png" class="w-100 h-100" alt="How to Fold (2)"/>
</div>
</div>
<div class="h-50 col-12 row m-0">
<div class="col-6 h-100 p-0">
<div class="o_event_foldable_badge_step font-weight-bold">3</div>
<img src="/event/static/src/img/how_to_fold_3.png" class="w-100 h-100" alt="How to Fold (3)"/>
</div>
<div class="col-6 h-100 p-0">
<div class="o_event_foldable_badge_step font-weight-bold">4</div>
<img src="/event/static/src/img/how_to_fold_4.png" class="w-100 h-100" alt="How to Fold (4)"/>
</div>
</div>
</div>
</div>
</div>
</template>
<template id="event_registration_report_template_foldable_badge">
<t t-call="web.basic_layout">
<t t-foreach="docs" t-as="attendee">
<t t-set="event" t-value="attendee.event_id.with_context(tz=attendee.event_id.date_tz)"/>
<t t-call="event.event_report_template_foldable_badge"/>
</t>
</t>
</template>
<template id="event_event_report_template_foldable_badge">
<t t-call="web.basic_layout">
<t t-foreach="docs" t-as="event">
<t t-set="event" t-value="event.with_context(tz=event.date_tz)"/>
<t t-call="event.event_report_template_foldable_badge"/>
</t>
</t>
</template>
<!-- EVENT FULL PAGE TICKET -->
<template id="event_report_template_full_page_ticket">
<div class="row page">
<div class="o_event_full_page_ticket_container page w-100">
<div class="o_event_full_page_ticket_wrapper">
<div class="o_event_full_page_ticket_details row">
<div class="col-10">
<div class="row">
<div class="col-8 page">
<div class="o_event_full_page_ticket_font_faded">
Event Ticket For
</div>
<h5 class="o_event_full_page_ticket_event_name font-weight-bold py-0 my-0" t-field="event.name"/>
<span itemprop="startDate" t-esc="event.date_begin.date()"
class="font-weight-bold"/>
<span itemprop="startDateTime" t-esc="event.date_begin"
class="font-weight-bold"
t-options='{"widget": "datetime", "time_only": True, "hide_seconds": True}'/>
<span class="fa fa-arrow-right o_event_full_page_ticket_font_faded"/>
<span t-if="not event.is_one_day"
itemprop="endDate" t-esc="event.date_end.date()"
class="font-weight-bold"/>
<span itemprop="endDateTime" t-esc="event.date_end"
class="font-weight-bold"
t-options='{"widget": "datetime", "time_only": True, "hide_seconds": True}'/>
<div t-if="event.address_id" class="o_event_full_page_ticket_font_faded">
<t t-call="event.event_report_template_formatted_event_address"/>
</div>
<br/>
<h5 t-if="attendee" t-field="attendee.name"></h5>
<h5 t-elif="not attendee"><span>John Doe</span></h5>
<t t-set="first_ticket" t-value="event.event_ticket_ids[0] if event.event_ticket_ids else None"/>
<div t-if="attendee" class="o_event_full_page_ticket_font_faded" t-field="attendee.event_ticket_id"/>
<div t-elif="first_ticket" t-esc="first_ticket.name"
class="o_event_full_page_ticket_font_faded"/>
</div>
<div class="col-4 o_event_full_page_ticket_side_info page">
<span t-if="event.organizer_id.image_128">
<img t-att-src="image_data_uri(event.organizer_id.image_128)" class="o_event_full_page_ticket_event_logo mb-2"/>
</span>
<div t-if="attendee and attendee.partner_id" class="mb-2 o_event_full_page_ticket_side_info_booked_by">
<div class="o_event_full_page_ticket_font_faded o_event_full_page_ticket_small_caps font-weight-bold">Booked By</div>
<div class="o_event_full_page_ticket_small" t-field="attendee.partner_id"/>
</div>
</div>
</div>
</div>
<div class="o_event_full_page_ticket_barcode col-2">
<div class="o_event_full_page_ticket_barcode_container">
</div>
</div>
</div>
</div>
<div class="page oe_structure"/>
<div t-field="event.ticket_instructions" class="o_event_full_page_extra_instructions px-2 pt-3"></div>
</div>
</div>
</template>
<template id="event_report_full_page_ticket_layout">
<!-- Inspired from "external_layout_standard" to get a repeated footer element. -->
<div class="article"
t-att-data-oe-model="main_object and main_object._name"
t-att-data-oe-id="main_object and main_object.id"
t-att-data-oe-lang="main_object and main_object.env.context.get('lang')">
<main>
<t t-out="0"/>
</main>
</div>
<div class="row footer o_event_full_page_ticket_footer d-block">
<div class="o_event_full_page_ticket_powered_by text-white text-center p-2 w-100">
<t t-if="event.organizer_id">
<span class="font-weight-bold" t-field="event.organizer_id.name"></span>
<span t-if="event.organizer_id.phone" class="pl-3 fa fa-phone"/>
<span t-if="event.organizer_id.phone" t-field="event.organizer_id.phone"/>
<span t-if="event.organizer_id.email_normalized" class="pl-3 fa fa-envelope"/>
<span t-if="event.organizer_id.email_normalized" t-field="event.organizer_id.email_normalized"/>
<span t-if="event.organizer_id.website" class="pl-3 fa fa-globe"/>
<span t-if="event.organizer_id.website" t-field="event.organizer_id.website"/>
</t>
<t t-else="">
<span t-esc="event.name"/> <!-- Force some content to avoid messing the layout -->
</t>
</div>
</div>
</template>
<template id="event_registration_report_template_full_page_ticket">
<t t-foreach="docs" t-as="attendee">
<t t-call="web.html_container">
<t t-set="event" t-value="attendee.event_id._set_tz_context()"/>
<t t-set="main_object" t-value="attendee"/>
<t t-call="event.event_report_full_page_ticket_layout">
<t t-call="event.event_report_template_full_page_ticket"/>
</t>
</t>
</template>
</t>
</template>
<!-- template use to edit Event Badget (allow to set the HTML badge fields) -->
<template id="event_event_report_template_badge">
<t t-call="web.basic_layout">
<div class="page">
<t t-foreach="docs" t-as="event">
<div class="row">
<!-- Front -->
<div class="col-6 text-center" style="padding-left:7mm; border-right:1px dashed black; height: 149mm; padding-top: 7mm">
<div class="row" t-ignore="true">
<div class="col-12">
<span t-if="event.organizer_id.is_company and event.organizer_id.company_id.logo_web">
<div t-field="event.event_logo">
<img t-att-src="image_data_uri(event.organizer_id.company_id.logo_web)" style="max-height:1cm; max-width:4cm;" alt="Logo"/>
</div>
</span>
<h4 t-field="event.name"/>
<h5>( <i class="fa fa-clock-o" aria-label="Period" role="img" title="Period"></i> <span itemprop="startDate" t-field="event.date_begin" t-options='{"hide_seconds": True}'> </span> <i>to</i> <span itemprop="endDate" t-field="event.date_end" t-options='{"hide_seconds": True}'> </span> )</h5>
</div>
</div>
<div class="row" t-ignore="true">
<div class="col-12 text-center" id="o_event_attendee_name">
<small><h3>Attendee Name</h3></small>
</div>
</div>
<div class="row">
<div t-field="event.badge_front"></div>
</div>
</div>
<!-- Back -->
<div class="col-6" style="padding-right:7mm; height: 149mm; padding-top: 2mm;">
<div t-field="event.badge_back"/>
</div>
</div>
<div class="row">
<!-- Inner left -->
<div class="col-6 text-center" style="padding-right:7mm; border-top:1px dashed black; height: 148mm;">
<div t-field="event.badge_innerleft"/>
</div>
<!-- Inner right -->
<div class="col-6 text-center" style="border-left:1px dashed black; border-top:1px dashed black; height: 148mm; text-center">
<div t-field="event.badge_innerright"/>
</div>
</div>
</t>
</div>
<template id="event_event_report_template_full_page_ticket">
<t t-foreach="docs" t-as="event">
<t t-call="web.html_container">
<t t-set="event" t-value="event._set_tz_context()"/>
<t t-set="main_object" t-value="event"/>
<t t-call="event.event_report_full_page_ticket_layout">
<t t-call="event.event_report_template_full_page_ticket"/>
</t>
</t>
</template>
</t>
</template>
<!-- MISC -->
<template id="event_report_template_formatted_event_address">
<!-- Small utility template to display "Venue" as:
fa-map-marker PartnerName
RestOfAddress -->
<span class="fa fa-map-marker"/>
<t t-if="event.address_id.contact_address.strip()">
<t t-set="address_bits" t-value="event.address_id.contact_address.split('\n')"/>
<t t-if="address_bits">
<t t-set="partner_name" t-value="address_bits[0]"/>
<span t-esc="partner_name"/>
</t>
<t t-if="len(address_bits) > 1">
<br/>
</t>
<t t-set="remaining_bits" t-value="address_bits[1:]"/>
<t t-foreach="remaining_bits" t-as="address_bit">
<t t-if="address_bit and address_bit.strip()">
<span t-esc="address_bit"/>
</t>
</t>
</t>
<t t-else="" t-esc="event.address_id.name"/>
</template>
</odoo>
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

@@ -0,0 +1,70 @@
.o_event_foldable_badge_container {
.o_event_foldable_badge_top {
height: 148mm;
&.o_event_foldable_badge_ticket {
border-left: 1px dashed black;
}
}
.o_event_foldable_badge_font_small {
font-size: .8rem;
}
.o_event_foldable_badge_bottom.o_event_foldable_badge_left {
border-top: 1px dashed black;
height: 148mm;
p {
margin: 0px; // to match editor style (.oe_form_field_html p)
}
}
.o_event_foldable_badge_bottom.o_event_foldable_badge_right {
border-left: 1px dashed black;
border-top:1px dashed black;
height: 148mm;
background: white;
}
.o_event_foldable_badge_ticket {
background-repeat: no-repeat;
background-image: url(/event/static/src/img/report_foldable_badge_background.png);
.o_event_foldable_badge_ticket_wrapper {
background-color: white;
border: solid 1px #939393;
border-radius: .7rem;
margin: 0px 8px;
padding: 10px 3px;
font-size: 1.2rem;
box-shadow: -3px 3px 9px 0px rgba(0,0,0,0.51);
.o_event_foldable_badge_ticket_wrapper_top {
min-height: 80mm;
}
.o_event_foldable_badge_event_name {
color: $o-brand-odoo;
}
.o_event_foldable_badge_font_faded {
color: #939393;
}
.o_event_foldable_badge_barcode {
min-height: 35mm;
}
}
}
.o_event_foldable_badge_step {
position: absolute;
padding: 3px 9px;
top: 5mm;
left: 0mm;
border-radius: 50%;
background-color: black;
color: white;
}
}
@@ -0,0 +1,68 @@
.o_event_full_page_ticket_footer {
.o_event_full_page_ticket_powered_by {
background-color: $o-brand-odoo;
font-size: .8rem;
line-height: 1rem;
}
}
.o_event_full_page_ticket_container {
z-index: 1;
background-repeat: no-repeat;
background-image: url(/event/static/src/img/report_full_page_ticket_background.png);
padding: 40px 40px 0px 40px;
.o_event_full_page_ticket_font_faded {
color: #939393;
}
.o_event_full_page_ticket_small {
font-size: .8rem;
}
.o_event_full_page_ticket_small_caps {
text-transform: uppercase;
font-size: .8rem;
}
.o_event_full_page_ticket_wrapper {
z-index: 2;
.o_event_full_page_ticket_details {
background-color: white;
border: solid 1px #939393;
border-radius: .7rem;
margin: 0px 8px;
padding: 10px 3px;
box-shadow: -3px 3px 9px 0px rgba(0,0,0,0.51);
.o_event_full_page_ticket_event_name {
color: $o-brand-odoo;
}
.o_event_full_page_ticket_event_logo {
max-height: 50px;
}
.o_event_full_page_ticket_barcode {
padding-left: 30px;
.o_event_full_page_ticket_barcode_container {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
width: 67px;
img {
padding: 0px 10px;
}
}
}
}
}
.o_event_full_page_extra_instructions {
p {
margin: 0px; // to match editor style (.oe_form_field_html p)
}
}
}
@@ -0,0 +1,6 @@
// The PDF layout behaves slightly differently from the layout shown in the report editor.
// This file gaps the differences with some additional custom rules to get a pixel perfect layout.
.o_event_full_page_ticket_footer {
// make sure to take entire with, including the margin imposed by "container-fluid"
width: calc(100% + 30px) !important;
}
+9 -1
View File
@@ -64,6 +64,9 @@
</page>
<page string="Notes">
<field name="note"/>
<label for="ticket_instructions" string="Ticket Extra Instructions"></label>
<br/>
<field name="ticket_instructions" nolabel="1" class="pt-2"/>
</page>
</notebook>
</sheet>
@@ -222,7 +225,12 @@
</field>
</page>
<page string="Notes" name="event_notes">
<field name="note" placeholder="Add a note..."/>
<group>
<label for="note" string="Note"/><br/>
<field nolabel="1" colspan="2" name="note" placeholder="Add a note..."/>
<label for="ticket_instructions" string="Ticket Intructions"/><br/>
<field nolabel="1" colspan="2" name="ticket_instructions"/>
</group>
</page>
</notebook>
</sheet>
@@ -1,24 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="event_registration_report_template_badge" inherit_id="event.event_registration_report_template_badge">
<xpath expr="//div[@id='o_event_name']" position="inside">
<div t-if="o.event_ticket_id" class="col-12 text-center" style="padding:0px;">
<div style="background: lightgrey; height: 65px;" class="mt16 text-center">
<h3><span t-field="o.event_ticket_id"/></h3>
</div>
<template id="event_report_template_full_page_ticket_inherit_sale" inherit_id="event.event_report_template_full_page_ticket">
<xpath expr="//div[hasclass('o_event_full_page_ticket_side_info_booked_by')]" position="before">
<div t-if="attendee and attendee.sale_order_id" class="mb-2">
<div class="o_event_full_page_ticket_font_faded o_event_full_page_ticket_small_caps font-weight-bold">Order Ref</div>
<div class="o_event_full_page_ticket_small" t-field="attendee.sale_order_id"/>
</div>
</xpath>
<xpath expr="//div[hasclass('o_event_full_page_ticket_side_info')]" position="inside">
<div t-if="attendee and attendee.sale_order_id" class="mb-2">
<div class="o_event_full_page_ticket_font_faded o_event_full_page_ticket_small_caps font-weight-bold">Order Date</div>
<div class="o_event_full_page_ticket_small" t-esc="attendee.sale_order_id.date_order.date()"/>
</div>
<div t-if="attendee and attendee.sale_order_line_id.price_total">
<div class="o_event_full_page_ticket_font_faded o_event_full_page_ticket_small_caps font-weight-bold">Price</div>
<div class="o_event_full_page_ticket_small" t-field="attendee.sale_order_line_id.price_total"
t-options="{'widget': 'monetary', 'display_currency': attendee.sale_order_line_id.currency_id}"/>
</div>
</xpath>
</template>
<template id="event_event_report_template_badge" inherit_id="event.event_event_report_template_badge">
<xpath expr="//div[@id='o_event_attendee_name']" position="inside">
<div t-if="bool(len(event.event_ticket_ids))" class="col-12" style="padding: 0px;" t-ignore="true">
<div style="background: lightgrey; height: 65px;" class="mt16 text-center">
<h3>Ticket Type</h3>
</div>
</div>
</xpath>
</template>
</odoo>
@@ -38,7 +38,8 @@
<xpath expr="//div[@name='button_box']" position="inside">
<button name="action_view_sale_order" type="object"
class="oe_stat_button" icon="fa-usd" string="Sale Order"
groups="sales_team.group_sale_salesman">
groups="sales_team.group_sale_salesman"
attrs="{'invisible': [('sale_order_id', '=', False)]}">
</button>
</xpath>
<xpath expr="//group" position="before">
@@ -395,15 +395,6 @@ class Event(models.Model):
return self.env.ref('website_event.mt_event_unpublished')
return super(Event, self)._track_subtype(init_values)
def action_open_badge_editor(self):
""" open the event badge editor : redirect to the report page of event badge report """
self.ensure_one()
return {
'type': 'ir.actions.act_url',
'target': 'new',
'url': '/report/html/%s/%s?enable_editor' % ('event.event_event_report_template_badge', self.id),
}
def _get_event_resource_urls(self):
url_date_start = self.date_begin.strftime('%Y%m%dT%H%M%SZ')
url_date_stop = self.date_end.strftime('%Y%m%dT%H%M%SZ')
@@ -14,11 +14,6 @@
<field name="website_url" invisible="1"/>
<field name="is_published" widget="website_redirect_button"/>
</div>
<xpath expr="//field[@name='stage_id']" position="before">
<button name="action_open_badge_editor"
type="object"
string="Preview Badges"/>
</xpath>
<xpath expr="//div[hasclass('oe_title')]" position="after">
<div name="event_menu_configuration" groups="base.group_no_one">
<label for="website_menu" string="Website Submenu"/>
@@ -18,6 +18,8 @@
'security/security.xml',
'security/ir.model.access.csv',
'data/event_sponsor_data.xml',
'report/website_event_exhibitor_reports.xml',
'report/website_event_exhibitor_templates.xml',
'views/event_templates_sponsor.xml',
'views/event_sponsor_views.xml',
'views/event_event_views.xml',
@@ -39,6 +41,9 @@
'website_event_exhibitor/static/src/js/event_exhibitor_connect.js',
'website_event_exhibitor/static/src/js/event_sponsor_search.js',
],
'web.report_assets_common': [
'/website_event_exhibitor/static/src/scss/event_full_page_ticket_report.scss',
],
},
'license': 'LGPL-3',
}
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="event.paperformat_event_full_page_ticket" model="report.paperformat">
<!-- Increase bottom margin to leave room to display the sponsor images -->
<field name="margin_bottom">29</field>
</record>
</odoo>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="event_report_full_page_ticket_layout_inherit_exhibitor" inherit_id="event.event_report_full_page_ticket_layout">
<xpath expr="//div[hasclass('o_event_full_page_ticket_powered_by')]" position="before">
<div class="o_event_full_page_ticket_sponsors_container text-center mb-2">
<t t-foreach="event.sponsor_ids.filtered(lambda sponsor: sponsor.image_128 and sponsor.website_published)[:10]"
t-as="sponsor">
<div class="o_event_full_page_ticket_sponsor_card d-inline-block">
<div class="h-100 p-2 pb-0">
<!-- Has to be base64-ified otherwise the reporting engine will sometimes load images
and sometimes not before printing, resulting in random results. -->
<img class="img img-fluid" t-attf-src="data:images/png;base64,#{sponsor.image_128}"/>
</div>
</div>
</t>
</div>
</xpath>
</template>
</odoo>
@@ -0,0 +1,9 @@
.o_event_full_page_ticket_footer {
.o_event_full_page_ticket_sponsors_container {
min-height: 70px;
.o_event_full_page_ticket_sponsor_card {
max-height: 70px;
max-width: 70px;
}
}
}