🚨 format python code using black

This commit is contained in:
Nikolai R Kristiansen committed 2021-10-27 19:22:25 +02:00
1 parent 9c4a5b3d84
commit a052397990
24 files changed
+643 -407

No files matched your search

+1
View File
@@ -5,6 +5,7 @@ from main.models import *
class ProductAdmin(admin.ModelAdmin):
pass
admin.site.register(Product, ProductAdmin)
admin.site.register(InventoryTransaction)
admin.site.register(Order)
+18 -9
View File
@@ -8,33 +8,42 @@ from main.models import Product, OrderLine, Order
class ProductSerializer(ModelSerializer):
class Meta:
model = Product
fields = '__all__'
fields = "__all__"
class ProductStatSerializer(ModelSerializer):
EXTERNAL_USER = 'Ekstern'
EXTERNAL_USER = "Ekstern"
counts = serializers.SerializerMethodField()
def _format_counts(self, per_user):
per_user = list(per_user)
for row in per_user:
first = row.pop('order__customer__first_name')
last = row.pop('order__customer__last_name')
first = row.pop("order__customer__first_name")
last = row.pop("order__customer__last_name")
if first is None:
who = self.EXTERNAL_USER
else:
who = '{} {}'.format(first, last)
row['full_name'] = who
who = "{} {}".format(first, last)
row["full_name"] = who
return per_user
def get_counts(self, obj):
name_fields = ['order__customer__first_name', 'order__customer__last_name']
name_fields = ["order__customer__first_name", "order__customer__last_name"]
per_user = OrderLine.objects.filter(product=obj)
per_user = per_user.values(*name_fields).annotate(amount_total=Sum('amount')).order_by('-amount_total')
per_user = per_user.values(*name_fields).annotate(amount_total=Sum("amount")).order_by("-amount_total")
return self._format_counts(per_user)
class Meta:
model = Product
fields = ['id', 'name', 'description', 'image', 'inventory_amount', 'active', 'created', 'counts']
fields = [
"id",
"name",
"description",
"image",
"inventory_amount",
"active",
"created",
"counts",
]
+2 -5
View File
@@ -7,16 +7,13 @@ from main.models import Product
from rest_framework.viewsets import GenericViewSet
class ProductViewSet(mixins.ListModelMixin,
mixins.RetrieveModelMixin,
GenericViewSet):
class ProductViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
serializer_class = ProductSerializer
queryset = Product.objects.all()
@action(detail=False, methods=['get'])
@action(detail=False, methods=["get"])
def group_by_user(self, request):
products = self.get_queryset().filter(active=True)
serializer = ProductStatSerializer(products, many=True)
return Response(serializer.data)
+2 -2
View File
@@ -2,8 +2,8 @@ from django.apps import AppConfig
class BBSAppConfig(AppConfig):
name = 'main'
verbose_name = 'Biceps Bar System'
name = "main"
verbose_name = "Biceps Bar System"
def ready(self):
# all models are loaded, could attach signals
+16 -17
View File
@@ -10,23 +10,23 @@ class OrderForm(forms.ModelForm):
customer_name = forms.CharField(required=False)
def clean(self):
if self.cleaned_data['customer'] is None and self.cleaned_data['customer_name'] != "Ekstern":
if self.cleaned_data["customer"] is None and self.cleaned_data["customer_name"] != "Ekstern":
raise forms.ValidationError(_("Du har ikke valgt hvem som skal kjøpe."))
return self.cleaned_data
def clean_customer(self):
if self.cleaned_data['customer'] is None:
return self.cleaned_data['customer']
if self.cleaned_data["customer"] is None:
return self.cleaned_data["customer"]
if self.cleaned_data['customer'].profile.balance <= 0:
if self.cleaned_data["customer"].profile.balance <= 0:
raise forms.ValidationError(_("Du har negativ saldo og kan ikke kjøpe noe."))
return self.cleaned_data['customer']
return self.cleaned_data["customer"]
class Meta:
model = Order
fields = ('customer',)
fields = ("customer",)
class OrderLineForm(forms.Form):
@@ -37,10 +37,9 @@ class OrderLineForm(forms.Form):
class DepositForm(forms.ModelForm):
class Meta:
model = Transaction
fields = ['user', 'amount']
fields = ["user", "amount"]
class SimpleCreateUserForm(forms.Form):
@@ -50,15 +49,15 @@ class SimpleCreateUserForm(forms.Form):
facebook_username = forms.CharField(required=False, label="Facebook-brukernavn")
def _get_facebook_url(self):
if self.cleaned_data['facebook_username'] == "":
if self.cleaned_data["facebook_username"] == "":
return ""
return "https://graph.facebook.com/{0}/picture".format(self.cleaned_data['facebook_username'])
return "https://graph.facebook.com/{0}/picture".format(self.cleaned_data["facebook_username"])
def save(self, commit=True):
username = format_username(self.cleaned_data['first_name'], self.cleaned_data['last_name'])
user = User.objects.create_user(username, email=self.cleaned_data['email'])
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
def save(self, commit=True):
username = format_username(self.cleaned_data["first_name"], self.cleaned_data["last_name"])
user = User.objects.create_user(username, email=self.cleaned_data["email"])
user.first_name = self.cleaned_data["first_name"]
user.last_name = self.cleaned_data["last_name"]
profile = UserProfile.objects.create(user=user)
profile.image = self._get_facebook_url()
@@ -76,11 +75,11 @@ class InventoryTransactionForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
# Only show active products
super(InventoryTransactionForm, self).__init__(*args, **kwargs)
self.fields['product'].queryset = Product.objects.filter(active=True)
self.fields["product"].queryset = Product.objects.filter(active=True)
class Meta:
model = InventoryTransaction
fields = ['product', 'amount', 'unit_price', 'comment']
fields = ["product", "amount", "unit_price", "comment"]
class DateRangeForm(forms.Form):
+1 -1
View File
@@ -1 +1 @@
__author__ = 'Nikolai'
__author__ = "Nikolai"
+1 -1
View File
@@ -1 +1 @@
__author__ = 'Nikolai'
__author__ = "Nikolai"
+9 -9
View File
@@ -1,4 +1,4 @@
xfrom django.contrib.auth.models import User
from django.contrib.auth.models import User
import difflib
from django.core.management.base import BaseCommand, CommandError
@@ -13,16 +13,17 @@ class Command(BaseCommand):
- Matches names against the local DB
- Saves the users Facebook picture in his/her user profile.
"""
KAK_GROUP_ID = '108265352570560'
KAK_GROUP_ID = "108265352570560"
graph = None
def get_kak_members(self):
members = self.graph.get_connections(id=self.KAK_GROUP_ID, connection_name='members')
return [(member['name'], member['id']) for member in members['data']]
members = self.graph.get_connections(id=self.KAK_GROUP_ID, connection_name="members")
return [(member["name"], member["id"]) for member in members["data"]]
def handle(self, *args, **options):
if len(args) != 1:
raise CommandError('Missing access token')
raise CommandError("Missing access token")
access_token = args[0]
self.graph = facebook.GraphAPI(access_token=access_token)
@@ -31,8 +32,8 @@ class Command(BaseCommand):
names = [] # to fuzzy search for a name
name_lookup = {} # to update the matching UserProfile object
for u in User.objects.all().order_by('id'):
fullname = u'{} {}'.format(u.first_name, u.last_name)
for u in User.objects.all().order_by("id"):
fullname = "{} {}".format(u.first_name, u.last_name)
names.append(fullname)
name_lookup[fullname] = u.id
@@ -41,6 +42,5 @@ class Command(BaseCommand):
if match:
u = UserProfile.objects.get(pk=name_lookup[match[0]])
if str(u.image) is "":
u.image = 'https://graph.facebook.com/{0}/picture'.format(member[1])
u.image = "https://graph.facebook.com/{0}/picture".format(member[1])
u.save()
+139 -52
View File
@@ -10,89 +10,176 @@ class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
name='InventoryTransaction',
name="InventoryTransaction",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('amount', models.FloatField(verbose_name='Antall')),
('unit_price', models.FloatField(verbose_name='Enhetspris')),
('comment', models.TextField(verbose_name='Kommentar', blank=True)),
('created', models.DateTimeField(auto_now_add=True)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("amount", models.FloatField(verbose_name="Antall")),
("unit_price", models.FloatField(verbose_name="Enhetspris")),
("comment", models.TextField(verbose_name="Kommentar", blank=True)),
("created", models.DateTimeField(auto_now_add=True)),
],
),
migrations.CreateModel(
name='Order',
name="Order",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('order_sum', models.FloatField(db_column='sum')),
('created', models.DateTimeField(auto_now_add=True)),
('customer', models.ForeignKey(related_name='orders', on_delete=models.CASCADE, blank=True, to=settings.AUTH_USER_MODEL, null=True)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("order_sum", models.FloatField(db_column="sum")),
("created", models.DateTimeField(auto_now_add=True)),
(
"customer",
models.ForeignKey(
related_name="orders",
on_delete=models.CASCADE,
blank=True,
to=settings.AUTH_USER_MODEL,
null=True,
),
),
],
),
migrations.CreateModel(
name='OrderLine',
name="OrderLine",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('amount', models.IntegerField()),
('unit_price', models.FloatField(verbose_name='Enhetspris')),
('order', models.ForeignKey(on_delete=models.CASCADE, related_name='orderlines', to='main.Order')),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("amount", models.IntegerField()),
("unit_price", models.FloatField(verbose_name="Enhetspris")),
(
"order",
models.ForeignKey(
on_delete=models.CASCADE,
related_name="orderlines",
to="main.Order",
),
),
],
),
migrations.CreateModel(
name='Product',
name="Product",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=64)),
('sale_price_int', models.FloatField()),
('sale_price_ext', models.FloatField()),
('description', models.CharField(max_length=256, blank=True)),
('volume_liter', models.FloatField(null=True)),
('alcohol_percent', models.FloatField(null=True)),
('image', models.ImageField(upload_to='products', blank=True)),
('customer_support', models.CharField(max_length=32, blank=True)),
('inventory_amount', models.FloatField(default=0)),
('active', models.BooleanField(default=True)),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("name", models.CharField(max_length=64)),
("sale_price_int", models.FloatField()),
("sale_price_ext", models.FloatField()),
("description", models.CharField(max_length=256, blank=True)),
("volume_liter", models.FloatField(null=True)),
("alcohol_percent", models.FloatField(null=True)),
("image", models.ImageField(upload_to="products", blank=True)),
("customer_support", models.CharField(max_length=32, blank=True)),
("inventory_amount", models.FloatField(default=0)),
("active", models.BooleanField(default=True)),
("created", models.DateTimeField(auto_now_add=True)),
("updated", models.DateTimeField(auto_now=True)),
],
options={
'ordering': ['name'],
"ordering": ["name"],
},
),
migrations.CreateModel(
name='Transaction',
name="Transaction",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('amount', models.FloatField()),
('created', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=models.CASCADE, related_name='transactions', to=settings.AUTH_USER_MODEL)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("amount", models.FloatField()),
("created", models.DateTimeField(auto_now_add=True)),
(
"user",
models.ForeignKey(
on_delete=models.CASCADE,
related_name="transactions",
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.CreateModel(
name='UserProfile',
name="UserProfile",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('balance', models.FloatField(default=0.0)),
('image', models.URLField(blank=True)),
('user', models.OneToOneField(on_delete=models.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("balance", models.FloatField(default=0.0)),
("image", models.URLField(blank=True)),
(
"user",
models.OneToOneField(
on_delete=models.CASCADE,
related_name="profile",
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.AddField(
model_name='orderline',
name='product',
field=models.ForeignKey(on_delete=models.CASCADE, related_name='orderlines', to='main.Product'),
model_name="orderline",
name="product",
field=models.ForeignKey(on_delete=models.CASCADE, related_name="orderlines", to="main.Product"),
),
migrations.AddField(
model_name='inventorytransaction',
name='product',
field=models.ForeignKey(on_delete=models.CASCADE, related_name='transactions', verbose_name='Produkt', to='main.Product'),
model_name="inventorytransaction",
name="product",
field=models.ForeignKey(
on_delete=models.CASCADE,
related_name="transactions",
verbose_name="Produkt",
to="main.Product",
),
),
migrations.AddField(
model_name='inventorytransaction',
name='user',
field=models.ForeignKey(on_delete=models.CASCADE, related_name='inventory_transactions', to=settings.AUTH_USER_MODEL),
model_name="inventorytransaction",
name="user",
field=models.ForeignKey(
on_delete=models.CASCADE,
related_name="inventory_transactions",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AlterUniqueTogether(
name='orderline',
unique_together=set([('order', 'product')]),
name="orderline",
unique_together=set([("order", "product")]),
),
]
+43 -36
View File
@@ -1,4 +1,3 @@
from datetime import datetime
from django.conf import settings
@@ -6,7 +5,6 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _
class Product(models.Model):
name = models.CharField(max_length=64)
sale_price_int = models.FloatField()
@@ -14,7 +12,7 @@ class Product(models.Model):
description = models.CharField(max_length=256, blank=True)
volume_liter = models.FloatField(null=True)
alcohol_percent = models.FloatField(null=True)
image = models.ImageField(upload_to='products', blank=True)
image = models.ImageField(upload_to="products", blank=True)
customer_support = models.CharField(max_length=32, blank=True)
inventory_amount = models.FloatField(default=0)
active = models.BooleanField(default=True)
@@ -24,20 +22,20 @@ class Product(models.Model):
@property
def wholesale_unit_price(self):
"""
This is not accurate.
This is not accurate.
"""
if self.inventory_amount <= 0:
return 0
unit_prices = self.transactions.order_by('created').values('amount', 'unit_price')
unit_prices = self.transactions.order_by("created").values("amount", "unit_price")
sum_units = 0
for up in unit_prices:
sum_units += up['amount']
sum_units += up["amount"]
if self.inventory_amount <= sum_units:
return up['unit_price']
return up["unit_price"]
if len(unit_prices) > 0:
return unit_prices[0]['unit_price']
return unit_prices[0]["unit_price"]
return 0
@@ -49,13 +47,18 @@ class Product(models.Model):
return self.name
class Meta:
ordering = ['name']
ordering = ["name"]
class Order(models.Model):
customer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True, related_name='orders')
order_sum = models.FloatField(db_column='sum')
customer = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="orders",
)
order_sum = models.FloatField(db_column="sum")
created = models.DateTimeField(auto_now_add=True)
def is_external(self):
@@ -68,12 +71,11 @@ class Order(models.Model):
return "{}: {} kr".format(self.customer or "Ekstern", self.order_sum)
class OrderLine(models.Model):
order = models.ForeignKey('main.Order', on_delete=models.CASCADE, related_name='orderlines')
product = models.ForeignKey('main.Product', on_delete=models.CASCADE, related_name='orderlines')
order = models.ForeignKey("main.Order", on_delete=models.CASCADE, related_name="orderlines")
product = models.ForeignKey("main.Product", on_delete=models.CASCADE, related_name="orderlines")
amount = models.IntegerField()
unit_price = models.FloatField(verbose_name=_('Enhetspris'))
unit_price = models.FloatField(verbose_name=_("Enhetspris"))
@property
def price(self):
@@ -83,13 +85,13 @@ class OrderLine(models.Model):
return "{} {} ({} kr per)".format(self.amount, self.product, self.unit_price)
class Meta:
unique_together = ('order', 'product')
unique_together = ("order", "product")
class Transaction(models.Model):
""" Money """
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='transactions')
"""Money"""
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="transactions")
amount = models.FloatField()
created = models.DateTimeField(auto_now_add=True)
@@ -97,14 +99,23 @@ class Transaction(models.Model):
return "{}: {}: {}".format(self.id, self.user, self.amount)
class InventoryTransaction(models.Model):
""" Goods """
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='inventory_transactions')
product = models.ForeignKey('main.Product', on_delete=models.CASCADE, related_name='transactions', verbose_name=_('Produkt'))
amount = models.FloatField(verbose_name=_('Antall'))
unit_price = models.FloatField(verbose_name=_('Enhetspris'))
comment = models.TextField(verbose_name=_('Kommentar'), blank=True)
"""Goods"""
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="inventory_transactions",
)
product = models.ForeignKey(
"main.Product",
on_delete=models.CASCADE,
related_name="transactions",
verbose_name=_("Produkt"),
)
amount = models.FloatField(verbose_name=_("Antall"))
unit_price = models.FloatField(verbose_name=_("Enhetspris"))
comment = models.TextField(verbose_name=_("Kommentar"), blank=True)
created = models.DateTimeField(auto_now_add=True)
@property
@@ -113,16 +124,12 @@ class InventoryTransaction(models.Model):
def __str__(self):
return "{}: {}: {}. {:.0f} stykker ({} kr per)".format(
self.id,
self.user,
self.product,
self.amount,
self.unit_price)
self.id, self.user, self.product, self.amount, self.unit_price
)
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profile')
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="profile")
balance = models.FloatField(default=0.0)
image = models.URLField(blank=True)
@@ -130,7 +137,7 @@ class UserProfile(models.Model):
if len(self.user.orders.all()) == 0:
return None
return self.user.orders.order_by('-created')[0]
return self.user.orders.order_by("-created")[0]
def last_purchase_date(self):
last = self.last_purchase()
@@ -141,7 +148,7 @@ class UserProfile(models.Model):
from django.templatetags.static import static
if not self.image:
return static('dist/images/unknown_person.png')
return static("dist/images/unknown_person.png")
return self.image
+44 -26
View File
@@ -2,46 +2,64 @@ from django.conf.urls import url
from django.contrib.staticfiles.views import serve
from main.api.views import ProductViewSet
from main.views.stats import (stats_list, stats_products_realtime, stats_products_per_user,
OrdersHourlyView, OrdersDailyView, OrdersMonthlyView, OrdersYearlyView)
from main.views.stats import (
stats_list,
stats_products_realtime,
stats_products_per_user,
OrdersHourlyView,
OrdersDailyView,
OrdersMonthlyView,
OrdersYearlyView,
)
from main.views.general import register, deposit, log
from main.views.reports import inventory, inventory_add, report
from main.views.users import create_user, profile
from rest_framework.routers import DefaultRouter
urlpatterns = [
url(r'^$', register, name='home'),
url(r'^register/$', register, name='register'),
url(r'^deposit/$', deposit, name='deposit'),
url(r'^log/$', log, name='log'),
url(r'^log/all$', log, kwargs={'limit': None}, name='log-all'),
url(r"^$", register, name="home"),
url(r"^register/$", register, name="register"),
url(r"^deposit/$", deposit, name="deposit"),
url(r"^log/$", log, name="log"),
url(r"^log/all$", log, kwargs={"limit": None}, name="log-all"),
# Users
url(r'^user/create/$', create_user, name='create-user'),
url(r'^profile/$', profile, name='profile'),
url(r"^user/create/$", create_user, name="create-user"),
url(r"^profile/$", profile, name="profile"),
# Reports
url(r'^inventory/$', inventory, name='inventory'),
url(r'^inventory/add/$', inventory_add, name='inventory-add'),
url(r'^report$', report, name='report'),
url(r"^inventory/$", inventory, name="inventory"),
url(r"^inventory/add/$", inventory_add, name="inventory-add"),
url(r"^report$", report, name="report"),
]
# Stats
urlpatterns += [
url(r'^stats/$', stats_list, name='stats'),
url(r'^stats/orders/hourly/$', OrdersHourlyView.as_view(), name='stats-orders-hourly'),
url(r'^stats/orders/daily/', OrdersDailyView.as_view(), name='stats-orders-daily'),
url(r'^stats/orders/monthly/', OrdersMonthlyView.as_view(), name='stats-orders-monthly'),
url(r'^stats/orders/yearly/', OrdersYearlyView.as_view(), name='stats-orders-yearly'),
url(r'^stats/orders/products_realtime$', stats_products_realtime, name='stats-products-realtime'),
url(r'^stats/products/by_user/(?P<user_id>[0-9]+)/$', stats_products_per_user, name='stats-products-per-user'),
url(r"^stats/$", stats_list, name="stats"),
url(
r"^stats/orders/hourly/$",
OrdersHourlyView.as_view(),
name="stats-orders-hourly",
),
url(r"^stats/orders/daily/", OrdersDailyView.as_view(), name="stats-orders-daily"),
url(
r"^stats/orders/monthly/",
OrdersMonthlyView.as_view(),
name="stats-orders-monthly",
),
url(r"^stats/orders/yearly/", OrdersYearlyView.as_view(), name="stats-orders-yearly"),
url(
r"^stats/orders/products_realtime$",
stats_products_realtime,
name="stats-products-realtime",
),
url(
r"^stats/products/by_user/(?P<user_id>[0-9]+)/$",
stats_products_per_user,
name="stats-products-per-user",
),
]
# Root level service-worker.js
urlpatterns += [
url(r'^service-worker\.js$', serve, kwargs={'path': 'dist/service-worker.js'})
]
urlpatterns += [url(r"^service-worker\.js$", serve, kwargs={"path": "dist/service-worker.js"})]
# API
router = DefaultRouter()
router.register(r'api/products', ProductViewSet)
router.register(r"api/products", ProductViewSet)
urlpatterns += router.urls
+6 -8
View File
@@ -1,25 +1,23 @@
from django.contrib.auth.models import User
from django.db.models import Q
def format_username(firstname, lastname):
first = firstname.lower().strip().replace(" ", "")[:6].encode('ascii', 'ignore').decode('utf-8')
last = lastname.lower().strip().replace(" ", "")[:6].encode('ascii', 'ignore').decode('utf-8')
first = firstname.lower().strip().replace(" ", "")[:6].encode("ascii", "ignore").decode("utf-8")
last = lastname.lower().strip().replace(" ", "")[:6].encode("ascii", "ignore").decode("utf-8")
return "{0}{1}".format(first, last)
def users_with_perm(perm_name):
return User.objects.filter(
Q(is_superuser=True) |
Q(user_permissions__codename=perm_name) |
Q(groups__permissions__codename=perm_name)).distinct()
Q(is_superuser=True) | Q(user_permissions__codename=perm_name) | Q(groups__permissions__codename=perm_name)
).distinct()
def users_format_js(users):
users_js = []
for user in users:
users_js.append('"' + user.first_name + ' ' + user.last_name[:1] + '"')
users_js = "[{}]".format(u",".join(users_js))
users_js.append('"' + user.first_name + " " + user.last_name[:1] + '"')
users_js = "[{}]".format(",".join(users_js))
return users_js
+72 -57
View File
@@ -16,7 +16,7 @@ from main.utils import users_format_js, users_with_perm
def register(request):
products = Product.objects.filter(active=True)
cheapest_product_price = list(products.aggregate(Min('sale_price_int')).values())[0] or 0
cheapest_product_price = list(products.aggregate(Min("sale_price_int")).values())[0] or 0
half_a_year_ago = datetime.now() - timedelta(days=180)
users = User.objects.filter(profile__balance__gte=cheapest_product_price)
@@ -34,24 +34,28 @@ def register(request):
order = orderform.save(commit=False)
if order.is_external():
order_sum = sum([ol['amount'] * ol['unit_price_ext'] for ol in formset.cleaned_data])
order_sum = sum([ol["amount"] * ol["unit_price_ext"] for ol in formset.cleaned_data])
else:
order_sum = sum([ol['amount'] * ol['unit_price_int'] for ol in formset.cleaned_data])
order_sum = sum([ol["amount"] * ol["unit_price_int"] for ol in formset.cleaned_data])
# empty order?
if order_sum == 0:
messages.error(request, 'Du har ikke valgt hva du skal kjøpe...')
return HttpResponseRedirect(reverse('register'))
messages.error(request, "Du har ikke valgt hva du skal kjøpe...")
return HttpResponseRedirect(reverse("register"))
if not order.is_external():
profile = order.customer.profile
# can she afford it?
if profile.balance < order_sum:
messages.error(request, '{0} {1} har ikke råd, mangler {2} kr.'.format(
order.customer.first_name,
order.customer.last_name,
int(order_sum - profile.balance)))
return HttpResponseRedirect(reverse('register'))
messages.error(
request,
"{0} {1} har ikke råd, mangler {2} kr.".format(
order.customer.first_name,
order.customer.last_name,
int(order_sum - profile.balance),
),
)
return HttpResponseRedirect(reverse("register"))
# substract order from balance
profile.balance -= order_sum
profile.save()
@@ -61,106 +65,117 @@ def register(request):
orderlines = []
for ol in formset.cleaned_data:
if ol['amount'] > 0:
product = Product.objects.get(pk=ol['product'])
if ol["amount"] > 0:
product = Product.objects.get(pk=ol["product"])
if order.is_external():
unit_price = ol['unit_price_ext']
unit_price = ol["unit_price_ext"]
else:
unit_price = ol['unit_price_int']
unit_price = ol["unit_price_int"]
OrderLine.objects.create(
order=order,
product=product,
amount=ol['amount'],
unit_price=unit_price)
amount=ol["amount"],
unit_price=unit_price,
)
product.inventory_amount -= ol['amount']
product.inventory_amount -= ol["amount"]
product.save()
orderlines.append("{0} {1}".format(ol['amount'], product))
orderlines.append("{0} {1}".format(ol["amount"], product))
if order.is_external():
messages.success(request, 'Ekstern kjøpte {0}.'.format(", ".join(orderlines)))
messages.success(request, "Ekstern kjøpte {0}.".format(", ".join(orderlines)))
else:
messages.success(request, '{0} {1} kjøpte {2}.'.format(
order.customer.first_name,
order.customer.last_name,
", ".join(orderlines)
))
messages.success(
request,
"{0} {1} kjøpte {2}.".format(
order.customer.first_name,
order.customer.last_name,
", ".join(orderlines),
),
)
return redirect('register')
return redirect("register")
else:
# TODO specify error(s)
messages.error(request, 'Skjemaet er ikke gyldig.')
messages.error(request, "Skjemaet er ikke gyldig.")
orderform = OrderForm(request.POST)
formset = OrderLineFormSet(request.POST)
else:
orderform = OrderForm()
formset = OrderLineFormSet()
return render(request, 'register.html', locals())
return render(request, "register.html", locals())
def deposit(request):
users = User.objects.all().order_by('first_name', 'last_name')
users = User.objects.all().order_by("first_name", "last_name")
users_js = users_format_js(users)
allowed_users = users_with_perm('add_transaction')
error_message_template = '{0} {1} kan ikke sette inn {2} kr, det overskrider maks saldo ({3} kr) med {4} kr'
allowed_users = users_with_perm("add_transaction")
error_message_template = "{0} {1} kan ikke sette inn {2} kr, det overskrider maks saldo ({3} kr) med {4} kr"
limit_deposists = settings.BBS_LIMIT_DEPOSITS
if request.method == "POST":
form = DepositForm(request.POST)
if form.is_valid():
amount = form.cleaned_data['amount']
user = form.cleaned_data['user']
amount = form.cleaned_data["amount"]
user = form.cleaned_data["user"]
if amount + user.profile.balance > settings.BBS_SALDO_MAX and amount + user.profile.balance != 1337:
messages.error(request, error_message_template.format(
user.first_name,
user.last_name,
amount,
settings.BBS_SALDO_MAX,
amount + user.profile.balance - settings.BBS_SALDO_MAX
))
return HttpResponseRedirect(reverse('deposit'))
messages.error(
request,
error_message_template.format(
user.first_name,
user.last_name,
amount,
settings.BBS_SALDO_MAX,
amount + user.profile.balance - settings.BBS_SALDO_MAX,
),
)
return HttpResponseRedirect(reverse("deposit"))
transaction = form.save()
profile = transaction.user.profile
profile.balance += transaction.amount
profile.save()
messages.success(request, '{0} {1} satte inn {2} kr. Ny saldo er {3}'.format(
transaction.user.first_name,
transaction.user.last_name,
transaction.amount,
profile.balance))
return HttpResponseRedirect(reverse('deposit'))
messages.success(
request,
"{0} {1} satte inn {2} kr. Ny saldo er {3}".format(
transaction.user.first_name,
transaction.user.last_name,
transaction.amount,
profile.balance,
),
)
return HttpResponseRedirect(reverse("deposit"))
else:
messages.error(request, 'Skjemaet er ikke gyldig.')
messages.error(request, "Skjemaet er ikke gyldig.")
form = DepositForm(request.POST)
else:
form = DepositForm()
return render(request, 'deposit.html', locals())
return render(request, "deposit.html", locals())
def log(request, limit=datetime.now()-timedelta(days=2)):
def log(request, limit=datetime.now() - timedelta(days=2)):
if limit:
# display last two days of orders and transactions
orders = Order.objects.filter(created__gte=limit).order_by('-created')
transactions = Transaction.objects.filter(created__gte=limit).order_by('-created')
orders = Order.objects.filter(created__gte=limit).order_by("-created")
transactions = Transaction.objects.filter(created__gte=limit).order_by("-created")
# no action in the last two days?
# ...then display the last 5 items
if len(orders) == 0:
orders = Order.objects.all().order_by('-created')[:5]
orders = Order.objects.all().order_by("-created")[:5]
if len(transactions) == 0:
transactions = Transaction.objects.all().order_by('-created')[:5]
transactions = Transaction.objects.all().order_by("-created")[:5]
else:
# display everything
orders = Order.objects.all().order_by('-created')
transactions = Transaction.objects.all().order_by('-created')
orders = Order.objects.all().order_by("-created")
transactions = Transaction.objects.all().order_by("-created")
return render(request, 'log.html', locals())
return render(request, "log.html", locals())
+55 -47
View File
@@ -16,58 +16,66 @@ def report(request):
# end of day
end_time = datetime.now().replace(hour=23, minute=59, second=59, microsecond=999)
if request.GET.get('start_time', False) or request.GET.get('end_time', False):
if request.GET.get("start_time", False) or request.GET.get("end_time", False):
form = DateRangeForm(request.GET)
if form.is_valid():
start_time = form.cleaned_data['start_time']
start_time = form.cleaned_data["start_time"]
# end of day
end_time = form.cleaned_data['end_time'].replace(hour=23, minute=59, second=59, microsecond=999)
end_time = form.cleaned_data["end_time"].replace(hour=23, minute=59, second=59, microsecond=999)
else:
form = DateRangeForm(initial={
'start_time': start_time.strftime("%Y-%m-%d"),
'end_time': end_time.strftime("%Y-%m-%d")
})
form = DateRangeForm(
initial={
"start_time": start_time.strftime("%Y-%m-%d"),
"end_time": end_time.strftime("%Y-%m-%d"),
}
)
# Inventory
products = Product.objects\
.filter(transactions__created__range=[start_time, end_time])\
.values('name', 'transactions__unit_price', 'transactions__amount')\
.order_by('name')
products = (
Product.objects.filter(transactions__created__range=[start_time, end_time])
.values("name", "transactions__unit_price", "transactions__amount")
.order_by("name")
)
# group by name and sum
inventory_products = {}
for k, g in groupby(products, lambda x: x['name']):
for k, g in groupby(products, lambda x: x["name"]):
group = []
for el in g:
el['transactions__price'] = el['transactions__amount'] * el['transactions__unit_price']
el["transactions__price"] = el["transactions__amount"] * el["transactions__unit_price"]
group.append(el)
inventory_products.update({k: {
'name': k,
"transactions": group,
"transactions_sum": sum(map(lambda x: x['transactions__price'], group)),
"transactions_units": sum(map(lambda x: x['transactions__amount'], group))
}})
inventory_products.update(
{
k: {
"name": k,
"transactions": group,
"transactions_sum": sum(map(lambda x: x["transactions__price"], group)),
"transactions_units": sum(map(lambda x: x["transactions__amount"], group)),
}
}
)
itrans = InventoryTransaction.objects.filter(created__range=[start_time, end_time])
inv_in = sum(map(lambda x: x[1].get('transactions_sum', 0), inventory_products.items()))
inv_in = sum(map(lambda x: x[1].get("transactions_sum", 0), inventory_products.items()))
# out
out_products = Product.objects\
.filter(orderlines__order__created__range=[start_time, end_time])\
.values('name', 'orderlines__unit_price', 'orderlines__amount')\
.order_by('name')
out_products = (
Product.objects.filter(orderlines__order__created__range=[start_time, end_time])
.values("name", "orderlines__unit_price", "orderlines__amount")
.order_by("name")
)
# group by name and sum
for k, g in groupby(out_products, lambda x: x['name']):
for k, g in groupby(out_products, lambda x: x["name"]):
group = []
for el in g:
el['orderlines__price'] = el['orderlines__amount'] * el['orderlines__unit_price']
el["orderlines__price"] = el["orderlines__amount"] * el["orderlines__unit_price"]
group.append(el)
product = {
'name': k,
"name": k,
"orderlines": group,
"orderlines_sum": sum(map(lambda x: x['orderlines__price'], group)),
"orderlines_units": sum(map(lambda x: x['orderlines__amount'], group))
"orderlines_sum": sum(map(lambda x: x["orderlines__price"], group)),
"orderlines_units": sum(map(lambda x: x["orderlines__amount"], group)),
}
if k in inventory_products:
# add diff
@@ -76,42 +84,42 @@ def report(request):
inventory_products.update({k: product})
for p in inventory_products.items():
p[1]['value_diff'] = p[1].get('transactions_sum', 0) - p[1].get('orderlines_sum', 0)
p[1]['units_diff'] = p[1].get('transactions_units', 0) - p[1].get('orderlines_units', 0)
p[1]["value_diff"] = p[1].get("transactions_sum", 0) - p[1].get("orderlines_sum", 0)
p[1]["units_diff"] = p[1].get("transactions_units", 0) - p[1].get("orderlines_units", 0)
inv_out = sum(map(lambda x: x[1].get('orderlines_sum', 0), inventory_products.items()))
inv_out = sum(map(lambda x: x[1].get("orderlines_sum", 0), inventory_products.items()))
inv_diff = inv_in - inv_out
# Deposits and sales
saldo_profiles = sum(UserProfile.objects.all().values_list('balance', flat=True))
deposits = sum(Transaction.objects.all().values_list('amount', flat=True))
purchases = sum(Order.objects.all().values_list('order_sum', flat=True))
saldo_profiles = sum(UserProfile.objects.all().values_list("balance", flat=True))
deposits = sum(Transaction.objects.all().values_list("amount", flat=True))
purchases = sum(Order.objects.all().values_list("order_sum", flat=True))
saldo = deposits - purchases
deposits_start = sum(Transaction.objects.filter(created__lt=start_time).values_list('amount', flat=True))
purchases_start = sum(Order.objects.filter(created__lt=start_time).values_list('order_sum', flat=True))
deposits_start = sum(Transaction.objects.filter(created__lt=start_time).values_list("amount", flat=True))
purchases_start = sum(Order.objects.filter(created__lt=start_time).values_list("order_sum", flat=True))
saldo_start = deposits_start - purchases_start
deposits_end = sum(Transaction.objects.filter(created__lt=end_time).values_list('amount', flat=True))
purchases_end = sum(Order.objects.filter(created__lt=end_time).values_list('order_sum', flat=True))
deposits_end = sum(Transaction.objects.filter(created__lt=end_time).values_list("amount", flat=True))
purchases_end = sum(Order.objects.filter(created__lt=end_time).values_list("order_sum", flat=True))
saldo_end = deposits_end - purchases_end
deposits_diff = deposits_end - deposits_start
purchases_diff = purchases_end - purchases_start
saldo_diff = saldo_end - saldo_start
return render(request, 'report.html', locals())
return render(request, "report.html", locals())
def inventory(request):
products = Product.objects.all().order_by('-active', 'inventory_amount', 'name')
transactions = InventoryTransaction.objects.all().order_by('-created')
products = Product.objects.all().order_by("-active", "inventory_amount", "name")
transactions = InventoryTransaction.objects.all().order_by("-created")
products_active = products.filter(active=True)
wholesale_value = sum([p.wholesale_value for p in products_active])
num_products = sum(products_active.values_list('inventory_amount', flat=True))
num_products = sum(products_active.values_list("inventory_amount", flat=True))
return render(request, 'inventory.html', locals())
return render(request, "inventory.html", locals())
def inventory_add(request):
@@ -125,12 +133,12 @@ def inventory_add(request):
itrans.product.save()
itrans.save()
messages.success(request, "Satt inn {0} stk {1}.".format(itrans.amount, itrans.product))
return redirect('inventory-add')
return redirect("inventory-add")
else:
messages.error(request, 'Feil med skjemaet, se under.')
messages.error(request, "Feil med skjemaet, se under.")
form = InventoryTransactionForm(data=request.POST)
else:
form = InventoryTransactionForm()
return render(request, 'inventory_add.html', locals())
return render(request, "inventory_add.html", locals())
+16 -23
View File
@@ -1,5 +1,3 @@
import time
from datetime import datetime, timedelta
from django.http import JsonResponse
@@ -13,13 +11,13 @@ from main.models import Product, OrderLine, Order
def stats_list(request):
products = Product.objects.filter(active=True)
order_groups = ['hourly', 'daily', 'monthly', 'yearly']
order_groups = ["hourly", "daily", "monthly", "yearly"]
return render(request, 'stats.html', {'products': products, 'order_groups': order_groups})
return render(request, "stats.html", {"products": products, "order_groups": order_groups})
class OrdersView(View):
grouping = 'orders'
grouping = "orders"
def get_range(self):
raise NotImplementedError
@@ -42,16 +40,16 @@ class OrdersView(View):
orders_grouped = self.group_by(orders)
data = {
'start': str(orders[0].created),
'orders': [[k, v] for k, v in orders_grouped.items()],
'total': sum(orders_grouped.values()),
'grouping': self.grouping
"start": str(orders[0].created),
"orders": [[k, v] for k, v in orders_grouped.items()],
"total": sum(orders_grouped.values()),
"grouping": self.grouping,
}
return JsonResponse(data)
class OrdersHourlyView(OrdersView):
grouping = 'hourly'
grouping = "hourly"
def get_range(self):
return range(0, 24)
@@ -61,7 +59,7 @@ class OrdersHourlyView(OrdersView):
class OrdersDailyView(OrdersView):
grouping = 'daily'
grouping = "daily"
def get_range(self):
return range(0, 7)
@@ -71,7 +69,7 @@ class OrdersDailyView(OrdersView):
class OrdersMonthlyView(OrdersView):
grouping = 'monthly'
grouping = "monthly"
def get_range(self):
return range(1, 13)
@@ -81,14 +79,14 @@ class OrdersMonthlyView(OrdersView):
class OrdersYearlyView(OrdersView):
grouping = 'yearly'
grouping = "yearly"
def get_range(self):
first = Order.objects.order_by('created').first()
first = Order.objects.order_by("created").first()
last = timezone.now().year
first = first.created.year if first else last
return range(first, last+1)
return range(first, last + 1)
def get_key(self, order):
return order.created.year
@@ -112,16 +110,14 @@ def stats_products_realtime(request):
for product, value in products.items():
serialized_products[product.name] = value
response = {
'products': serialized_products
}
response = {"products": serialized_products}
return JsonResponse(response)
def stats_products_per_user(request, user_id=None):
if not user_id:
return JsonResponse({'error': 'Missing param user_id'})
return JsonResponse({"error": "Missing param user_id"})
order_lines = OrderLine.objects.filter(order__customer__pk=user_id).order_by("order__created")
products = {}
@@ -135,8 +131,5 @@ def stats_products_per_user(request, user_id=None):
serialized_products = []
for product, value in products.items():
serialized_products.append({
'name': product.name,
'data': value
})
serialized_products.append({"name": product.name, "data": value})
return JsonResponse(serialized_products, safe=False)
+16 -17
View File
@@ -13,40 +13,39 @@ def create_user(request):
form = SimpleCreateUserForm(data=request.POST)
if form.is_valid():
user = form.save()
messages.success(request, "Hurra! {} {} er lagt til".format(user.first_name, user.last_name))
return redirect('create-user')
messages.success(
request,
"Hurra! {} {} er lagt til".format(user.first_name, user.last_name),
)
return redirect("create-user")
else:
messages.error(request, 'Feil med skjemaet, se under.')
messages.error(request, "Feil med skjemaet, se under.")
form = SimpleCreateUserForm(data=request.POST)
else:
form = SimpleCreateUserForm()
return render(request, 'registration/create_user.html', {'form': form})
return render(request, "registration/create_user.html", {"form": form})
@login_required
def profile(request):
transactions = Transaction.objects.filter(user=request.user.pk)
transaction_totals = {
'sum': sum([t.amount for t in transactions])
}
transaction_totals = {"sum": sum([t.amount for t in transactions])}
orders = Order.objects.filter(customer=request.user.pk)
orders_totals = {
'sum': sum([o.order_sum for o in orders])
}
orders_totals = {"sum": sum([o.order_sum for o in orders])}
# order_lines = OrderLine.objects.filter(order__customer__pk=1).order_by("order__created")
order_report = _orders_monthly(filter_by={'customer': request.user.pk})
top_months = order_report.order_by('-sum')[:5]
order_report = _orders_monthly(filter_by={"customer": request.user.pk})
top_months = order_report.order_by("-sum")[:5]
return render(request, 'profile.html', locals())
return render(request, "profile.html", locals())
def _orders_monthly(filter_by={}, order_by='month'):
def _orders_monthly(filter_by={}, order_by="month"):
truncate_date = connection.ops.date_trunc_sql('month', 'created')
qs = Order.objects.filter(**filter_by).extra({'month': truncate_date})
order_report = qs.values('month').annotate(sum=Sum('order_sum'), num=Count('pk')).order_by(order_by)
truncate_date = connection.ops.date_trunc_sql("month", "created")
qs = Order.objects.filter(**filter_by).extra({"month": truncate_date})
order_report = qs.values("month").annotate(sum=Sum("order_sum"), num=Count("pk")).order_by(order_by)
return order_report