diff --git a/.gitignore b/.gitignore
index 80202a96..c096b799 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,4 +50,7 @@ media/
# themes
static/css/themes/*
-!static/css/themes/default.css
\ No newline at end of file
+!static/css/themes/default.css
+
+templates/default_invoice.html
+templates/default_voucher.html
\ No newline at end of file
diff --git a/README.md b/README.md
index a78caafb..b23816e0 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,13 @@ Les données stockées dans Re2o sont disponibles via un API Rest. Les services
Le [Wiki](https://gitlab.federez.net/re2o/re2o/-/wikis/home) est accessible sur le gitlab de Federez. Il regroupe les informations et instructions pour la plupart des composants de Re2o.
+# Crédits
+
+Ce projet inclus des versions modifiées de fichiers du projet [Simple HTML Invoice Template](https://github.com/sparksuite/simple-html-invoice-template), publié sous [license MIT](https://github.com/sparksuite/simple-html-invoice-template/blob/master/LICENSE) :
+
+* [invoice.html](./cotisations/templates/cotisations/invoice.html),
+* [voucher.html](./cotisations/templates/cotisations/voucher.html).
+
----
# Re2o
@@ -62,3 +69,10 @@ Re2o provide a Rest API to allow external services (dhcp, dns, firewall,...) ins
# Wiki
The [Wiki](https://gitlab.federez.net/re2o/re2o/-/wikis/home) is available to provide information and instruction for most components of Re2o.
+
+# Credits
+
+This project includes modified versions of files from the [Simple HTML Invoice Template](https://github.com/sparksuite/simple-html-invoice-template) project, published under an [MIT licence](https://github.com/sparksuite/simple-html-invoice-template/blob/master/LICENSE):
+
+* [invoice.html](./cotisations/templates/cotisations/invoice.html),
+* [voucher.html](./cotisations/templates/cotisations/voucher.html).
diff --git a/apt_requirements.txt b/apt_requirements.txt
index 0eddc3b1..8f17f74a 100644
--- a/apt_requirements.txt
+++ b/apt_requirements.txt
@@ -1,9 +1,8 @@
python3-django
python3-dateutil
-texlive-latex-base
-texlive-fonts-recommended
python3-djangorestframework
python3-django-reversion
+python3-xhtml2pdf
python3-pip
python3-pil
libsasl2-dev
diff --git a/apt_requirements_radius.txt b/apt_requirements_radius.txt
index c8003bcb..9b7e8691 100644
--- a/apt_requirements_radius.txt
+++ b/apt_requirements_radius.txt
@@ -1,7 +1,5 @@
python3-django
python3-dateutil
-texlive-latex-base
-texlive-fonts-recommended
python3-djangorestframework
python3-django-reversion
python3-pip
diff --git a/cotisations/tex.py b/cotisations/pdf.py
similarity index 61%
rename from cotisations/tex.py
rename to cotisations/pdf.py
index 49697699..221eb486 100644
--- a/cotisations/tex.py
+++ b/cotisations/pdf.py
@@ -6,6 +6,7 @@
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Lara Kermarec
# Copyright © 2017 Augustin Lemesle
+# Copyright © 2021 Jean-Romain Garnier
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -20,29 +21,25 @@
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-"""tex.py
-Module in charge of rendering some LaTex templates.
-Used to generated PDF invoice.
+
+"""pdf.py
+Module in charge of rendering some HTML templates to generated PDF invoices.
"""
import os
import tempfile
from datetime import datetime
-from subprocess import PIPE, Popen
from django.conf import settings
-from django.db import models
from django.http import HttpResponse
from django.template.loader import get_template
from django.utils.text import slugify
from preferences.models import CotisationsOption
-from re2o.mixins import AclMixin, RevMixin
-TEMP_PREFIX = getattr(settings, "TEX_TEMP_PREFIX", "render_tex-")
-CACHE_PREFIX = getattr(settings, "TEX_CACHE_PREFIX", "render-tex")
-CACHE_TIMEOUT = getattr(settings, "TEX_CACHE_TIMEOUT", 86400) # 1 day
+from xhtml2pdf import pisa
+from django.contrib.staticfiles import finders
def render_invoice(_request, ctx={}):
@@ -63,8 +60,7 @@ def render_invoice(_request, ctx={}):
]
)
templatename = options.invoice_template.template.name.split("/")[-1]
- r = render_tex(_request, templatename, ctx)
- r["Content-Disposition"] = 'attachment; filename="{name}.pdf"'.format(name=filename)
+ r = render_pdf(_request, templatename, ctx, filename)
return r
@@ -85,18 +81,48 @@ def render_voucher(_request, ctx={}):
]
)
templatename = options.voucher_template.template.name.split("/")[-1]
- r = render_tex(_request, templatename, ctx)
- r["Content-Disposition"] = 'attachment; filename="{name}.pdf"'.format(name=filename)
+ r = render_pdf(_request, templatename, ctx, filename)
return r
+def link_callback(uri, rel):
+ """
+ Convert HTML URIs to absolute system paths so xhtml2pdf can access those
+ resources
+ See https://xhtml2pdf.readthedocs.io/en/latest/usage.html#using-xhtml2pdf-in-django
+ """
+ result = finders.find(uri)
+ if result:
+ if not isinstance(result, (list, tuple)):
+ result = [result]
+ result = list(os.path.realpath(path) for path in result)
+ path = result[0]
+ else:
+ sUrl = settings.STATIC_URL # Typically /static/
+ sRoot = settings.STATIC_ROOT # Typically /project_static/
+ mUrl = settings.MEDIA_URL # Typically /media/
+ mRoot = settings.MEDIA_ROOT # Typically /project_static/media/
+
+ if uri.startswith(mUrl):
+ path = os.path.join(mRoot, uri.replace(mUrl, ""))
+ elif uri.startswith(sUrl):
+ path = os.path.join(sRoot, uri.replace(sUrl, ""))
+ else:
+ return uri
+
+ # Make sure that file exists
+ if not os.path.isfile(path):
+ raise Exception("media URI must start with %s or %s" % (sUrl, mUrl))
+ return path
+
+
def create_pdf(template, ctx={}):
- """Creates and returns a PDF from a LaTeX template using pdflatex.
+ """Creates and returns a PDF from an HTML template using xhtml2pdf.
It create a temporary file for the PDF then read it to return its content.
Args:
- template: Path to the LaTeX template.
+ template: Path to the HTML template.
ctx: Dict with the context for rendering the template.
Returns:
@@ -106,46 +132,37 @@ def create_pdf(template, ctx={}):
template = get_template(template)
rendered_tpl = template.render(context).encode("utf-8")
- with tempfile.TemporaryDirectory() as tempdir:
- for _ in range(2):
- process = Popen(
- ["pdflatex", "-output-directory", tempdir],
- stdin=PIPE,
- stdout=PIPE,
- )
- process.communicate(rendered_tpl)
- with open(os.path.join(tempdir, "texput.pdf"), "rb") as f:
- pdf = f.read()
+ with tempfile.TemporaryFile("wb+") as tempf:
+ pisa_status = pisa.CreatePDF(rendered_tpl, dest=tempf)
+
+ if pisa_status.err:
+ raise pisa_status.err
+
+ tempf.seek(0)
+ pdf = tempf.read()
return pdf
-def escape_chars(string):
- """Escape the '%' and the '€' signs to avoid messing with LaTeX"""
- if not isinstance(string, str):
- return string
- mapping = (("€", r"\euro"), ("%", r"\%"))
- r = str(string)
- for k, v in mapping:
- r = r.replace(k, v)
- return r
+def render_pdf(_request, template, ctx={}, filename="invoice"):
+ """
+ Creates a PDF from an HTML template using xhtml2pdf.
-
-def render_tex(_request, template, ctx={}):
- """Creates a PDF from a LaTex templates using pdflatex.
-
- Calls `create_pdf` and send back an HTTP response for
- accessing this file.
+ Calls `create_pdf` and send back an HTTP response for accessing this file.
Args:
_request: Unused, but allow using this function as a Django view.
- template: Path to the LaTeX template.
+ template: Path to the HTML template.
ctx: Dict with the context for rendering the template.
+ filename: The name of the file to include in the request headers.
Returns:
- An HttpResponse with type `application/pdf` containing the PDF file.
+ The content of the temporary PDF file generated.
"""
pdf = create_pdf(template, ctx)
+
r = HttpResponse(content_type="application/pdf")
+ r["Content-Disposition"] = 'attachment; filename="{name}.pdf"'.format(name=filename)
r.write(pdf)
+
return r
diff --git a/cotisations/templates/cotisations/factures.tex b/cotisations/templates/cotisations/factures.tex
deleted file mode 100644
index 2cfd4f46..00000000
--- a/cotisations/templates/cotisations/factures.tex
+++ /dev/null
@@ -1,150 +0,0 @@
-{% load i18n %}
-{% language 'fr' %}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Invoice Template
-% LaTeX Template
-% Version 1.0 (3/11/12)
-%% This template has been downloaded from:
-% http://www.LaTeXTemplates.com
-%
-% Original author:
-% Trey Hunner (http://www.treyhunner.com/)
-%
-% License:
-% CC BY-NC-SA 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/)
-%
-% Important note:
-% This template requires the invoice.cls file to be in the same directory as
-% the .tex file. The invoice.cls file provides the style used for structuring the
-% document.
-%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%----------------------------------------------------------------------------------------
-% DOCUMENT CONFIGURATION
-%----------------------------------------------------------------------------------------
-
-\documentclass[12pt]{article} % Use the custom invoice class (invoice.cls)
-\usepackage[utf8]{inputenc}
-\usepackage[letterpaper,hmargin=0.79in,vmargin=0.79in]{geometry}
-\usepackage{longtable}
-\usepackage{graphicx}
-\usepackage{tabularx}
-\usepackage{eurosym}
-\usepackage{multicol}
-
-\pagestyle{empty} % No page numbers
-\linespread{1.5} % Line spacing
-
-\newcommand{\doublehline}{\noalign{\hrule height 1pt}}
-\setlength{\parindent}{0cm}
-
-
-
-\begin{document}
-
- %----------------------------------------------------------------------------------------
- % HEADING SECTION
- %----------------------------------------------------------------------------------------
- \begin{center}
- {\Huge\bf {{asso_name|safe}} } % Company providing the invoice
- \end{center}
-
- \bigskip
- \hrule
- \smallskip
-
- {\setlength{\tabcolsep}{0pt} % Make table columns tighter, usefull for postionning
- \begin{tabular}{l l}
- {\bf Adresse :}~ & {{line1|safe}} \\
- & {{line2|safe}} \\
- \end{tabular}
- \hfill
- \begin{tabular}{r}
- {\bf Téléphone :} {{phone}} \\
- {\bf Mail :} {{email|safe}} \\
- \end{tabular}
- }
- \\
- {\bf Siret :} {{siret|safe}}
-
- \vspace{2cm}
-
- \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}} l r}
- {\bf Pour :} {{recipient_name|safe}} & {\bf Date :} {{DATE}} \\
- {\bf Adresse :} {% if address is None %}Aucune adresse renseignée{% else %}{{address}}{% endif %} & \\
- {% if fid is not None %}
- {% if is_estimate %}
- {\bf Devis n\textsuperscript{o} :} {{ fid }} & \\
- {% else %}
- {\bf Facture n\textsuperscript{o} :} {{ fid }} & \\
- {% endif %}
- {% endif %}
- \end{tabular*}
- \\
-
-
- %----------------------------------------------------------------------------------------
- % TABLE OF EXPENSES
- %----------------------------------------------------------------------------------------
-
- \begin{tabularx}{\textwidth}{|X|r|r|r|}
-
- \hline
- \textbf{Désignation} & \textbf{Prix Unit.} \euro & \textbf{Quantité} & \textbf{Prix total} \euro\\
- \doublehline
-
- {% for a in article %}
- {{a.name}} & {{a.price}} \euro & {{a.quantity}} & {{a.total_price}} \euro\\
- \hline
- {% endfor %}
-
- \end{tabularx}
-
- \vspace{1cm}
-
- \hfill
- \begin{tabular}{|l|r|}
- \hline
- \textbf{Total} & {{total|floatformat:2}} \euro \\
- {% if not is_estimate %}
- \textbf{Votre règlement} & {% if paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro \\
- \doublehline
- \textbf{À PAYER} & {% if not paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro\\
- {% endif %}
- \hline
- \end{tabular}
-
- \vspace{1cm}
- \begin{tabularx}{\textwidth}{r X}
- \hline
- \textbf{Moyen de paiement} & {{payment_method|default:"Non spécifié"}} \\
- \hline
- {% if remark %}
- \textbf{Remarque} & {{remark|safe}} \\
- \hline
- {% endif %}
- {% if end_validity %}
- \textbf{Validité} & Jusqu'au {{end_validity}} \\
- \hline
- {% endif %}
- \end{tabularx}
-
-
- \vfill
-
-
- %----------------------------------------------------------------------------------------
- % FOOTNOTE
- %----------------------------------------------------------------------------------------
-
- \hrule
- \smallskip
- \footnotesize{TVA non applicable, art. 293 B du CGI}
-
- %----------------------------------------------------------------------------------------
-
-\end{document}
-
-{% endlanguage %}
diff --git a/cotisations/templates/cotisations/invoice.html b/cotisations/templates/cotisations/invoice.html
new file mode 100755
index 00000000..53b85738
--- /dev/null
+++ b/cotisations/templates/cotisations/invoice.html
@@ -0,0 +1,249 @@
+
+
+
+
+
+
+
+ Facture {{asso_name|safe}}
+
+
+
+
+
+
+
+
+ Facture {{asso_name|safe}}
+
+
+
+
+
+ {% if phone != "0000000000" %}Téléphone : {{phone|safe}} {% endif %}
+ Mail : {{email|safe}}
+ {% if siret != "00000000000000" %}Siret : {{siret|safe}}{% endif %}
+ |
+
+ Adresse :
+ {{line1|safe}}
+ {{line2|safe}}
+ |
+
+
+
+
+ {% if fid is not None %}
+ {% if is_estimate %}
+ Devis n° : {{fid}}
+ {% else %}
+ Facture n° : {{fid}}
+ {% endif %}
+ {% endif %}
+ Date : {{DATE}}
+ |
+
+
+
+
+ Pour : {{recipient_name|safe}}
+ Adresse : {% if address is None %}Aucune adresse renseignée{% else %}{{address}}{% endif %}
+ |
+
+
+
+
+ Moyen de paiement
+ |
+
+
+
+
+ {{payment_method|default:"Non spécifié"}}
+ |
+
+
+
+ Désignation |
+ Prix unitaire HT |
+ Quantité |
+ Prix total HT |
+
+
+ {% for a in article %}
+
+ {{a.name}} |
+ {{a.price|floatformat:2}} € |
+ {{a.quantity}} |
+ {{a.total_price|floatformat:2}} € |
+
+ {% endfor %}
+
+
+ |
+
+ Total HT : {{total|floatformat:2}} €
+ |
+
+
+
+ {% if not is_estimate %}
+
+ |
+
+ Votre règlement : {% if paid %}{{total|floatformat:2}}{% else %}00,00{% endif %} €
+ |
+
+
+
+ |
+
+ À payer : {% if not paid %}{{total|floatformat:2}}{% else %}00,00{% endif %} €
+ |
+
+ {% endif %}
+
+
+
+
+ TVA non applicable, art. 261 7.1°a du CGI
+ |
+
+
+
+ {% if remark %}
+
+
+ Remarque
+ |
+
+
+
+
+ {{remark|safe}}
+ |
+
+ {% endif %}
+
+ {% if end_validity %}
+
+
+ Validité
+ |
+
+
+
+
+ Jusqu'au {{end_validity}}
+ |
+
+ {% endif %}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cotisations/templates/cotisations/voucher.html b/cotisations/templates/cotisations/voucher.html
new file mode 100755
index 00000000..029fe354
--- /dev/null
+++ b/cotisations/templates/cotisations/voucher.html
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+ Reçu d'adhésion {{asso_name|safe}}
+
+
+
+
+
+
+
Reçu d'adhésion {{asso_name|safe}}
+
+
+
+ Je sousigné {{pres_name|safe}} déclare par la présente avoir reçu le bulletin d'adhésion de :
+
+
+
+
+ Prénom : |
+ {{firstname|safe}} |
+
+
+
+ Nom : |
+ {{lastname|safe}} |
+
+
+
+ Mail : |
+ {{email|safe}} |
+
+
+
+
+ ainsi que sa cotisation.
+
+
+
+ Le postulant déclare reconnaître l'objet de l'association et en a accepté les statuts ainsi que le règlement intérieur qui sont mis à sa disposition dans les locaux de l'association. L'adhésion du membre sus-nommé est ainsi validée. Ce reçu confirme la qualité de membre du postulant, et ouvre droit à la participation à l'assemblée générale de l'association jusqu'au {{date_end|date:"d F Y"}}.
+
+
+
+ Validé électroniquement par {{pres_name|safe}} le {{date_begin|date:"d/m/Y"}}.
+
+
+
+
+
+
+ Les informations recueillies sont nécessaires pour votre adhésion. Conformément à la loi "Informatique et Libertés" du 6 janvier 1978, vous disposez d'un droit d'accès et de rectification aux données personnelles vous concernant. Pour l'exercer, adressez-vous au secrétariat de l'association.
+
+
+
+
+
diff --git a/cotisations/templates/cotisations/voucher.tex b/cotisations/templates/cotisations/voucher.tex
deleted file mode 100644
index aeebc187..00000000
--- a/cotisations/templates/cotisations/voucher.tex
+++ /dev/null
@@ -1,87 +0,0 @@
-{% load i18n %}
-{% language 'fr' %}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Invoice Template
-% LaTeX Template
-% Version 1.0 (3/11/12)
-%% This template has been downloaded from:
-% http://www.LaTeXTemplates.com
-%
-% Original author:
-% Trey Hunner (http://www.treyhunner.com/)
-%
-% License:
-% CC BY-NC-SA 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/)
-%
-% Important note:
-% This template requires the invoice.cls file to be in the same directory as
-% the .tex file. The invoice.cls file provides the style used for structuring the
-% document.
-%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%----------------------------------------------------------------------------------------
-% DOCUMENT CONFIGURATION
-%----------------------------------------------------------------------------------------
-
-\documentclass[12pt]{article} % Use the custom invoice class (invoice.cls)
-\usepackage[utf8]{inputenc}
-\usepackage[letterpaper,hmargin=0.79in,vmargin=0.79in]{geometry}
-\usepackage{longtable}
-\usepackage{graphicx}
-\usepackage{tabularx}
-\usepackage{eurosym}
-\usepackage{multicol}
-
-\pagestyle{empty} % No page numbers
-
-\linespread{1.5}
-
-\newcommand{\doublehline}{\noalign{\hrule height 1pt}}
-\setlength{\parindent}{0cm}
-
-
-\begin{document}
-
- %----------------------------------------------------------------------------------------
- % HEADING SECTION
- %----------------------------------------------------------------------------------------
- \begin{center}
- {\Huge\bf Reçu d'adhésion \\ {{asso_name|safe}} } % Company providing the invoice
- \end{center}
-
- \bigskip
- \hrule
- \bigskip
-
- \vfill
-
- Je sousigné, {{pres_name|safe}}, déclare par la présente avoir reçu le bulletin d'adhésion de:
-
- \begin{center}
- \setlength{\tabcolsep}{10pt} % Make table columns tighter, usefull for postionning
- \begin{tabular}{r l r l}
- {\bf Prénom :}~ & {{firstname|safe}} & {% if phone %}{\bf Téléphone :}~ & {{phone}}{% else %} & {% endif %} \\
- {\bf Nom :}~ & {{lastname|safe}} & {\bf Mail :}~ & {{email|safe}} \\
- \end{tabular}
- \end{center}
- \bigskip
-
- ainsi que sa cotisation.
-
- Le postulant, déclare reconnaître l'objet de l'association, et en a accepté les statuts ainsi que le règlement intérieur qui sont mis à sa disposition dans les locaux de l'association. L'adhésion du membre sus-nommé est ainsi validée. Ce reçu confirme la qualité de membre du postulant, et ouvre droit à la participation à l'assemblée générale de l'association jusqu'au {{date_end|date:"d F Y"}}.
-
- \bigskip
-
- Validé électroniquement par {{pres_name|safe}}, le {{date_begin|date:"d/m/Y"}}.
-
- \vfill
- \hrule
- \smallskip
- \footnotesize
- Les informations recueillies sont nécessaires pour votre adhésion. Conformément à la loi "Informatique et Libertés" du 6 janvier 1978, vous disposez d'un droit d'accès et de rectification aux données personnelles vous concernant. Pour l'exercer, adressez-vous au secrétariat de l'association.
-
-
-\end{document}
-{% endlanguage %}
diff --git a/cotisations/utils.py b/cotisations/utils.py
index b287f78d..5478d857 100644
--- a/cotisations/utils.py
+++ b/cotisations/utils.py
@@ -30,7 +30,7 @@ from re2o import settings
from re2o.mail_utils import send_mail_object
from re2o.settings import LOGO_PATH
-from .tex import create_pdf
+from .pdf import create_pdf
def find_payment_method(payment):
diff --git a/cotisations/views.py b/cotisations/views.py
index d6fda3f5..f98dd358 100644
--- a/cotisations/views.py
+++ b/cotisations/views.py
@@ -60,7 +60,7 @@ from .forms import (ArticleForm, BanqueForm, CostEstimateForm,
from .models import (Article, Banque, BaseInvoice, CostEstimate, CustomInvoice,
Facture, Paiement, Vente)
from .payment_methods.forms import payment_method_factory
-from .tex import escape_chars, render_invoice, render_voucher
+from .pdf import render_invoice, render_voucher
from .utils import find_payment_method
@@ -443,7 +443,7 @@ def cost_estimate_pdf(request, invoice, **_kwargs):
for purchase in purchases_objects:
purchases_info.append(
{
- "name": escape_chars(purchase.name),
+ "name": purchase.name,
"price": purchase.prix,
"quantity": purchase.number,
"total_price": purchase.prix_total,
@@ -508,7 +508,7 @@ def custom_invoice_pdf(request, invoice, **_kwargs):
for purchase in purchases_objects:
purchases_info.append(
{
- "name": escape_chars(purchase.name),
+ "name": purchase.name,
"price": purchase.prix,
"quantity": purchase.number,
"total_price": purchase.prix_total,
diff --git a/dev-requirements.txt b/dev-requirements.txt
index f3989da9..d089fb44 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -4,6 +4,10 @@ alabaster==0.7.12; python_version >= "3.5" \
appdirs==1.4.4; python_version >= "3.6" \
--hash=sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128 \
--hash=sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41
+arabic-reshaper==2.1.3 \
+ --hash=sha256:43f58136dbbfecab54ce0434e556c75689e46b0f11010578b893f72c504cd27b \
+ --hash=sha256:15078431d8f45eaca0a1710100aabc87abba13759c67eeb4538cca22fe167da1 \
+ --hash=sha256:a236fc6e9dde2a61cc6a5ca962b522e42694e1bb2a2d86894ed7a4eba4ce1890
babel==2.9.0; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5" \
--hash=sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5 \
--hash=sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05
@@ -99,12 +103,17 @@ docstr-coverage==2.0.0 \
docutils==0.16; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5" \
--hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \
--hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc
+future==0.18.2; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \
+ --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d
gitdb==4.0.5; python_version >= "3.4" \
--hash=sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac \
--hash=sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9
gitpython==3.1.13; python_version >= "3.4" \
--hash=sha256:c5347c81d232d9b8e7f47b68a83e5dc92e7952127133c5f2df9133f2c75a1b29 \
--hash=sha256:8621a7e777e276a5ec838b59280ba5272dd144a18169c36c903d8b38b99f750a
+html5lib==1.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
+ --hash=sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d \
+ --hash=sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f
idna==2.10; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5" \
--hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0 \
--hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6
@@ -226,6 +235,11 @@ pygments==2.7.4; python_version >= "3.5" \
pyparsing==2.4.7; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5" \
--hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
--hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1
+pypdf2==1.26.0 \
+ --hash=sha256:e28f902f2f0a1603ea95ebe21dff311ef09be3d0f0ef29a3e44a932729564385
+python-bidi==0.4.2 \
+ --hash=sha256:5347f71e82b3e9976dc657f09ded2bfe39ba8d6777ca81a5b2c56c30121c496e \
+ --hash=sha256:50eef6f6a0bbdd685f9e8c207f3c9050f5b578d0a46e37c76a9c4baea2cc2e13
python-dateutil==2.8.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") \
--hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \
--hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a
@@ -239,18 +253,26 @@ pyyaml==5.4.1; python_version >= "2.7" and python_full_version < "3.0.0" or pyth
--hash=sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185 \
--hash=sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253 \
--hash=sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc \
+ --hash=sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347 \
+ --hash=sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541 \
--hash=sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5 \
--hash=sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df \
--hash=sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018 \
--hash=sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63 \
+ --hash=sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa \
+ --hash=sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0 \
--hash=sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b \
--hash=sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf \
--hash=sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46 \
--hash=sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb \
+ --hash=sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247 \
+ --hash=sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc \
--hash=sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc \
--hash=sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696 \
--hash=sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77 \
--hash=sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183 \
+ --hash=sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122 \
+ --hash=sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6 \
--hash=sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10 \
--hash=sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db \
--hash=sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e
@@ -296,12 +318,42 @@ regex==2020.11.13; python_version >= "3.6" \
--hash=sha256:f8f295db00ef5f8bae530fc39af0b40486ca6068733fb860b42115052206466f \
--hash=sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d \
--hash=sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562
+reportlab==3.5.68; python_version >= "3.6" and python_version < "4" \
+ --hash=sha256:c0612d9101f40679245e7d9edb169d8d79378a47f38cd8e6b38c55d7ff31db3f \
+ --hash=sha256:19708801278f600d712c04ee6bfb650e45d1b2898713f7bd97b39ab89bd08c1e \
+ --hash=sha256:46f15f5a34a50375c332ab8eaa907a0212c88787b0885ac25a9505c0741ee9ba \
+ --hash=sha256:28c72d27f21d74a7301789c7950b5e82a430ed38817ecee060fa1f2f3e959360 \
+ --hash=sha256:81d1958d90fccf86f62b38ecbedf9208a973d99e0747b6cd75036914ae8641c4 \
+ --hash=sha256:7e466276f1a1121dac23b703af6c22db0cedf6cec5139969f8387e8d8046f203 \
+ --hash=sha256:a48221d4ab7de37975ad052f7e565cf13ab708def63f203a38ae9927ab5442cd \
+ --hash=sha256:ced16daf89f948eeb4e376b5d814da5d99f7205fbd42e17a96f257e35dc31bdd \
+ --hash=sha256:70e7461aa47eff810be8c4e4a0cbc6fcf47aecaddd46de6ca4524c76065f8490 \
+ --hash=sha256:332f836ff4c975c92d307302e86a54d6f0e3d2ce33a35759812e7a1d17e2091f \
+ --hash=sha256:010f86a192c397f7c8ae667953a85d913395a8a6a8da112bff1c1ea28e679bcd \
+ --hash=sha256:6f905390f5e5801b21b6027c8ffaed915e5eec1e46bbdf6a74c8838213717b44 \
+ --hash=sha256:63578cab96fc4383e71dd9fe1877bb26ab78b2a6c91139068e99d130687289ab \
+ --hash=sha256:45113c1c359ba314499032c891487802cccd7c4225a3e930d6cf492d62ea4f07 \
+ --hash=sha256:b9ae0c534c09274b80f8fd87408071c1f814d56c5f51fe450b2157f1f13e921b \
+ --hash=sha256:66b5a08cbeb910edee7201efa786bd1bf7027c7ec526dddf7d60fc2252e2b30f \
+ --hash=sha256:08b53568979228b6969b790339d06a0b8db8883f92ae7339013f9878042dd9ca \
+ --hash=sha256:b57ebeb28f7a58a9da6f8c293acb6d31d89f634b3eba0b728a040cef08afc4ea \
+ --hash=sha256:dd3409ebabe699c98058690b7b730f93e6b0bd4ed5e49ca3b15e1530ae07b40b \
+ --hash=sha256:2dc5ee0c5b659697cdfbc218ec9abea54dd9c5a95ea8ca95245fe94f5ef111f9 \
+ --hash=sha256:b25608059558910585a9e229bae0fd3d67af49ae5e1c7a20057680c6b3d5f6f7 \
+ --hash=sha256:ad9a49890de59e8dd16fa0ce03ef607e46a5ff2f39de44f8556f796b3d4ddffb \
+ --hash=sha256:6063466779e438375bcdd2c15fc551ebd68f16ebfb2766497234df9cfa57e5b1 \
+ --hash=sha256:5865c4247229584408515055b5b19c7f935ae94433d6258c7a9234c4a07d6d34 \
+ --hash=sha256:2c0c88a7cf83a20a2bb355f97a1a9d0373a6de60c3aec35d301d3cc75dc4bb72 \
+ --hash=sha256:6b448a1824d381d282c5ea1da1669a5fa53dac67c57a1ecad6bcc149f286d1fd \
+ --hash=sha256:9a00feb8eafbce1283cd3edbb29735bd40c9566b3f45913110a301700c16b63a \
+ --hash=sha256:580eed6d9e5c20870ea909bec6840f9ceb9d13c33316d448cae21eb3ca47c7fd \
+ --hash=sha256:efef6a97e3ab49f3f40037dbf9a4166668a17cc6aaba13d5ecbabdf854a9b332
requests==2.25.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5" \
--hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e \
--hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804
rope==0.18.0 \
--hash=sha256:786b5c38c530d4846aa68a42604f61b4e69a493390e3ca11b88df0fbfdc3ed04
-six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \
+six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259
smmap==3.0.5; python_version >= "3.4" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.4" \
@@ -378,6 +430,11 @@ typing-extensions==3.7.4.3; python_version >= "3.6" \
urllib3==1.26.3; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.5" \
--hash=sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80 \
--hash=sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73
+webencodings==0.5.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
+ --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
+ --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
+xhtml2pdf==0.2.5 \
+ --hash=sha256:6797e974fac66f0efbe927c1539a2756ca4fe8777eaa5882bac132fc76b39421
zipp==3.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.7" or python_version >= "3.6" and python_version < "3.7" and python_full_version >= "3.5.0" \
--hash=sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108 \
--hash=sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb
diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh
index 150950d0..c3bd374f 100755
--- a/docker/docker-entrypoint.sh
+++ b/docker/docker-entrypoint.sh
@@ -3,6 +3,9 @@ set -euo pipefail
cat docker/settings_local.template.py | envsubst > re2o/settings_local.py
+cp cotisations/templates/cotisations/invoice.html templates/default_invoice.html
+cp cotisations/templates/cotisations/voucher.html templates/default_voucher.html
+
AUTOMIGRATE=${AUTOMIGRATE:-yes}
if [ "$AUTOMIGRATE" != "skip" ]; then
diff --git a/install_re2o.sh b/install_re2o.sh
index 428f475d..9995f264 100755
--- a/install_re2o.sh
+++ b/install_re2o.sh
@@ -376,14 +376,14 @@ update_django() {
copy_templates_files() {
### Usage: copy_templates_files
#
- # This will copy LaTeX templates in the media root.
+ # This will copy HTML templates in the media root.
- echo "Copying LaTeX templates ..."
+ echo "Copying HTML invoice templates ..."
mkdir -p media/templates/
- cp cotisations/templates/cotisations/factures.tex media/templates/default_invoice.tex
- cp cotisations/templates/cotisations/voucher.tex media/templates/default_voucher.tex
+ cp cotisations/templates/cotisations/invoice.html media/templates/default_invoice.html
+ cp cotisations/templates/cotisations/voucher.html media/templates/default_voucher.html
chown -R www-data:www-data media/templates/
- echo "Copying LaTeX templates: Done"
+ echo "Copying HTML invoice templates: Done"
}
@@ -1099,12 +1099,12 @@ main_function() {
echo " * {setup-radius} -- Launch the full interactive guide to setup entirely"
echo " re2o radius from scratch"
echo " * {update} -------- Collect frontend statics, install the missing APT"
- echo " and pip packages, copy LaTeX templates files"
+ echo " and pip packages, copy invoice template files"
echo " and apply the migrations to the DB"
echo " * {update-radius} - Update radius apt and pip packages and copy radius"
echo " configuration files to their proper location."
echo " * {update-django} - Apply Django migration and collect frontend statics"
- echo " * {copy-template-files} - Copy LaTeX templates files to media/templates"
+ echo " * {copy-template-files} - Copy invoice template files to media/templates"
echo " * {update-packages} Install the missing APT and pip packages"
echo " * {update-settings} Interactively rewrite the settings file"
echo " * {reset-db} ------ Erase the previous local database, setup a new empty"
diff --git a/ldap-requirements.txt b/ldap-requirements.txt
index 11ad0e73..bdbc4a33 100644
--- a/ldap-requirements.txt
+++ b/ldap-requirements.txt
@@ -1,3 +1,7 @@
+arabic-reshaper==2.1.3 \
+ --hash=sha256:43f58136dbbfecab54ce0434e556c75689e46b0f11010578b893f72c504cd27b \
+ --hash=sha256:15078431d8f45eaca0a1710100aabc87abba13759c67eeb4538cca22fe167da1 \
+ --hash=sha256:a236fc6e9dde2a61cc6a5ca962b522e42694e1bb2a2d86894ed7a4eba4ce1890
django-autocomplete-light==3.8.1 \
--hash=sha256:4e84a6d95d272b0d7221614332e2bd54ffff15ec06e78947279398f6507ce225
django-bootstrap3==14.2.0; python_version >= "3.6" and python_version < "4.0" \
@@ -20,12 +24,17 @@ django==2.2.18; python_version >= "3.5" \
djangorestframework==3.12.2; python_version >= "3.5" \
--hash=sha256:0209bafcb7b5010fdfec784034f059d512256424de2a0f084cb82b096d6dd6a7 \
--hash=sha256:0898182b4737a7b584a2c73735d89816343369f259fea932d90dc78e35d8ac33
+future==0.18.2; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \
+ --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d
gitdb==4.0.5; python_version >= "3.4" \
--hash=sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac \
--hash=sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9
gitpython==3.1.13; python_version >= "3.4" \
--hash=sha256:c5347c81d232d9b8e7f47b68a83e5dc92e7952127133c5f2df9133f2c75a1b29 \
--hash=sha256:8621a7e777e276a5ec838b59280ba5272dd144a18169c36c903d8b38b99f750a
+html5lib==1.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
+ --hash=sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d \
+ --hash=sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f
importlib-metadata==1.7.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_version >= "3.6" and python_version < "3.8" and python_full_version >= "3.5.0" \
--hash=sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070 \
--hash=sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83
@@ -98,6 +107,11 @@ pyasn1==0.4.8; python_version >= "3.6" and python_full_version < "3.0.0" or pyth
--hash=sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba
pycrypto==2.6.1 \
--hash=sha256:f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c
+pypdf2==1.26.0 \
+ --hash=sha256:e28f902f2f0a1603ea95ebe21dff311ef09be3d0f0ef29a3e44a932729564385
+python-bidi==0.4.2 \
+ --hash=sha256:5347f71e82b3e9976dc657f09ded2bfe39ba8d6777ca81a5b2c56c30121c496e \
+ --hash=sha256:50eef6f6a0bbdd685f9e8c207f3c9050f5b578d0a46e37c76a9c4baea2cc2e13
python-dateutil==2.8.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") \
--hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \
--hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a
@@ -106,7 +120,37 @@ python-ldap==3.3.1; python_version >= "3.6" and python_full_version < "3.0.0" or
pytz==2021.1; python_version >= "3.6" and python_version < "4.0" \
--hash=sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798 \
--hash=sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da
-six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \
+reportlab==3.5.68; python_version >= "3.6" and python_version < "4" \
+ --hash=sha256:c0612d9101f40679245e7d9edb169d8d79378a47f38cd8e6b38c55d7ff31db3f \
+ --hash=sha256:19708801278f600d712c04ee6bfb650e45d1b2898713f7bd97b39ab89bd08c1e \
+ --hash=sha256:46f15f5a34a50375c332ab8eaa907a0212c88787b0885ac25a9505c0741ee9ba \
+ --hash=sha256:28c72d27f21d74a7301789c7950b5e82a430ed38817ecee060fa1f2f3e959360 \
+ --hash=sha256:81d1958d90fccf86f62b38ecbedf9208a973d99e0747b6cd75036914ae8641c4 \
+ --hash=sha256:7e466276f1a1121dac23b703af6c22db0cedf6cec5139969f8387e8d8046f203 \
+ --hash=sha256:a48221d4ab7de37975ad052f7e565cf13ab708def63f203a38ae9927ab5442cd \
+ --hash=sha256:ced16daf89f948eeb4e376b5d814da5d99f7205fbd42e17a96f257e35dc31bdd \
+ --hash=sha256:70e7461aa47eff810be8c4e4a0cbc6fcf47aecaddd46de6ca4524c76065f8490 \
+ --hash=sha256:332f836ff4c975c92d307302e86a54d6f0e3d2ce33a35759812e7a1d17e2091f \
+ --hash=sha256:010f86a192c397f7c8ae667953a85d913395a8a6a8da112bff1c1ea28e679bcd \
+ --hash=sha256:6f905390f5e5801b21b6027c8ffaed915e5eec1e46bbdf6a74c8838213717b44 \
+ --hash=sha256:63578cab96fc4383e71dd9fe1877bb26ab78b2a6c91139068e99d130687289ab \
+ --hash=sha256:45113c1c359ba314499032c891487802cccd7c4225a3e930d6cf492d62ea4f07 \
+ --hash=sha256:b9ae0c534c09274b80f8fd87408071c1f814d56c5f51fe450b2157f1f13e921b \
+ --hash=sha256:66b5a08cbeb910edee7201efa786bd1bf7027c7ec526dddf7d60fc2252e2b30f \
+ --hash=sha256:08b53568979228b6969b790339d06a0b8db8883f92ae7339013f9878042dd9ca \
+ --hash=sha256:b57ebeb28f7a58a9da6f8c293acb6d31d89f634b3eba0b728a040cef08afc4ea \
+ --hash=sha256:dd3409ebabe699c98058690b7b730f93e6b0bd4ed5e49ca3b15e1530ae07b40b \
+ --hash=sha256:2dc5ee0c5b659697cdfbc218ec9abea54dd9c5a95ea8ca95245fe94f5ef111f9 \
+ --hash=sha256:b25608059558910585a9e229bae0fd3d67af49ae5e1c7a20057680c6b3d5f6f7 \
+ --hash=sha256:ad9a49890de59e8dd16fa0ce03ef607e46a5ff2f39de44f8556f796b3d4ddffb \
+ --hash=sha256:6063466779e438375bcdd2c15fc551ebd68f16ebfb2766497234df9cfa57e5b1 \
+ --hash=sha256:5865c4247229584408515055b5b19c7f935ae94433d6258c7a9234c4a07d6d34 \
+ --hash=sha256:2c0c88a7cf83a20a2bb355f97a1a9d0373a6de60c3aec35d301d3cc75dc4bb72 \
+ --hash=sha256:6b448a1824d381d282c5ea1da1669a5fa53dac67c57a1ecad6bcc149f286d1fd \
+ --hash=sha256:9a00feb8eafbce1283cd3edbb29735bd40c9566b3f45913110a301700c16b63a \
+ --hash=sha256:580eed6d9e5c20870ea909bec6840f9ceb9d13c33316d448cae21eb3ca47c7fd \
+ --hash=sha256:efef6a97e3ab49f3f40037dbf9a4166668a17cc6aaba13d5ecbabdf854a9b332
+six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259
smmap==3.0.5; python_version >= "3.4" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.4" \
@@ -115,6 +159,11 @@ smmap==3.0.5; python_version >= "3.4" and python_full_version < "3.0.0" or pytho
sqlparse==0.4.1; python_version >= "3.6" and python_version < "4.0" \
--hash=sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0 \
--hash=sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8
+webencodings==0.5.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
+ --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
+ --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
+xhtml2pdf==0.2.5 \
+ --hash=sha256:6797e974fac66f0efbe927c1539a2756ca4fe8777eaa5882bac132fc76b39421
zipp==3.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.7" or python_version >= "3.6" and python_version < "3.7" and python_full_version >= "3.5.0" \
--hash=sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108 \
--hash=sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb
diff --git a/mysql-requirements.txt b/mysql-requirements.txt
index 11868b0c..cfd7da0c 100644
--- a/mysql-requirements.txt
+++ b/mysql-requirements.txt
@@ -1,3 +1,7 @@
+arabic-reshaper==2.1.3 \
+ --hash=sha256:43f58136dbbfecab54ce0434e556c75689e46b0f11010578b893f72c504cd27b \
+ --hash=sha256:15078431d8f45eaca0a1710100aabc87abba13759c67eeb4538cca22fe167da1 \
+ --hash=sha256:a236fc6e9dde2a61cc6a5ca962b522e42694e1bb2a2d86894ed7a4eba4ce1890
django-autocomplete-light==3.8.1 \
--hash=sha256:4e84a6d95d272b0d7221614332e2bd54ffff15ec06e78947279398f6507ce225
django-bootstrap3==14.2.0; python_version >= "3.6" and python_version < "4.0" \
@@ -17,12 +21,17 @@ django==2.2.18; python_version >= "3.5" \
djangorestframework==3.12.2; python_version >= "3.5" \
--hash=sha256:0209bafcb7b5010fdfec784034f059d512256424de2a0f084cb82b096d6dd6a7 \
--hash=sha256:0898182b4737a7b584a2c73735d89816343369f259fea932d90dc78e35d8ac33
+future==0.18.2; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \
+ --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d
gitdb==4.0.5; python_version >= "3.4" \
--hash=sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac \
--hash=sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9
gitpython==3.1.13; python_version >= "3.4" \
--hash=sha256:c5347c81d232d9b8e7f47b68a83e5dc92e7952127133c5f2df9133f2c75a1b29 \
--hash=sha256:8621a7e777e276a5ec838b59280ba5272dd144a18169c36c903d8b38b99f750a
+html5lib==1.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
+ --hash=sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d \
+ --hash=sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f
importlib-metadata==1.7.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_version >= "3.6" and python_version < "3.8" and python_full_version >= "3.5.0" \
--hash=sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070 \
--hash=sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83
@@ -73,13 +82,48 @@ pillow==8.1.0; python_version >= "3.6" \
--hash=sha256:887668e792b7edbfb1d3c9d8b5d8c859269a0f0eba4dda562adb95500f60dbba
pycrypto==2.6.1 \
--hash=sha256:f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c
+pypdf2==1.26.0 \
+ --hash=sha256:e28f902f2f0a1603ea95ebe21dff311ef09be3d0f0ef29a3e44a932729564385
+python-bidi==0.4.2 \
+ --hash=sha256:5347f71e82b3e9976dc657f09ded2bfe39ba8d6777ca81a5b2c56c30121c496e \
+ --hash=sha256:50eef6f6a0bbdd685f9e8c207f3c9050f5b578d0a46e37c76a9c4baea2cc2e13
python-dateutil==2.8.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") \
--hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \
--hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a
pytz==2021.1; python_version >= "3.6" and python_version < "4.0" \
--hash=sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798 \
--hash=sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da
-six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \
+reportlab==3.5.68; python_version >= "3.6" and python_version < "4" \
+ --hash=sha256:c0612d9101f40679245e7d9edb169d8d79378a47f38cd8e6b38c55d7ff31db3f \
+ --hash=sha256:19708801278f600d712c04ee6bfb650e45d1b2898713f7bd97b39ab89bd08c1e \
+ --hash=sha256:46f15f5a34a50375c332ab8eaa907a0212c88787b0885ac25a9505c0741ee9ba \
+ --hash=sha256:28c72d27f21d74a7301789c7950b5e82a430ed38817ecee060fa1f2f3e959360 \
+ --hash=sha256:81d1958d90fccf86f62b38ecbedf9208a973d99e0747b6cd75036914ae8641c4 \
+ --hash=sha256:7e466276f1a1121dac23b703af6c22db0cedf6cec5139969f8387e8d8046f203 \
+ --hash=sha256:a48221d4ab7de37975ad052f7e565cf13ab708def63f203a38ae9927ab5442cd \
+ --hash=sha256:ced16daf89f948eeb4e376b5d814da5d99f7205fbd42e17a96f257e35dc31bdd \
+ --hash=sha256:70e7461aa47eff810be8c4e4a0cbc6fcf47aecaddd46de6ca4524c76065f8490 \
+ --hash=sha256:332f836ff4c975c92d307302e86a54d6f0e3d2ce33a35759812e7a1d17e2091f \
+ --hash=sha256:010f86a192c397f7c8ae667953a85d913395a8a6a8da112bff1c1ea28e679bcd \
+ --hash=sha256:6f905390f5e5801b21b6027c8ffaed915e5eec1e46bbdf6a74c8838213717b44 \
+ --hash=sha256:63578cab96fc4383e71dd9fe1877bb26ab78b2a6c91139068e99d130687289ab \
+ --hash=sha256:45113c1c359ba314499032c891487802cccd7c4225a3e930d6cf492d62ea4f07 \
+ --hash=sha256:b9ae0c534c09274b80f8fd87408071c1f814d56c5f51fe450b2157f1f13e921b \
+ --hash=sha256:66b5a08cbeb910edee7201efa786bd1bf7027c7ec526dddf7d60fc2252e2b30f \
+ --hash=sha256:08b53568979228b6969b790339d06a0b8db8883f92ae7339013f9878042dd9ca \
+ --hash=sha256:b57ebeb28f7a58a9da6f8c293acb6d31d89f634b3eba0b728a040cef08afc4ea \
+ --hash=sha256:dd3409ebabe699c98058690b7b730f93e6b0bd4ed5e49ca3b15e1530ae07b40b \
+ --hash=sha256:2dc5ee0c5b659697cdfbc218ec9abea54dd9c5a95ea8ca95245fe94f5ef111f9 \
+ --hash=sha256:b25608059558910585a9e229bae0fd3d67af49ae5e1c7a20057680c6b3d5f6f7 \
+ --hash=sha256:ad9a49890de59e8dd16fa0ce03ef607e46a5ff2f39de44f8556f796b3d4ddffb \
+ --hash=sha256:6063466779e438375bcdd2c15fc551ebd68f16ebfb2766497234df9cfa57e5b1 \
+ --hash=sha256:5865c4247229584408515055b5b19c7f935ae94433d6258c7a9234c4a07d6d34 \
+ --hash=sha256:2c0c88a7cf83a20a2bb355f97a1a9d0373a6de60c3aec35d301d3cc75dc4bb72 \
+ --hash=sha256:6b448a1824d381d282c5ea1da1669a5fa53dac67c57a1ecad6bcc149f286d1fd \
+ --hash=sha256:9a00feb8eafbce1283cd3edbb29735bd40c9566b3f45913110a301700c16b63a \
+ --hash=sha256:580eed6d9e5c20870ea909bec6840f9ceb9d13c33316d448cae21eb3ca47c7fd \
+ --hash=sha256:efef6a97e3ab49f3f40037dbf9a4166668a17cc6aaba13d5ecbabdf854a9b332
+six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259
smmap==3.0.5; python_version >= "3.4" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.4" \
@@ -88,6 +132,11 @@ smmap==3.0.5; python_version >= "3.4" and python_full_version < "3.0.0" or pytho
sqlparse==0.4.1; python_version >= "3.6" and python_version < "4.0" \
--hash=sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0 \
--hash=sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8
+webencodings==0.5.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
+ --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
+ --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
+xhtml2pdf==0.2.5 \
+ --hash=sha256:6797e974fac66f0efbe927c1539a2756ca4fe8777eaa5882bac132fc76b39421
zipp==3.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.7" or python_version >= "3.6" and python_version < "3.7" and python_full_version >= "3.5.0" \
--hash=sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108 \
--hash=sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb
diff --git a/poetry.lock b/poetry.lock
index d2100b7e..7947ee29 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -14,6 +14,20 @@ category = "dev"
optional = false
python-versions = "*"
+[[package]]
+name = "arabic-reshaper"
+version = "2.1.3"
+description = "Reconstruct Arabic sentences to be used in applications that don't support Arabic"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+future = "*"
+
+[package.extras]
+with-fonttools = ["fonttools (>=3.0)", "fonttools (>=4.0)"]
+
[[package]]
name = "babel"
version = "2.9.0"
@@ -230,6 +244,14 @@ category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+[[package]]
+name = "future"
+version = "0.18.2"
+description = "Clean single-source support for Python 3 and 2"
+category = "main"
+optional = false
+python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+
[[package]]
name = "gitdb"
version = "4.0.5"
@@ -252,6 +274,24 @@ python-versions = ">=3.4"
[package.dependencies]
gitdb = ">=4.0.1,<5"
+[[package]]
+name = "html5lib"
+version = "1.1"
+description = "HTML parser based on the WHATWG HTML specification"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+
+[package.dependencies]
+six = ">=1.9"
+webencodings = "*"
+
+[package.extras]
+all = ["genshi", "chardet (>=2.2)", "lxml"]
+chardet = ["chardet (>=2.2)"]
+genshi = ["genshi"]
+lxml = ["lxml"]
+
[[package]]
name = "idna"
version = "2.10"
@@ -425,6 +465,25 @@ category = "dev"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+[[package]]
+name = "pypdf2"
+version = "1.26.0"
+description = "PDF toolkit"
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "python-bidi"
+version = "0.4.2"
+description = "Pure python implementation of the BiDi layout algorithm"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+six = "*"
+
[[package]]
name = "python-dateutil"
version = "2.8.1"
@@ -472,6 +531,20 @@ category = "dev"
optional = false
python-versions = "*"
+[[package]]
+name = "reportlab"
+version = "3.5.68"
+description = "The Reportlab Toolkit"
+category = "main"
+optional = false
+python-versions = ">=2.7, >=3.6, <4"
+
+[package.dependencies]
+pillow = ">=4.0.0"
+
+[package.extras]
+rlpycairo = ["rlPyCairo (>=0.0.5)"]
+
[[package]]
name = "requests"
version = "2.25.1"
@@ -686,6 +759,31 @@ brotli = ["brotlipy (>=0.6.0)"]
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
+[[package]]
+name = "webencodings"
+version = "0.5.1"
+description = "Character encoding aliases for legacy web content"
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "xhtml2pdf"
+version = "0.2.5"
+description = "PDF generator using HTML and CSS"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+arabic-reshaper = ">=2.1.0"
+html5lib = ">=1.0"
+Pillow = "*"
+pyPdf2 = "*"
+python-bidi = ">=0.4.2"
+reportlab = ">=3.3.0"
+six = "*"
+
[[package]]
name = "zipp"
version = "3.4.0"
@@ -706,7 +804,7 @@ postgresql = ["psycopg2"]
[metadata]
lock-version = "1.1"
python-versions = ">=3.6,<4.0"
-content-hash = "c914e5f3cc676263f65d9489e9ea748770edb046ec45625424a67375760c791a"
+content-hash = "dcff1c3e9000841ed41011e854cde16f15cf671daf31efc0a1514ea283ccad2d"
[metadata.files]
alabaster = [
@@ -717,6 +815,11 @@ appdirs = [
{file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
{file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
]
+arabic-reshaper = [
+ {file = "arabic_reshaper-2.1.3-py2-none-any.whl", hash = "sha256:43f58136dbbfecab54ce0434e556c75689e46b0f11010578b893f72c504cd27b"},
+ {file = "arabic_reshaper-2.1.3-py3-none-any.whl", hash = "sha256:15078431d8f45eaca0a1710100aabc87abba13759c67eeb4538cca22fe167da1"},
+ {file = "arabic_reshaper-2.1.3.tar.gz", hash = "sha256:a236fc6e9dde2a61cc6a5ca962b522e42694e1bb2a2d86894ed7a4eba4ce1890"},
+]
babel = [
{file = "Babel-2.9.0-py2.py3-none-any.whl", hash = "sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5"},
{file = "Babel-2.9.0.tar.gz", hash = "sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05"},
@@ -833,6 +936,9 @@ docutils = [
{file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"},
{file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"},
]
+future = [
+ {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"},
+]
gitdb = [
{file = "gitdb-4.0.5-py3-none-any.whl", hash = "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac"},
{file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"},
@@ -841,6 +947,10 @@ gitpython = [
{file = "GitPython-3.1.13-py3-none-any.whl", hash = "sha256:c5347c81d232d9b8e7f47b68a83e5dc92e7952127133c5f2df9133f2c75a1b29"},
{file = "GitPython-3.1.13.tar.gz", hash = "sha256:8621a7e777e276a5ec838b59280ba5272dd144a18169c36c903d8b38b99f750a"},
]
+html5lib = [
+ {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"},
+ {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"},
+]
idna = [
{file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"},
{file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"},
@@ -1030,6 +1140,13 @@ pyparsing = [
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
]
+pypdf2 = [
+ {file = "PyPDF2-1.26.0.tar.gz", hash = "sha256:e28f902f2f0a1603ea95ebe21dff311ef09be3d0f0ef29a3e44a932729564385"},
+]
+python-bidi = [
+ {file = "python-bidi-0.4.2.tar.gz", hash = "sha256:5347f71e82b3e9976dc657f09ded2bfe39ba8d6777ca81a5b2c56c30121c496e"},
+ {file = "python_bidi-0.4.2-py2.py3-none-any.whl", hash = "sha256:50eef6f6a0bbdd685f9e8c207f3c9050f5b578d0a46e37c76a9c4baea2cc2e13"},
+]
python-dateutil = [
{file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
@@ -1048,18 +1165,26 @@ pyyaml = [
{file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"},
{file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"},
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"},
+ {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"},
+ {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"},
{file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"},
{file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"},
{file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"},
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"},
+ {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"},
+ {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"},
{file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"},
{file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"},
{file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"},
{file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"},
+ {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"},
+ {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"},
{file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"},
{file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"},
{file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"},
{file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"},
+ {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"},
+ {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"},
{file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"},
{file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"},
{file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
@@ -1107,6 +1232,37 @@ regex = [
{file = "regex-2020.11.13-cp39-cp39-win_amd64.whl", hash = "sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d"},
{file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"},
]
+reportlab = [
+ {file = "reportlab-3.5.68-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:c0612d9101f40679245e7d9edb169d8d79378a47f38cd8e6b38c55d7ff31db3f"},
+ {file = "reportlab-3.5.68-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:19708801278f600d712c04ee6bfb650e45d1b2898713f7bd97b39ab89bd08c1e"},
+ {file = "reportlab-3.5.68-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:46f15f5a34a50375c332ab8eaa907a0212c88787b0885ac25a9505c0741ee9ba"},
+ {file = "reportlab-3.5.68-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28c72d27f21d74a7301789c7950b5e82a430ed38817ecee060fa1f2f3e959360"},
+ {file = "reportlab-3.5.68-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:81d1958d90fccf86f62b38ecbedf9208a973d99e0747b6cd75036914ae8641c4"},
+ {file = "reportlab-3.5.68-cp36-cp36m-win32.whl", hash = "sha256:7e466276f1a1121dac23b703af6c22db0cedf6cec5139969f8387e8d8046f203"},
+ {file = "reportlab-3.5.68-cp36-cp36m-win_amd64.whl", hash = "sha256:a48221d4ab7de37975ad052f7e565cf13ab708def63f203a38ae9927ab5442cd"},
+ {file = "reportlab-3.5.68-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:ced16daf89f948eeb4e376b5d814da5d99f7205fbd42e17a96f257e35dc31bdd"},
+ {file = "reportlab-3.5.68-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:70e7461aa47eff810be8c4e4a0cbc6fcf47aecaddd46de6ca4524c76065f8490"},
+ {file = "reportlab-3.5.68-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:332f836ff4c975c92d307302e86a54d6f0e3d2ce33a35759812e7a1d17e2091f"},
+ {file = "reportlab-3.5.68-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:010f86a192c397f7c8ae667953a85d913395a8a6a8da112bff1c1ea28e679bcd"},
+ {file = "reportlab-3.5.68-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6f905390f5e5801b21b6027c8ffaed915e5eec1e46bbdf6a74c8838213717b44"},
+ {file = "reportlab-3.5.68-cp37-cp37m-win32.whl", hash = "sha256:63578cab96fc4383e71dd9fe1877bb26ab78b2a6c91139068e99d130687289ab"},
+ {file = "reportlab-3.5.68-cp37-cp37m-win_amd64.whl", hash = "sha256:45113c1c359ba314499032c891487802cccd7c4225a3e930d6cf492d62ea4f07"},
+ {file = "reportlab-3.5.68-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b9ae0c534c09274b80f8fd87408071c1f814d56c5f51fe450b2157f1f13e921b"},
+ {file = "reportlab-3.5.68-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:66b5a08cbeb910edee7201efa786bd1bf7027c7ec526dddf7d60fc2252e2b30f"},
+ {file = "reportlab-3.5.68-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:08b53568979228b6969b790339d06a0b8db8883f92ae7339013f9878042dd9ca"},
+ {file = "reportlab-3.5.68-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b57ebeb28f7a58a9da6f8c293acb6d31d89f634b3eba0b728a040cef08afc4ea"},
+ {file = "reportlab-3.5.68-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:dd3409ebabe699c98058690b7b730f93e6b0bd4ed5e49ca3b15e1530ae07b40b"},
+ {file = "reportlab-3.5.68-cp38-cp38-win32.whl", hash = "sha256:2dc5ee0c5b659697cdfbc218ec9abea54dd9c5a95ea8ca95245fe94f5ef111f9"},
+ {file = "reportlab-3.5.68-cp38-cp38-win_amd64.whl", hash = "sha256:b25608059558910585a9e229bae0fd3d67af49ae5e1c7a20057680c6b3d5f6f7"},
+ {file = "reportlab-3.5.68-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:ad9a49890de59e8dd16fa0ce03ef607e46a5ff2f39de44f8556f796b3d4ddffb"},
+ {file = "reportlab-3.5.68-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6063466779e438375bcdd2c15fc551ebd68f16ebfb2766497234df9cfa57e5b1"},
+ {file = "reportlab-3.5.68-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5865c4247229584408515055b5b19c7f935ae94433d6258c7a9234c4a07d6d34"},
+ {file = "reportlab-3.5.68-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c0c88a7cf83a20a2bb355f97a1a9d0373a6de60c3aec35d301d3cc75dc4bb72"},
+ {file = "reportlab-3.5.68-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6b448a1824d381d282c5ea1da1669a5fa53dac67c57a1ecad6bcc149f286d1fd"},
+ {file = "reportlab-3.5.68-cp39-cp39-win32.whl", hash = "sha256:9a00feb8eafbce1283cd3edbb29735bd40c9566b3f45913110a301700c16b63a"},
+ {file = "reportlab-3.5.68-cp39-cp39-win_amd64.whl", hash = "sha256:580eed6d9e5c20870ea909bec6840f9ceb9d13c33316d448cae21eb3ca47c7fd"},
+ {file = "reportlab-3.5.68.tar.gz", hash = "sha256:efef6a97e3ab49f3f40037dbf9a4166668a17cc6aaba13d5ecbabdf854a9b332"},
+]
requests = [
{file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"},
{file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"},
@@ -1207,6 +1363,13 @@ urllib3 = [
{file = "urllib3-1.26.3-py2.py3-none-any.whl", hash = "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80"},
{file = "urllib3-1.26.3.tar.gz", hash = "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73"},
]
+webencodings = [
+ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
+ {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
+]
+xhtml2pdf = [
+ {file = "xhtml2pdf-0.2.5.tar.gz", hash = "sha256:6797e974fac66f0efbe927c1539a2756ca4fe8777eaa5882bac132fc76b39421"},
+]
zipp = [
{file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"},
{file = "zipp-3.4.0.tar.gz", hash = "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb"},
diff --git a/postgresql-requirements.txt b/postgresql-requirements.txt
index 5a149681..62880c0b 100644
--- a/postgresql-requirements.txt
+++ b/postgresql-requirements.txt
@@ -1,3 +1,7 @@
+arabic-reshaper==2.1.3 \
+ --hash=sha256:43f58136dbbfecab54ce0434e556c75689e46b0f11010578b893f72c504cd27b \
+ --hash=sha256:15078431d8f45eaca0a1710100aabc87abba13759c67eeb4538cca22fe167da1 \
+ --hash=sha256:a236fc6e9dde2a61cc6a5ca962b522e42694e1bb2a2d86894ed7a4eba4ce1890
django-autocomplete-light==3.8.1 \
--hash=sha256:4e84a6d95d272b0d7221614332e2bd54ffff15ec06e78947279398f6507ce225
django-bootstrap3==14.2.0; python_version >= "3.6" and python_version < "4.0" \
@@ -17,12 +21,17 @@ django==2.2.18; python_version >= "3.5" \
djangorestframework==3.12.2; python_version >= "3.5" \
--hash=sha256:0209bafcb7b5010fdfec784034f059d512256424de2a0f084cb82b096d6dd6a7 \
--hash=sha256:0898182b4737a7b584a2c73735d89816343369f259fea932d90dc78e35d8ac33
+future==0.18.2; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \
+ --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d
gitdb==4.0.5; python_version >= "3.4" \
--hash=sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac \
--hash=sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9
gitpython==3.1.13; python_version >= "3.4" \
--hash=sha256:c5347c81d232d9b8e7f47b68a83e5dc92e7952127133c5f2df9133f2c75a1b29 \
--hash=sha256:8621a7e777e276a5ec838b59280ba5272dd144a18169c36c903d8b38b99f750a
+html5lib==1.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
+ --hash=sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d \
+ --hash=sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f
importlib-metadata==1.7.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_version >= "3.6" and python_version < "3.8" and python_full_version >= "3.5.0" \
--hash=sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070 \
--hash=sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83
@@ -83,13 +92,48 @@ psycopg2==2.8.6; (python_version >= "2.7" and python_full_version < "3.0.0") or
--hash=sha256:fb23f6c71107c37fd667cb4ea363ddeb936b348bbd6449278eb92c189699f543
pycrypto==2.6.1 \
--hash=sha256:f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c
+pypdf2==1.26.0 \
+ --hash=sha256:e28f902f2f0a1603ea95ebe21dff311ef09be3d0f0ef29a3e44a932729564385
+python-bidi==0.4.2 \
+ --hash=sha256:5347f71e82b3e9976dc657f09ded2bfe39ba8d6777ca81a5b2c56c30121c496e \
+ --hash=sha256:50eef6f6a0bbdd685f9e8c207f3c9050f5b578d0a46e37c76a9c4baea2cc2e13
python-dateutil==2.8.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") \
--hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \
--hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a
pytz==2021.1; python_version >= "3.6" and python_version < "4.0" \
--hash=sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798 \
--hash=sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da
-six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \
+reportlab==3.5.68; python_version >= "3.6" and python_version < "4" \
+ --hash=sha256:c0612d9101f40679245e7d9edb169d8d79378a47f38cd8e6b38c55d7ff31db3f \
+ --hash=sha256:19708801278f600d712c04ee6bfb650e45d1b2898713f7bd97b39ab89bd08c1e \
+ --hash=sha256:46f15f5a34a50375c332ab8eaa907a0212c88787b0885ac25a9505c0741ee9ba \
+ --hash=sha256:28c72d27f21d74a7301789c7950b5e82a430ed38817ecee060fa1f2f3e959360 \
+ --hash=sha256:81d1958d90fccf86f62b38ecbedf9208a973d99e0747b6cd75036914ae8641c4 \
+ --hash=sha256:7e466276f1a1121dac23b703af6c22db0cedf6cec5139969f8387e8d8046f203 \
+ --hash=sha256:a48221d4ab7de37975ad052f7e565cf13ab708def63f203a38ae9927ab5442cd \
+ --hash=sha256:ced16daf89f948eeb4e376b5d814da5d99f7205fbd42e17a96f257e35dc31bdd \
+ --hash=sha256:70e7461aa47eff810be8c4e4a0cbc6fcf47aecaddd46de6ca4524c76065f8490 \
+ --hash=sha256:332f836ff4c975c92d307302e86a54d6f0e3d2ce33a35759812e7a1d17e2091f \
+ --hash=sha256:010f86a192c397f7c8ae667953a85d913395a8a6a8da112bff1c1ea28e679bcd \
+ --hash=sha256:6f905390f5e5801b21b6027c8ffaed915e5eec1e46bbdf6a74c8838213717b44 \
+ --hash=sha256:63578cab96fc4383e71dd9fe1877bb26ab78b2a6c91139068e99d130687289ab \
+ --hash=sha256:45113c1c359ba314499032c891487802cccd7c4225a3e930d6cf492d62ea4f07 \
+ --hash=sha256:b9ae0c534c09274b80f8fd87408071c1f814d56c5f51fe450b2157f1f13e921b \
+ --hash=sha256:66b5a08cbeb910edee7201efa786bd1bf7027c7ec526dddf7d60fc2252e2b30f \
+ --hash=sha256:08b53568979228b6969b790339d06a0b8db8883f92ae7339013f9878042dd9ca \
+ --hash=sha256:b57ebeb28f7a58a9da6f8c293acb6d31d89f634b3eba0b728a040cef08afc4ea \
+ --hash=sha256:dd3409ebabe699c98058690b7b730f93e6b0bd4ed5e49ca3b15e1530ae07b40b \
+ --hash=sha256:2dc5ee0c5b659697cdfbc218ec9abea54dd9c5a95ea8ca95245fe94f5ef111f9 \
+ --hash=sha256:b25608059558910585a9e229bae0fd3d67af49ae5e1c7a20057680c6b3d5f6f7 \
+ --hash=sha256:ad9a49890de59e8dd16fa0ce03ef607e46a5ff2f39de44f8556f796b3d4ddffb \
+ --hash=sha256:6063466779e438375bcdd2c15fc551ebd68f16ebfb2766497234df9cfa57e5b1 \
+ --hash=sha256:5865c4247229584408515055b5b19c7f935ae94433d6258c7a9234c4a07d6d34 \
+ --hash=sha256:2c0c88a7cf83a20a2bb355f97a1a9d0373a6de60c3aec35d301d3cc75dc4bb72 \
+ --hash=sha256:6b448a1824d381d282c5ea1da1669a5fa53dac67c57a1ecad6bcc149f286d1fd \
+ --hash=sha256:9a00feb8eafbce1283cd3edbb29735bd40c9566b3f45913110a301700c16b63a \
+ --hash=sha256:580eed6d9e5c20870ea909bec6840f9ceb9d13c33316d448cae21eb3ca47c7fd \
+ --hash=sha256:efef6a97e3ab49f3f40037dbf9a4166668a17cc6aaba13d5ecbabdf854a9b332
+six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259
smmap==3.0.5; python_version >= "3.4" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.4" \
@@ -98,6 +142,11 @@ smmap==3.0.5; python_version >= "3.4" and python_full_version < "3.0.0" or pytho
sqlparse==0.4.1; python_version >= "3.6" and python_version < "4.0" \
--hash=sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0 \
--hash=sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8
+webencodings==0.5.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
+ --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
+ --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
+xhtml2pdf==0.2.5 \
+ --hash=sha256:6797e974fac66f0efbe927c1539a2756ca4fe8777eaa5882bac132fc76b39421
zipp==3.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.7" or python_version >= "3.6" and python_version < "3.7" and python_full_version >= "3.5.0" \
--hash=sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108 \
--hash=sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb
diff --git a/preferences/models.py b/preferences/models.py
index 799fd006..84750e09 100644
--- a/preferences/models.py
+++ b/preferences/models.py
@@ -986,14 +986,14 @@ class RadiusOption(AclMixin, PreferencesModel):
def default_invoice():
tpl, _ = DocumentTemplate.objects.get_or_create(
- name="Re2o default invoice", template="templates/default_invoice.tex"
+ name="Re2o default invoice", template="templates/default_invoice.html"
)
return tpl.id
def default_voucher():
tpl, _ = DocumentTemplate.objects.get_or_create(
- name="Re2o default voucher", template="templates/default_voucher.tex"
+ name="Re2o default voucher", template="templates/default_voucher.html"
)
return tpl.id
diff --git a/pyproject.toml b/pyproject.toml
index 008450ee..af537f62 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -58,6 +58,7 @@ GitPython = "^3.1.13"
mysqlclient = {version = "^2.0.3", optional=true}
psycopg2 = {version = "^2.8.6", optional=true}
django-ldapdb = {version = "^1.5.1", optional=true}
+xhtml2pdf = "^0.2.5"
[tool.poetry.extras]
mysql = ["mysqlclient"]
diff --git a/requirements.txt b/requirements.txt
index 5c8e4a5a..49512a64 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,7 @@
+arabic-reshaper==2.1.3 \
+ --hash=sha256:43f58136dbbfecab54ce0434e556c75689e46b0f11010578b893f72c504cd27b \
+ --hash=sha256:15078431d8f45eaca0a1710100aabc87abba13759c67eeb4538cca22fe167da1 \
+ --hash=sha256:a236fc6e9dde2a61cc6a5ca962b522e42694e1bb2a2d86894ed7a4eba4ce1890
django-autocomplete-light==3.8.1 \
--hash=sha256:4e84a6d95d272b0d7221614332e2bd54ffff15ec06e78947279398f6507ce225
django-bootstrap3==14.2.0; python_version >= "3.6" and python_version < "4.0" \
@@ -17,12 +21,17 @@ django==2.2.18; python_version >= "3.5" \
djangorestframework==3.12.2; python_version >= "3.5" \
--hash=sha256:0209bafcb7b5010fdfec784034f059d512256424de2a0f084cb82b096d6dd6a7 \
--hash=sha256:0898182b4737a7b584a2c73735d89816343369f259fea932d90dc78e35d8ac33
+future==0.18.2; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \
+ --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d
gitdb==4.0.5; python_version >= "3.4" \
--hash=sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac \
--hash=sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9
gitpython==3.1.13; python_version >= "3.4" \
--hash=sha256:c5347c81d232d9b8e7f47b68a83e5dc92e7952127133c5f2df9133f2c75a1b29 \
--hash=sha256:8621a7e777e276a5ec838b59280ba5272dd144a18169c36c903d8b38b99f750a
+html5lib==1.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
+ --hash=sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d \
+ --hash=sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f
importlib-metadata==1.7.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_version >= "3.6" and python_version < "3.8" and python_full_version >= "3.5.0" \
--hash=sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070 \
--hash=sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83
@@ -67,13 +76,48 @@ pillow==8.1.0; python_version >= "3.6" \
--hash=sha256:887668e792b7edbfb1d3c9d8b5d8c859269a0f0eba4dda562adb95500f60dbba
pycrypto==2.6.1 \
--hash=sha256:f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c
+pypdf2==1.26.0 \
+ --hash=sha256:e28f902f2f0a1603ea95ebe21dff311ef09be3d0f0ef29a3e44a932729564385
+python-bidi==0.4.2 \
+ --hash=sha256:5347f71e82b3e9976dc657f09ded2bfe39ba8d6777ca81a5b2c56c30121c496e \
+ --hash=sha256:50eef6f6a0bbdd685f9e8c207f3c9050f5b578d0a46e37c76a9c4baea2cc2e13
python-dateutil==2.8.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") \
--hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \
--hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a
pytz==2021.1; python_version >= "3.6" and python_version < "4.0" \
--hash=sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798 \
--hash=sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da
-six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \
+reportlab==3.5.68; python_version >= "3.6" and python_version < "4" \
+ --hash=sha256:c0612d9101f40679245e7d9edb169d8d79378a47f38cd8e6b38c55d7ff31db3f \
+ --hash=sha256:19708801278f600d712c04ee6bfb650e45d1b2898713f7bd97b39ab89bd08c1e \
+ --hash=sha256:46f15f5a34a50375c332ab8eaa907a0212c88787b0885ac25a9505c0741ee9ba \
+ --hash=sha256:28c72d27f21d74a7301789c7950b5e82a430ed38817ecee060fa1f2f3e959360 \
+ --hash=sha256:81d1958d90fccf86f62b38ecbedf9208a973d99e0747b6cd75036914ae8641c4 \
+ --hash=sha256:7e466276f1a1121dac23b703af6c22db0cedf6cec5139969f8387e8d8046f203 \
+ --hash=sha256:a48221d4ab7de37975ad052f7e565cf13ab708def63f203a38ae9927ab5442cd \
+ --hash=sha256:ced16daf89f948eeb4e376b5d814da5d99f7205fbd42e17a96f257e35dc31bdd \
+ --hash=sha256:70e7461aa47eff810be8c4e4a0cbc6fcf47aecaddd46de6ca4524c76065f8490 \
+ --hash=sha256:332f836ff4c975c92d307302e86a54d6f0e3d2ce33a35759812e7a1d17e2091f \
+ --hash=sha256:010f86a192c397f7c8ae667953a85d913395a8a6a8da112bff1c1ea28e679bcd \
+ --hash=sha256:6f905390f5e5801b21b6027c8ffaed915e5eec1e46bbdf6a74c8838213717b44 \
+ --hash=sha256:63578cab96fc4383e71dd9fe1877bb26ab78b2a6c91139068e99d130687289ab \
+ --hash=sha256:45113c1c359ba314499032c891487802cccd7c4225a3e930d6cf492d62ea4f07 \
+ --hash=sha256:b9ae0c534c09274b80f8fd87408071c1f814d56c5f51fe450b2157f1f13e921b \
+ --hash=sha256:66b5a08cbeb910edee7201efa786bd1bf7027c7ec526dddf7d60fc2252e2b30f \
+ --hash=sha256:08b53568979228b6969b790339d06a0b8db8883f92ae7339013f9878042dd9ca \
+ --hash=sha256:b57ebeb28f7a58a9da6f8c293acb6d31d89f634b3eba0b728a040cef08afc4ea \
+ --hash=sha256:dd3409ebabe699c98058690b7b730f93e6b0bd4ed5e49ca3b15e1530ae07b40b \
+ --hash=sha256:2dc5ee0c5b659697cdfbc218ec9abea54dd9c5a95ea8ca95245fe94f5ef111f9 \
+ --hash=sha256:b25608059558910585a9e229bae0fd3d67af49ae5e1c7a20057680c6b3d5f6f7 \
+ --hash=sha256:ad9a49890de59e8dd16fa0ce03ef607e46a5ff2f39de44f8556f796b3d4ddffb \
+ --hash=sha256:6063466779e438375bcdd2c15fc551ebd68f16ebfb2766497234df9cfa57e5b1 \
+ --hash=sha256:5865c4247229584408515055b5b19c7f935ae94433d6258c7a9234c4a07d6d34 \
+ --hash=sha256:2c0c88a7cf83a20a2bb355f97a1a9d0373a6de60c3aec35d301d3cc75dc4bb72 \
+ --hash=sha256:6b448a1824d381d282c5ea1da1669a5fa53dac67c57a1ecad6bcc149f286d1fd \
+ --hash=sha256:9a00feb8eafbce1283cd3edbb29735bd40c9566b3f45913110a301700c16b63a \
+ --hash=sha256:580eed6d9e5c20870ea909bec6840f9ceb9d13c33316d448cae21eb3ca47c7fd \
+ --hash=sha256:efef6a97e3ab49f3f40037dbf9a4166668a17cc6aaba13d5ecbabdf854a9b332
+six==1.15.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259
smmap==3.0.5; python_version >= "3.4" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.4" \
@@ -82,6 +126,11 @@ smmap==3.0.5; python_version >= "3.4" and python_full_version < "3.0.0" or pytho
sqlparse==0.4.1; python_version >= "3.6" and python_version < "4.0" \
--hash=sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0 \
--hash=sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8
+webencodings==0.5.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
+ --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
+ --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
+xhtml2pdf==0.2.5 \
+ --hash=sha256:6797e974fac66f0efbe927c1539a2756ca4fe8777eaa5882bac132fc76b39421
zipp==3.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.7" or python_version >= "3.6" and python_version < "3.7" and python_full_version >= "3.5.0" \
--hash=sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108 \
--hash=sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb