diff --git a/abonapp/forms.py b/abonapp/forms.py index 9068eda..acfa9e8 100644 --- a/abonapp/forms.py +++ b/abonapp/forms.py @@ -7,6 +7,7 @@ from random import choice from string import digits, ascii_lowercase from . import models from django.conf import settings +from bitfield.forms import BitFieldCheckboxSelectMultiple TELEPHONE_REGEXP = getattr(settings, 'TELEPHONE_REGEXP', r'^\+[7,8,9,3]\d{10,11}$') @@ -179,3 +180,13 @@ class ExportUsersForm(forms.Form): fields = forms.MultipleChoiceField(choices=FIELDS_CHOICES, widget=forms.CheckboxSelectMultiple(attrs={"checked": ""}), label=_('Fields')) + + +class MarkersForm(forms.ModelForm): + class Meta: + model = models.Abon + fields = ['markers'] + + def save(self, commit=True): + instance = super(MarkersForm, self).save(commit=False) + return instance.save(update_fields=['markers']) diff --git a/abonapp/migrations/0006_abon_markers.py b/abonapp/migrations/0006_abon_markers.py new file mode 100644 index 0000000..ba76123 --- /dev/null +++ b/abonapp/migrations/0006_abon_markers.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2018-02-13 14:06 +from __future__ import unicode_literals + +import bitfield.models +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ('abonapp', '0005_auto_20180123_1353'), + ] + + operations = [ + migrations.AddField( + model_name='abon', + name='markers', + field=bitfield.models.BitField((('icon_donkey', 'Donkey'), ('icon_fire', 'Fire'), ('icon_ok', 'Ok'), + ('icon_king', 'King'), ('icon_tv', 'TV'), ('icon_smile', 'Smile'), + ('icon_dollar', 'Dollar'), ('icon_service', 'Service'), + ('icon_mrk', 'Marker')), default=None), + ), + ] diff --git a/abonapp/models.py b/abonapp/models.py index 676d23a..f329859 100644 --- a/abonapp/models.py +++ b/abonapp/models.py @@ -1,17 +1,20 @@ from datetime import datetime + +from django.conf import settings +from django.core import validators from django.core.exceptions import ValidationError from django.core.validators import RegexValidator +from django.db import models, connection, transaction from django.db.models.signals import post_save, post_delete, pre_delete, post_init from django.dispatch import receiver from django.utils import timezone -from django.db import models, connection, transaction -from django.core import validators -from django.utils.translation import ugettext as _ -from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult, NasNetworkError -from tariff_app.models import Tariff, PeriodicPay +from django.utils.translation import ugettext_lazy as _ + from accounts_app.models import UserProfile, MyUserManager +from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult, NasNetworkError from mydefs import MyGenericIPAddressField, ip2int, LogicError, ip_addr_regex -from django.conf import settings +from tariff_app.models import Tariff, PeriodicPay +from bitfield import BitField TELEPHONE_REGEXP = getattr(settings, 'TELEPHONE_REGEXP', r'^\+[7,8,9,3]\d{10,11}$') @@ -159,6 +162,29 @@ class Abon(UserProfile): dev_port = models.ForeignKey('devapp.Port', null=True, blank=True, on_delete=models.SET_NULL) is_dynamic_ip = models.BooleanField(default=False) + MARKER_FLAGS = ( + ('icon_donkey', _('Donkey')), + ('icon_fire', _('Fire')), + ('icon_ok', _('Ok')), + ('icon_king', _('King')), + ('icon_tv', _('TV')), + ('icon_smile', _('Smile')), + ('icon_dollar', _('Dollar')), + ('icon_service', _('Service')), + ('icon_mrk', _('Marker')) + ) + markers = BitField(flags=MARKER_FLAGS, default=0) + + def get_flag_icons(self): + """ + Return icon list of set flags from self.markers + :return: ['m-icon-donkey', 'm-icon-tv', ...] + """ + return ["m-%s" % name for name, state in self.markers if state] + + def is_markers_empty(self): + return int(self.markers) == 0 + def active_tariff(self): return self.current_tariff diff --git a/abonapp/templates/abonapp/editAbon.html b/abonapp/templates/abonapp/editAbon.html index 6a95b76..bde8882 100644 --- a/abonapp/templates/abonapp/editAbon.html +++ b/abonapp/templates/abonapp/editAbon.html @@ -216,6 +216,23 @@ {% endif %} +
+
+

{% trans 'User flags' %}

+
+
+ {% for user_icon in abon.get_flag_icons %} + + {% endfor %} +
+ +
diff --git a/abonapp/templates/abonapp/group_list.html b/abonapp/templates/abonapp/group_list.html index 761efec..175c42f 100644 --- a/abonapp/templates/abonapp/group_list.html +++ b/abonapp/templates/abonapp/group_list.html @@ -83,6 +83,6 @@ - {% include 'toolbar_page_cbv.html' %} + {% include 'pagination.html' %} {% endblock %} diff --git a/abonapp/templates/abonapp/modal_user_markers.html b/abonapp/templates/abonapp/modal_user_markers.html new file mode 100644 index 0000000..934535b --- /dev/null +++ b/abonapp/templates/abonapp/modal_user_markers.html @@ -0,0 +1,31 @@ +{% load i18n %} +
{% csrf_token %} + + + + + + +
diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html index 0632827..bc52466 100644 --- a/abonapp/templates/abonapp/peoples.html +++ b/abonapp/templates/abonapp/peoples.html @@ -167,6 +167,6 @@ - {% include 'toolbar_page_cbv.html' %} + {% include 'pagination.html' %} {% endblock %} diff --git a/abonapp/urls_abon.py b/abonapp/urls_abon.py index 755b33f..404889c 100644 --- a/abonapp/urls_abon.py +++ b/abonapp/urls_abon.py @@ -41,6 +41,8 @@ urlpatterns = [ url(r'^(?P\d+)/tel/add$', views.tel_add, name='telephone_new'), url(r'^(?P\d+)/tel/del$', views.tel_del, name='telephone_del'), + url(r'^(?P\d+)/markers$', views.EditSibscriberMarkers.as_view(), name='markers_edit'), + url(r'^(?P\d+)/periodic_pay$', views.add_edit_periodic_pay, name='add_periodic_pay'), url(r'^(?P\d+)/periodic_pay(?P\d+)$', views.add_edit_periodic_pay, name='add_periodic_pay'), url(r'^(?P\d+)/periodic_pay(?P\d+)/del$', views.del_periodic_pay, name='del_periodic_pay') diff --git a/abonapp/views.py b/abonapp/views.py index b651e57..7f1d7e8 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -10,7 +10,7 @@ from django.http import HttpResponse, HttpResponseBadRequest from django.contrib import messages from django.utils.translation import gettext_lazy as _ from django.utils.decorators import method_decorator -from django.views.generic import ListView +from django.views.generic import ListView, UpdateView from django.conf import settings from statistics.models import StatCache @@ -1036,6 +1036,34 @@ def del_periodic_pay(request, gid, uid, periodic_pay_id): return redirect('abonapp:abon_services', gid, uid) +@method_decorator([login_required, mydefs.only_admins], name='dispatch') +class EditSibscriberMarkers(UpdateView): + http_method_names = ['get', 'post'] + template_name = 'abonapp/modal_user_markers.html' + form_class = forms.MarkersForm + + def get_object(self, queryset=None): + obj = models.Abon.objects.get(pk=self.kwargs.get('uid')) + return obj + + def get_success_url(self): + return resolve_url('abonapp:abon_home', self.kwargs.get('gid'), self.kwargs.get('uid')) + + def get_context_data(self, **kwargs): + context = super(EditSibscriberMarkers, self).get_context_data(**kwargs) + context['gid'] = self.kwargs.get('gid') + context['uid'] = self.kwargs.get('uid') + return context + + def form_invalid(self, form): + messages.add_message(self.request, messages.ERROR, _('fix form errors')) + return super(EditSibscriberMarkers, self).form_invalid(form) + + def form_valid(self, form): + v = super(EditSibscriberMarkers, self).form_valid(form) + messages.add_message(self.request, messages.SUCCESS, _('User flags has changed successfully')) + return v + # API's diff --git a/requirements.txt b/requirements.txt index 6f17527..4b8ad89 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,3 +21,4 @@ requests webdavclient pyst2 django-jsonview +django-bitfield diff --git a/static/css/custom.css b/static/css/custom.css index ade7ac7..4e12389 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -280,3 +280,22 @@ pre { word-wrap: break-word; } +/* + * Markers icons + */ +.m-icon{ + background-image: url(../img/user_markers.png); + width: 26px; + height: 26px; + display: inline-block; + margin-bottom: -9px; +} +.m-icon_donkey{background-position: 0 0;} +.m-icon_fire{background-position: -26px 0;} +.m-icon_ok{background-position: -52px 0;} +.m-icon_king{background-position: 0 -26px;} +.m-icon_tv{background-position: -26px -26px;} +.m-icon_smile{background-position: -52px -26px;} +.m-icon_dollar{background-position: 0 -52px;} +.m-icon_service{background-position: -26px -52px;} +.m-icon_mrk{background-position: -52px -52px;} diff --git a/static/img/user_markers.png b/static/img/user_markers.png new file mode 100644 index 0000000..6fb8fdc Binary files /dev/null and b/static/img/user_markers.png differ