Browse Source

Merge branch 'devel' of https://github.com/nerosketch/djing into djing_dial

# Conflicts:
#	dialing_app/views.py
devel
bashmak 8 years ago
parent
commit
8ddfa5cbf8
  1. 1064
      abonapp/locale/ru/LC_MESSAGES/django.po
  2. 19
      abonapp/models.py
  3. 49
      abonapp/templates/abonapp/fin_report.html
  4. 13
      abonapp/templates/abonapp/group_list.html
  5. 2
      abonapp/urls.py
  6. 26
      abonapp/views.py
  7. 4
      dialing_app/models.py
  8. 22
      dialing_app/templates/index.html
  9. 22
      dialing_app/views.py
  10. 4
      taskapp/locale/ru/LC_MESSAGES/django.po
  11. 19
      taskapp/models.py
  12. 65
      taskapp/templates/taskapp/add_edit_task.html
  13. 2
      taskapp/views.py

1064
abonapp/locale/ru/LC_MESSAGES/django.po
File diff suppressed because it is too large
View File

19
abonapp/models.py

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from datetime import datetime
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.db.models.signals import post_save, post_delete, pre_delete, post_init from django.db.models.signals import post_save, post_delete, pre_delete, post_init
from django.dispatch import receiver from django.dispatch import receiver
from django.utils import timezone from django.utils import timezone
from django.db import models
from django.db import models, connection
from django.core import validators from django.core import validators
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult, NasNetworkError from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult, NasNetworkError
@ -316,12 +317,28 @@ class InvoiceForPayment(models.Model):
verbose_name_plural = _('Debts') verbose_name_plural = _('Debts')
class AllTimePayLogManager(models.Manager):
def by_days(self):
cur = connection.cursor()
cur.execute(r'SELECT SUM(summ) as alsum, DATE_FORMAT(date_add, "%Y-%m-%d") AS pay_date FROM all_time_pay_log '
r'GROUP BY DATE_FORMAT(date_add, "%Y-%m-%d")')
while True:
r = cur.fetchone()
if r is None: break
summ, dat = r
print(summ, dat)
yield {'summ': summ, 'pay_date': datetime.strptime(dat, '%Y-%m-%d')}
# Log for pay system "AllTime" # Log for pay system "AllTime"
class AllTimePayLog(models.Model): class AllTimePayLog(models.Model):
pay_id = models.CharField(max_length=36, unique=True, primary_key=True) pay_id = models.CharField(max_length=36, unique=True, primary_key=True)
date_add = models.DateTimeField(auto_now_add=True) date_add = models.DateTimeField(auto_now_add=True)
summ = models.FloatField(default=0.0) summ = models.FloatField(default=0.0)
objects = AllTimePayLogManager()
def __str__(self): def __str__(self):
return self.pay_id return self.pay_id

49
abonapp/templates/abonapp/fin_report.html

@ -0,0 +1,49 @@
{% extends 'base.html' %}
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li class="active">{% trans 'Fin report' %}</li>
</ol>
{% include 'message_block.html' %}
<h3>{% trans 'Money by days' %}</h3>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>{% trans 'Sum' %}</th>
<th>{% trans 'Date' %}</th>
</tr>
</thead>
<tbody>
{% for l in logs %}
<tr>
<td>{{ l.summ }}</td>
<td>{{ l.pay_date|date:"d E Y" }}</td>
</tr>
{% empty %}
<tr>
<td colspan="2">{% trans 'Pays not found' %}</td>
</tr>
{% endfor %}
</tbody>
<thead>
<tr>
<td colspan="2">
<a href="{% url 'abonapp:fin_report' %}?f=csv" target="_blank" class="btn btn-sm btn-default">
<span class="glyphicon glyphicon-download"></span> <span class="hidden-xs">{% trans 'Export to csv' %}</span>
</a>
</td>
</tr>
</thead>
</table>
</div>
{# {% include 'toolbar_page.html' with pag=logs %} #}
{% endblock %}

13
abonapp/templates/abonapp/group_list.html

@ -57,22 +57,27 @@
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="4" class="btn-group">
<td colspan="4" class="btn-group btn-group-sm">
{% if perms.abonapp.add_abongroup %} {% if perms.abonapp.add_abongroup %}
<a href="{% url 'abonapp:add_group' %}" class="btn btn-success btn-sm">
<a href="{% url 'abonapp:add_group' %}" class="btn btn-success">
<span class="glyphicon glyphicon-plus"></span> <span class="hidden-xs">{% trans 'Add group' %}</span> <span class="glyphicon glyphicon-plus"></span> <span class="hidden-xs">{% trans 'Add group' %}</span>
</a> </a>
{% endif %} {% endif %}
{% if perms.abonapp.can_view_abonlog %} {% if perms.abonapp.can_view_abonlog %}
<a href="{% url 'abonapp:log' %}" class="btn btn-default btn-sm">
<a href="{% url 'abonapp:log' %}" class="btn btn-default">
<span class="glyphicon glyphicon-record"></span> <span class="hidden-xs">{% trans 'Subscribers actions' %}</span> <span class="glyphicon glyphicon-record"></span> <span class="hidden-xs">{% trans 'Subscribers actions' %}</span>
</a> </a>
{% endif %} {% endif %}
{% if perms.abonapp.can_view_invoiceforpayment %} {% if perms.abonapp.can_view_invoiceforpayment %}
<a href="{% url 'abonapp:debtors' %}" class="btn btn-default btn-sm">
<a href="{% url 'abonapp:debtors' %}" class="btn btn-default">
<span class="glyphicon glyphicon-exclamation-sign"></span> <span class="hidden-xs">{% trans 'List of debtors' %}</span> <span class="glyphicon glyphicon-exclamation-sign"></span> <span class="hidden-xs">{% trans 'List of debtors' %}</span>
</a> </a>
{% endif %} {% endif %}
{% if request.user.is_superuser %}
<a href="{% url 'abonapp:fin_report' %}" class="btn btn-default">
<span class="glyphicon glyphicon-usd"></span> <span class="hidden-xs">{% trans 'Fin report' %}</span>
</a>
{% endif %}
</td> </td>
</tr> </tr>
</tfoot> </tfoot>

2
abonapp/urls.py

@ -9,6 +9,8 @@ urlpatterns = [
url(r'^addgroup$', views.addgroup, name='add_group'), url(r'^addgroup$', views.addgroup, name='add_group'),
url(r'^delgroup', views.delgroup, name='del_group'), url(r'^delgroup', views.delgroup, name='del_group'),
url(r'^fin_report$', views.fin_report, name='fin_report'),
url(r'^(?P<gid>\d+)/', include('abonapp.urls_abon')), url(r'^(?P<gid>\d+)/', include('abonapp.urls_abon')),
url(r'^log$', views.log_page, name='log'), url(r'^log$', views.log_page, name='log'),

26
abonapp/views.py

@ -690,14 +690,14 @@ def abon_ping(request):
else: else:
if type(ping_result) is tuple: if type(ping_result) is tuple:
loses_percent = (ping_result[0] / ping_result[1] if ping_result[1] != 0 else 1) loses_percent = (ping_result[0] / ping_result[1] if ping_result[1] != 0 else 1)
print(ping_result, loses_percent)
ping_result = {'all':ping_result[0], 'return': ping_result[1]}
if loses_percent > 1.0: if loses_percent > 1.0:
text = '<span class="glyphicon glyphicon-exclamation-sign"></span> %s' % _('IP Conflict! %d/%d results') % ping_result
text = '<span class="glyphicon glyphicon-exclamation-sign"></span> %s' % _('IP Conflict! %(all)d/%(return)d results') % ping_result
elif loses_percent > 0.5: elif loses_percent > 0.5:
text = '<span class="glyphicon glyphicon-ok"></span> %s' % _('ok ping, %d/%d loses') % ping_result
text = '<span class="glyphicon glyphicon-ok"></span> %s' % _('ok ping, %(all)d/%(return)d loses') % ping_result
status = True status = True
else: else:
text = '<span class="glyphicon glyphicon-exclamation-sign"></span> %s' % _('no ping, %d/%d loses') % ping_result
text = '<span class="glyphicon glyphicon-exclamation-sign"></span> %s' % _('no ping, %(all)d/%(return)d loses') % ping_result
else: else:
text = '<span class="glyphicon glyphicon-ok"></span> %s' % _('ping ok') + ' ' + str(ping_result) text = '<span class="glyphicon glyphicon-ok"></span> %s' % _('ping ok') + ' ' + str(ping_result)
status = True status = True
@ -907,6 +907,24 @@ def reset_ip(request, gid, uid):
@login_required
@mydefs.only_admins
def fin_report(request):
q = models.AllTimePayLog.objects.by_days()
res_format = request.GET.get('f')
if res_format == 'csv':
import csv
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="report.csv"'
writer = csv.writer(response, quoting=csv.QUOTE_NONNUMERIC)
for row in q:
writer.writerow((row['summ'], row['pay_date'].strftime('%Y-%m-%d')))
return response
return render(request, 'abonapp/fin_report.html', {
'logs': q
})
# API's # API's
def abons(request): def abons(request):

4
dialing_app/models.py

@ -1,4 +1,5 @@
from django.db import models from django.db import models
from datetime import datetime
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.conf import settings from django.conf import settings
@ -60,7 +61,8 @@ class AsteriskCDR(models.Model):
return "%s/monitor" % path return "%s/monitor" % path
def url(self): def url(self):
return "%s/%s-%s-%s.wav" % ( self.path_to_media(), self.calldate.strftime('%Y/%m/%d/%H_%M'), self.src, self.dst )
if type(self.calldate) is datetime:
return "%s/%s-%s-%s.wav" % (self.path_to_media(), self.calldate.strftime('%Y/%m/%d/%H_%M'), self.src, self.dst)
class Meta: class Meta:
db_table = 'cdr' db_table = 'cdr'

22
dialing_app/templates/index.html

@ -31,6 +31,24 @@
</div> </div>
</div> </div>
</div> </div>
<div class="form-group">
<label class="sr-only" for="dialtime">{% trans 'Find by dates' %}</label>
<div class="input-group input-group-sm">
<input type="text" class="form-control" id="dialtime" placeholder="{% trans 'calldate' %}" name="sd"{% if sd %} value="{{ sd }}"{% endif %}>
<script type="text/javascript">
$(function () {
$('#dialtime').datetimepicker({
format: 'YYYY-MM-DD'
});
});
</script>
<div class="input-group-btn">
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search"></span>
</button>
</div>
</div>
</div>
</form> </form>
</th> </th>
</tr> </tr>
@ -42,9 +60,9 @@
<td class="btn-group btn-group-xs btn-group-justify"> <td class="btn-group btn-group-xs btn-group-justify">
<button class="btn btn-default player-btn disabled"> <button class="btn btn-default player-btn disabled">
<span class="glyphicon glyphicon-play"></span> <span class="glyphicon glyphicon-play"></span>
<audio preload="metadata" src="{{ lurl }}"></audio>
<audio preload="metadata" src="{{ lurl|default:'#' }}"></audio>
</button> </button>
<a href="{{ lurl }}" class="btn btn-default disabled" target="_blank" title="{% trans 'Download' %}">
<a href="{{ lurl|default:'#' }}" class="btn btn-default disabled" target="_blank" title="{% trans 'Download' %}">
<span class="glyphicon glyphicon-download-alt"></span> <span class="glyphicon glyphicon-download-alt"></span>
</a> </a>
</td> </td>

22
dialing_app/views.py

@ -1,3 +1,4 @@
from datetime import datetime
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib import messages from django.contrib import messages
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
@ -66,13 +67,32 @@ def vmail_report(request):
@login_required @login_required
@only_admins @only_admins
def vfilter(request): def vfilter(request):
cdr_q = None
sd = request.GET.get('sd')
s = request.GET.get('s') s = request.GET.get('s')
if s:
cdr_q = Q(src__icontains=s) | Q(dst__icontains=s) cdr_q = Q(src__icontains=s) | Q(dst__icontains=s)
try:
if sd:
sd_date = datetime.strptime(sd, '%Y-%m-%d')
if cdr_q:
cdr_q |= Q(calldate__date=sd_date)
else:
cdr_q = Q(calldate__date=sd_date)
except ValueError:
messages.error(request, _('Make sure that your date format is correct'))
if cdr_q is None:
cdr = AsteriskCDR.objects.all()
else:
cdr = AsteriskCDR.objects.filter(cdr_q) cdr = AsteriskCDR.objects.filter(cdr_q)
cdr = pag_mn(request, cdr)
return render(request, 'index.html', { return render(request, 'index.html', {
'logs': cdr, 'logs': cdr,
'title': _('Find dials'), 'title': _('Find dials'),
's': s
's': s,
'sd': sd
}) })

4
taskapp/locale/ru/LC_MESSAGES/django.po

@ -202,7 +202,7 @@ msgid "Subscriber"
msgstr "Абонент" msgstr "Абонент"
#: taskapp/templates/taskapp/add_edit_task.html:75 #: taskapp/templates/taskapp/add_edit_task.html:75
msgid "Reality (the date by which you must complete the task)"
msgid "Reality"
msgstr "Актуальность (дата, до которой нужно завершить задачу)" msgstr "Актуальность (дата, до которой нужно завершить задачу)"
#: taskapp/templates/taskapp/add_edit_task.html:90 #: taskapp/templates/taskapp/add_edit_task.html:90
@ -243,7 +243,7 @@ msgstr "Адрес"
#: taskapp/templates/taskapp/tasklist_finish.html:14 #: taskapp/templates/taskapp/tasklist_finish.html:14
#: taskapp/templates/taskapp/view.html:21 #: taskapp/templates/taskapp/view.html:21
msgid "Task author" msgid "Task author"
msgstr "Кто назначил"
msgstr "Автор задачи"
#: taskapp/templates/taskapp/tasklist.html:15 #: taskapp/templates/taskapp/tasklist.html:15
#: taskapp/templates/taskapp/tasklist_active.html:15 #: taskapp/templates/taskapp/tasklist_active.html:15

19
taskapp/models.py

@ -60,17 +60,16 @@ def _delta_add_days():
class Task(models.Model): class Task(models.Model):
descr = models.CharField(max_length=128, null=True, blank=True)
descr = models.CharField(_('Description'), max_length=128, null=True, blank=True)
recipients = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='them_task') recipients = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='them_task')
author = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='+', on_delete=models.SET_NULL, null=True, blank=True)
#device = models.ForeignKey(Device, related_name='dev')
priority = models.CharField(max_length=1, choices=TASK_PRIORITIES, default=TASK_PRIORITIES[2][0])
out_date = models.DateField(null=True, blank=True, default=_delta_add_days)
time_of_create = models.DateTimeField(auto_now_add=True)
state = models.CharField(max_length=1, choices=TASK_STATES, default=TASK_STATES[0][0])
attachment = models.ImageField(upload_to='task_attachments/%Y.%m.%d', blank=True, null=True)
mode = models.CharField(max_length=2, choices=TASK_TYPES, default=TASK_TYPES[0][0])
abon = models.ForeignKey(Abon, null=True, blank=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='+', on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_('Task author'))
priority = models.CharField(_('A priority'), max_length=1, choices=TASK_PRIORITIES, default=TASK_PRIORITIES[2][0])
out_date = models.DateField(_('Reality'), null=True, blank=True, default=_delta_add_days)
time_of_create = models.DateTimeField(_('Date of create'), auto_now_add=True)
state = models.CharField(_('Condition'), max_length=1, choices=TASK_STATES, default=TASK_STATES[0][0])
attachment = models.ImageField(_('Attached image'), upload_to='task_attachments/%Y.%m.%d', blank=True, null=True)
mode = models.CharField(_('The nature of the damage'), max_length=2, choices=TASK_TYPES, default=TASK_TYPES[0][0])
abon = models.ForeignKey(Abon, null=True, blank=True, verbose_name=_('Subscriber'))
class Meta: class Meta:
db_table = 'task' db_table = 'task'

65
taskapp/templates/taskapp/add_edit_task.html

@ -1,5 +1,6 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %} {% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %} {% load i18n %}
{% load bootstrap3 %}
{% block main %} {% block main %}
<ol class="breadcrumb"> <ol class="breadcrumb">
@ -12,7 +13,11 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
{% if task_id %}
<h3 class="panel-title">{% trans 'Add new task' %}</h3> <h3 class="panel-title">{% trans 'Add new task' %}</h3>
{% else %}
<h3 class="panel-title">{% trans 'Edit task' %}</h3>
{% endif %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
@ -23,38 +28,18 @@
{% endif %} {% endif %}
{% csrf_token %}<input type="hidden" name="MAX_FILE_SIZE" value="{{ FILE_UPLOAD_MAX_MEMORY_SIZE }}"/> {% csrf_token %}<input type="hidden" name="MAX_FILE_SIZE" value="{{ FILE_UPLOAD_MAX_MEMORY_SIZE }}"/>
<div class="form-group">
<label for="id_descr">{% trans 'Description' %}</label>
{% bootstrap_icon 'tag' as ic %}
{% bootstrap_field form.descr addon_before=ic %}
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-tag"></span></span>
{{ form.descr }}{{ form.descr.errors }}
</div>
</div>
<div class="form-group">
<label for="id_mode">{% trans 'The nature of the damage' %}</label>
{% bootstrap_icon 'pawn' as ic %}
{% bootstrap_field form.mode addon_before=ic %}
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-pawn"></span></span>
{{ form.mode }}{{ form.mode.errors }}
</div>
</div>
<div class="form-group">
<label for="id_priority">{% trans 'A priority' %}</label>
{% bootstrap_icon 'sort-by-order' as ic %}
{% bootstrap_field form.priority addon_before=ic %}
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-sort-by-order"></span></span>
{{ form.priority }}{{ form.priority.errors }}
</div>
</div>
<div class="form-group">
<label for="id_state">{% trans 'Condition' %}</label>
{% bootstrap_icon 'retweet' as ic %}
{% bootstrap_field form.state addon_before=ic %}
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-retweet"></span></span>
{{ form.state }}{{ form.state.errors }}
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="id_abon">{% trans 'Subscriber' %}</label> <label for="id_abon">{% trans 'Subscriber' %}</label>
@ -72,7 +57,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="id_out_date">{% trans 'Reality (the date by which you must complete the task)' %}</label>
<label for="id_out_date">{% trans 'Reality' %}</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span> <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
@ -86,20 +71,22 @@
}); });
</script> </script>
</div> </div>
<div class="form-group">
<label for="id_attachment">{% trans 'Attached image' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-picture"></span></span>
{{ form.attachment }}{{ form.attachment.errors }}
</div>
</div>
<div class="btn-group">
<button type="submit" class="btn btn-sm btn-primary">
{% bootstrap_icon 'picture' as ic %}
{% bootstrap_field form.attachment addon_before=ic %}
<div class="btn-group btn-group-sm">
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %} <span class="glyphicon glyphicon-save"></span> {% trans 'Save' %}
</button> </button>
<button type="reset" class="btn btn-sm btn-default">
<button type="reset" class="btn btn-default">
<span class="glyphicon glyphicon-remove-circle"></span> {% trans 'Reset' %} <span class="glyphicon glyphicon-remove-circle"></span> {% trans 'Reset' %}
</button> </button>
{% if task_id %}
<a href="{% url 'taskapp:delete' task_id %}" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span> {% trans 'Delete' %}
</a>
{% endif %}
</div> </div>
</form> </form>
</div> </div>

2
taskapp/views.py

@ -82,7 +82,7 @@ def all_tasks(request):
def task_delete(request, task_id): def task_delete(request, task_id):
task = get_object_or_404(Task, id=task_id) task = get_object_or_404(Task, id=task_id)
# нельзя удалить назначенную мне задачу # нельзя удалить назначенную мне задачу
if request.user not in task.recipients.all():
if request.user.is_superuser or request.user not in task.recipients.all():
task.delete() task.delete()
else: else:
messages.warning(request, _('You cannot delete task that assigned to you')) messages.warning(request, _('You cannot delete task that assigned to you'))

Loading…
Cancel
Save