add langs pdf and split from file-scheme

This commit is contained in:
Cayo Puigdefabregas 2024-03-14 19:18:19 +01:00
parent fd27e82203
commit 92e9517b7e
8 changed files with 551 additions and 36 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1,126 @@
{% load i18n static %}
<!DOCTYPE html>
<html>
<head>
<title>Certificat</title>
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
<link rel="stylesheet" href= "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<link href="{% static "/css/bootstrap.min.css" %}" rel="stylesheet">
<style type="text/css" media="all">
@page {
size: A4 portrait; /* can use also 'landscape' for orientation */
margin: 1.0cm 1.5cm 3.5cm 1.5cm;
font-family: "Source Sans Pro", Calibri, Candra, Sans serif;
@top {
content: element(header);
}
@bottom {
content: element(footer);
}
}
body {
width: 100% !important;
height: 100%;
background: #fff;
color: black;
font-size: 100%;
line-height: 1.65;
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
}
header {
position: running(header);
/*height: 100px;*/
font-size: 12px;
/* color: #000; */
font-family: Arial;
width: 100%;
/* position: relative;*/
}
footer {
position: running(footer);
/*height: 150px;*/
}
.body_content {
position: relative;
page-break-inside: auto;
width: 100%;
/*overflow: hidden;*/
}
img {max-height: 150px; width: auto;}
.company-logo {float: left;}
.customer-logo {float: right;}
.page-break:not(section:first-of-type) {
page-break-before: always
}
}
</style>
</head>
<body>
<div class="container body-content">
<div class="row">
<div class="col">
<img style="width: 100%; height: auto;" src="data:image/jpeg;base64,{{ image_header }}" />
</div>
</div>
<div class="row mt-3">
<div class="col-12" style="text-align: center;">
<b>
<span style="color: #ea5e0f;">LAFEDE.CAT ORGANITZACIONS PER A LA JUSTÍCIA GLOBAL</span><br />CERTIFICA QUE:</b><br />
<b>{{ firstName }} {{ lastName }}</b> amb DNI <b>{{ document_id|default:"falta el dni" }}</b><br/>
Ha realitzat el curs <b>{{ courseName }}</b>, a {{ address|default:"falta address" }} / de manera {{ modeOfInstruction }}, els dies {{ date_course|default:"falta fecha del curso" }}<br />
La durada del curs ha estat de {{ courseDuration }} hores lectives corresponents a {{ courseDays }} sessions.<br />
<br />
<br />
<br />
</div>
<div class="col-12" style="text-align: left;">
I per deixar-ne constància als efectes oportuns, signo el present certificat en data de {{ issuedDate }}
</div>
</div>
<div class="row" style="padding-top: 20px;">
<div class="col-12">
<img style="width: 129px; height: 88px;" src="data:image/jpeg;base64,{{ image_signature }}" />
</div>
</div>
<div class="row" style="padding-top: 20px;">
<div class="col-12">
Pepa Martínez Peyrats<br />
Directora<br />
Lafede.cat - Federació d'Organitzacions per a la Justícia Global
</div>
</div>
{% if qr %}
<div class="row" style="padding-top: 20px;">
<div class="col-12">
<img style="width: 129px; height: 129px;" src="data:image/jpeg;base64,{{ qr }}" />
</div>
</div>
{% endif %}
<div class="row" style="padding-top: 20px;">
<div class="col" style="display: flex; justify-content: space-between;">
<span style="color: #ea5e0f;">Organitza:</span>
<span style="color: #ea5e0f;">Amb el suport de:</span>
<span style="color: #ea5e0f;">Amb la col·laboració de:</span>
</div>
<div class="col">
<div class="row">
<img style="width: auto; height: 50px;" src="data:image/jpeg;base64,{{ image_footer }}" />
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,126 @@
{% load i18n static %}
<!DOCTYPE html>
<html>
<head>
<title>Certificado</title>
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
<link rel="stylesheet" href= "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<link href="{% static "/css/bootstrap.min.css" %}" rel="stylesheet">
<style type="text/css" media="all">
@page {
size: A4 portrait; /* can use also 'landscape' for orientation */
margin: 1.0cm 1.5cm 3.5cm 1.5cm;
font-family: "Source Sans Pro", Calibri, Candra, Sans serif;
@top {
content: element(header);
}
@bottom {
content: element(footer);
}
}
body {
width: 100% !important;
height: 100%;
background: #fff;
color: black;
font-size: 100%;
line-height: 1.65;
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
}
header {
position: running(header);
/*height: 100px;*/
font-size: 12px;
/* color: #000; */
font-family: Arial;
width: 100%;
/* position: relative;*/
}
footer {
position: running(footer);
/*height: 150px;*/
}
.body_content {
position: relative;
page-break-inside: auto;
width: 100%;
/*overflow: hidden;*/
}
img {max-height: 150px; width: auto;}
.company-logo {float: left;}
.customer-logo {float: right;}
.page-break:not(section:first-of-type) {
page-break-before: always
}
}
</style>
</head>
<body>
<div class="container body-content">
<div class="row">
<div class="col">
<img style="width: 100%; height: auto;" src="data:image/jpeg;base64,{{ image_header }}" />
</div>
</div>
<div class="row mt-3">
<div class="col-12" style="text-align: center;">
<b>
<span style="color: #ea5e0f;">LAFEDE.CAT ORGANIZACIONES PARA LA JUSTÍCIA GLOBAL</span><br />CERTIFICA QUE:</b><br />
<b>{{ firstName }} {{ lastName }}</b> con DNI <b>{{ document_id|default:"falta el dni" }}</b><br/>
Ha realizado el curso <b>{{ courseName }}</b>, en {{ address|default:"falta address" }} / de manera {{ modeOfInstruction }}, los días {{ date_course|default:"falta fecha del curso" }}<br />
La duración del curso ha sido de {{ courseDuration }} horas lectivas correspondientes a {{ courseDays }} sessiones.<br />
<br />
<br />
<br />
</div>
<div class="col-12" style="text-align: left;">
Y para dejar constancia a los efectos oportunos, firmo el presente certificado en fecha de {{ issuedDate }}
</div>
</div>
<div class="row" style="padding-top: 20px;">
<div class="col-12">
<img style="width: 129px; height: 88px;" src="data:image/jpeg;base64,{{ image_signature }}" />
</div>
</div>
<div class="row" style="padding-top: 20px;">
<div class="col-12">
Pepa Martínez Peyrats<br />
Directora<br />
Lafede.cat - Federación de Organizaciones por la Justícia Global
</div>
</div>
{% if qr %}
<div class="row" style="padding-top: 20px;">
<div class="col-12">
<img style="width: 129px; height: 129px;" src="data:image/jpeg;base64,{{ qr }}" />
</div>
</div>
{% endif %}
<div class="row" style="padding-top: 20px;">
<div class="col" style="display: flex; justify-content: space-between;">
<span style="color: #ea5e0f;">Organiza:</span>
<span style="color: #ea5e0f;">Con el soporte de:</span>
<span style="color: #ea5e0f;">Con la colaboración de:</span>
</div>
<div class="col">
<div class="row">
<img style="width: auto; height: 50px;" src="data:image/jpeg;base64,{{ image_footer }}" />
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,122 @@
{% load i18n static %}
<!DOCTYPE html>
<html>
<head>
<title>Certificat</title>
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
<link rel="stylesheet" href= "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<link href="{% static "/css/bootstrap.min.css" %}" rel="stylesheet">
<style type="text/css" media="all">
@page {
size: A4 portrait; /* can use also 'landscape' for orientation */
margin: 1.0cm 1.5cm 3.5cm 1.5cm;
font-family: "Source Sans Pro", Calibri, Candra, Sans serif;
@top {
content: element(header);
}
@bottom {
content: element(footer);
}
}
body {
width: 100% !important;
height: 100%;
background: #fff;
color: black;
font-size: 100%;
line-height: 1.65;
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
}
header {
position: running(header);
/*height: 100px;*/
font-size: 12px;
/* color: #000; */
font-family: Arial;
width: 100%;
/* position: relative;*/
}
footer {
position: running(footer);
/*height: 150px;*/
}
.body_content {
position: relative;
page-break-inside: auto;
width: 100%;
/*overflow: hidden;*/
}
img {max-height: 150px; width: auto;}
.company-logo {float: left;}
.customer-logo {float: right;}
.page-break:not(section:first-of-type) {
page-break-before: always
}
}
</style>
</head>
<body>
<div class="container body-content">
<div class="row">
<div class="col">
<img style="width: 100%; height: auto;" src="data:image/jpeg;base64,{{ image_header }}" />
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<p>A qui correspongui,</p>
</p>
Pepa Martínez Peyrats, com a directora de Lafede.cat - <strong>Federació d'Organitzacions per a la Justícia Global</strong>,
</p>
</div>
</div>
<div class="row mt-3">
<div class="col-12 text-center">
<strong>CERTIFICA</strong><br />
<ul>
<li class="text-justify">
Que lentitat <b>{{ legalName }}</b>, amb NIF <b>{{ registrationIdentifier }}</b> i domicili a {{ streetAddress }} {{ postCode }} {{ city }} forma part com a entitat membre de {{ federation }} (ple dret/observadora) de <b>Lafede.cat - Federació d'Organitzacions per a la Justícia Global</b>, des de lAssemblea General Ordinària celebrada el {{ membershipSince }}
</li>
</ul>
<br />
<br />
<br />
I per deixar-ne constància als efectes oportuns, signo el present certificat en data de {{ issue_date_now }}
</div>
</div>
<div class="row" style="padding-top: 20px;">
<div class="col-12">
<img style="width: 129px; height: 88px;" src="data:image/jpeg;base64,{{ image_signature }}" />
</div>
</div>
<div class="row" style="padding-top: 20px;">
<div class="col-12">
Pepa Martínez Peyrats<br />
Directora<br />
Lafede.cat - Federació d'Organitzacions per a la Justícia Global
</div>
</div>
{% if qr %}
<div class="row" style="padding-top: 20px;">
<div class="col-12">
<img style="width: 129px; height: 129px;" src="data:image/jpeg;base64,{{ qr }}" />
</div>
</div>
{% endif %}
</div>
</body>
</html>

View File

@ -0,0 +1,122 @@
{% load i18n static %}
<!DOCTYPE html>
<html>
<head>
<title>Certificado</title>
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
<link rel="stylesheet" href= "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<link href="{% static "/css/bootstrap.min.css" %}" rel="stylesheet">
<style type="text/css" media="all">
@page {
size: A4 portrait; /* can use also 'landscape' for orientation */
margin: 1.0cm 1.5cm 3.5cm 1.5cm;
font-family: "Source Sans Pro", Calibri, Candra, Sans serif;
@top {
content: element(header);
}
@bottom {
content: element(footer);
}
}
body {
width: 100% !important;
height: 100%;
background: #fff;
color: black;
font-size: 100%;
line-height: 1.65;
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
}
header {
position: running(header);
/*height: 100px;*/
font-size: 12px;
/* color: #000; */
font-family: Arial;
width: 100%;
/* position: relative;*/
}
footer {
position: running(footer);
/*height: 150px;*/
}
.body_content {
position: relative;
page-break-inside: auto;
width: 100%;
/*overflow: hidden;*/
}
img {max-height: 150px; width: auto;}
.company-logo {float: left;}
.customer-logo {float: right;}
.page-break:not(section:first-of-type) {
page-break-before: always
}
}
</style>
</head>
<body>
<div class="container body-content">
<div class="row">
<div class="col">
<img style="width: 100%; height: auto;" src="data:image/jpeg;base64,{{ image_header }}" />
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<p>A quién corresponda,</p>
</p>
Pepa Martínez Peyrats, como directora de Lafede.cat - <strong>Federación de Organizaciones para la Justícia Global</strong>,
</p>
</div>
</div>
<div class="row mt-3">
<div class="col-12 text-center">
<strong>CERTIFICA</strong><br />
<ul>
<li class="text-justify">
Que la entidad <b>{{ legalName }}</b>, con NIF <b>{{ registrationIdentifier }}</b> y domicilio {{ streetAddress }} {{ postCode }} {{ city }} forma parte como entidad miembro de {{ federation }} (por el derecho/observadora) de <b>Lafede.cat - Federación de Organizaciones para la Justícia Global</b>, desde la Asamblea General Ordinaria celebrada el {{ membershipSince }}
</li>
</ul>
<br />
<br />
<br />
Y para dejar constancia a los efectos oportunos, firmo el presente certificado en fecha de {{ issue_date_now }}
</div>
</div>
<div class="row" style="padding-top: 20px;">
<div class="col-12">
<img style="width: 129px; height: 88px;" src="data:image/jpeg;base64,{{ image_signature }}" />
</div>
</div>
<div class="row" style="padding-top: 20px;">
<div class="col-12">
Pepa Martínez Peyrats<br />
Directora<br />
Lafede.cat - Federació d'Organitzacions per a la Justícia Global
</div>
</div>
{% if qr %}
<div class="row" style="padding-top: 20px;">
<div class="col-12">
<img style="width: 129px; height: 129px;" src="data:image/jpeg;base64,{{ qr }}" />
</div>
</div>
{% endif %}
</div>
</body>
</html>

View File

@ -9,19 +9,24 @@
{{ subtitle }} {{ subtitle }}
</h3> </h3>
</div> </div>
{% if object.get_status == 'Issued' %}
{% if object.eidas1_did and admin_validated %}
<div class="col text-end">
<a class="btn btn-green-user me-2" href="{{ url_ca }}">{% trans 'Download as PDF (Catalan)' %}</a>
</div>
<div class="col text-end">
<a class="btn btn-green-user me-2" href="{{ url_es }}">{% trans 'Download as PDF (Spanish)' %}</a>
</div>
{% endif %}
{% endif %}
<div class="col text-end"> <div class="col text-end">
{% if object.get_status == 'Issued' %} {% if object.get_status == 'Issued' %}
<div class="col">
{% if object.eidas1_did and admin_validated %} {% if object.eidas1_did and admin_validated %}
<a class="btn btn-green-user me-2" href="{% url 'idhub:user_credential_pdf' object.id %}">{% trans 'Download as PDF' %}</a>
{% endif %} {% endif %}
<a class="btn btn-green-user" href="{% url 'idhub:user_credential_json' object.id %}">{% trans 'Download as JSON' %}</a> <a class="btn btn-green-user" href="{% url 'idhub:user_credential_json' object.id %}">{% trans 'Download as JSON' %}</a>
</div>
{% endif %} {% endif %}
{% if object.get_status == 'Enabled' %} {% if object.get_status == 'Enabled' %}
<div class="col">
<a class="btn btn-green-user" href="{% url 'idhub:user_credentials_request' %}">{% trans 'Request credential' %}</a> <a class="btn btn-green-user" href="{% url 'idhub:user_credentials_request' %}">{% trans 'Request credential' %}</a>
</div>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -73,7 +73,7 @@ urlpatterns = [
name='user_credentials'), name='user_credentials'),
path('user/credentials/<int:pk>', views_user.CredentialView.as_view(), path('user/credentials/<int:pk>', views_user.CredentialView.as_view(),
name='user_credential'), name='user_credential'),
path('user/credentials/<int:pk>/pdf', views_user.CredentialPdfView.as_view(), path('user/credentials/<int:pk>/pdf/<str:lang>', views_user.CredentialPdfView.as_view(),
name='user_credential_pdf'), name='user_credential_pdf'),
path('credentials/<int:pk>/', views_user.CredentialJsonView.as_view(), path('credentials/<int:pk>/', views_user.CredentialJsonView.as_view(),
name='user_credential_json'), name='user_credential_json'),

View File

@ -209,14 +209,19 @@ class CredentialView(MyWallet, TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
url_ca = reverse_lazy('idhub:user_credential_pdf', args=[self.object.id, 'ca'])
url_es = reverse_lazy('idhub:user_credential_pdf', args=[self.object.id, 'es'])
context.update({ context.update({
'object': self.object, 'object': self.object,
'url_ca': url_ca,
'url_es': url_es,
}) })
return context return context
class CredentialPdfView(MyWallet, TemplateView): class CredentialPdfView(MyWallet, TemplateView):
template_name = "certificates/4_Model_Certificat.html" template_name = "certificates/{}_{}.html"
template_name = "certificates/{}_{}.html"
subtitle = _('Credential management') subtitle = _('Credential management')
icon = 'bi bi-patch-check-fill' icon = 'bi bi-patch-check-fill'
file_name = "certificate.pdf" file_name = "certificate.pdf"
@ -225,6 +230,7 @@ class CredentialPdfView(MyWallet, TemplateView):
if not cache.get("KEY_DIDS"): if not cache.get("KEY_DIDS"):
return redirect(reverse_lazy('idhub:user_dashboard')) return redirect(reverse_lazy('idhub:user_dashboard'))
pk = kwargs['pk'] pk = kwargs['pk']
lang = kwargs.get('lang', 'ca')
self.user = self.request.user self.user = self.request.user
self.object = get_object_or_404( self.object = get_object_or_404(
VerificableCredential, VerificableCredential,
@ -232,6 +238,11 @@ class CredentialPdfView(MyWallet, TemplateView):
eidas1_did__isnull=False, eidas1_did__isnull=False,
user=self.request.user user=self.request.user
) )
self.credential_type = self.object.schema.file_schema.split(".json")[0]
self.template_name = self.template_name.format(
self.credential_type,
lang
)
self.url_id = "{}://{}/public/credentials/{}".format( self.url_id = "{}://{}/public/credentials/{}".format(
self.request.scheme, self.request.scheme,
self.request.get_host(), self.request.get_host(),
@ -247,48 +258,51 @@ class CredentialPdfView(MyWallet, TemplateView):
response['Content-Disposition'] = 'attachment; filename={}'.format(self.file_name) response['Content-Disposition'] = 'attachment; filename={}'.format(self.file_name)
return response return response
def get_context_data(self, **kwargs): def get_img_sign(self):
context = super().get_context_data(**kwargs)
# this_folder = str(Path.cwd())
path_img_sig = "idhub/static/images/4_Model_Certificat_html_58d7f7eeb828cf29.jpg" path_img_sig = "idhub/static/images/4_Model_Certificat_html_58d7f7eeb828cf29.jpg"
img_signature = next(Path.cwd().glob(path_img_sig)) img_signature = next(Path.cwd().glob(path_img_sig))
with open(img_signature, 'rb') as _f: with open(img_signature, 'rb') as _f:
img_sig = base64.b64encode(_f.read()).decode('utf-8') img_sig = base64.b64encode(_f.read()).decode('utf-8')
return img_sig
def get_img_header(self):
path_img_head = "idhub/static/images/4_Model_Certificat_html_7a0214c6fc8f2309.jpg" path_img_head = "idhub/static/images/4_Model_Certificat_html_7a0214c6fc8f2309.jpg"
img_header= next(Path.cwd().glob(path_img_head)) img_header= next(Path.cwd().glob(path_img_head))
with open(img_header, 'rb') as _f: with open(img_header, 'rb') as _f:
img_head = base64.b64encode(_f.read()).decode('utf-8') img_head = base64.b64encode(_f.read()).decode('utf-8')
return img_head
def get_img_footer(self):
path_img_foot = "idhub/static/images/4_Model_Certificat_html_941e7b967953b3f3.jpg"
img_foot= next(Path.cwd().glob(path_img_foot))
with open(img_foot, 'rb') as _f:
img_foot = base64.b64encode(_f.read()).decode('utf-8')
return img_foot
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
img_sig = self.get_img_sign()
img_head = self.get_img_header()
img_foot = self.get_img_footer()
qr = self.generate_qr_code(self.url_id) qr = self.generate_qr_code(self.url_id)
issue_date_now = datetime.datetime.now()
first_name = self.user.first_name and self.user.first_name.upper() or "" context.update(dict(self.object.get_datas()))
last_name = self.user.first_name and self.user.last_name.upper() or ""
document_id = "0000000-L"
course = "COURSE 1"
address = "ADDRESS"
date_course = datetime.datetime.now()
n_hours = 40
n_lections = 5
issue_date = datetime.datetime.now()
context.update({ context.update({
'object': self.object, 'object': self.object,
"image_signature": img_sig, "image_signature": img_sig,
"image_header": img_head, "image_header": img_head,
"first_name": first_name, "image_footer": img_foot,
"last_name": last_name, "issue_date_now": issue_date_now.strftime("%d/%m/%Y"),
"document_id": document_id, "qr": qr,
"course": course,
"address": address,
"date_course": date_course,
"n_hours": n_hours,
"n_lections": n_lections,
"issue_date": issue_date,
"qr": qr
}) })
return context return context
def build_certificate(self): def build_certificate(self):
try:
doc = self.render_to_response(context=self.get_context_data())
except Exception:
self.template_name = "certificates/4_Model_Certificat_ca.html"
doc = self.render_to_response(context=self.get_context_data()) doc = self.render_to_response(context=self.get_context_data())
doc.render() doc.render()
pdf = weasyprint.HTML(string=doc.content) pdf = weasyprint.HTML(string=doc.content)
@ -340,7 +354,7 @@ class CredentialPdfView(MyWallet, TemplateView):
w = IncrementalPdfFileWriter(_buffer) w = IncrementalPdfFileWriter(_buffer)
fields.append_signature_field( fields.append_signature_field(
w, sig_field_spec=fields.SigFieldSpec( w, sig_field_spec=fields.SigFieldSpec(
'Signature', box=(150, 100, 450, 150) 'Signature', box=(150, 75, 450, 100)
) )
) )