From b4507320ae8dd2c46203c30e3821c3e5f3b5b862 Mon Sep 17 00:00:00 2001 From: "Denis V. Dedkov" Date: Sat, 20 Jun 2015 20:22:45 +0500 Subject: [PATCH 1/5] =?UTF-8?q?=D0=A1=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86?= =?UTF-8?q?=D0=B0=20=D0=B6=D1=83=D1=80=D0=BD=D0=B0=D0=BB=D0=B0=20=D0=B4?= =?UTF-8?q?=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавил страницу журнала действий --- asuzr/tables.py | 12 ++++++++++++ asuzr/views.py | 8 ++++++++ record/urls.py | 1 + templates/asuzr/base.html | 5 ++++- 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/asuzr/tables.py b/asuzr/tables.py index 34bf073..95c197e 100644 --- a/asuzr/tables.py +++ b/asuzr/tables.py @@ -3,6 +3,7 @@ from django.core.urlresolvers import reverse from django.utils.safestring import mark_safe from django.utils.html import escape +from django.contrib.admin.models import LogEntry import django_tables2 as tables from models import * @@ -200,3 +201,14 @@ class ProdPlanTable(tables.Table): class Meta: attrs = {'class': 'paleblue'} + +class LogTable(tables.Table): + def render_action_flag(self, value): + return {1: 'Добавление', + 2: 'Изменение', + 3: 'Удаление', + 4: 'Авторизация'}[value] + + class Meta: + model = LogEntry + attrs = {'class': 'paleblue'} diff --git a/asuzr/views.py b/asuzr/views.py index 2021c5e..e69e517 100644 --- a/asuzr/views.py +++ b/asuzr/views.py @@ -3,6 +3,7 @@ from django.shortcuts import render, redirect, get_object_or_404 from django.http import HttpResponse, HttpResponseRedirect from django.template import RequestContext, Context, loader +from django.contrib.admin.models import LogEntry from asuzr.models import * from datetime import datetime, date, timedelta import calendar @@ -267,3 +268,10 @@ def prod_plan_view(request): title = u'Производственный план на %s - %s' % (sdate.strftime('%d.%m.%Y'), edate.strftime('%d.%m.%Y')) RequestConfig(request).configure(table) return render(request, 'asuzr/table.html', {'table': table, 'title': title}) + +@login_required +def log_view(request): + log = LogEntry.objects.all() + table = LogTable(log) + RequestConfig(request).configure(table) + return render(request, 'asuzr/table.html', {'table': table, 'title': 'Журнал операций'}) diff --git a/record/urls.py b/record/urls.py index 390c34f..f574d7a 100644 --- a/record/urls.py +++ b/record/urls.py @@ -23,6 +23,7 @@ urlpatterns = patterns('', url(r'^sketches/delete/$', 'asuzr.views.delete_sketch'), url(r'^prodplan/$', 'asuzr.views.prod_plan_view'), url(r'^admin/', include(admin.site.urls)), + url(r'^log/$', 'asuzr.views.log_view'), url(r'^inplaceeditform/', include('inplaceeditform.urls')), url(r'^accounts/login/$', login), url(r'^accounts/logout/$', logout), diff --git a/templates/asuzr/base.html b/templates/asuzr/base.html index 188f494..3e53559 100644 --- a/templates/asuzr/base.html +++ b/templates/asuzr/base.html @@ -48,7 +48,10 @@
  • Архивная таблица
  • Отчет по дизайнерам
  • Производственный план
  • - {% if request.user.is_staff %}
  • Администрирование
  • {% endif %} + {% if request.user.is_staff %} +
  • Журнал операций
  • +
  • Администрирование
  • + {% endif %}
    {% if request.user.is_authenticated %} From 8e05a228bb71854046c2ab1aa8676e2e812aa69b Mon Sep 17 00:00:00 2001 From: "Denis V. Dedkov" Date: Sat, 20 Jun 2015 20:23:29 +0500 Subject: [PATCH 2/5] =?UTF-8?q?=D0=9B=D0=BE=D0=B3=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавил логирование событий авторизации: 1. Вход в систему 2. Выход из системы 3. Ошибка входа в систему --- asuzr/models.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/asuzr/models.py b/asuzr/models.py index 885c3fc..bd96baa 100644 --- a/asuzr/models.py +++ b/asuzr/models.py @@ -4,6 +4,8 @@ from django.db import models from django.contrib.auth.models import User from datetime import date, timedelta +from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed +from django.contrib.admin.models import LogEntry #Изделия class Product(models.Model): @@ -158,3 +160,23 @@ class OrderCosts(models.Model): def __unicode__(self): return ', '.join((self.order.product.name, self.cost_item.name)) + + +############################################################################################ +# Signal handlers +############################################################################################ + +def auth_log(message, user = None): + if user == None: + user = User.objects.get(pk = 1) + + entry = LogEntry(user = user, object_repr = message, action_flag = 4) + entry.save() + +on_login = lambda **kwargs: auth_log(u'Вход в систему', kwargs['user']) +on_logout = lambda **kwargs: auth_log(u'Выход из системы', kwargs['user']) +on_login_error = lambda **kwargs: auth_log(u'Ошибка входа пользователя %s' % kwargs['credentials']['username']) + +user_logged_in.connect(on_login) +user_logged_out.connect(on_logout) +user_login_failed.connect(on_login_error) From 9771529f8515516613bc45a73022598d3f07f764 Mon Sep 17 00:00:00 2001 From: "Denis V. Dedkov" Date: Sat, 27 Jun 2015 12:18:12 +0500 Subject: [PATCH 3/5] =?UTF-8?q?=D0=A0=D0=B0=D0=B7=D0=BC=D0=B5=D1=80=20?= =?UTF-8?q?=D1=81=D0=BA=D0=B5=D1=82=D1=87=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Поменял размер скетчей (требование заказчика) --- asuzr/tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asuzr/tables.py b/asuzr/tables.py index 95c197e..1b36260 100644 --- a/asuzr/tables.py +++ b/asuzr/tables.py @@ -49,7 +49,7 @@ class ThumbnailColumn(tables.TemplateColumn): template = ''' {{% load thumbnail %}} - {{% thumbnail record.{field} "100x100" as im %}} + {{% thumbnail record.{field} "200x200" as im %}} {{% endthumbnail %}} '''.format(field = field_name) From 02c97afe22a2a8763b17c8d8714294369d4671c1 Mon Sep 17 00:00:00 2001 From: "Denis V. Dedkov" Date: Sat, 27 Jun 2015 13:16:41 +0500 Subject: [PATCH 4/5] =?UTF-8?q?=D0=94=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8?= =?UTF-8?q?=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D0=BB=D0=B1=D1=86=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BA=D0=B0=D0=B7=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В заказы для текущего дня добавлены дополнительные столбцы по требованию заказчика --- asuzr/tables.py | 11 +++++------ asuzr/views.py | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/asuzr/tables.py b/asuzr/tables.py index 1b36260..46c0a2f 100644 --- a/asuzr/tables.py +++ b/asuzr/tables.py @@ -163,10 +163,11 @@ class VisitTable(tables.Table): class DayOrdersTable(OrdersTable): designer = tables.Column(verbose_name = 'Дизайнер') - summary = ['Итого:', 0, '', '', '',] + summary = ['Итого:', 0, 0, '', '', '', '', ''] - def set_summary(self, price): + def set_summary(self, price, paid): self.summary[1] = price + self.summary[2] = paid def render_designer(self, value): return ' '.join((value.first_name, value.last_name)) @@ -175,9 +176,6 @@ class DayOrdersTable(OrdersTable): empty_text = 'Заказов для этого дня нет' attrs = {'class': 'paleblue'} exclude = ('date', - 'delivery', - 'lifting', - 'paid', 'ostatok', 'approved', 'sketch', @@ -185,7 +183,8 @@ class DayOrdersTable(OrdersTable): 'is_done', ) sequence = ('product', - 'price', + 'price', + 'paid', 'address', 'designer', 'deadline', diff --git a/asuzr/views.py b/asuzr/views.py index e69e517..db92e25 100644 --- a/asuzr/views.py +++ b/asuzr/views.py @@ -94,10 +94,10 @@ def get_attendance_table(year, month, prefix): def get_day_orders_table(date, prefix): orders = Order.objects.filter(date = date) - orders_price = orders.aggregate(Sum('price')) + summaries = orders.aggregate(Sum('price'), Sum('paid')) table = DayOrdersTable(orders, prefix = prefix) table.verbose_name = 'Заказы на %s' % date.strftime('%d %B %Y г') - table.set_summary(orders_price['price__sum'] or 0) + table.set_summary(summaries['price__sum'] or 0, summaries['paid__sum'] or 0) return table From 9ac9d9d01813c06c0010290b6f4af36f7561cadd Mon Sep 17 00:00:00 2001 From: "Denis V. Dedkov" Date: Tue, 14 Jul 2015 23:08:54 +0500 Subject: [PATCH 5/5] =?UTF-8?q?=D0=A2=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D0=B0?= =?UTF-8?q?=20=D0=BF=D0=BE=D1=81=D0=B5=D1=89=D0=B0=D0=B5=D0=BC=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Сделал автосоздание звонков/посещений при отсутствии --- asuzr/views.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/asuzr/views.py b/asuzr/views.py index 7164566..590aa34 100644 --- a/asuzr/views.py +++ b/asuzr/views.py @@ -101,10 +101,17 @@ def get_day_orders_table(date, prefix): return table +def create_attendance_if_need(date): + attendance, created = Attendance.objects.get_or_create(date = date, + defaults={'calls': 0, 'visits': 0}) + if created: + attendance.save() + @login_required def visit_view(request): curr_date = datetime.strptime(request.GET.get('date', date.today().strftime('%d.%m.%Y')), '%d.%m.%Y') form = DateForm({'date':curr_date}) + create_attendance_if_need(curr_date) attendance_table, add_info = get_attendance_table(curr_date.year, curr_date.month, 'attendance-') RequestConfig(request, paginate={'per_page': 32}).configure(attendance_table)