8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-05 01:16:27 +00:00

Add Document templates to re2o

This commit is contained in:
Hugo LEVY-FALK 2019-01-03 19:52:06 +01:00
parent 1cc5d7bba0
commit 6fdf8a0406
10 changed files with 366 additions and 19 deletions

View file

@ -31,6 +31,7 @@ from reversion.admin import VersionAdmin
from .models import Facture, Article, Banque, Paiement, Cotisation, Vente from .models import Facture, Article, Banque, Paiement, Cotisation, Vente
from .models import CustomInvoice, CostEstimate from .models import CustomInvoice, CostEstimate
from .tex import DocumentTemplate
class FactureAdmin(VersionAdmin): class FactureAdmin(VersionAdmin):
@ -74,6 +75,11 @@ class CotisationAdmin(VersionAdmin):
pass pass
class DocumentTemplateAdmin(VersionAdmin):
"""Admin class for DocumentTemplate"""
pass
admin.site.register(Facture, FactureAdmin) admin.site.register(Facture, FactureAdmin)
admin.site.register(Article, ArticleAdmin) admin.site.register(Article, ArticleAdmin)
admin.site.register(Banque, BanqueAdmin) admin.site.register(Banque, BanqueAdmin)
@ -82,3 +88,4 @@ admin.site.register(Vente, VenteAdmin)
admin.site.register(Cotisation, CotisationAdmin) admin.site.register(Cotisation, CotisationAdmin)
admin.site.register(CustomInvoice, CustomInvoiceAdmin) admin.site.register(CustomInvoice, CustomInvoiceAdmin)
admin.site.register(CostEstimate, CostEstimateAdmin) admin.site.register(CostEstimate, CostEstimateAdmin)
admin.site.register(DocumentTemplate, DocumentTemplateAdmin)

View file

@ -50,6 +50,7 @@ from .models import (
Article, Paiement, Facture, Banque, Article, Paiement, Facture, Banque,
CustomInvoice, Vente, CostEstimate CustomInvoice, Vente, CostEstimate
) )
from .tex import DocumentTemplate
from .payment_methods import balance from .payment_methods import balance
@ -316,3 +317,37 @@ class RechargeForm(FormRevMixin, Form):
} }
) )
return self.cleaned_data return self.cleaned_data
class DocumentTemplateForm(FormRevMixin, ModelForm):
"""
Form used to create a document template.
"""
class Meta:
model = DocumentTemplate
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(DocumentTemplateForm, self).__init__(
*args, prefix=prefix, **kwargs)
class DelDocumentTemplateForm(FormRevMixin, Form):
"""
Form used to delete one or more document templatess.
The use must choose the one to delete by checking the boxes.
"""
document_templates = forms.ModelMultipleChoiceField(
queryset=DocumentTemplate.objects.none(),
label=_("Available document templates"),
widget=forms.CheckboxSelectMultiple
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop('instances', None)
super(DelDocumentTemplateForm, self).__init__(*args, **kwargs)
if instances:
self.fields['document_templates'].queryset = instances
else:
self.fields['document_templates'].queryset = Banque.objects.all()

View file

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2019-01-03 16:48
from __future__ import unicode_literals
import os
from django.db import migrations, models
from django.core.files import File
from django.conf import settings
import re2o.mixins
def create_default_templates(apps, schema_editor):
DocumentTemplate = apps.get_model('cotisations', 'DocumentTemplate')
invoice_path = os.path.join(
settings.BASE_DIR,
"cotisations",
"templates",
"cotisations",
"factures.tex"
)
with open(invoice_path) as f:
tpl, _ = DocumentTemplate.objects.get_or_create(
name="Re2o default invoice",
)
tpl.template.save('default_invoice.tex', File(f))
tpl.save()
class Migration(migrations.Migration):
dependencies = [
('cotisations', '0038_auto_20181231_1657'),
]
operations = [
migrations.CreateModel(
name='DocumentTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('template', models.FileField(upload_to='templates/', verbose_name='template')),
('name', models.CharField(max_length=255, verbose_name='name')),
],
options={
'verbose_name_plural': 'document templates',
'verbose_name': 'document template',
},
bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model),
),
migrations.RunPython(create_default_templates),
]

View file

@ -0,0 +1,50 @@
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2017 Gabriel Détraz
Copyright © 2017 Goulven Kermarec
Copyright © 2017 Augustin Lemesle
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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.
{% endcomment %}
{% load acl %}
{% load i18n %}
{% load logs_extra %}
<table class="table table-striped">
<thead>
<tr>
<th>{% trans "Document template" %}</th>
<th>{% trans "File" %}</th>
<th></th>
</tr>
</thead>
{% for template in document_template_list %}
<tr>
<td>{{ template.name }}</td>
<td><a href="{{template.template.url}}">{{template.template}}</a></td>
<td class="text-right">
{% can_edit template %}
{% include 'buttons/edit.html' with href='cotisations:edit-document-template' id=template.id %}
{% acl_end %}
{% history_button template %}
</td>
</tr>
{% endfor %}
</table>

View file

@ -0,0 +1,42 @@
{% extends "cotisations/sidebar.html" %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2019 Hugo LEVY-FALK
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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.
{% endcomment %}
{% load bootstrap3 %}
{% load acl %}
{% load i18n %}
{% block title %}{% trans "Document Templates" %}{% endblock %}
{% block content %}
<h2>{% trans "Document templates list" %}</h2>
{% can_create Banque %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:add-document-template' %}">
<i class="fa fa-cart-plus"></i> {% trans "Add a document template" %}
</a>
{% acl_end %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:del-document-template' %}">
<i class="fa fa-trash"></i> {% trans "Delete one or several document templates" %}
</a>
{% include 'cotisations/aff_document_template.html' %}
{% endblock %}

View file

@ -65,5 +65,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<i class="fa fa-list-ul"></i> {% trans "Payment methods" %} <i class="fa fa-list-ul"></i> {% trans "Payment methods" %}
</a> </a>
{% acl_end %} {% acl_end %}
{% can_view_all DocumentTemplate %}
<a class="list-group-item list-group-item-info" href="{% url "cotisations:index-document-template" %}">
<i class="fa fa-list-ul"></i> {% trans "Document templates" %}
</a>
{% acl_end %}
{% endblock %} {% endblock %}

View file

@ -31,12 +31,15 @@ from subprocess import Popen, PIPE
import os import os
from datetime import datetime from datetime import datetime
from django.db import models
from django.template.loader import get_template from django.template.loader import get_template
from django.template import Context from django.template import Context
from django.http import HttpResponse from django.http import HttpResponse
from django.conf import settings from django.conf import settings
from django.utils.text import slugify from django.utils.text import slugify
import logging from django.utils.translation import ugettext_lazy as _
from re2o.mixins import AclMixin, RevMixin
TEMP_PREFIX = getattr(settings, 'TEX_TEMP_PREFIX', 'render_tex-') TEMP_PREFIX = getattr(settings, 'TEX_TEMP_PREFIX', 'render_tex-')
@ -44,6 +47,27 @@ CACHE_PREFIX = getattr(settings, 'TEX_CACHE_PREFIX', 'render-tex')
CACHE_TIMEOUT = getattr(settings, 'TEX_CACHE_TIMEOUT', 86400) # 1 day CACHE_TIMEOUT = getattr(settings, 'TEX_CACHE_TIMEOUT', 86400) # 1 day
class DocumentTemplate(RevMixin, AclMixin, models.Model):
"""Represent a template in order to create documents such as invoice or
subscribtion voucher.
"""
template = models.FileField(
upload_to='templates/',
verbose_name=_('template')
)
name = models.CharField(
max_length=255,
verbose_name=_('name')
)
class Meta:
verbose_name = _("document template")
verbose_name_plural = _("document templates")
def __str__(self):
return str(self.name)
def render_invoice(_request, ctx={}): def render_invoice(_request, ctx={}):
""" """
Render an invoice using some available information such as the current Render an invoice using some available information such as the current

View file

@ -176,5 +176,25 @@ urlpatterns = [
views.control, views.control,
name='control' name='control'
), ),
url(
r'^add_document_template/$',
views.add_document_template,
name='add-document-template'
),
url(
r'^edit_document_template/(?P<documenttemplateid>[0-9]+)$',
views.edit_document_template,
name='edit-document-template'
),
url(
r'^del_document_template/$',
views.del_document_template,
name='del-document-template'
),
url(
r'^index_document_template/$',
views.index_document_template,
name='index-document-template'
),
url(r'^$', views.index, name='index'), url(r'^$', views.index, name='index'),
] + payment_methods.urls.urlpatterns ] + payment_methods.urls.urlpatterns

View file

@ -84,8 +84,10 @@ from .forms import (
CustomInvoiceForm, CustomInvoiceForm,
DiscountForm, DiscountForm,
CostEstimateForm, CostEstimateForm,
DocumentTemplateForm,
DelDocumentTemplateForm
) )
from .tex import render_invoice, escape_chars from .tex import render_invoice, escape_chars, DocumentTemplate
from .payment_methods.forms import payment_method_factory from .payment_methods.forms import payment_method_factory
from .utils import find_payment_method from .utils import find_payment_method
@ -720,7 +722,7 @@ def edit_paiement(request, paiement_instance, **_kwargs):
if payment_method is not None: if payment_method is not None:
payment_method.save() payment_method.save()
messages.success( messages.success(
request,_("The payment method was edited.") request, _("The payment method was edited.")
) )
return redirect(reverse('cotisations:index-paiement')) return redirect(reverse('cotisations:index-paiement'))
return form({ return form({
@ -954,7 +956,8 @@ def index_custom_invoice(request):
"""View used to display every custom invoice.""" """View used to display every custom invoice."""
pagination_number = GeneralOption.get_cached_value('pagination_number') pagination_number = GeneralOption.get_cached_value('pagination_number')
cost_estimate_ids = [i for i, in CostEstimate.objects.values_list('id')] cost_estimate_ids = [i for i, in CostEstimate.objects.values_list('id')]
custom_invoice_list = CustomInvoice.objects.prefetch_related('vente_set').exclude(id__in=cost_estimate_ids) custom_invoice_list = CustomInvoice.objects.prefetch_related(
'vente_set').exclude(id__in=cost_estimate_ids)
custom_invoice_list = SortTable.sort( custom_invoice_list = SortTable.sort(
custom_invoice_list, custom_invoice_list,
request.GET.get('col'), request.GET.get('col'),
@ -1020,7 +1023,8 @@ def credit_solde(request, user, **_kwargs):
kwargs={'userid': user.id} kwargs={'userid': user.id}
)) ))
refill_form = RechargeForm(request.POST or None, user=user, user_source=request.user) refill_form = RechargeForm(
request.POST or None, user=user, user_source=request.user)
if refill_form.is_valid(): if refill_form.is_valid():
price = refill_form.cleaned_data['value'] price = refill_form.cleaned_data['value']
invoice = Facture(user=user) invoice = Facture(user=user)
@ -1050,3 +1054,93 @@ def credit_solde(request, user, **_kwargs):
'max_balance': find_payment_method(p).maximum_balance, 'max_balance': find_payment_method(p).maximum_balance,
}, 'cotisations/facture.html', request) }, 'cotisations/facture.html', request)
@login_required
@can_create(DocumentTemplate)
def add_document_template(request):
"""
View used to add a document template.
"""
document_template = DocumentTemplateForm(request.POST or None)
if document_template.is_valid():
document_template.save()
messages.success(
request,
_("The document template was created.")
)
return redirect(reverse('cotisations:index-document-template'))
return form({
'factureform': document_template,
'action_name': _("Add"),
'title': _("New document template")
}, 'cotisations/facture.html', request)
@login_required
@can_edit(DocumentTemplate)
def edit_document_template(request, document_template_instance, **_kwargs):
"""
View used to edit a document_template.
"""
document_template = DocumentTemplateForm(
request.POST or None, instance=document_template_instance)
if document_template.is_valid():
if document_template.changed_data:
document_template.save()
messages.success(
request,
_("The document template was edited.")
)
return redirect(reverse('cotisations:index-document-template'))
return form({
'factureform': document_template,
'action_name': _("Edit"),
'title': _("Edit document template")
}, 'cotisations/facture.html', request)
@login_required
@can_delete_set(DocumentTemplate)
def del_document_template(request, instances):
"""
View used to delete a set of document template.
"""
document_template = DelDocumentTemplateForm(
request.POST or None, instances=instances)
if document_template.is_valid():
document_template_del = document_template.cleaned_data['document_templates']
for document_template in document_template_del:
try:
document_template.delete()
messages.success(
request,
_("The document template %(document_template)s was deleted.") % {
'document_template': document_template
}
)
except ProtectedError:
messages.error(
request,
_("The document template %(document_template)s can't be deleted \
because it is currently being used.") % {
'document_template': document_template
}
)
return redirect(reverse('cotisations:index-document-template'))
return form({
'factureform': document_template,
'action_name': _("Delete"),
'title': _("Delete document template")
}, 'cotisations/facture.html', request)
@login_required
@can_view_all(DocumentTemplate)
def index_document_template(request):
"""
View used to display the list of all available document templates.
"""
document_template_list = DocumentTemplate.objects.order_by('name')
return render(request, 'cotisations/index_document_template.html', {
'document_template_list': document_template_list
})

View file

@ -59,7 +59,7 @@ _ask_value() {
install_requirements() { install_requirements() {
### Usage: install_requirements ### Usage: install_requirements
# #
# This function will install the required packages from APT repository # This function will install the required packages from APT repository
# and Pypi repository. Those packages are all required for Re2o to work # and Pypi repository. Those packages are all required for Re2o to work
@ -273,7 +273,7 @@ write_settings_file() {
django_secret_key="$(python -c "import random; print(''.join([random.SystemRandom().choice('abcdefghijklmnopqrstuvwxyz0123456789%=+') for i in range(50)]))")" django_secret_key="$(python -c "import random; print(''.join([random.SystemRandom().choice('abcdefghijklmnopqrstuvwxyz0123456789%=+') for i in range(50)]))")"
aes_key="$(python -c "import random; print(''.join([random.SystemRandom().choice('abcdefghijklmnopqrstuvwxyz0123456789%=+') for i in range(32)]))")" aes_key="$(python -c "import random; print(''.join([random.SystemRandom().choice('abcdefghijklmnopqrstuvwxyz0123456789%=+') for i in range(32)]))")"
if [ "$db_engine_type" == 1 ]; then if [ "$db_engine_type" == 1 ]; then
sed -i 's/db_engine/django.db.backends.mysql/g' "$SETTINGS_LOCAL_FILE" sed -i 's/db_engine/django.db.backends.mysql/g' "$SETTINGS_LOCAL_FILE"
else else
@ -324,6 +324,19 @@ update_django() {
copy_templates_files() {
### Usage: copy_templates_files
#
# This will copy LaTeX templates in the media root.
echo "Copying LaTeX templates ..."
mkdir -p media/templates/
cp cotisations/templates/cotisations/factures.tex media/templates
echo "Copying LaTeX templates: Done"
}
create_superuser() { create_superuser() {
### Usage: create_superuser ### Usage: create_superuser
# #
@ -476,7 +489,7 @@ interactive_guide() {
sql_host="$(dialog --clear --backtitle "$BACKTITLE" \ sql_host="$(dialog --clear --backtitle "$BACKTITLE" \
--title "$TITLE" --inputbox "$INPUTBOX" \ --title "$TITLE" --inputbox "$INPUTBOX" \
$HEIGHT $WIDTH 2>&1 >/dev/tty)" $HEIGHT $WIDTH 2>&1 >/dev/tty)"
# Prompt to enter the remote database name # Prompt to enter the remote database name
TITLE="SQL database name" TITLE="SQL database name"
INPUTBOX="The name of the remote SQL database" INPUTBOX="The name of the remote SQL database"
@ -523,14 +536,14 @@ interactive_guide() {
ldap_is_local="$(dialog --clear --backtitle "$BACKTITLE" \ ldap_is_local="$(dialog --clear --backtitle "$BACKTITLE" \
--title "$TITLE" --menu "$MENU" \ --title "$TITLE" --menu "$MENU" \
$HEIGHT $WIDTH $CHOICE_HEIGHT "${OPTIONS[@]}" 2>&1 >/dev/tty)" $HEIGHT $WIDTH $CHOICE_HEIGHT "${OPTIONS[@]}" 2>&1 >/dev/tty)"
# Prompt to enter the LDAP domain extension # Prompt to enter the LDAP domain extension
TITLE="Domain extension" TITLE="Domain extension"
INPUTBOX="The local domain extension to use (e.g. 'example.net'). This is used in the LDAP configuration." INPUTBOX="The local domain extension to use (e.g. 'example.net'). This is used in the LDAP configuration."
extension_locale="$(dialog --clear --backtitle "$BACKTITLE" \ extension_locale="$(dialog --clear --backtitle "$BACKTITLE" \
--title "$TITLE" --inputbox "$INPUTBOX" \ --title "$TITLE" --inputbox "$INPUTBOX" \
$HEIGHT $WIDTH 2>&1 >/dev/tty)" $HEIGHT $WIDTH 2>&1 >/dev/tty)"
# Building the DN of the LDAP from the extension # Building the DN of the LDAP from the extension
IFS='.' read -a extension_locale_array <<< $extension_locale IFS='.' read -a extension_locale_array <<< $extension_locale
for i in "${extension_locale_array[@]}" for i in "${extension_locale_array[@]}"
@ -546,7 +559,7 @@ interactive_guide() {
ldap_host="$(dialog --clear --backtitle "$BACKTITLE" \ ldap_host="$(dialog --clear --backtitle "$BACKTITLE" \
--title "$TITLE" --inputbox "$INPUTBOX" \ --title "$TITLE" --inputbox "$INPUTBOX" \
$HEIGHT $WIDTH 2>&1 >/dev/tty)" $HEIGHT $WIDTH 2>&1 >/dev/tty)"
# Prompt to choose if TLS should be activated or not for the LDAP # Prompt to choose if TLS should be activated or not for the LDAP
TITLE="TLS on LDAP" TITLE="TLS on LDAP"
MENU="Would you like to activate TLS for communicating with the remote LDAP ?" MENU="Would you like to activate TLS for communicating with the remote LDAP ?"
@ -583,7 +596,7 @@ interactive_guide() {
######################### #########################
BACKTITLE="Re2o setup - configuration of the mail server" BACKTITLE="Re2o setup - configuration of the mail server"
# Prompt to enter the hostname of the mail server # Prompt to enter the hostname of the mail server
TITLE="Mail server hostname" TITLE="Mail server hostname"
INPUTBOX="The hostname of the mail server to use" INPUTBOX="The hostname of the mail server to use"
@ -591,7 +604,7 @@ interactive_guide() {
--title "$TITLE" --inputbox "$TITLE" \ --title "$TITLE" --inputbox "$TITLE" \
$HEIGHT $WIDTH 2>&1 >/dev/tty)" $HEIGHT $WIDTH 2>&1 >/dev/tty)"
# Prompt to choose the port of the mail server # Prompt to choose the port of the mail server
TITLE="Mail server port" TITLE="Mail server port"
MENU="Which port (thus which protocol) to use to contact the mail server" MENU="Which port (thus which protocol) to use to contact the mail server"
OPTIONS=(25 "SMTP" OPTIONS=(25 "SMTP"
@ -608,7 +621,7 @@ interactive_guide() {
######################## ########################
BACKTITLE="Re2o setup - configuration of the web server" BACKTITLE="Re2o setup - configuration of the web server"
# Prompt to choose the web server # Prompt to choose the web server
TITLE="Web server to use" TITLE="Web server to use"
MENU="Which web server to install for accessing Re2o web frontend (automatic setup of nginx is not supported) ?" MENU="Which web server to install for accessing Re2o web frontend (automatic setup of nginx is not supported) ?"
@ -617,14 +630,14 @@ interactive_guide() {
web_serveur="$(dialog --clear --backtitle "$BACKTITLE" \ web_serveur="$(dialog --clear --backtitle "$BACKTITLE" \
--title "$TITLE" --menu "$MENU" \ --title "$TITLE" --menu "$MENU" \
$HEIGHT $WIDTH $CHOICE_HEIGHT "${OPTIONS[@]}" 2>&1 >/dev/tty)" $HEIGHT $WIDTH $CHOICE_HEIGHT "${OPTIONS[@]}" 2>&1 >/dev/tty)"
# Prompt to enter the requested URL for the web frontend # Prompt to enter the requested URL for the web frontend
TITLE="Web URL" TITLE="Web URL"
INPUTBOX="URL for accessing the web server (e.g. re2o.example.net). Be sure that this URL is accessible and correspond to a DNS entry (if applicable)." INPUTBOX="URL for accessing the web server (e.g. re2o.example.net). Be sure that this URL is accessible and correspond to a DNS entry (if applicable)."
url_server="$(dialog --clear --backtitle "$BACKTITLE" \ url_server="$(dialog --clear --backtitle "$BACKTITLE" \
--title "$TITLE" --inputbox "$INPUTBOX" \ --title "$TITLE" --inputbox "$INPUTBOX" \
$HEIGHT $WIDTH 2>&1 >/dev/tty)" $HEIGHT $WIDTH 2>&1 >/dev/tty)"
# Prompt to choose if the TLS should be setup or not for the web server # Prompt to choose if the TLS should be setup or not for the web server
TITLE="TLS on web server" TITLE="TLS on web server"
MENU="Would you like to activate the TLS (with Let'Encrypt) on the web server ?" MENU="Would you like to activate the TLS (with Let'Encrypt) on the web server ?"
@ -679,7 +692,7 @@ interactive_guide() {
update_django update_django
create_superuser create_superuser
install_webserver "$web_serveur" "$is_tls" "$url_server" install_webserver "$web_serveur" "$is_tls" "$url_server"
@ -748,9 +761,10 @@ main_function() {
echo " * {help} ---------- Display this quick usage documentation" echo " * {help} ---------- Display this quick usage documentation"
echo " * {setup} --------- Launch the full interactive guide to setup entirely" echo " * {setup} --------- Launch the full interactive guide to setup entirely"
echo " re2o from scratch" echo " re2o from scratch"
echo " * {update} -------- Collect frontend statics, install the missing APT" echo " * {update} -------- Collect frontend statics, install the missing APT and copy LaTeX templates files"
echo " and pip packages and apply the migrations to the DB" echo " and pip packages and apply the migrations to the DB"
echo " * {update-django} - Apply Django migration and collect frontend statics" echo " * {update-django} - Apply Django migration and collect frontend statics"
echo " * {copy-template-files} - Copy LaTeX templates files to media/templates"
echo " * {update-packages} Install the missing APT and pip packages" echo " * {update-packages} Install the missing APT and pip packages"
echo " * {update-settings} Interactively rewrite the settings file" echo " * {update-settings} Interactively rewrite the settings file"
echo " * {reset-db} ------ Erase the previous local database, setup a new empty" echo " * {reset-db} ------ Erase the previous local database, setup a new empty"
@ -783,6 +797,11 @@ main_function() {
update ) update )
install_requirements install_requirements
update_django update_django
copy_templates_files
;;
copy-templates-files )
copy_templates_files
;; ;;
update-django ) update-django )
@ -800,7 +819,7 @@ main_function() {
reset-db ) reset-db )
if [ ! -z "$2" ]; then if [ ! -z "$2" ]; then
db_password="$2" db_password="$2"
case "$3" in case "$3" in
mysql ) mysql )
db_engine_type=1;; db_engine_type=1;;
postresql ) postresql )