41 changed files with 533 additions and 113 deletions
-
4abonapp/locale/ru/LC_MESSAGES/django.po
-
4abonapp/templates/abonapp/editAbon.html
-
4abonapp/views.py
-
1accounts_app/forms.py
-
4agent/netflow/netflow_collect.sh
-
6clientsideapp/views.py
-
33devapp/dev_types.py
-
2devapp/locale/ru/LC_MESSAGES/django.po
-
4devapp/templates/devapp/custom_dev_page/onu.html
-
4devapp/templates/devapp/custom_dev_page/onu_for_zte.html
-
2devapp/templates/devapp/devices.html
-
2devapp/views.py
-
2djing/__init__.py
-
10djing/settings.py
-
3djing/urls.py
-
0docsapp/__init__.py
-
5docsapp/apps.py
-
8docsapp/forms.py
-
71docsapp/locale/ru/LC_MESSAGES/django.po
-
27docsapp/migrations/0001_initial.py
-
0docsapp/migrations/__init__.py
-
24docsapp/models.py
-
14docsapp/templates/docsapp/documenttemplatemodel_confirm_delete.html
-
39docsapp/templates/docsapp/documenttemplatemodel_form.html
-
77docsapp/templates/docsapp/documenttemplatemodel_list.html
-
26docsapp/templates/docsapp/simple_list.html
-
14docsapp/urls.py
-
101docsapp/views.py
-
2gw_app/nas_managers/mod_mikrotik.py
-
85migrate2v2_dump.py
-
2periodic.py
-
33requirements.txt
-
1systemd_units/djing.timer
-
1systemd_units/djing_backup.timer
-
7systemd_units/webdav_backup.py
-
8tariff_app/custom_tariffs.py
-
6templates/base.html
-
2templates/custom_pages/footer.htm
-
2templates/custom_pages/main_page.htm
-
4templates/custom_pages/service.htm
-
2templates/custom_pages/service_bottom.htm
@ -0,0 +1,5 @@ |
|||
from django.apps import AppConfig |
|||
|
|||
|
|||
class DocsappConfig(AppConfig): |
|||
name = 'docsapp' |
|||
@ -0,0 +1,8 @@ |
|||
from django import forms |
|||
from docsapp.models import DocumentTemplateModel |
|||
|
|||
|
|||
class DocumentTemplateModelForm(forms.ModelForm): |
|||
class Meta: |
|||
model = DocumentTemplateModel |
|||
fields = '__all__' |
|||
@ -0,0 +1,71 @@ |
|||
# SOME DESCRIPTIVE TITLE. |
|||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
|||
# This file is distributed under the same license as the PACKAGE package. |
|||
# Dmitry Novikov nerosketch@gmail.com, 2019. |
|||
# |
|||
#, fuzzy |
|||
msgid "" |
|||
msgstr "" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2019-09-12 13:57+0300\n" |
|||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
|||
"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n" |
|||
"Language: ru\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: 8bit\n" |
|||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" |
|||
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" |
|||
"%100>=11 && n%100<=14)? 2 : 3);\n" |
|||
|
|||
#: models.py:8 templates/docsapp/documenttemplatemodel_list.html:25 |
|||
msgid "Title" |
|||
msgstr "Название" |
|||
|
|||
#: models.py:10 |
|||
msgid "File docx template" |
|||
msgstr "Файл шаблон docx" |
|||
|
|||
#: templates/docsapp/documenttemplatemodel_confirm_delete.html:9 |
|||
msgid "Remove document" |
|||
msgstr "Удалить документ" |
|||
|
|||
#: templates/docsapp/documenttemplatemodel_confirm_delete.html:13 |
|||
msgid "Are you sure you want to delete this document?" |
|||
msgstr "Вы уверены что хотите удалить документ?" |
|||
|
|||
#: templates/docsapp/documenttemplatemodel_form.html:19 |
|||
msgid "Change document" |
|||
msgstr "Изменить документ" |
|||
|
|||
#: templates/docsapp/documenttemplatemodel_form.html:21 |
|||
#: templates/docsapp/documenttemplatemodel_list.html:58 |
|||
#: templates/docsapp/documenttemplatemodel_list.html:69 |
|||
msgid "Add document" |
|||
msgstr "Добавить документ" |
|||
|
|||
#: templates/docsapp/documenttemplatemodel_form.html:30 |
|||
msgid "Save" |
|||
msgstr "Сохранить" |
|||
|
|||
#: templates/docsapp/documenttemplatemodel_form.html:34 |
|||
msgid "Back" |
|||
msgstr "Назад" |
|||
|
|||
#: templates/docsapp/documenttemplatemodel_list.html:5 |
|||
#: templates/docsapp/documenttemplatemodel_list.html:11 |
|||
#: templates/docsapp/documenttemplatemodel_list.html:16 |
|||
msgid "Documents" |
|||
msgstr "Документы" |
|||
|
|||
#: templates/docsapp/documenttemplatemodel_list.html:26 |
|||
msgid "File" |
|||
msgstr "Файл" |
|||
|
|||
#: templates/docsapp/documenttemplatemodel_list.html:27 |
|||
msgid "Document type" |
|||
msgstr "Тип документа" |
|||
|
|||
#: templates/docsapp/documenttemplatemodel_list.html:57 |
|||
msgid "Documents not found" |
|||
msgstr "Документы не найдены" |
|||
@ -0,0 +1,27 @@ |
|||
# Generated by Django 2.2.4 on 2019-09-12 12:52 |
|||
|
|||
import django.core.validators |
|||
from django.db import migrations, models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
initial = True |
|||
|
|||
dependencies = [ |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.CreateModel( |
|||
name='DocumentTemplateModel', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('title', models.CharField(max_length=80, verbose_name='Title', unique=True)), |
|||
('doc_template', models.FileField(upload_to='word_docs', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=('docx',))], verbose_name='File docx template')), |
|||
], |
|||
options={ |
|||
'db_table': 'documents', |
|||
'ordering': ('title',), |
|||
}, |
|||
), |
|||
] |
|||
@ -0,0 +1,24 @@ |
|||
from django.shortcuts import resolve_url |
|||
from django.utils.translation import gettext_lazy as _ |
|||
from django.core.validators import FileExtensionValidator |
|||
from django.db import models |
|||
|
|||
from abonapp.models import Abon |
|||
|
|||
|
|||
class DocumentTemplateModel(models.Model): |
|||
title = models.CharField(_('Title'), max_length=80, unique=True) |
|||
doc_template = models.FileField( |
|||
_('File docx template'), upload_to='word_docs', |
|||
validators=[FileExtensionValidator(allowed_extensions=('docx',))] |
|||
) |
|||
|
|||
def get_absolute_url(self): |
|||
return resolve_url('docsapp:doc_edit', pk=self.pk) |
|||
|
|||
def __str__(self): |
|||
return self.title |
|||
|
|||
class Meta: |
|||
db_table = 'documents' |
|||
ordering = ('title',) |
|||
@ -0,0 +1,14 @@ |
|||
{% extends 'base_delete_modal.html' %} |
|||
{% load i18n %} |
|||
|
|||
{% block modal_form_url %} |
|||
{% url 'docsapp:doc_del' object.pk %} |
|||
{% endblock %} |
|||
|
|||
{% block modal_form_title %} |
|||
{% trans 'Remove document' %} |
|||
{% endblock %} |
|||
|
|||
{% block modal_form_text %} |
|||
<h4>{% trans 'Are you sure you want to delete this document?' %}</h4> |
|||
{% endblock %} |
|||
@ -0,0 +1,39 @@ |
|||
{% extends request.is_ajax|yesno:'bajax.html,base.html' %} |
|||
{% load i18n bootstrap3 %} |
|||
|
|||
{% block main %} |
|||
|
|||
{% if object %} |
|||
{% url 'docsapp:doc_edit' object.pk as objurl %} |
|||
{% else %} |
|||
{% url 'docsapp:doc_add' as objurl %} |
|||
{% endif %} |
|||
|
|||
<form action="{{ objurl }}" method="post" enctype="multipart/form-data">{% csrf_token %} |
|||
<div class="modal-header primary"> |
|||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
|||
<h4 class="modal-title"> |
|||
<span class="glyphicon glyphicon-exclamation-sign"></span> |
|||
|
|||
{% if object %} |
|||
{% trans 'Change document' %} |
|||
{% else %} |
|||
{% trans 'Add document' %} |
|||
{% endif %} |
|||
|
|||
</h4> |
|||
</div> |
|||
<div class="modal-body"> |
|||
{% bootstrap_form form %} |
|||
|
|||
<div class="btn-group btn-group-sm"> |
|||
{% bootstrap_button _('Save') button_type="submit" button_class="btn-primary" icon="save" %} |
|||
|
|||
{% if not request.is_ajax %} |
|||
{% url 'docsapp:docs_list' as backurl %} |
|||
{% bootstrap_button _('Back') button_type="link" href=backurl icon="fast-backward" %} |
|||
{% endif %} |
|||
</div> |
|||
</div> |
|||
</form> |
|||
{% endblock %} |
|||
@ -0,0 +1,77 @@ |
|||
{% extends request.is_ajax|yesno:'bajax.html,base.html' %} |
|||
{% load i18n %} |
|||
|
|||
{% block title %} |
|||
{% trans 'Documents' %} |
|||
{% endblock %} |
|||
|
|||
{% block breadcrumb %} |
|||
<ol class="breadcrumb"> |
|||
<li><span class="glyphicon glyphicon-home"></span></li> |
|||
<li class="active">{% trans 'Documents' %}</li> |
|||
</ol> |
|||
{% endblock %} |
|||
|
|||
{% block page-header %} |
|||
{% trans 'Documents' %} |
|||
{% endblock %} |
|||
|
|||
{% block main %} |
|||
<div class="table-responsive"> |
|||
<table class="table table-bordered"> |
|||
<thead> |
|||
<tr> |
|||
<th>.</th> |
|||
<th class="col-md-2">{% trans 'Title' %}</th> |
|||
<th class="col-md-4">{% trans 'File' %}</th> |
|||
<th class="col-md-3">{% trans 'Document type' %}</th> |
|||
<th>#</th> |
|||
</tr> |
|||
</thead> |
|||
|
|||
<tbody> |
|||
{% with can_del_doc=perms.docsapp.delete_documenttemplatemodel can_ch_doc=perms.docsapp.change_documenttemplatemodel %} |
|||
{% for doc in object_list %} |
|||
<tr> |
|||
<td>{{ doc.id }}</td> |
|||
<td>{{ doc.title }}</td> |
|||
<td>{{ doc.doc_template }}</td> |
|||
<td>DocX</td> |
|||
|
|||
<td class="btn-group btn-group-xs btn-group-justified"> |
|||
{% if can_del_doc %} |
|||
<a href="{% url 'docsapp:doc_del' doc.pk %}" class="btn btn-danger btn-modal"> |
|||
<span class="glyphicon glyphicon-remove"></span> |
|||
</a> |
|||
{% endif %} |
|||
{% if can_ch_doc %} |
|||
<a href="{% url 'docsapp:doc_edit' doc.id %}" class="btn btn-default btn-modal"> |
|||
<span class="glyphicon glyphicon-edit"></span> |
|||
</a> |
|||
{% endif %} |
|||
</td> |
|||
</tr> |
|||
{% empty %} |
|||
<tr> |
|||
<td colspan="6"> |
|||
{% trans 'Documents not found' %}. |
|||
<a href="{% url 'docsapp:doc_add' %}" class="btn-modal">{% trans 'Add document' %}</a> |
|||
</td> |
|||
</tr> |
|||
{% endfor %} |
|||
{% endwith %} |
|||
</tbody> |
|||
|
|||
<tfoot> |
|||
<tr> |
|||
<td colspan="6"> |
|||
<a href="{% url 'docsapp:doc_add' %}" class="btn btn-success btn-sm btn-modal"> |
|||
<span class="glyphicon glyphicon-plus"></span> {% trans 'Add document' %} |
|||
</a> |
|||
</td> |
|||
</tr> |
|||
</tfoot> |
|||
|
|||
</table> |
|||
</div> |
|||
{% endblock %} |
|||
@ -0,0 +1,26 @@ |
|||
{% load i18n %} |
|||
|
|||
<div class="modal-header primary"> |
|||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
|||
<h4 class="modal-title">{% trans 'Documents' %}</h4> |
|||
</div> |
|||
<div class="modal-body"> |
|||
|
|||
<div class="panel panel-default"> |
|||
<div class="panel-body"> |
|||
<ul class="list-group"> |
|||
{% for obj in object_list %} |
|||
<li class="list-group-item"> |
|||
<b>{{ obj.title }}</b> |
|||
<a href="{% url 'docsapp:doc_render' obj.pk account_name %}" class="btn btn-default"> |
|||
<span class="glyphicon glyphicon-print"></span> {% trans 'Render document' %} |
|||
</a> |
|||
</li> |
|||
{% empty %} |
|||
{% trans 'Documents not found' %} |
|||
{% endfor %} |
|||
</ul> |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
@ -0,0 +1,14 @@ |
|||
from django.urls import path |
|||
from docsapp import views |
|||
|
|||
app_name = 'docsapp' |
|||
|
|||
|
|||
urlpatterns = [ |
|||
path('', views.DocumentsListView.as_view(), name='docs_list'), |
|||
path('add/', views.DocumentCreateView.as_view(), name='doc_add'), |
|||
path('<int:pk>/', views.DocumentUpdateView.as_view(), name='doc_edit'), |
|||
path('<int:pk>/del/', views.DocumentDeleteView.as_view(), name='doc_del'), |
|||
path('<int:pk>/<slug:uname>/render/', views.RenderDocument.as_view(), name='doc_render'), |
|||
path('<slug:account_name>/simple_list/', views.SimpleListView.as_view(), name='simple_list'), |
|||
] |
|||
@ -0,0 +1,101 @@ |
|||
from io import BytesIO |
|||
|
|||
from django.contrib import messages |
|||
from django.utils.datetime_safe import datetime |
|||
from django.utils.translation import gettext_lazy as _ |
|||
from django.views.generic import UpdateView, DeleteView, CreateView, DetailView, ListView |
|||
from django.contrib.auth.mixins import PermissionRequiredMixin |
|||
from django.core.exceptions import ValidationError |
|||
from django.http import HttpResponse |
|||
from django.shortcuts import redirect, get_object_or_404 |
|||
from django.urls import reverse_lazy |
|||
from docxtpl import DocxTemplate |
|||
from docx.opc.constants import CONTENT_TYPE |
|||
from jinja2.exceptions import UndefinedError, TemplateSyntaxError |
|||
|
|||
from abonapp.models import Abon |
|||
from djing.global_base_views import OrderedFilteredList |
|||
from djing.lib.mixins import LoginAdminMixin, LoginAdminPermissionMixin |
|||
from docsapp.models import DocumentTemplateModel |
|||
from docsapp.forms import DocumentTemplateModelForm |
|||
|
|||
|
|||
class DocumentsListView(LoginAdminMixin, OrderedFilteredList): |
|||
model = DocumentTemplateModel |
|||
|
|||
|
|||
class SimpleListView(LoginAdminMixin, ListView): |
|||
template_name = 'docsapp/simple_list.html' |
|||
model = DocumentTemplateModel |
|||
|
|||
def get_context_data(self, **kwargs): |
|||
kwargs.update({ |
|||
'account_name': self.kwargs.get('account_name') |
|||
}) |
|||
return super().get_context_data(**kwargs) |
|||
|
|||
|
|||
class DocumentUpdateView(LoginAdminPermissionMixin, UpdateView): |
|||
permission_required = 'docsapp.change_documenttemplatemodel' |
|||
model = DocumentTemplateModel |
|||
form_class = DocumentTemplateModelForm |
|||
|
|||
|
|||
class DocumentDeleteView(LoginAdminPermissionMixin, DeleteView): |
|||
permission_required = 'docsapp.delete_documenttemplatemodel' |
|||
model = DocumentTemplateModel |
|||
success_url = reverse_lazy('docsapp:docs_list') |
|||
|
|||
|
|||
class DocumentCreateView(LoginAdminMixin, PermissionRequiredMixin, CreateView): |
|||
model = DocumentTemplateModel |
|||
form_class = DocumentTemplateModelForm |
|||
permission_required = 'docsapp.add_documenttemplatemodel' |
|||
|
|||
|
|||
class RenderDocument(LoginAdminPermissionMixin, DetailView): |
|||
model = DocumentTemplateModel |
|||
permission_required = 'docsapp.view_documenttemplatemodel' |
|||
context_object_name = 'document' |
|||
extra_context = { |
|||
'date': datetime.now() |
|||
} |
|||
|
|||
def get(self, request, *args, **kwargs): |
|||
obj = self.get_object() |
|||
self.object = obj |
|||
acc = get_object_or_404(Abon, username=self.kwargs.get('uname')) |
|||
|
|||
try: |
|||
doc = DocxTemplate( |
|||
obj.doc_template.path |
|||
) |
|||
context = self.get_context_data(object=obj) |
|||
context.update(self.get_context_account(acc)) |
|||
doc.render(context) |
|||
|
|||
destination_document_file = BytesIO() |
|||
doc.get_docx().save(destination_document_file) |
|||
resp = HttpResponse( |
|||
destination_document_file.getvalue(), |
|||
content_type=CONTENT_TYPE.WML_DOCUMENT |
|||
) |
|||
resp['Content-Disposition'] = 'attachment; filename="document.docx"' |
|||
return resp |
|||
except (UndefinedError, ValidationError, TemplateSyntaxError) as e: |
|||
messages.error(request, str(e)) |
|||
return redirect('docsapp:docs_list') |
|||
|
|||
def get_context_account(self, account): |
|||
if not isinstance(account, Abon): |
|||
raise ValidationError(message=_('Account required and must be Abon')) |
|||
bp = '_' * 20 |
|||
return { |
|||
'account': account, |
|||
'passport': getattr(account, 'passportinfo', { |
|||
'series': bp, |
|||
'number': bp, |
|||
'distributor': bp, |
|||
'date_of_acceptance': bp |
|||
}) |
|||
} |
|||
@ -1 +1 @@ |
|||
Your custom content <i>here</i>. |
|||
{# Your custom content <i>here</i>. #} |
|||
@ -1 +1 @@ |
|||
<h1>You can change this page</h1> |
|||
{# <h1>You can change this page</h1> #} |
|||
@ -1,2 +1,2 @@ |
|||
<h1>Your custom content</h1> |
|||
<p>You have service variable {{ active_service }}</p> |
|||
{# <h1>Your custom content</h1> #} |
|||
{# <p>You have service variable {{ active_service }}</p> #} |
|||
@ -1 +1 @@ |
|||
<h1>Your custom content on bottom</h1> |
|||
{# <h1>Your custom content on bottom</h1> #} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue