Ticket Generator opérational
This commit is contained in:
parent
f0ec02c295
commit
777b4e4835
|
|
@ -0,0 +1,231 @@
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
{# <link rel="stylesheet" href="{% static 'ticket/ticket.css' %}"/>#}
|
||||||
|
|
||||||
|
<title>Boarding ticket</title>
|
||||||
|
<meta name="description" content="Boarding ticket">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: Libre Barcode;
|
||||||
|
src: url({% static 'ticket/librebarcode128-regular.ttf' %});
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
src: url({% static 'ticket/barlowcondensed-regular.otf' %});
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
font-weight: 300;
|
||||||
|
src: url({% static 'ticket/barlowcondensed-light.otf' %});
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url({% static 'ticket/barlowcondensed-bold.otf' %});
|
||||||
|
}
|
||||||
|
|
||||||
|
@page {
|
||||||
|
margin: 0;
|
||||||
|
size: landscape;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: #fff;
|
||||||
|
display: flex;
|
||||||
|
font-family: Barlow Condensed, sans-serif;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: #eef1f5;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #2A3239;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
height: 8cm;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0;
|
||||||
|
width: 25cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl {
|
||||||
|
columns: 4;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-size: 9pt;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations h1 {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 25pt;
|
||||||
|
font-weight: 300;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations #name {
|
||||||
|
margin-left: 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations #destination {
|
||||||
|
position: absolute;
|
||||||
|
right: 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations dl {
|
||||||
|
background: #2A3239;
|
||||||
|
color: #fff;
|
||||||
|
margin: 0;
|
||||||
|
padding: 1cm 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations dd {
|
||||||
|
border-left: 1pt solid #fff;
|
||||||
|
font-size: 35pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations dd:first-of-type {
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations ul {
|
||||||
|
margin-left: 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations li {
|
||||||
|
font-weight: 300;
|
||||||
|
padding: 0.15cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations li:first-of-type {
|
||||||
|
background: #2A3239;
|
||||||
|
border-radius: 4pt;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations li:last-of-type {
|
||||||
|
font-family: Libre Barcode, cursive;
|
||||||
|
color: black;
|
||||||
|
font-size: 25pt;
|
||||||
|
margin-left: auto;
|
||||||
|
padding-right: 1cm;
|
||||||
|
padding-top: 0.5cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket {
|
||||||
|
border-left: 1pt dashed #2A3239;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 8cm;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 0 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket h2 {
|
||||||
|
font-weight: 300;
|
||||||
|
margin: 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket p {
|
||||||
|
font-family: Libre Barcode, cursive;
|
||||||
|
font-size: 25pt;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket dl {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket li {
|
||||||
|
margin: 0 0.25cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<section id="informations">
|
||||||
|
<h1 id="name">{{ ticket.first_name }} {{ ticket.last_name }}</h1>
|
||||||
|
<h1 id="destination">{{ ticket.reservation.event.name }}</h1>
|
||||||
|
<dl>
|
||||||
|
<dt>Flight</dt>
|
||||||
|
<dd>DL31</dd>
|
||||||
|
<dt>Gate</dt>
|
||||||
|
<dd>29</dd>
|
||||||
|
<dt>Seat</dt>
|
||||||
|
<dd>26E</dd>
|
||||||
|
<dt>Zone</dt>
|
||||||
|
<dd>4</dd>
|
||||||
|
</dl>
|
||||||
|
<ul>
|
||||||
|
<li>5:10pm</li>
|
||||||
|
<li>Dec 15, 2018</li>
|
||||||
|
<li>Coach</li>
|
||||||
|
<li>PROUTPROUT</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="ticket">
|
||||||
|
<p>1257797706706</p>
|
||||||
|
<h2>{{ ticket.first_name }} {{ ticket.last_name }}</h2>
|
||||||
|
<dl>
|
||||||
|
<dt>Flight</dt>
|
||||||
|
<dd>DL31</dd>
|
||||||
|
<dt>Gate</dt>
|
||||||
|
<dd>29</dd>
|
||||||
|
<dt>Seat</dt>
|
||||||
|
<dd>26E</dd>
|
||||||
|
<dt>Zone</dt>
|
||||||
|
<dd>4</dd>
|
||||||
|
</dl>
|
||||||
|
<ul>
|
||||||
|
<li>{{ ticket.reservation.event.name }}</li>
|
||||||
|
<li>5:10pm</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -2,7 +2,14 @@
|
||||||
{{ img_svg | safe }}
|
{{ img_svg | safe }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#<object type="image/svg+xml" data="data:image/svg+xml;base64,{{ img_svg64 }}">#}
|
||||||
|
{# fallback#}
|
||||||
|
{#</object>#}
|
||||||
|
|
||||||
<object type="image/svg+xml" data="data:image/svg+xml;base64,{{ img_svg64 }}">
|
{#<div>#}
|
||||||
|
{# {{ bar_svg | safe }}#}
|
||||||
|
{#</div>#}
|
||||||
|
|
||||||
|
<object type="image/svg+xml" data="data:image/svg+xml;base64,{{ bar_svg64 }}">
|
||||||
fallback
|
fallback
|
||||||
</object>
|
</object>
|
||||||
|
|
|
||||||
|
|
@ -1,235 +1,24 @@
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
{% load static %}
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|
||||||
<title>Boarding ticket</title>
|
<title>Boarding ticket</title>
|
||||||
<meta name="description" content="Boarding ticket">
|
<meta name="description" content="Boarding ticket">
|
||||||
|
|
||||||
<style>
|
|
||||||
@font-face {
|
|
||||||
font-family: Libre Barcode;
|
|
||||||
src: url(librebarcode128-regular.ttf);
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: Barlow Condensed;
|
|
||||||
src: url(barlowcondensed-regular.otf);
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: Barlow Condensed;
|
|
||||||
font-weight: 300;
|
|
||||||
src: url(barlowcondensed-light.otf);
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: Barlow Condensed;
|
|
||||||
font-weight: 700;
|
|
||||||
src: url(barlowcondensed-bold.otf);
|
|
||||||
}
|
|
||||||
|
|
||||||
@page {
|
|
||||||
margin: 0;
|
|
||||||
size: landscape;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
align-content: center;
|
|
||||||
align-items: center;
|
|
||||||
background: #fff;
|
|
||||||
display: flex;
|
|
||||||
font-family: Barlow Condensed, sans-serif;
|
|
||||||
height: 100%;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background: #eef1f5;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
color: #2A3239;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
height: 8cm;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin: 0;
|
|
||||||
width: 25cm;
|
|
||||||
}
|
|
||||||
|
|
||||||
section {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl {
|
|
||||||
columns: 4;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt {
|
|
||||||
font-size: 9pt;
|
|
||||||
font-weight: 700;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
font-weight: 700;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations h1 {
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 25pt;
|
|
||||||
font-weight: 300;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations #name {
|
|
||||||
margin-left: 1cm;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations #destination {
|
|
||||||
position: absolute;
|
|
||||||
right: 1cm;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations dl {
|
|
||||||
background: #2A3239;
|
|
||||||
color: #fff;
|
|
||||||
margin: 0;
|
|
||||||
padding: 1cm 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations dd {
|
|
||||||
border-left: 1pt solid #fff;
|
|
||||||
font-size: 35pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations dd:first-of-type {
|
|
||||||
border-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations ul {
|
|
||||||
margin-left: 1cm;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations li {
|
|
||||||
font-weight: 300;
|
|
||||||
padding: 0.15cm;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations li:first-of-type {
|
|
||||||
background: #2A3239;
|
|
||||||
border-radius: 4pt;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#informations li:last-of-type {
|
|
||||||
font-family: Libre Barcode, cursive;
|
|
||||||
color: black;
|
|
||||||
font-size: 25pt;
|
|
||||||
margin-left: auto;
|
|
||||||
padding-right: 1cm;
|
|
||||||
padding-top: 0.5cm;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ticket {
|
|
||||||
border-left: 1pt dashed #2A3239;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 8cm;
|
|
||||||
justify-content: space-around;
|
|
||||||
padding: 0 1cm;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ticket h2 {
|
|
||||||
font-weight: 300;
|
|
||||||
margin: 0;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ticket p {
|
|
||||||
font-family: Libre Barcode, cursive;
|
|
||||||
font-size: 25pt;
|
|
||||||
margin: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ticket dl {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ticket li {
|
|
||||||
margin: 0 0.25cm;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div>
|
|
||||||
{{ img_svg | safe }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<section id="informations">
|
<section id="informations">
|
||||||
<h1 id="name">{{ ticket.first_name }} {{ ticket.last_name }}</h1>
|
|
||||||
<h1 id="destination">{{ ticket.reservation.event.name }}</h1>
|
|
||||||
<dl>
|
|
||||||
<dt>IMG</dt>
|
|
||||||
<dd>Prout</dd>
|
|
||||||
<dt>Gate</dt>
|
|
||||||
<dd>img_svg</dd>
|
|
||||||
<dt>Seat</dt>
|
|
||||||
<dd>26E</dd>
|
|
||||||
<dt>Zone</dt>
|
|
||||||
<dd>4</dd>
|
|
||||||
</dl>
|
|
||||||
<ul>
|
|
||||||
<li>5:10pm</li>
|
|
||||||
<li>Dec 15, 2018</li>
|
|
||||||
<li>Coach</li>
|
|
||||||
<li>PROUTPROUT</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="ticket">
|
<h1>{{ ticket.first_name }} {{ ticket.last_name }}</h1>
|
||||||
<p>proutproutprout</p>
|
<h1>{{ config.organisation }}</h1>
|
||||||
<h2>{{ ticket.first_name }} {{ ticket.last_name }}</h2>
|
<h1>{{ ticket.reservation.event.name }}</h1>
|
||||||
<dl>
|
<h1>{{ ticket.reservation.event.datetime }}</h1>
|
||||||
<dt>Flight</dt>
|
<h1>Siège : {{ ticket.seat }}</h1>
|
||||||
<dd>DL31</dd>
|
<h1>Numéro de billet : {{ ticket.numero_uuid }}</h1>
|
||||||
<dt>Gate</dt>
|
|
||||||
<dd>29</dd>
|
|
||||||
<dt>Seat</dt>
|
|
||||||
<dd>26E</dd>
|
|
||||||
<dt>Zone</dt>
|
|
||||||
<dd>4</dd>
|
|
||||||
</dl>
|
|
||||||
<ul>
|
|
||||||
<li>{{ ticket.reservation.event.name }}</li>
|
|
||||||
<li>5:10pm</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
<div>{{ img_svg | safe }}</div>
|
||||||
|
<div>{{ bar_svg | safe }}</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,9 @@ class Ticket(models.Model):
|
||||||
datetime.short_description = 'Date de reservation'
|
datetime.short_description = 'Date de reservation'
|
||||||
datetime.admin_order_field = 'reservation__datetime'
|
datetime.admin_order_field = 'reservation__datetime'
|
||||||
|
|
||||||
|
def numero_uuid(self):
|
||||||
|
return f"{self.uuid}".split('-')[0]
|
||||||
|
|
||||||
class meta:
|
class meta:
|
||||||
ordering = ('-datetime',)
|
ordering = ('-datetime',)
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,15 @@
|
||||||
|
<div>
|
||||||
|
{{ img_svg | safe }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#<object type="image/svg+xml" data="data:image/svg+xml;base64,{{ img_svg64 }}">#}
|
||||||
|
{# fallback#}
|
||||||
|
{#</object>#}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{ bar_svg | safe }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#<object type="image/svg+xml" data="data:image/svg+xml;base64,{{ bar_svg64 }}">#}
|
||||||
|
{# fallback#}
|
||||||
|
{#</object>#}
|
||||||
|
|
@ -0,0 +1,151 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: Libre Barcode;
|
||||||
|
src: url(librebarcode128-regular.ttf);
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
src: url(barlowcondensed-regular.otf);
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
font-weight: 300;
|
||||||
|
src: url(barlowcondensed-light.otf);
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(barlowcondensed-bold.otf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@page {
|
||||||
|
margin: 0;
|
||||||
|
size: landscape;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: #fff;
|
||||||
|
display: flex;
|
||||||
|
font-family: Barlow Condensed, sans-serif;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #eef1f5;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #2A3239;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
height: 8cm;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0;
|
||||||
|
width: 25cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl {
|
||||||
|
columns: 4;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
dt {
|
||||||
|
font-size: 9pt;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
dd {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
#informations h1 {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 25pt;
|
||||||
|
font-weight: 300;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
#informations #name {
|
||||||
|
margin-left: 1cm;
|
||||||
|
}
|
||||||
|
#informations #destination {
|
||||||
|
position: absolute;
|
||||||
|
right: 1cm;
|
||||||
|
}
|
||||||
|
#informations dl {
|
||||||
|
background: #2A3239;
|
||||||
|
color: #fff;
|
||||||
|
margin: 0;
|
||||||
|
padding: 1cm 0;
|
||||||
|
}
|
||||||
|
#informations dd {
|
||||||
|
border-left: 1pt solid #fff;
|
||||||
|
font-size: 35pt;
|
||||||
|
}
|
||||||
|
#informations dd:first-of-type {
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
#informations ul {
|
||||||
|
margin-left: 1cm;
|
||||||
|
}
|
||||||
|
#informations li {
|
||||||
|
font-weight: 300;
|
||||||
|
padding: 0.15cm;
|
||||||
|
}
|
||||||
|
#informations li:first-of-type {
|
||||||
|
background: #2A3239;
|
||||||
|
border-radius: 4pt;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
#informations li:last-of-type {
|
||||||
|
font-family: Libre Barcode, cursive;
|
||||||
|
color: black;
|
||||||
|
font-size: 25pt;
|
||||||
|
margin-left: auto;
|
||||||
|
padding-right: 1cm;
|
||||||
|
padding-top: 0.5cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket {
|
||||||
|
border-left: 1pt dashed #2A3239;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 8cm;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 0 1cm;
|
||||||
|
}
|
||||||
|
#ticket h2 {
|
||||||
|
font-weight: 300;
|
||||||
|
margin: 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
#ticket p {
|
||||||
|
font-family: Libre Barcode, cursive;
|
||||||
|
font-size: 25pt;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#ticket dl {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#ticket li {
|
||||||
|
margin: 0 0.25cm;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,231 @@
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
{# <link rel="stylesheet" href="{% static 'ticket/ticket.css' %}"/>#}
|
||||||
|
|
||||||
|
<title>Boarding ticket</title>
|
||||||
|
<meta name="description" content="Boarding ticket">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: Libre Barcode;
|
||||||
|
src: url({% static 'ticket/librebarcode128-regular.ttf' %});
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
src: url(barlowcondensed-regular.otf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
font-weight: 300;
|
||||||
|
src: url(barlowcondensed-light.otf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Barlow Condensed;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(barlowcondensed-bold.otf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@page {
|
||||||
|
margin: 0;
|
||||||
|
size: landscape;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: #fff;
|
||||||
|
display: flex;
|
||||||
|
font-family: Barlow Condensed, sans-serif;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: #eef1f5;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #2A3239;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
height: 8cm;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0;
|
||||||
|
width: 25cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl {
|
||||||
|
columns: 4;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-size: 9pt;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations h1 {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 25pt;
|
||||||
|
font-weight: 300;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations #name {
|
||||||
|
margin-left: 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations #destination {
|
||||||
|
position: absolute;
|
||||||
|
right: 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations dl {
|
||||||
|
background: #2A3239;
|
||||||
|
color: #fff;
|
||||||
|
margin: 0;
|
||||||
|
padding: 1cm 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations dd {
|
||||||
|
border-left: 1pt solid #fff;
|
||||||
|
font-size: 35pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations dd:first-of-type {
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations ul {
|
||||||
|
margin-left: 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations li {
|
||||||
|
font-weight: 300;
|
||||||
|
padding: 0.15cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations li:first-of-type {
|
||||||
|
background: #2A3239;
|
||||||
|
border-radius: 4pt;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#informations li:last-of-type {
|
||||||
|
font-family: Libre Barcode, cursive;
|
||||||
|
color: black;
|
||||||
|
font-size: 25pt;
|
||||||
|
margin-left: auto;
|
||||||
|
padding-right: 1cm;
|
||||||
|
padding-top: 0.5cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket {
|
||||||
|
border-left: 1pt dashed #2A3239;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 8cm;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 0 1cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket h2 {
|
||||||
|
font-weight: 300;
|
||||||
|
margin: 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket p {
|
||||||
|
font-family: Libre Barcode, cursive;
|
||||||
|
font-size: 25pt;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket dl {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ticket li {
|
||||||
|
margin: 0 0.25cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<section id="informations">
|
||||||
|
<h1 id="name">{{ ticket.first_name }} {{ ticket.last_name }}</h1>
|
||||||
|
<h1 id="destination">{{ ticket.reservation.event.name }}</h1>
|
||||||
|
<dl>
|
||||||
|
<dt>Flight</dt>
|
||||||
|
<dd>DL31</dd>
|
||||||
|
<dt>Gate</dt>
|
||||||
|
<dd>29</dd>
|
||||||
|
<dt>Seat</dt>
|
||||||
|
<dd>26E</dd>
|
||||||
|
<dt>Zone</dt>
|
||||||
|
<dd>4</dd>
|
||||||
|
</dl>
|
||||||
|
<ul>
|
||||||
|
<li>5:10pm</li>
|
||||||
|
<li>Dec 15, 2018</li>
|
||||||
|
<li>Coach</li>
|
||||||
|
<li>PROUTPROUT</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="ticket">
|
||||||
|
<p>1257797706706</p>
|
||||||
|
<h2>{{ ticket.first_name }} {{ ticket.last_name }}</h2>
|
||||||
|
<dl>
|
||||||
|
<dt>Flight</dt>
|
||||||
|
<dd>DL31</dd>
|
||||||
|
<dt>Gate</dt>
|
||||||
|
<dd>29</dd>
|
||||||
|
<dt>Seat</dt>
|
||||||
|
<dd>26E</dd>
|
||||||
|
<dt>Zone</dt>
|
||||||
|
<dd>4</dd>
|
||||||
|
</dl>
|
||||||
|
<ul>
|
||||||
|
<li>{{ ticket.reservation.event.name }}</li>
|
||||||
|
<li>5:10pm</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Binary file not shown.
|
|
@ -1,7 +1,9 @@
|
||||||
|
import base64
|
||||||
import os
|
import os
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import base64
|
|
||||||
import segno
|
import segno
|
||||||
|
import barcode
|
||||||
|
from djoser import utils
|
||||||
|
|
||||||
from weasyprint import HTML, CSS
|
from weasyprint import HTML, CSS
|
||||||
from weasyprint.text.fonts import FontConfiguration
|
from weasyprint.text.fonts import FontConfiguration
|
||||||
|
|
@ -35,6 +37,7 @@ class CeleryMailerClass():
|
||||||
self.config = Configuration.get_solo()
|
self.config = Configuration.get_solo()
|
||||||
self.context = context
|
self.context = context
|
||||||
self.attached_files = attached_files
|
self.attached_files = attached_files
|
||||||
|
self.sended = None
|
||||||
|
|
||||||
if template and context:
|
if template and context:
|
||||||
self.html = render_to_string(template, context=context)
|
self.html = render_to_string(template, context=context)
|
||||||
|
|
@ -68,9 +71,11 @@ class CeleryMailerClass():
|
||||||
mail_return = mail.send(fail_silently=False)
|
mail_return = mail.send(fail_silently=False)
|
||||||
|
|
||||||
if mail_return == 1:
|
if mail_return == 1:
|
||||||
|
self.sended = True
|
||||||
logger.info(f' mail envoyé : {mail_return} - {self.email}')
|
logger.info(f' mail envoyé : {mail_return} - {self.email}')
|
||||||
else:
|
else:
|
||||||
logger.error(f' mail non envoyé : {mail_return} - {self.email}')
|
logger.error(f' mail non envoyé : {mail_return} - {self.email}')
|
||||||
|
|
||||||
return mail_return
|
return mail_return
|
||||||
else:
|
else:
|
||||||
logger.error(f'Pas de contenu HTML ou de configuration email valide')
|
logger.error(f'Pas de contenu HTML ou de configuration email valide')
|
||||||
|
|
@ -79,32 +84,38 @@ class CeleryMailerClass():
|
||||||
|
|
||||||
|
|
||||||
def create_ticket_pdf(ticket: Ticket):
|
def create_ticket_pdf(ticket: Ticket):
|
||||||
qr = segno.make(f'{ticket.uuid}')
|
qr = segno.make(f"{ticket.uuid}", micro=False)
|
||||||
|
|
||||||
buffer_png = BytesIO()
|
|
||||||
qr.save(buffer_png, kind='PNG', scale=15)
|
|
||||||
img_str = base64.b64encode(buffer_png.getvalue()).decode('utf-8')
|
|
||||||
|
|
||||||
buffer_svg = BytesIO()
|
buffer_svg = BytesIO()
|
||||||
qr.save(buffer_svg, kind='svg', scale=10)
|
qr.save(buffer_svg, kind='svg', scale=8)
|
||||||
|
|
||||||
|
CODE128 = barcode.get_barcode_class('code128')
|
||||||
|
bar_svg = BytesIO()
|
||||||
|
bar_secret = utils.encode_uid(f"{ticket.uuid}".split('-')[4])
|
||||||
|
|
||||||
|
bar = CODE128(f"{bar_secret}")
|
||||||
|
options = {
|
||||||
|
'module_height': 30,
|
||||||
|
'module_width': 0.6,
|
||||||
|
'font_size': 10,
|
||||||
|
}
|
||||||
|
bar.write(bar_svg, options = options)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'ticket': ticket,
|
'ticket': ticket,
|
||||||
'config': Configuration.get_solo(),
|
'config': Configuration.get_solo(),
|
||||||
'img_str': base64.b64encode(buffer_png.getvalue()).decode('utf-8'),
|
|
||||||
'img_svg': buffer_svg.getvalue().decode('utf-8'),
|
'img_svg': buffer_svg.getvalue().decode('utf-8'),
|
||||||
'img_svg64': base64.b64encode(buffer_svg.getvalue()).decode('utf-8'),
|
'bar_svg': bar_svg.getvalue().decode('utf-8'),
|
||||||
|
# 'bar_svg64': base64.b64encode(bar_svg.getvalue()).decode('utf-8'),
|
||||||
}
|
}
|
||||||
|
|
||||||
template_name = 'ticket/ticket.html'
|
template_name = 'ticket/ticket.html'
|
||||||
# template_name = 'ticket/qrtest.html'
|
# template_name = 'ticket/example_flight_ticket.html'
|
||||||
font_config = FontConfiguration()
|
font_config = FontConfiguration()
|
||||||
|
|
||||||
template = get_template(template_name)
|
template = get_template(template_name)
|
||||||
|
|
||||||
html = template.render(context)
|
html = template.render(context)
|
||||||
|
|
||||||
|
|
||||||
css = CSS(string=
|
css = CSS(string=
|
||||||
'''
|
'''
|
||||||
@font-face {
|
@font-face {
|
||||||
|
|
@ -130,7 +141,7 @@ def create_ticket_pdf(ticket: Ticket):
|
||||||
|
|
||||||
pdf_binary = HTML(string=html).write_pdf(
|
pdf_binary = HTML(string=html).write_pdf(
|
||||||
stylesheets=[css],
|
stylesheets=[css],
|
||||||
font_config=font_config
|
font_config=font_config,
|
||||||
)
|
)
|
||||||
|
|
||||||
return pdf_binary
|
return pdf_binary
|
||||||
|
|
@ -138,11 +149,6 @@ def create_ticket_pdf(ticket: Ticket):
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def ticket_celery_mailer(reservation_uuid: str):
|
def ticket_celery_mailer(reservation_uuid: str):
|
||||||
'''
|
|
||||||
for ticket in reservation.tickets.filter(status=Ticket.NOT_SCANNED):
|
|
||||||
response = requests.get(ticket.pdf_url())
|
|
||||||
print(response.status_code)
|
|
||||||
'''
|
|
||||||
|
|
||||||
config = Configuration.get_solo()
|
config = Configuration.get_solo()
|
||||||
reservation = Reservation.objects.get(pk=reservation_uuid)
|
reservation = Reservation.objects.get(pk=reservation_uuid)
|
||||||
|
|
@ -163,7 +169,13 @@ def ticket_celery_mailer(reservation_uuid: str):
|
||||||
attached_files=attached_files,
|
attached_files=attached_files,
|
||||||
)
|
)
|
||||||
mail.send()
|
mail.send()
|
||||||
return True
|
|
||||||
|
logger.info(f"mail.sended : {mail.sended}")
|
||||||
|
if mail.sended :
|
||||||
|
reservation.mail_send = True
|
||||||
|
reservation.status = Reservation.VALID
|
||||||
|
reservation.save()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{timezone.now()} Erreur envoie de mail pour reservation {reservation} : {e}")
|
logger.error(f"{timezone.now()} Erreur envoie de mail pour reservation {reservation} : {e}")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ from BaseBillet.models import Configuration, Event, Ticket
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import segno
|
import segno
|
||||||
|
import barcode
|
||||||
|
from djoser import utils
|
||||||
|
|
||||||
from io import StringIO, BytesIO
|
from io import StringIO, BytesIO
|
||||||
|
|
||||||
from django.template import engines
|
from django.template import engines
|
||||||
|
|
@ -47,20 +50,31 @@ class Ticket_html_view(APIView):
|
||||||
|
|
||||||
ticket = get_object_or_404(Ticket, uuid=pk_uuid)
|
ticket = get_object_or_404(Ticket, uuid=pk_uuid)
|
||||||
|
|
||||||
qr = segno.make(f'{ticket.uuid}')
|
qr = segno.make(f"{ticket.uuid}", micro=False)
|
||||||
|
|
||||||
buffer_png = BytesIO()
|
|
||||||
qr.save(buffer_png, kind='PNG', scale=3)
|
|
||||||
|
|
||||||
buffer_svg = BytesIO()
|
buffer_svg = BytesIO()
|
||||||
qr.save(buffer_svg, kind='svg', scale=10)
|
qr.save(buffer_svg, kind='svg', scale=8)
|
||||||
|
|
||||||
|
CODE128 = barcode.get_barcode_class('code128')
|
||||||
|
buffer_barcode_SVG = BytesIO()
|
||||||
|
bar_secret = utils.encode_uid(f"{ticket.uuid}".split('-')[4])
|
||||||
|
|
||||||
|
bar = CODE128(f"{bar_secret}")
|
||||||
|
options = {
|
||||||
|
'module_height': 30,
|
||||||
|
'module_width': 0.6,
|
||||||
|
'font_size': 10,
|
||||||
|
}
|
||||||
|
bar.write(buffer_barcode_SVG, options=options)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'ticket': ticket,
|
'ticket': ticket,
|
||||||
'config': Configuration.get_solo(),
|
'config': Configuration.get_solo(),
|
||||||
'img_str': base64.b64encode(buffer_png.getvalue()).decode('utf-8'),
|
|
||||||
'img_svg': buffer_svg.getvalue().decode('utf-8'),
|
'img_svg': buffer_svg.getvalue().decode('utf-8'),
|
||||||
'img_svg64': base64.b64encode(buffer_svg.getvalue()).decode('utf-8'),
|
# 'img_svg64': base64.b64encode(buffer_svg.getvalue()).decode('utf-8'),
|
||||||
|
'bar_svg': buffer_barcode_SVG.getvalue().decode('utf-8'),
|
||||||
|
# 'bar_svg64': base64.b64encode(buffer_barcode_SVG.getvalue()).decode('utf-8'),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'ticket/ticket.html', context=context)
|
return render(request, 'ticket/ticket.html', context=context)
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ RUN pip install redis
|
||||||
RUN pip install tenant-schemas-celery
|
RUN pip install tenant-schemas-celery
|
||||||
|
|
||||||
RUN pip install segno
|
RUN pip install segno
|
||||||
|
RUN pip install python-barcode
|
||||||
|
|
||||||
RUN apt-get -y clean
|
RUN apt-get -y clean
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue