From f780559c9da949984b637c50e49a264165bac418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lian?= Date: Thu, 27 Sep 2018 21:32:54 +0200 Subject: [PATCH 1/2] Start work on add user and update credit stuff --- p0sx/urls.py | 14 +++- pos/forms.py | 11 +++ pos/management/commands/import-ge-crew.py | 3 +- pos/migrations/0006_auto_20180925_2035.py | 23 ++++++ pos/migrations/0007_user_is_crew.py | 20 ++++++ pos/models/user.py | 18 +++++ pos/views/littleadmin.py | 87 +++++++++++++++++++++-- templates/pos/add_user.djhtml | 13 ++++ 8 files changed, 182 insertions(+), 7 deletions(-) create mode 100644 pos/migrations/0006_auto_20180925_2035.py create mode 100644 pos/migrations/0007_user_is_crew.py create mode 100644 templates/pos/add_user.djhtml diff --git a/p0sx/urls.py b/p0sx/urls.py index c129baa..5fbbeb1 100644 --- a/p0sx/urls.py +++ b/p0sx/urls.py @@ -5,7 +5,14 @@ from django.core.urlresolvers import reverse_lazy from django.views.generic.base import RedirectView -from pos.views.littleadmin import check_credit, credit_edit, credit_overview, crew_report, sale_overview +from pos.views.littleadmin import (add_user, + check_credit, + credit_edit, + credit_overview, + crew_report, + edit_user_credit, + sale_overview, + scan_user_card) from pos.views.shift import AllShiftsViewSet, CurrentShiftViewSet, NewShiftViewSet, ShiftViewSet from pos.views.stock import (CategoryViewSet, CreditCheckViewSet, @@ -29,7 +36,10 @@ url(r'overview/', credit_overview, name='overview'), url(r'edit/(?P\w+)', credit_edit, name='edit'), url(r'sale/', include(sale_url, namespace='sale')), - url(r'crew_report/', crew_report, name='crew_report') + url(r'crew_report/', crew_report, name='crew_report'), + url(r'scan_user_card', scan_user_card, name='scan_user_card'), + url(r'edit_user_credit/(?P\w+)', edit_user_credit, name='edit_user_credit'), + url(r'add_user/(?P\w+)', add_user, name='add_user') ] # Routers provide an easy way of automatically determining the URL conf. diff --git a/pos/forms.py b/pos/forms.py index 6fbe199..ade08ad 100644 --- a/pos/forms.py +++ b/pos/forms.py @@ -12,3 +12,14 @@ class ChangeCreditForm(forms.ModelForm): class Meta: model = User fields = ['credit'] + + +class AddUserForm(forms.ModelForm): + + class Meta: + model = User + fields = ['first_name', 'last_name', 'phone', 'email', 'credit', 'card'] + widgets = { + 'card': forms.PasswordInput(render_value=True), + 'first_name': forms.TextInput(attrs={'autofocus': 'autofocus'}) + } diff --git a/pos/management/commands/import-ge-crew.py b/pos/management/commands/import-ge-crew.py index 471a2ef..1e79479 100644 --- a/pos/management/commands/import-ge-crew.py +++ b/pos/management/commands/import-ge-crew.py @@ -44,7 +44,8 @@ def handle(self, *args, **options): crew=data['crew'], role=data['role'], email=data['email'], - credit=0 + credit=0, + is_crew=True ) crew.save() # print('Added new user {} {}'.format(data['first_name'], data['last_name'])) diff --git a/pos/migrations/0006_auto_20180925_2035.py b/pos/migrations/0006_auto_20180925_2035.py new file mode 100644 index 0000000..35fdf53 --- /dev/null +++ b/pos/migrations/0006_auto_20180925_2035.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.8 on 2018-09-25 18:35 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('pos', '0005_auto_20170902_1225'), + ] + + operations = [ + migrations.AlterModelOptions( + name='category', + options={'verbose_name_plural': 'Categories'}, + ), + migrations.AlterModelOptions( + name='user', + options={'permissions': (('create_user', 'Can add a new user to the system'), ('update_credit', 'Can update the credit limit on a user'))}, + ), + ] diff --git a/pos/migrations/0007_user_is_crew.py b/pos/migrations/0007_user_is_crew.py new file mode 100644 index 0000000..765007f --- /dev/null +++ b/pos/migrations/0007_user_is_crew.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.8 on 2018-09-25 18:49 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pos', '0006_auto_20180925_2035'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='is_crew', + field=models.BooleanField(default=False), + ), + ] diff --git a/pos/models/user.py b/pos/models/user.py index 2133418..e023c2a 100644 --- a/pos/models/user.py +++ b/pos/models/user.py @@ -15,6 +15,7 @@ class User(models.Model): role = models.CharField(max_length=255) email = models.EmailField() is_cashier = models.BooleanField(default=False) + is_crew = models.BooleanField(default=False) @property def used(self): @@ -25,9 +26,26 @@ def used(self): def left(self): return self.credit - self.used + @classmethod + def create(cls, card, credit, first_name, last_name, phone, email): + user = cls(card=card, + credit=credit, + first_name=first_name, + last_name=last_name, + phone=phone, + email=email) + + return user + def __str__(self): return '{} {}'.format(self.first_name, self.last_name) + class Meta: + permissions = ( + ("create_user", "Can add a new user to the system"), + ("update_credit", "Can update the credit limit on a user") + ) + class UserSession(models.Model): start = models.DateTimeField(auto_now_add=True) diff --git a/pos/views/littleadmin.py b/pos/views/littleadmin.py index e63cf69..bc9e2f3 100644 --- a/pos/views/littleadmin.py +++ b/pos/views/littleadmin.py @@ -1,10 +1,10 @@ -from django.contrib.auth.decorators import login_required +from django.contrib.auth.decorators import login_required, permission_required from django.db.models import Case, IntegerField, Sum, When -from django.http import HttpResponseRedirect -from django.shortcuts import get_object_or_404, render +from django.http import HttpResponseRedirect, HttpResponseBadRequest +from django.shortcuts import get_object_or_404, render, redirect from django.urls import reverse_lazy -from ..forms import ChangeCreditForm, CheckCreditForm +from ..forms import AddUserForm, ChangeCreditForm, CheckCreditForm from ..models.shift import Shift from ..models.stock import Item, OrderLine from ..models.user import User @@ -133,3 +133,82 @@ def sale_overview(request): shifts = ShiftSerializer(Shift.objects.all(), many=True) print(shifts.data) return render(request, 'pos/sale_overview.djhtml', {'overview': overview, 'shifts': shifts.data, 'total': total}) + + +@permission_required("user.update_credit") +def scan_user_card(request): + if request.POST: + form = CheckCreditForm(request.POST) + + if form.is_valid(): + card = form.cleaned_data['card'] + + user = User.objects.filter(card=card) + + if not user: + return redirect('littleadmin:add_user', card=card) + + return redirect('littleadmin:edit_user_credit', card=card) + else: + return HttpResponseRedirect(reverse_lazy('littleadmin:scan_user_card')) + else: + return render(request, 'pos/credit_check.djhtml', { + 'form': CheckCreditForm(), + 'table': False, + }) + + +@permission_required('user.update_credit') +def edit_user_credit(request, card=None): + if request.POST: + form = ChangeCreditForm(request.POST) + if form.is_valid(): + credit = form.cleaned_data['credit'] + user = get_object_or_404(User, card=card) + + if user.is_crew: + return HttpResponseBadRequest(b'Not allowed to update crew credit') + + user.credit = credit + user.save() + return redirect('littleadmin:scan_user_card') + else: + user = get_object_or_404(User, card=card) + form = ChangeCreditForm(instance=user) + + return render(request, 'pos/credit_edit.djhtml', {'form': form, 'target': user}) + + +@permission_required('user.create_user') +def add_user(request, card=None): + if request.POST: + form = AddUserForm(request.POST) + + if form.is_valid(): + card = form.cleaned_data['card'] + credit = form.cleaned_data['credit'] + first_name = form.cleaned_data['first_name'] + last_name = form.cleaned_data['last_name'] + phone = form.cleaned_data['phone'] + email = form.cleaned_data['email'] + + user = User.create(card, credit, first_name, last_name, phone, email) + + user.save() + + return redirect('littleadmin:scan_user_card') + else: + return HttpResponseRedirect(reverse_lazy('littleadmin:add_user')) + else: + form = AddUserForm(initial={'card': card}) + print(form['card'].value()) + return render(request, 'pos/add_user.djhtml', { + 'form': form + }) + + + + + + + diff --git a/templates/pos/add_user.djhtml b/templates/pos/add_user.djhtml new file mode 100644 index 0000000..d287018 --- /dev/null +++ b/templates/pos/add_user.djhtml @@ -0,0 +1,13 @@ +{% extends "base.djhtml" %} +{% block title %} +Add user +{% endblock title %} +{% block content %} +

Add new user!

+ +
{% csrf_token %} + {{ form }} + +
+ +{% endblock content %} \ No newline at end of file From ec64c05c99f6b9c4959872140bd13dc2b817dd61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Lian?= Date: Sun, 30 Sep 2018 14:58:01 +0200 Subject: [PATCH 2/2] More cashless work, lets test this. --- .gitignore | 1 + p0sx/settings/base.py | 2 ++ p0sx/urls.py | 6 +++- pos/forms.py | 9 ++++- pos/migrations/0006_auto_20180925_2035.py | 2 +- pos/models/stock.py | 7 ++-- pos/models/user.py | 3 +- pos/views/littleadmin.py | 42 ++++++++++++++--------- templates/base.djhtml | 30 +++++++++------- templates/pos/add_credit.djhtml | 33 ++++++++++++++++++ templates/pos/add_user.djhtml | 7 ++-- templates/pos/credit_check.djhtml | 8 ++--- templates/pos/credit_edit.djhtml | 9 +++-- templates/pos/credit_overview.djhtml | 12 +++++-- templates/pos/login.djhtml | 10 ++++++ templates/pos/scan_card.djhtml | 12 +++++++ version.py | 2 +- 17 files changed, 144 insertions(+), 51 deletions(-) create mode 100644 templates/pos/add_credit.djhtml create mode 100644 templates/pos/login.djhtml create mode 100644 templates/pos/scan_card.djhtml diff --git a/.gitignore b/.gitignore index cae5b69..645a4b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ env/ +venv/ collected_static/ prod.py .tox/ diff --git a/p0sx/settings/base.py b/p0sx/settings/base.py index 32845c6..247d9f3 100755 --- a/p0sx/settings/base.py +++ b/p0sx/settings/base.py @@ -129,3 +129,5 @@ MEDIA_ROOT = os.path.join(BASE_DIR, '..', 'media') MEDIA_URL = '/media/' + +LOGIN_REDIRECT_URL = '/littleadmin/scan_user_card' diff --git a/p0sx/urls.py b/p0sx/urls.py index 5fbbeb1..f78654a 100644 --- a/p0sx/urls.py +++ b/p0sx/urls.py @@ -4,6 +4,7 @@ from django.contrib import admin from django.core.urlresolvers import reverse_lazy from django.views.generic.base import RedirectView +from django.contrib.auth import views as auth_views from pos.views.littleadmin import (add_user, check_credit, @@ -34,7 +35,7 @@ url(r'^$', RedirectView.as_view(url=reverse_lazy('littleadmin:overview'))), url(r'check/', check_credit, name='check'), url(r'overview/', credit_overview, name='overview'), - url(r'edit/(?P\w+)', credit_edit, name='edit'), + url(r'edit_crew_credit/(?P\w+)', credit_edit, name='edit_crew_credit'), url(r'sale/', include(sale_url, namespace='sale')), url(r'crew_report/', crew_report, name='crew_report'), url(r'scan_user_card', scan_user_card, name='scan_user_card'), @@ -58,8 +59,11 @@ router.register(r'purchases', PurchaseViewSet, 'purchase') router.register(r'credit', CreditCheckViewSet, 'credit') router.register(r'discounts', DiscountViewSet, 'discount') + urlpatterns = [ url(r'^$', RedirectView.as_view(url=reverse_lazy('admin:index'))), + url(r'^login/$', auth_views.login, {'template_name': 'pos/login.djhtml'}, name='login'), + url(r'^logout/$', auth_views.logout, {'next_page': '/login'}, name='logout'), url(r'^admin/', include(admin.site.urls)), url(r'^', include(router.urls)), url(r'littleadmin/', include(littleadmin_url, namespace='littleadmin')) diff --git a/pos/forms.py b/pos/forms.py index ade08ad..84510ac 100644 --- a/pos/forms.py +++ b/pos/forms.py @@ -4,7 +4,11 @@ class CheckCreditForm(forms.Form): - card = forms.CharField(max_length=100, widget=forms.PasswordInput()) + card = forms.CharField(max_length=100, widget=forms.PasswordInput(attrs={'autofocus': 'autofocus'})) + + +class AddCreditForm(forms.Form): + credit = forms.CharField(widget=forms.NumberInput(attrs={'autofocus': 'autofocus'})) class ChangeCreditForm(forms.ModelForm): @@ -12,6 +16,9 @@ class ChangeCreditForm(forms.ModelForm): class Meta: model = User fields = ['credit'] + widgets = { + 'credit': forms.NumberInput(attrs={'autofocus': 'autofocus'}) + } class AddUserForm(forms.ModelForm): diff --git a/pos/migrations/0006_auto_20180925_2035.py b/pos/migrations/0006_auto_20180925_2035.py index 35fdf53..c5f04fd 100644 --- a/pos/migrations/0006_auto_20180925_2035.py +++ b/pos/migrations/0006_auto_20180925_2035.py @@ -18,6 +18,6 @@ class Migration(migrations.Migration): ), migrations.AlterModelOptions( name='user', - options={'permissions': (('create_user', 'Can add a new user to the system'), ('update_credit', 'Can update the credit limit on a user'))}, + options={'permissions': (("update_credit", "Can update the credit limit on a user"),)}, ), ] diff --git a/pos/models/stock.py b/pos/models/stock.py index d9d33ab..a18f0ab 100644 --- a/pos/models/stock.py +++ b/pos/models/stock.py @@ -80,14 +80,17 @@ class Order(models.Model): def __str__(self): return str(self.user) + ' ' + self.date.strftime('%Y-%m-%d %H:%M:%S') + @property + def info(self): + return f"{self.sum} {self.date:%Y-%m-%d %H:%M:%S}" + @classmethod def create(cls, user, cashier, authenticated_user, payment_method, message): order = cls(user=user, cashier=cashier, authenticated_user=authenticated_user, payment_method=payment_method, - message=message - ) + message=message) return order diff --git a/pos/models/user.py b/pos/models/user.py index e023c2a..dc6e5ce 100644 --- a/pos/models/user.py +++ b/pos/models/user.py @@ -42,8 +42,7 @@ def __str__(self): class Meta: permissions = ( - ("create_user", "Can add a new user to the system"), - ("update_credit", "Can update the credit limit on a user") + ("update_credit", "Can update the credit limit on a user"), ) diff --git a/pos/views/littleadmin.py b/pos/views/littleadmin.py index bc9e2f3..2037b04 100644 --- a/pos/views/littleadmin.py +++ b/pos/views/littleadmin.py @@ -1,12 +1,13 @@ from django.contrib.auth.decorators import login_required, permission_required from django.db.models import Case, IntegerField, Sum, When -from django.http import HttpResponseRedirect, HttpResponseBadRequest +from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, render, redirect from django.urls import reverse_lazy +from django.contrib import messages -from ..forms import AddUserForm, ChangeCreditForm, CheckCreditForm +from ..forms import AddCreditForm, AddUserForm, ChangeCreditForm, CheckCreditForm from ..models.shift import Shift -from ..models.stock import Item, OrderLine +from ..models.stock import Item, OrderLine, Order from ..models.user import User from ..serializers.shift import ShiftSerializer @@ -17,14 +18,16 @@ def check_credit(request): if form.is_valid(): card = form.cleaned_data['card'] - user = User.objects.filter(card=card) if not user: return HttpResponseRedirect(reverse_lazy('littleadmin:check')) + orders = Order.objects.filter(user_id=user.id).order_by('date')[0:3] + return render(request, 'pos/credit_check.djhtml', { 'form': CheckCreditForm(), + 'orders': [o.info for o in orders], 'table': True, 'used': user[0].used, 'credit': user[0].credit, @@ -43,7 +46,6 @@ def check_credit(request): def credit_overview(request): bought = OrderLine.objects.all().exclude(order__user__isnull=True).values('order__user').annotate(used=Sum('price')) users = User.objects.all().values() - print(bought) for user in users: for b in bought: user['used'] = 0 @@ -131,11 +133,10 @@ def sale_overview(request): total['total'] += item['total'] shifts = ShiftSerializer(Shift.objects.all(), many=True) - print(shifts.data) return render(request, 'pos/sale_overview.djhtml', {'overview': overview, 'shifts': shifts.data, 'total': total}) -@permission_required("user.update_credit") +@permission_required("pos.update_credit") def scan_user_card(request): if request.POST: form = CheckCreditForm(request.POST) @@ -152,34 +153,41 @@ def scan_user_card(request): else: return HttpResponseRedirect(reverse_lazy('littleadmin:scan_user_card')) else: - return render(request, 'pos/credit_check.djhtml', { + return render(request, 'pos/scan_card.djhtml', { 'form': CheckCreditForm(), 'table': False, }) -@permission_required('user.update_credit') +@permission_required('pos.update_credit') def edit_user_credit(request, card=None): if request.POST: - form = ChangeCreditForm(request.POST) + form = AddCreditForm(request.POST) if form.is_valid(): credit = form.cleaned_data['credit'] user = get_object_or_404(User, card=card) if user.is_crew: - return HttpResponseBadRequest(b'Not allowed to update crew credit') + messages.error(request, "You cannot change the credit of Crew") + return redirect('littleadmin:scan_user_card') - user.credit = credit + user.credit = user.credit + credit user.save() + messages.success(request, "Credit updated successfully") return redirect('littleadmin:scan_user_card') else: user = get_object_or_404(User, card=card) - form = ChangeCreditForm(instance=user) - return render(request, 'pos/credit_edit.djhtml', {'form': form, 'target': user}) + if user.is_crew: + messages.error(request, "You cannot change the credit of Crew") + return redirect('littleadmin:scan_user_card') + + form = AddCreditForm() + return render(request, 'pos/add_credit.djhtml', {'form': form, 'target': user}) -@permission_required('user.create_user') + +@permission_required('pos.update_credit') def add_user(request, card=None): if request.POST: form = AddUserForm(request.POST) @@ -195,13 +203,13 @@ def add_user(request, card=None): user = User.create(card, credit, first_name, last_name, phone, email) user.save() - + messages.success(request, "User added successfully") return redirect('littleadmin:scan_user_card') else: + messages.error(request, "Failed to add user") return HttpResponseRedirect(reverse_lazy('littleadmin:add_user')) else: form = AddUserForm(initial={'card': card}) - print(form['card'].value()) return render(request, 'pos/add_user.djhtml', { 'form': form }) diff --git a/templates/base.djhtml b/templates/base.djhtml index c2a87ad..c539c54 100644 --- a/templates/base.djhtml +++ b/templates/base.djhtml @@ -4,12 +4,11 @@ - - + + - - + {% block script%} {% endblock script %} @@ -30,34 +29,39 @@ - {% if user.is_authenticated %} + {% if messages %} + + {% endif %} - {% endif %}
{% block content %}{% endblock content %}
-