From 933e2d972781f354a3026eff9dd7bf8573e43ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20H=C3=B8rl=C3=BCck=20Berg?= <36937807+henrikhorluck@users.noreply.github.com> Date: Sat, 6 Apr 2024 22:15:56 +0200 Subject: [PATCH] Remove nibble No longer used, data has been exported --- .../api/serializers/user_data.py | 37 -- apps/dashboard/tools.py | 7 - apps/inventory/admin.py | 25 -- apps/inventory/dashboard/__init__.py | 0 apps/inventory/dashboard/forms.py | 39 -- apps/inventory/dashboard/urls.py | 57 --- apps/inventory/dashboard/views.py | 354 ------------------ ...remove_item_image_delete_batch_and_more.py | 30 ++ apps/inventory/models.py | 148 -------- apps/inventory/tests.py | 1 - apps/inventory/views.py | 1 - apps/profiles/urls.py | 2 - apps/profiles/views.py | 8 +- apps/shop/admin.py | 33 -- apps/shop/forms.py | 5 - ...t_type_remove_order_order_line_and_more.py | 38 ++ apps/shop/models.py | 127 ------- apps/shop/serializers.py | 92 ----- apps/shop/templates/shop/email/magic_link.txt | 14 - apps/shop/templates/shop/set_rfid.html | 28 -- apps/shop/tests.py | 34 -- apps/shop/urls.py | 19 - apps/shop/utils.py | 37 -- apps/shop/views.py | 91 ----- assets/dashboard/inventory/Inventory.js | 79 ---- assets/dashboard/inventory/InventoryStats.js | 40 -- assets/dashboard/inventory/index.js | 9 - assets/dashboard/inventory/index.less | 3 - esbuild.mjs | 1 - onlineweb4/urls.py | 8 - templates/dashboard/dashboard.html | 1 - templates/dashboard_base.html | 17 - .../inventory/dashboard/category_index.html | 51 --- .../inventory/dashboard/category_new.html | 34 -- templates/inventory/dashboard/details.html | 166 -------- .../inventory/dashboard/discontinued.html | 65 ---- templates/inventory/dashboard/edit.html | 14 - templates/inventory/dashboard/index.html | 77 ---- templates/inventory/dashboard/new.html | 35 -- templates/inventory/dashboard/statistics.html | 29 -- 40 files changed, 69 insertions(+), 1787 deletions(-) delete mode 100644 apps/inventory/admin.py delete mode 100644 apps/inventory/dashboard/__init__.py delete mode 100644 apps/inventory/dashboard/forms.py delete mode 100644 apps/inventory/dashboard/urls.py delete mode 100644 apps/inventory/dashboard/views.py create mode 100644 apps/inventory/migrations/0009_remove_item_category_remove_item_image_delete_batch_and_more.py delete mode 100644 apps/inventory/tests.py delete mode 100644 apps/inventory/views.py delete mode 100644 apps/shop/admin.py delete mode 100644 apps/shop/forms.py create mode 100644 apps/shop/migrations/0009_remove_order_content_type_remove_order_order_line_and_more.py delete mode 100644 apps/shop/serializers.py delete mode 100644 apps/shop/templates/shop/email/magic_link.txt delete mode 100644 apps/shop/templates/shop/set_rfid.html delete mode 100644 apps/shop/tests.py delete mode 100644 apps/shop/urls.py delete mode 100644 apps/shop/utils.py delete mode 100644 apps/shop/views.py delete mode 100644 assets/dashboard/inventory/Inventory.js delete mode 100644 assets/dashboard/inventory/InventoryStats.js delete mode 100644 assets/dashboard/inventory/index.js delete mode 100644 assets/dashboard/inventory/index.less delete mode 100644 templates/inventory/dashboard/category_index.html delete mode 100644 templates/inventory/dashboard/category_new.html delete mode 100644 templates/inventory/dashboard/details.html delete mode 100644 templates/inventory/dashboard/discontinued.html delete mode 100644 templates/inventory/dashboard/edit.html delete mode 100644 templates/inventory/dashboard/index.html delete mode 100644 templates/inventory/dashboard/new.html delete mode 100644 templates/inventory/dashboard/statistics.html diff --git a/apps/authentication/api/serializers/user_data.py b/apps/authentication/api/serializers/user_data.py index 16e8801f5..3e71140e6 100644 --- a/apps/authentication/api/serializers/user_data.py +++ b/apps/authentication/api/serializers/user_data.py @@ -17,7 +17,6 @@ FeedbackRelationListSerializer, GenericSurveySerializer, ) -from apps.inventory.models import Item, ItemCategory from apps.marks.serializers import ( MarkUserSerializer, RuleAcceptanceSerializer, @@ -31,8 +30,6 @@ PaymentTransaction, ) from apps.profiles.serializers import PrivacySerializer -from apps.shop.models import Order as ShopOrder -from apps.shop.models import OrderLine as ShopOrderLine from apps.webshop.models import Order as WebshopOrder from apps.webshop.models import OrderLine as WebshopOrderLine from apps.webshop.models import Product as WebshopProduct @@ -234,37 +231,6 @@ class Meta: fields = ("datetime", "paid", "delivered", "orders", "subtotal") -class CategorySerializer(serializers.ModelSerializer): - class Meta: - model = ItemCategory - - fields = ("name",) - - -class ItemSerializer(serializers.ModelSerializer): - category = CategorySerializer() - - class Meta: - model = Item - fields = ("name", "category") - - -class ShopOrderSerializer(serializers.ModelSerializer): - content_object = ItemSerializer() - - class Meta: - model = ShopOrder - fields = ("price", "quantity", "content_object") - - -class ShopOrderLineSerializer(serializers.ModelSerializer): - orders = ShopOrderSerializer(many=True) - - class Meta: - model = ShopOrderLine - fields = ("orders", "paid", "datetime") - - class MembershipApprovalSerializer(serializers.ModelSerializer): applicant = serializers.SerializerMethodField() approver = serializers.SerializerMethodField() @@ -317,7 +283,6 @@ class UserDataSerializer(serializers.ModelSerializer): ) # Purchases orderline_set = WebshopOrderLineSerializer(many=True) - shop_order_lines = ShopOrderLineSerializer(many=True) # Marks accepted_mark_rule_sets = RuleAcceptanceSerializer(many=True) marks = MarkUserSerializer(many=True, source="markuser_set") @@ -413,7 +378,6 @@ class Meta: "payment_transactions", # Purchases "orderline_set", - "shop_order_lines", # Approval "applications", "approved_applications", @@ -421,6 +385,5 @@ class Meta: "ordered_posters", "assigned_posters", # Other - "magictoken_set", "object_revisions", ) diff --git a/apps/dashboard/tools.py b/apps/dashboard/tools.py index 5de761196..fafd3398a 100644 --- a/apps/dashboard/tools.py +++ b/apps/dashboard/tools.py @@ -1,12 +1,10 @@ # -*- encoding: utf-8 -*- -from datetime import date from django.core.exceptions import PermissionDenied from guardian.mixins import PermissionRequiredMixin from apps.approval.models import MembershipApproval from apps.gallery.models import UnhandledImage -from apps.inventory.models import Batch from apps.posters.models import Poster @@ -51,11 +49,6 @@ def get_base_context(request): processed=False ).count() - # Check if there exists a batch in inventory that has expired - if request.user.has_perm("inventory.view_item"): - if Batch.objects.filter(expiration_date__lt=date.today()): - context["inventory_expired"] = True - if request.user.has_perm("posters.view_poster"): if Poster.objects.filter(assigned_to=None) or Poster.objects.filter( assigned_to=request.user diff --git a/apps/inventory/admin.py b/apps/inventory/admin.py deleted file mode 100644 index 10a14c0eb..000000000 --- a/apps/inventory/admin.py +++ /dev/null @@ -1,25 +0,0 @@ -from django.contrib import admin - -from apps.inventory.models import Batch, Item - - -class BatchInline(admin.TabularInline): - model = Batch - extra = 0 - - -class ItemAdmin(admin.ModelAdmin): - inlines = [BatchInline] - model = Item - list_display = [ - "name", - "category", - "total_amount", - "oldest_expiration_date", - "last_added", - "available", - "price", - ] - - -admin.site.register(Item, ItemAdmin) diff --git a/apps/inventory/dashboard/__init__.py b/apps/inventory/dashboard/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/inventory/dashboard/forms.py b/apps/inventory/dashboard/forms.py deleted file mode 100644 index 60b2c06b8..000000000 --- a/apps/inventory/dashboard/forms.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -from django import forms - -from apps.gallery.constants import ImageFormat -from apps.gallery.widgets import SingleImageInput -from apps.inventory.models import Batch, Item, ItemCategory - - -class ItemForm(forms.ModelForm): - class Meta: - model = Item - fields = ( - "name", - "description", - "category", - "available", - "price", - "low_stock_treshold", - "image", - ) - - # Widget generator accepts a form widget, and a list of tuples between field name and an attribute dict - widgets = { - "image": SingleImageInput( - attrs={"id": "responsive-image-id", "preset": ImageFormat.PRODUCT} - ), - } - - -class CategoryForm(forms.ModelForm): - class Meta: - model = ItemCategory - fields = ("name",) - - -class BatchForm(forms.ModelForm): - class Meta: - model = Batch - exclude = ["item"] diff --git a/apps/inventory/dashboard/urls.py b/apps/inventory/dashboard/urls.py deleted file mode 100644 index 934f66182..000000000 --- a/apps/inventory/dashboard/urls.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- encoding: utf-8 -*- - -from django.urls import re_path - -from apps.inventory.dashboard import views - -urlpatterns = [ - re_path(r"^$", views.index, name="dashboard_inventory_index"), - re_path(r"^discontinued", views.discontinued, name="dashboard_discontinued_index"), - re_path(r"^statistics/$", views.statistics, name="dashboard_inventory_statistics"), - re_path( - r"^statistics/orders/$", - views.order_statistics, - name="dashboard_inventory_order_statistics", - ), - re_path(r"^category/$", views.category_index, name="dashboard_category_index"), - re_path( - r"^category/(?P\d+)/$", - views.category_details, - name="dashboard_category_details", - ), - re_path(r"^category/new/$", views.category_new, name="dashboard_category_new"), - re_path( - r"^category/(?P\d+)/delete/$", - views.category_delete, - name="dashboard_category_delete", - ), - re_path(r"^new/$", views.new, name="dashboard_inventory_new"), - re_path( - r"^item/(?P\d+)/$", views.details, name="dashboard_inventory_details" - ), - re_path( - r"^item/(?P\d+)/delete/$", - views.item_delete, - name="dashboard_inventory_delete", - ), - re_path( - r"^item/(?P\d+)/change/$", - views.item_change_availability, - name="dashboard_inventory_change", - ), - re_path( - r"^item/(?P\d+)/batch/new/$", - views.batch_new, - name="dashboard_inventory_batch_new", - ), - re_path( - r"^item/(?P\d+)/batch/(?P\d+)/$", - views.batch, - name="dashboard_inventory_batch", - ), - re_path( - r"^item/(?P\d+)/batch/(?P\d+)/delete/$", - views.batch_delete, - name="dashboard_inventory_batch_delete", - ), -] diff --git a/apps/inventory/dashboard/views.py b/apps/inventory/dashboard/views.py deleted file mode 100644 index a4da7f6ad..000000000 --- a/apps/inventory/dashboard/views.py +++ /dev/null @@ -1,354 +0,0 @@ -# -*- encoding: utf-8 -*- - -from logging import getLogger - -from django.contrib import messages -from django.contrib.auth.decorators import login_required -from django.contrib.contenttypes.models import ContentType -from django.core.exceptions import PermissionDenied -from django.db.models import Count -from django.http import JsonResponse -from django.shortcuts import get_object_or_404, redirect, render -from guardian.decorators import permission_required - -from apps.dashboard.tools import get_base_context, has_access -from apps.inventory.dashboard.forms import BatchForm, CategoryForm, ItemForm -from apps.inventory.models import Batch, Item, ItemCategory -from apps.shop.models import Order - - -@login_required -@permission_required("inventory.view_item", return_403=True) -def index(request): - # Generic check to see if user has access to dashboard. (Is staff or superuser) - if not has_access(request): - raise PermissionDenied - - # Create the base context needed for the sidebar - context = get_base_context(request) - # Select all items that are available for purchase - context["items"] = Item.objects.filter(available=True).order_by("name") - - return render(request, "inventory/dashboard/index.html", context) - - -@login_required -@permission_required("inventory.view_item", return_403=True) -def discontinued(request): - if not has_access(request): - raise PermissionDenied - - # Create the base context needed for the sidebar - context = get_base_context(request) - # Select all items that are not available for purchase - context["items"] = Item.objects.filter(available=False).order_by("name") - - return render(request, "inventory/dashboard/discontinued.html", context) - - -@login_required -@permission_required("inventory.add_item", return_403=True) -def new(request): - if not has_access(request): - raise PermissionDenied - - # Get base context - context = get_base_context(request) - - if request.method == "POST": - inventory_form = ItemForm(request.POST) - - if not inventory_form.is_valid(): - messages.error(request, "Noen av de påkrevde feltene inneholder feil.") - else: - item = inventory_form.save() - messages.success(request, "Varen ble opprettet") - return redirect(details, item.id) - - context["form"] = inventory_form - - else: - context["form"] = ItemForm() - - return render(request, "inventory/dashboard/new.html", context) - - -@login_required -@permission_required("inventory.view_item", return_403=True) -def details(request, item_pk): - # Generic check to see if user has access to dashboard. (Is staff or superuser) - if not has_access(request): - raise PermissionDenied - - # Create the base context needed for the sidebar - context = get_base_context(request) - - context["item"] = get_object_or_404(Item, pk=item_pk) - - if request.method == "POST": - if "inventory.change_item" not in context["user_permissions"]: - raise PermissionDenied - - item_form = ItemForm(request.POST, instance=context["item"]) - if not item_form.is_valid(): - messages.error(request, "Noen av de påkrevde feltene inneholder feil.") - else: - item_form.save() - messages.success(request, "Varen ble oppdatert") - context["form"] = item_form - else: - context["form"] = ItemForm(instance=context["item"]) - - context["new_batch_form"] = BatchForm() - - context["batch_forms"] = [ - (b.id, BatchForm(instance=b)) - for b in Batch.objects.filter(item=context["item"]) - ] - - return render(request, "inventory/dashboard/details.html", context) - - -@login_required -@permission_required("inventory.delete_item", return_403=True) -def item_delete(request, item_pk): - if not has_access(request): - raise PermissionDenied - - item = get_object_or_404(Item, pk=item_pk) - - if request.method == "POST": - item.delete() - - messages.success(request, "Varen %s ble slettet." % item.name) - - return redirect(index) - - raise PermissionDenied - - -@login_required -@permission_required("inventory.change_item", return_403=True) -def item_change_availability(request, item_pk): - if not has_access(request): - raise PermissionDenied - - item = get_object_or_404(Item, pk=item_pk) - - if request.method == "POST": - if "action" in request.POST: - item.available = not item.available - item.save() - - return JsonResponse({"message": "OK", "status": 200}) - - -@login_required -@permission_required("inventory.add_batch", return_403=True) -def batch_new(request, item_pk): - if not has_access(request): - raise PermissionDenied - - # Field mapper - fieldmap = {"amount": "Mengde", "expiration_date": "Utløpsdato"} - - item = get_object_or_404(Item, pk=item_pk) - - if request.method == "POST": - batch_form = BatchForm(request.POST) - - if not batch_form.is_valid(): - # Dirty hack to display errors since the form is not passed in redirect context - error_reply = "Feil i felt:" - for field, error in batch_form.errors.items(): - error_reply += ( - " " - + fieldmap[field] - + " (" - + batch_form.error_class.as_text(error) - + ")," - ) - - messages.error(request, error_reply.rstrip(",")) - else: - b = batch_form.save(commit=False) - b.item = item - b.save() - messages.success(request, "Batchen ble lagt til.") - - return redirect(details, item_pk=item_pk) - - raise PermissionDenied - - -@login_required -@permission_required("inventory.change_batch", return_403=True) -def batch(request, item_pk, batch_pk): - if not has_access(request): - raise PermissionDenied - - # Get base context - - get_object_or_404(Item, pk=item_pk) - b = get_object_or_404(Batch, pk=batch_pk) - - if request.method == "POST": - batch_form = BatchForm(request.POST, instance=b) - - if not batch_form.is_valid(): - messages.error(request, "Noen av de påkrevde feltene inneholder feil.") - else: - batch_form.save() - messages.success(request, "Batchen ble oppdatert.") - - return redirect(details, item_pk=item_pk) - - raise PermissionDenied - - -@login_required -@permission_required("inventory.delete_batch", return_403=True) -def batch_delete(request, item_pk, batch_pk): - if not has_access(request): - raise PermissionDenied - - b = get_object_or_404(Batch, pk=batch_pk) - - if request.method == "POST": - b.delete() - messages.success(request, "Batchen ble slettet.") - - return redirect(details, item_pk=item_pk) - - raise PermissionDenied - - -@login_required -@permission_required("inventory.view_itemcategory", return_403=True) -def category_index(request): - # Generic check to see if user has access to dashboard. (Is staff or superuser) - if not has_access(request): - raise PermissionDenied - - # Create the base context needed for the sidebar - context = get_base_context(request) - - context["categories"] = ItemCategory.objects.all() - - return render(request, "inventory/dashboard/category_index.html", context) - - -@login_required -@permission_required("inventory.view_itemcategory", return_403=True) -def category_details(request, category_pk): - # Generic check to see if user has access to dashboard. (Is staff or superuser) - if not has_access(request): - raise PermissionDenied - - # Create the base context needed for the sidebar - context = get_base_context(request) - - context["category"] = get_object_or_404(ItemCategory, pk=category_pk) - - if request.method == "POST": - form = CategoryForm(request.POST, instance=context["category"]) - if not form.is_valid(): - messages.error(request, "Noen av de påkrevde feltene inneholder feil.") - else: - form.save() - messages.success(request, "Kategorien ble oppdatert") - return redirect(category_index) - - context["form"] = form - else: - context["form"] = CategoryForm(instance=context["category"]) - - return render(request, "inventory/dashboard/category_new.html", context) - - -@login_required -@permission_required("inventory.add_itemcategory", return_403=True) -def category_new(request): - if not has_access(request): - raise PermissionDenied - - # Get base context - context = get_base_context(request) - - if request.method == "POST": - form = CategoryForm(request.POST) - - if not form.is_valid(): - messages.error(request, "Noen av de påkrevde feltene inneholder feil.") - else: - form.save() - messages.success(request, "Kategorien ble opprettet") - return redirect(category_index) - - context["form"] = form - else: - context["form"] = CategoryForm() - - return render(request, "inventory/dashboard/category_new.html", context) - - -@login_required -@permission_required("inventory.delete_itemcategory", return_403=True) -def category_delete(request, category_pk): - if not has_access(request): - raise PermissionDenied - - category = get_object_or_404(ItemCategory, pk=category_pk) - - items = Item.objects.filter(category=category) - - # Removes the category binding to prevent cascading delete - for item in items: - item.category = None - item.save() - - category.delete() - messages.success(request, "Kategorien %s ble slettet." % category.name) - return redirect(category_index) - - -@login_required -# @permission_required('inventory.delete_batch', return_403=True) -def statistics(request): - # if not has_access(request): - # raise PermissionDenied - - context = get_base_context(request) - - return render(request, "inventory/dashboard/statistics.html", context) - - -@login_required -def order_statistics(request): - # TODO check permissions - - statistics = dict() - - counts = ( - Order.objects.all() - .values("object_id", "content_type") - .annotate(total=Count("object_id")) - ) - item_type = ContentType.objects.get_for_model(Item) - - for count in counts: - print(count) - if item_type.id == count["content_type"]: - try: - item = Item.objects.get(pk=count["object_id"]) - except Item.DoesNotExist: - getLogger(__name__).error( - "Item with pk %s does not exist (DoesNotExist error)" - % count["object_id"] - ) - except KeyError: - getLogger(__name__).error('Key "object_id" does not exist') - if count["total"] > 0: - statistics[item.name] = count["total"] - - return JsonResponse(statistics) diff --git a/apps/inventory/migrations/0009_remove_item_category_remove_item_image_delete_batch_and_more.py b/apps/inventory/migrations/0009_remove_item_category_remove_item_image_delete_batch_and_more.py new file mode 100644 index 000000000..2b388e17c --- /dev/null +++ b/apps/inventory/migrations/0009_remove_item_category_remove_item_image_delete_batch_and_more.py @@ -0,0 +1,30 @@ +# Generated by Django 5.0.4 on 2024-04-06 15:49 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("inventory", "0008_auto_20190506_1719"), + ] + + operations = [ + migrations.RemoveField( + model_name="item", + name="category", + ), + migrations.RemoveField( + model_name="item", + name="image", + ), + migrations.DeleteModel( + name="Batch", + ), + migrations.DeleteModel( + name="ItemCategory", + ), + migrations.DeleteModel( + name="Item", + ), + ] diff --git a/apps/inventory/models.py b/apps/inventory/models.py index 724465188..e69de29bb 100644 --- a/apps/inventory/models.py +++ b/apps/inventory/models.py @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- - -from django.conf import settings -from django.core.mail import EmailMessage -from django.db import models -from django.utils import timezone -from django.utils.translation import gettext as _ - -from apps.gallery.models import ResponsiveImage - - -class ItemCategory(models.Model): - name = models.CharField(_("Kategori"), max_length=50) - - def __str__(self): - return self.name - - class Meta: - verbose_name = _("Kategori") - verbose_name_plural = _("Kategorier") - permissions = (("view_itemcategory", "View Item Category"),) - default_permissions = ("add", "change", "delete") - - -class Item(models.Model): - name = models.CharField(_("Varetype"), max_length=50) - description = models.CharField( - _("Beskrivelse"), max_length=50, null=True, blank=True - ) - price = models.IntegerField(_("Pris"), null=True, blank=True) - available = models.BooleanField(_("Til salgs"), default=False) - category = models.ForeignKey( - ItemCategory, - verbose_name=_("Kategori"), - related_name="category", - null=True, - blank=True, - on_delete=models.CASCADE, - ) - image = models.ForeignKey( - ResponsiveImage, null=True, blank=True, default=None, on_delete=models.CASCADE - ) - low_stock_treshold = models.IntegerField( - "Grense for email om lav beholdning", default=10 - ) - - @property - def oldest_expiration_date(self): - batches = self.batches.all().order_by("expiration_date") - if batches: - return batches[0].expiration_date - else: - return None - - @property - def last_added(self): - batches = self.batches.all().order_by("-date_added") - if batches: - return batches[0].date_added - else: - return None - - def oldest_batch(self): - batches = self.batches.filter(amount__gt=0).order_by("date_added") - if batches: - return batches[0] - else: - return None - - @property - def total_amount(self): - return sum([batch.amount for batch in self.batches.all()]) - - @property - def has_expired_batch(self): - if ( - self.oldest_expiration_date - and timezone.now().date() >= self.oldest_expiration_date - ): - return True - return False - - def reduce_stock(self, amount): - """ - Makes an assumption that the oldest batches are sold first and reduce them first. - """ - - oldest_batch = self.oldest_batch() - - if oldest_batch: - if oldest_batch.amount > amount: - oldest_batch.amount = oldest_batch.amount - amount - oldest_batch.save() - else: - diff = amount - oldest_batch.amount - oldest_batch.amount = 0 - oldest_batch.save() - self.reduce_stock(diff) - - self.handle_notifications(amount) - - def handle_notifications(self, amount): - # Send one notification when the stock goes to or below 10 - if ( - self.total_amount <= self.low_stock_treshold - and self.total_amount + amount > self.low_stock_treshold - ): - message = ( - "Det er kun " - + str(self.total_amount) - + " igjen av " - + str(self.name) - + " på kontoret.\n\n" - "Dette er en automatisk generert melding og antallet kan være noe feil." - ) - - EmailMessage( - "[Nibble] Lav stock på " + self.name, - str(message), - "online@online.ntnu.no", - [], - [settings.EMAIL_TRIKOM], - ).send() - - def __str__(self): - return self.name - - class Meta: - verbose_name = _("Vare") - verbose_name_plural = _("Varer") - permissions = (("view_item", "View Inventory Item"),) - default_permissions = ("add", "change", "delete") - - -class Batch(models.Model): - item = models.ForeignKey( - Item, verbose_name=_("Vare"), related_name="batches", on_delete=models.CASCADE - ) - amount = models.IntegerField(_("Antall"), default=0) - date_added = models.DateField(_("Dato lagt til"), editable=False, auto_now_add=True) - expiration_date = models.DateField( - _("Utløpsdato"), null=True, blank=True, editable=True - ) - - class Meta: - verbose_name = _("Batch") - verbose_name_plural = _("Batches") - default_permissions = ("add", "change", "delete") diff --git a/apps/inventory/tests.py b/apps/inventory/tests.py deleted file mode 100644 index a39b155ac..000000000 --- a/apps/inventory/tests.py +++ /dev/null @@ -1 +0,0 @@ -# Create your tests here. diff --git a/apps/inventory/views.py b/apps/inventory/views.py deleted file mode 100644 index 60f00ef0e..000000000 --- a/apps/inventory/views.py +++ /dev/null @@ -1 +0,0 @@ -# Create your views here. diff --git a/apps/profiles/urls.py b/apps/profiles/urls.py index 4e5841eab..dc4c71f08 100644 --- a/apps/profiles/urls.py +++ b/apps/profiles/urls.py @@ -5,7 +5,6 @@ from apps.api.utils import SharedAPIRootRouter from apps.marks.views import MarksViewSet, SuspensionViewSet from apps.profiles import views -from apps.shop.views import UserOrderViewSet urlpatterns = [ re_path(r"^$", views.index, name="profiles"), @@ -65,7 +64,6 @@ router.register( "profile/search", views.PublicProfileSearchSet, basename="profile-search" ) -router.register("profile/orders", UserOrderViewSet, basename="profile-orders") router.register( "profile/privacy", views.PersonalPrivacyView, basename="profile-privacy" ) diff --git a/apps/profiles/views.py b/apps/profiles/views.py index b6e031539..bbd0196f5 100644 --- a/apps/profiles/views.py +++ b/apps/profiles/views.py @@ -27,7 +27,7 @@ reset_password_g_suite_account, ) from apps.marks.models import Mark, MarkRuleSet, Suspension -from apps.payment.models import PaymentDelay, PaymentRelation, PaymentTransaction +from apps.payment.models import PaymentDelay, PaymentRelation from apps.profiles.filters import PublicProfileFilter from apps.profiles.forms import PositionForm, PrivacyForm, ProfileForm from apps.profiles.models import Privacy @@ -36,7 +36,6 @@ ProfileSerializer, PublicProfileSerializer, ) -from apps.shop.models import Order from utils.shortcuts import render_json """ @@ -71,11 +70,6 @@ def _create_profile_context(request): "groups": groups, # privacy "privacy_form": PrivacyForm(instance=request.user.privacy), - # nibble information - "transactions": PaymentTransaction.objects.filter(user=request.user), - "orders": Order.objects.filter(order_line__user=request.user).order_by( - "-order_line__datetime" - ), # marks "mark_rule_set": MarkRuleSet.get_current_rule_set(), "mark_rules_accepted": request.user.mark_rules_accepted, diff --git a/apps/shop/admin.py b/apps/shop/admin.py deleted file mode 100644 index 980a44ebb..000000000 --- a/apps/shop/admin.py +++ /dev/null @@ -1,33 +0,0 @@ -from django.contrib import admin - -from apps.shop.models import Order, OrderLine - - -class OrderAdmin(admin.ModelAdmin): - model = Order - list_display = ("__str__", "price", "quantity", "order_line") - - -class OrderInline(admin.TabularInline): - model = Order - extra = 0 - readonly_fields = ["__str__"] - fields = ["__str__", "price", "quantity"] - - -class OrderLineAdmin(admin.ModelAdmin): - model = OrderLine - list_display = ("__str__", "user", "datetime", "paid") - list_filter = ["paid"] - search_fields = [ - "user__first_name", - "user__last_name", - "user__username", - "user__ntnu_username", - ] - - inlines = [OrderInline] - - -admin.site.register(Order, OrderAdmin) -admin.site.register(OrderLine, OrderLineAdmin) diff --git a/apps/shop/forms.py b/apps/shop/forms.py deleted file mode 100644 index 1172aa394..000000000 --- a/apps/shop/forms.py +++ /dev/null @@ -1,5 +0,0 @@ -from django import forms - - -class SetRFIDForm(forms.Form): - rfid = forms.CharField() diff --git a/apps/shop/migrations/0009_remove_order_content_type_remove_order_order_line_and_more.py b/apps/shop/migrations/0009_remove_order_content_type_remove_order_order_line_and_more.py new file mode 100644 index 000000000..1d7b54a7d --- /dev/null +++ b/apps/shop/migrations/0009_remove_order_content_type_remove_order_order_line_and_more.py @@ -0,0 +1,38 @@ +# Generated by Django 5.0.4 on 2024-04-06 15:49 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("shop", "0008_auto_20200307_1537"), + ] + + operations = [ + migrations.RemoveField( + model_name="order", + name="content_type", + ), + migrations.RemoveField( + model_name="order", + name="order_line", + ), + migrations.RemoveField( + model_name="orderline", + name="transaction", + ), + migrations.RemoveField( + model_name="orderline", + name="user", + ), + migrations.DeleteModel( + name="MagicToken", + ), + migrations.DeleteModel( + name="Order", + ), + migrations.DeleteModel( + name="OrderLine", + ), + ] diff --git a/apps/shop/models.py b/apps/shop/models.py index 62fd0b03b..e69de29bb 100644 --- a/apps/shop/models.py +++ b/apps/shop/models.py @@ -1,127 +0,0 @@ -# -*- coding: utf-8 -*- -import uuid - -from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType -from django.core.validators import MinValueValidator, ValidationError -from django.db import models -from django.utils.translation import gettext_lazy as _ -from rest_framework.exceptions import NotAcceptable - -from apps.authentication.models import OnlineUser as User -from apps.inventory.models import Item -from apps.payment.models import PaymentTransaction -from apps.payment.transaction_constants import TransactionSource - - -class Order(models.Model): - content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) - object_id = models.PositiveIntegerField() - content_object = GenericForeignKey("content_type", "object_id") - - order_line = models.ForeignKey( - "OrderLine", related_name="orders", on_delete=models.CASCADE - ) - # Price of product when paid - price = models.DecimalField(max_digits=10, decimal_places=2, blank=True) - # Quantity of products ordered - quantity = models.PositiveIntegerField(validators=[MinValueValidator(1)]) - - def total_price(self): - return self.content_object.price * self.quantity - - def reduce_stock(self): - self.content_object.reduce_stock(self.quantity) - - def __str__(self): - return str(self.content_object) - - class Meta: - default_permissions = ("add", "change", "delete") - - -class OrderLine(models.Model): - user = models.ForeignKey( - to=User, - related_name="shop_order_lines", - on_delete=models.CASCADE, - verbose_name=_("Bruker"), - ) - datetime = models.DateTimeField(auto_now_add=True, verbose_name=_("Tidspunkt")) - paid = models.BooleanField(default=False, verbose_name=_("Betalt")) - transaction = models.OneToOneField( - to=PaymentTransaction, - verbose_name=_("Transaksjon"), - related_name="shop_order_line", - on_delete=models.SET_NULL, - null=True, - blank=True, - ) - - def count_orders(self): - return sum((order.quantity for order in self.orders.all())) - - def subtotal(self): - return sum((order.total_price() for order in self.orders.all())) - - def get_order_descriptions(self): - descriptions = [] - for order in self.orders.all(): - item: Item = order.content_object - if item: - descriptions.append( - {"name": item.name, "price": item.price, "quantity": order.quantity} - ) - return descriptions - - def pay(self): - if self.paid: - return - - subtotal = self.subtotal() - - if subtotal > self.user.saldo: - self.delete() - raise NotAcceptable("Insufficient funds") - - # Setting price for orders in case product price changes later - for order in self.orders.all(): - order.price = order.total_price() - order.save() - order.reduce_stock() - - # Create the transaction for the user, which will track the actual balance of their wallet - transaction = PaymentTransaction.objects.create( - source=TransactionSource.SHOP, - amount=-subtotal, - user=self.user, - # Do not create receipt immediately, create after relation to order_line has been saved - create_receipt=False, - ) - self.transaction = transaction - self.paid = True - self.save() - - transaction.create_receipt = True - transaction.save() - - def clean(self): - super().clean() - if not self.orders.exists(): - raise ValidationError("An orderline must contain at least one order") - - def __str__(self): - return str(self.pk) - - class Meta: - default_permissions = ("add", "change", "delete") - - -class MagicToken(models.Model): - user = models.ForeignKey(User, on_delete=models.CASCADE) - token = models.CharField("token", default=uuid.uuid4, max_length=36) - data = models.TextField("data") - created = models.DateTimeField("created", editable=False, auto_now_add=True) - - class Meta: - default_permissions = ("add", "change", "delete") diff --git a/apps/shop/serializers.py b/apps/shop/serializers.py deleted file mode 100644 index fc3814dff..000000000 --- a/apps/shop/serializers.py +++ /dev/null @@ -1,92 +0,0 @@ -# -*- coding: utf-8 -*- - -from rest_framework import serializers - -from apps.authentication.models import OnlineUser as User -from apps.gallery.serializers import ResponsiveImageSerializer -from apps.inventory.models import Item, ItemCategory -from apps.payment.models import PaymentTransaction -from apps.shop.models import Order, OrderLine - - -class OrderSerializer(serializers.ModelSerializer): - class Meta: - model = Order - fields = ("object_id", "quantity") - - -class OrderLineSerializer(serializers.ModelSerializer): - orders = OrderSerializer(many=True) - - def validate_orders(self, orders: dict): - for order in orders: - item = Item.objects.get(pk=order.get("object_id")) - if not item.available: - raise serializers.ValidationError( - "Enklte av de gitte produktene er ikke tilgjengelig" - ) - - return orders - - def create(self, validated_data): - order_list = validated_data.pop("orders") - order_line = OrderLine.objects.create(**validated_data) - while len(order_list) > 0: - order_data = order_list.pop() - order = Order(order_line=order_line, **order_data) - item = Item.objects.get(pk=order.object_id) - order.content_object = item - order.price = item.price - order.save() - - order_line.pay() - - return order_line - - class Meta: - model = OrderLine - fields = ("user", "orders") - - -class UserSerializer(serializers.ModelSerializer): - class Meta: - model = User - fields = ("pk", "first_name", "last_name", "saldo") - - -class TransactionSerializer(serializers.ModelSerializer): - class Meta: - model = PaymentTransaction - fields = ("user", "amount") - - -class CategorySerializer(serializers.ModelSerializer): - class Meta: - model = ItemCategory - - fields = ("pk", "name") - - -class ItemSerializer(serializers.ModelSerializer): - image = ResponsiveImageSerializer() - category = CategorySerializer() - - class Meta: - model = Item - fields = ("pk", "name", "price", "description", "image", "category") - - -class UserOrderSerializer(serializers.ModelSerializer): - content_object = ItemSerializer() - - class Meta: - model = Order - fields = ("price", "quantity", "content_object") - - -class UserOrderLineSerializer(serializers.ModelSerializer): - orders = UserOrderSerializer(many=True) - - class Meta: - model = OrderLine - fields = ("orders", "paid", "datetime") diff --git a/apps/shop/templates/shop/email/magic_link.txt b/apps/shop/templates/shop/email/magic_link.txt deleted file mode 100644 index 7ab54e8ee..000000000 --- a/apps/shop/templates/shop/email/magic_link.txt +++ /dev/null @@ -1,14 +0,0 @@ -Hei {{ user }}. - -Noen har bedt om å oppdatere RFID-en tilkyttet din brukerkonto på https://online.ntnu.no - -For å gjennomføre dette, vennligst klikk her: {{ rfid_confirm_link }} - -Dersom dette ikke var deg kan du se bort i fra denne e-posten. - -Dette er en automatisk generert e-post og det er derfor ikke mulig å svare på den. - -Dersom du har spørsmål kan du ta kontakt med dotkom på dotkom@online.ntnu.no - -Mvh, -Linjeforeningen Online diff --git a/apps/shop/templates/shop/set_rfid.html b/apps/shop/templates/shop/set_rfid.html deleted file mode 100644 index a8ebd524b..000000000 --- a/apps/shop/templates/shop/set_rfid.html +++ /dev/null @@ -1,28 +0,0 @@ -{% extends "base.html" %} -{% load addcss %} - -{% block title %}Oppdater RFID | Online{% endblock %} - -{% block content %} -
-
-
-
-

Oppdater RFID

-
-

Nåværende RFID: {% if current_rfid %}{{ current_rfid }}{% else %}Ingen{% endif %}

-

Ny RFID: {{ form.rfid.value }}

- {% for error in form.errors %} -

{{ error }}

- {% endfor %} -
- {% csrf_token %} - - -
-
-
-
-{% endblock %} diff --git a/apps/shop/tests.py b/apps/shop/tests.py deleted file mode 100644 index b9fefe262..000000000 --- a/apps/shop/tests.py +++ /dev/null @@ -1,34 +0,0 @@ -from django.urls import reverse -from django_dynamic_fixture import G -from rest_framework import status -from rest_framework.test import APITestCase - -from apps.inventory.models import Item - - -class ShopItemTestCase(APITestCase): - basename = "shop_inventory" - - def get_list_url(self): - return reverse(f"{self.basename}-list") - - def get_detail_url(self, _id): - return reverse(f"{self.basename}-detail", args=(_id,)) - - def test_item_list_empty(self): - response = self.client.get(self.get_list_url()) - - self.assertEqual(response.status_code, status.HTTP_200_OK) - - def test_item_list_exists(self): - G(Item, available=True) - response = self.client.get(self.get_list_url()) - - self.assertEqual(response.status_code, status.HTTP_200_OK) - - def test_item_detail(self): - item = G(Item, available=True) - - response = self.client.get(self.get_detail_url(item.id)) - - self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/apps/shop/urls.py b/apps/shop/urls.py deleted file mode 100644 index fbe22b0d4..000000000 --- a/apps/shop/urls.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- encoding: utf-8 -*- - -from django.urls import re_path - -# API v1 -from apps.api.utils import SharedAPIRootRouter -from apps.shop import views - -urlpatterns = [ - re_path( - r"^token/(?P[\w-]+)/$", - views.SetRFIDWebView.as_view(), - name="shop_set_rfid", - ) -] - - -router = SharedAPIRootRouter() -router.register("inventory", views.InventoryViewSet, basename="shop_inventory") diff --git a/apps/shop/utils.py b/apps/shop/utils.py deleted file mode 100644 index 5690188a2..000000000 --- a/apps/shop/utils.py +++ /dev/null @@ -1,37 +0,0 @@ -from django.conf import settings -from django.template.loader import render_to_string -from django.urls import reverse - -from apps.notifications.constants import PermissionType -from apps.notifications.utils import send_message_to_users - -from .models import MagicToken - - -def send_magic_link(user, token): - rfid_confirm_link = reverse("shop_set_rfid", args=[str(token.token)]) - - message = render_to_string( - "shop/email/magic_link.txt", - { - "user": token.user, - "rfid_confirm_link": "{}{}".format(settings.BASE_URL, rfid_confirm_link), - }, - ) - send_message_to_users( - title="Oppdatert RFID på online.ntnu.no", - content=message, - recipients=[user], - permission_type=PermissionType.DEFAULT, - url=rfid_confirm_link, - ) - - return token - - -def create_magic_token(user, rfid, send_token_by_email=False): - token = MagicToken.objects.create(user=user, data=rfid) - - if send_token_by_email: - send_magic_link(user, token) - return token diff --git a/apps/shop/views.py b/apps/shop/views.py deleted file mode 100644 index 40daeb49c..000000000 --- a/apps/shop/views.py +++ /dev/null @@ -1,91 +0,0 @@ -# API v1 -import logging - -from django.contrib import messages -from django.contrib.auth.decorators import login_required -from django.shortcuts import get_object_or_404 -from django.urls import reverse_lazy -from django.utils.decorators import method_decorator -from django.views.generic import FormView -from rest_framework import mixins, viewsets -from rest_framework.permissions import AllowAny, IsAuthenticated - -from apps.inventory.models import Item -from apps.shop.forms import SetRFIDForm -from apps.shop.models import MagicToken, OrderLine -from apps.shop.serializers import ItemSerializer, UserOrderLineSerializer - - -class UserOrderViewSet( - viewsets.GenericViewSet, mixins.ListModelMixin, mixins.RetrieveModelMixin -): - serializer_class = UserOrderLineSerializer - permission_classes = (IsAuthenticated,) - - def get_queryset(self): - return OrderLine.objects.filter(user=self.request.user) - - -class InventoryViewSet( - viewsets.GenericViewSet, mixins.RetrieveModelMixin, mixins.ListModelMixin -): - queryset = Item.objects.filter(available=True).order_by("pk") - serializer_class = ItemSerializer - permission_classes = (AllowAny,) - pagination_class = None - - -@method_decorator(login_required, name="dispatch") -class SetRFIDWebView(FormView): - form_class = SetRFIDForm - template_name = "shop/set_rfid.html" - success_url = reverse_lazy("home") - - def get(self, request, token="", *args, **kwargs): - get_object_or_404(MagicToken, token=token) - return super().get(request, token, *args, **kwargs) - - def get_context_data(self, **kwargs): - kwargs["current_rfid"] = self.request.user.rfid - kwargs["token"] = self.kwargs.get("token") - return super().get_context_data(**kwargs) - - def get_initial(self): - initial = super().get_initial() - initial["rfid"] = MagicToken.objects.get(token=self.kwargs.get("token")).data - return initial - - def post(self, request, token="", *args, **kwargs): - logger = logging.getLogger(__name__) - form = self.get_form() - if not form.is_valid(): - return self.form_invalid(form) - - if not token: - form.add_error("Det finnes ingen token i denne forespørselen.") - return self.form_invalid(form) - - magictoken = None - try: - magictoken = MagicToken.objects.get(token=token) - except MagicToken.DoesNotExist: - form.add_error("Tokenet du prøver å bruke eksisterer ikke.") - return self.form_invalid(form) - - old_rfid = magictoken.user.rfid - magictoken.user.rfid = magictoken.data - magictoken.user.save() - - logger.debug( - '{authed_user} updated RFID for {user} (from "{old}" to "{new}").'.format( - authed_user=self.request.user, - user=magictoken.user, - old=old_rfid, - new=magictoken.data, - ) - ) - - magictoken.delete() - - messages.success(request, "Oppdaterte RFID for {}".format(magictoken.user)) - return self.form_valid(form) diff --git a/assets/dashboard/inventory/Inventory.js b/assets/dashboard/inventory/Inventory.js deleted file mode 100644 index 50c046a9e..000000000 --- a/assets/dashboard/inventory/Inventory.js +++ /dev/null @@ -1,79 +0,0 @@ -// import jQuery from 'jquery'; -import { ajax, showStatusMessage, toggleChecked } from 'common/utils'; -import './index.less'; - -/* - The Company module exposes functionality needed in the company section - of the dashboard. -*/ - -const Inventory = (function PrivateInventory($) { - const postDeleteForm = (url) => { - $(`
` + - `
`).submit(); - }; - - // Toggle inventory item - $('.toggle-inventory-item').each(function toggleItem() { - $(this).on('click', function toggleItemClick() { - if ($(this).hasClass('in-stock')) { - Inventory.item.toggle(this, 'in-stock'); - } - }); - }); - - return { - // Bind them buttons and other initial functionality here - init() { - $('#inventory-delete-item').on('click', function deleteItem(e) { - e.preventDefault(); - $('.confirm-delete-item').data('id', $(this).data('id')); - }); - - $('.deletebatch').on('click', function deleteBatch(e) { - e.preventDefault(); - $('.confirm-delete-batch').data('id', $(this).data('id')); - }); - - $('.confirm-delete-item').on('click', function confirmDeleteItem() { - const url = `/dashboard/inventory/item/${$(this).data('id')}/delete/`; - postDeleteForm(url); - }); - - $('.confirm-delete-batch').on('click', function confirmDeleteBatch() { - const itemId = $('#item_id').val(); - const url = `/dashboard/inventory/item/${itemId}/batch/${$(this).data('id')}/delete/`; - postDeleteForm(url); - }); - - $('#inventory-add-batch').on('click', (e) => { - e.preventDefault(); - $('#inventory-add-batch-form').slideToggle(200); - }); - }, - - item: { - toggle(cell, action) { - const data = { - item_id: $(cell).data('id'), - action, - }; - - const success = () => { - toggleChecked(cell); - }; - const error = (xhr, txt, errorMessage) => { - showStatusMessage(errorMessage, 'alert-danger'); - }; - - const url = `/dashboard/inventory/item/${data.item_id}/change/`; - - ajax('POST', url, data, success, error, null); - }, - }, - }; -}(jQuery)); - - -export default Inventory; diff --git a/assets/dashboard/inventory/InventoryStats.js b/assets/dashboard/inventory/InventoryStats.js deleted file mode 100644 index 4518c5110..000000000 --- a/assets/dashboard/inventory/InventoryStats.js +++ /dev/null @@ -1,40 +0,0 @@ -// import $ from 'jquery'; - -const google = window.google; - -const inventoryGraphs = () => { - let jsonData = {}; - - function drawChart() { - const data = new google.visualization.DataTable(); - - data.addColumn('string', 'Vare'); - data.addColumn('number', 'Antall'); - - Object.keys(jsonData).forEach((key) => { - data.addRow([key, jsonData[key]]); - }); - - const view = new google.visualization.DataView(data); - - const options = { - title: 'Varesalg', - height: 500, - bar: { groupWidth: '95%' }, - legend: { position: 'none' }, - }; - const chart = new google.visualization.ColumnChart(document.getElementById('columnchart_values')); - chart.draw(view, options); - } - - $.getJSON('orders/', (data) => { - jsonData = data; - google.charts.load('current', { packages: ['corechart'] }); - google.charts.setOnLoadCallback(drawChart); - }); -}; - - -export default { - init: inventoryGraphs, -}; diff --git a/assets/dashboard/inventory/index.js b/assets/dashboard/inventory/index.js deleted file mode 100644 index ee8ca51c3..000000000 --- a/assets/dashboard/inventory/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import Inventory from './Inventory'; -import InventoryStats from './InventoryStats'; - -Inventory.init(); - -const columnChart = document.getElementById('columnchart_values'); -if (columnChart) { - InventoryStats.init(); -} diff --git a/assets/dashboard/inventory/index.less b/assets/dashboard/inventory/index.less deleted file mode 100644 index 65885877a..000000000 --- a/assets/dashboard/inventory/index.less +++ /dev/null @@ -1,3 +0,0 @@ -.checkbox { color: red; } - -.checkbox.checked { color: green; } diff --git a/esbuild.mjs b/esbuild.mjs index aa586474a..6a1292720 100644 --- a/esbuild.mjs +++ b/esbuild.mjs @@ -18,7 +18,6 @@ let entryPoints = [ { out: 'dashboardGallery', in: 'assets/dashboard/gallery/index.js' }, { out: 'dashboardGroups', in: 'assets/dashboard/groups/index.js' }, { out: 'dashboardHobbies', in: 'assets/dashboard/hobbies/index.jsx' }, - { out: 'dashboardInventory', in: 'assets/dashboard/inventory/index.js' }, { out: 'dashboardMarks', in: 'assets/dashboard/marks/index.js' }, { out: 'dashboardPosters', in: 'assets/dashboard/posters/index.js' }, { out: 'dashboardResources', in: 'assets/dashboard/resources/index.jsx' }, diff --git a/onlineweb4/urls.py b/onlineweb4/urls.py index 574de17b5..ecbd4fb70 100755 --- a/onlineweb4/urls.py +++ b/onlineweb4/urls.py @@ -164,14 +164,6 @@ def get_context_data(self, **kwargs): re_path(r"^notifications/", include("apps.notifications.urls")), ] -if "apps.inventory" in settings.INSTALLED_APPS: - urlpatterns += [ - re_path(r"^dashboard/inventory/", include("apps.inventory.dashboard.urls")) - ] - -if "apps.shop" in settings.INSTALLED_APPS: - urlpatterns += [re_path(r"^shop/", include("apps.shop.urls"))] - if "apps.posters" in settings.INSTALLED_APPS: urlpatterns += [ re_path(r"^dashboard/posters/", include("apps.posters.dashboard.urls")) diff --git a/templates/dashboard/dashboard.html b/templates/dashboard/dashboard.html index d4846ae0b..b8c46f743 100644 --- a/templates/dashboard/dashboard.html +++ b/templates/dashboard/dashboard.html @@ -25,7 +25,6 @@

Velkommen til Online Dashboard

  • Grupper
  • Søknader
  • Bedrifter
  • -
  • Varelager
  • Arrangement
  • Karrieremuligheter
  • Artikler
  • diff --git a/templates/dashboard_base.html b/templates/dashboard_base.html index 99fd40f90..2e43e5f2a 100644 --- a/templates/dashboard_base.html +++ b/templates/dashboard_base.html @@ -238,23 +238,6 @@

    Velkommen
    {{ request.user.first_name {% endif %} - {% if 'inventory.view_item' in user_permissions %} -
  • - - Varelager - - {% if inventory_expired %} -    - {% endif %} - - -
  • - {% endif %} {% if 'webshop.view_category' in user_permissions or 'webshop.view_order' in user_permissions %}
  • diff --git a/templates/inventory/dashboard/category_index.html b/templates/inventory/dashboard/category_index.html deleted file mode 100644 index 7e8efcc30..000000000 --- a/templates/inventory/dashboard/category_index.html +++ /dev/null @@ -1,51 +0,0 @@ -{% extends "dashboard_base.html" %} - -{% block title %} -Varelager - Online Dashboard -{% endblock title %} - -{% block page-header %} -Kategorier -{% endblock %} - -{% block breadcrumbs %} -
  • Kategorier
  • -{% endblock %} - -{% block content %} - -
    -
    -
    -
    -
    -

    Kategorioversikt

    -
    -
    - {% if categories %} - - - - - - - - {% for category in categories %} - - - - {% endfor %} - -
    Navn
    {{ category.name }}
    - {% else %} -

    Ingen kategorier

    - {% endif %} -
    -
    -
    -
    -{% endblock content %} diff --git a/templates/inventory/dashboard/category_new.html b/templates/inventory/dashboard/category_new.html deleted file mode 100644 index 3ff623b6a..000000000 --- a/templates/inventory/dashboard/category_new.html +++ /dev/null @@ -1,34 +0,0 @@ -{% extends "dashboard_base.html" %} -{% load addcss %} -{% load crispy_forms_tags %} - -{% block title %} -Kategori - Online Dashboard -{% endblock title %} - -{% block page-header %} -Kategori -{% endblock %} - -{% block breadcrumbs %} -
  • Kategorier
  • -
  • Kategori
  • -{% endblock %} - -{% block content %} - {% if category.id %} - - {% endif %} - -
    -
    - {% include "inventory/dashboard/edit.html" %} -
    -
    -{% endblock content %} diff --git a/templates/inventory/dashboard/details.html b/templates/inventory/dashboard/details.html deleted file mode 100644 index 0277ddfa9..000000000 --- a/templates/inventory/dashboard/details.html +++ /dev/null @@ -1,166 +0,0 @@ -{% extends "dashboard_base.html" %} -{% load addcss %} -{% load crispy_forms_tags %} -{% load render_bundle from webpack_loader %} - -{% block title %} - {{ item.name }} - Online Dashboard -{% endblock title %} - -{% block styles %} - {{ block.super }} - {% render_bundle 'dashboardInventory' 'css' %} -{% endblock %} - -{% block js %} - {{ block.super }} - {% render_bundle 'dashboardInventory' 'js' attrs='async type="module"' %} -{% endblock %} - -{% block page-header %} - Endre {{ item.name }} -{% endblock %} - -{% block breadcrumbs %} -
  • Varelager
  • -
  • {{ item.name }}
  • -{% endblock %} - -{% block content %} -
    - - -
    -
    -
    -
    -
    -
    -

    Vare

    -
    -
    -
    - {% include "inventory/dashboard/edit.html" %} -
    -
    -
    -
    -
    -
    -
    -

    Batch

    -
    -
    - {% for pk, form in batch_forms %} -
    -
    - {% csrf_token %} - {% for field in form %} - {% if field.name != 'item' %} -
    -
    -
    - {{ field.label }} - {{ field|addclass:"form-control" }} - {% if field.name == 'expiration_date' %} - - - - - - {% endif %} -
    -
    -
    - {% else %} - {{ field.as_hidden }} - {% endif %} - {% endfor %} -
    -
    - - - - -
    -
    -
    -
    - {% endfor %} -
    -
    -
    -
    - - - -{% endblock content %} diff --git a/templates/inventory/dashboard/discontinued.html b/templates/inventory/dashboard/discontinued.html deleted file mode 100644 index 12088f3a3..000000000 --- a/templates/inventory/dashboard/discontinued.html +++ /dev/null @@ -1,65 +0,0 @@ -{% extends "dashboard_base.html" %} -{% load render_bundle from webpack_loader %} - -{% block title %} -Utgått varelager - Online Dashboard -{% endblock title %} - -{% block styles %} - {{ block.super }} - {% render_bundle 'dashboardInventory' 'css' %} -{% endblock %} - -{% block js %} - {{ block.super }} - {% render_bundle 'dashboardInventory' 'js' attrs='async type="module"' %} -{% endblock %} - -{% block page-header %} -Utgått varelager -{% endblock %} - -{% block breadcrumbs %} -
  • Utgått varelager
  • -{% endblock %} - -{% block content %} -
    -
    -
    -
    -

    Vareoversikt

    -
    -
    -

    Her finner du en oversikt over utgåtte varer. Varene som er her blir ikke solgt på Nibble.

    - - - - - - - - - - - - {% for item in items %} - - - - - - - - {% endfor %} - -
    NavnMengdeKategoriPrisTil salgs
    {{ item.name }}{{ item.total_amount }}{{ item.category}}{% if item.available %}{{ item.price }},-{% else %}-{% endif %} - - - -
    -
    -
    -
    -
    -{% endblock content %} diff --git a/templates/inventory/dashboard/edit.html b/templates/inventory/dashboard/edit.html deleted file mode 100644 index 6e902cfe5..000000000 --- a/templates/inventory/dashboard/edit.html +++ /dev/null @@ -1,14 +0,0 @@ -{% load addcss %} -
    - {% csrf_token %} - {% for field in form %} -
    - - {{ field|addclass:"form-control" }} -
    - {% endfor %} - -
    -{% include 'gallery/formwidget.html' %} \ No newline at end of file diff --git a/templates/inventory/dashboard/index.html b/templates/inventory/dashboard/index.html deleted file mode 100644 index ba955acf3..000000000 --- a/templates/inventory/dashboard/index.html +++ /dev/null @@ -1,77 +0,0 @@ -{% extends "dashboard_base.html" %} -{% load render_bundle from webpack_loader %} - -{% block title %} -Varelager - Online Dashboard -{% endblock title %} - -{% block styles %} - {{ block.super }} - {% render_bundle 'dashboardInventory' 'css' %} -{% endblock %} - -{% block js %} - {{ block.super }} - {% render_bundle 'dashboardInventory' 'js' attrs='async type="module"' %} -{% endblock %} - -{% block page-header %} -Varelager -{% endblock %} - -{% block breadcrumbs %} -
  • Varelager
  • -{% endblock %} - -{% block content %} -
    - -
    -
    -
    -
    -
    -
    -

    Vareoversikt

    -
    -
    -

    Her finner du en oversikt over varelageret. Alle oppføringer vil ha en eller flere mengder av varen tilknyttet seg, slik at man kan skille på utløpsdatoer i batch.

    - - - - - - - - - - - - - - {% for item in items %} - - - - - - - - - - {% endfor %} - -
    NavnMengdeKategoriTidligste utløpsdatoNyeste oppføringPrisTil salgs
    {{ item.name }}{{ item.total_amount }}{{ item.category}} - {{ item.oldest_expiration_date|date:'Y-m-d' }} - {{ item.last_added|date:'Y-m-d' }}{% if item.available %}{{ item.price }},-{% else %}-{% endif %} - - - -
    -
    -
    -
    -
    -{% endblock content %} diff --git a/templates/inventory/dashboard/new.html b/templates/inventory/dashboard/new.html deleted file mode 100644 index c2dbbee31..000000000 --- a/templates/inventory/dashboard/new.html +++ /dev/null @@ -1,35 +0,0 @@ -{% extends "dashboard_base.html" %} -{% load render_bundle from webpack_loader %} -{% load addcss %} -{% load crispy_forms_tags %} - -{% block title %} -Ny vare - Online Dashboard -{% endblock title %} - -{% block styles %} - {{ block.super }} - {% render_bundle 'dashboardInventory' 'css' %} -{% endblock %} - -{% block js %} - {{ block.super }} - {% render_bundle 'dashboardInventory' 'js' attrs='async type="module"' %} -{% endblock %} - -{% block page-header %} -Ny vare -{% endblock %} - -{% block breadcrumbs %} -
  • Varelager
  • -
  • Ny vare
  • -{% endblock %} - -{% block content %} -
    -
    - {% include "inventory/dashboard/edit.html" %} -
    -
    -{% endblock content %} diff --git a/templates/inventory/dashboard/statistics.html b/templates/inventory/dashboard/statistics.html deleted file mode 100644 index b05aa9760..000000000 --- a/templates/inventory/dashboard/statistics.html +++ /dev/null @@ -1,29 +0,0 @@ -{% extends "dashboard_base.html" %} -{% load render_bundle from webpack_loader %} - -{% block title %} -Varelager statistikk - Online Dashboard -{% endblock title %} - -{% block page-header %} -Varelager statistikk -{% endblock %} - -{% block breadcrumbs %} -
  • Varelager
  • -
  • Statistikk
  • -{% endblock %} - -{% block js %} - {{ block.super }} - - {% render_bundle 'dashboardInventory' 'js' attrs='async type="module"' %} -{% endblock %} - -{% block content %} -
    -
    -
    -
    -
    -{% endblock %}