From c21f4b3dacd597a15a5ec39d525df1dfe1b70376 Mon Sep 17 00:00:00 2001 From: jdlugosz963 Date: Mon, 17 Jul 2023 01:47:57 +0200 Subject: Add project. --- restaurant_orders/dashboard/__init__.py | 0 restaurant_orders/dashboard/admin.py | 3 + restaurant_orders/dashboard/apps.py | 6 + restaurant_orders/dashboard/consumers.py | 49 +++++++ restaurant_orders/dashboard/forms.py | 30 ++++ .../dashboard/templates/dashboard/dashboard.html | 152 +++++++++++++++++++++ .../templates/dashboard/dashboard_order.html | 89 ++++++++++++ restaurant_orders/dashboard/urls.py | 17 +++ restaurant_orders/dashboard/views.py | 95 +++++++++++++ 9 files changed, 441 insertions(+) create mode 100644 restaurant_orders/dashboard/__init__.py create mode 100644 restaurant_orders/dashboard/admin.py create mode 100644 restaurant_orders/dashboard/apps.py create mode 100644 restaurant_orders/dashboard/consumers.py create mode 100644 restaurant_orders/dashboard/forms.py create mode 100644 restaurant_orders/dashboard/templates/dashboard/dashboard.html create mode 100644 restaurant_orders/dashboard/templates/dashboard/dashboard_order.html create mode 100644 restaurant_orders/dashboard/urls.py create mode 100644 restaurant_orders/dashboard/views.py (limited to 'restaurant_orders/dashboard') diff --git a/restaurant_orders/dashboard/__init__.py b/restaurant_orders/dashboard/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/restaurant_orders/dashboard/admin.py b/restaurant_orders/dashboard/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/restaurant_orders/dashboard/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/restaurant_orders/dashboard/apps.py b/restaurant_orders/dashboard/apps.py new file mode 100644 index 0000000..7b1cc05 --- /dev/null +++ b/restaurant_orders/dashboard/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class DashboardConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'dashboard' diff --git a/restaurant_orders/dashboard/consumers.py b/restaurant_orders/dashboard/consumers.py new file mode 100644 index 0000000..17a5d34 --- /dev/null +++ b/restaurant_orders/dashboard/consumers.py @@ -0,0 +1,49 @@ +from channels.generic.websocket import AsyncWebsocketConsumer +from channels.exceptions import StopConsumer +import channels.layers + +from asgiref.sync import sync_to_async, async_to_sync + +from core.models import Restaurant, Order + +from django.db.models import signals +from django.dispatch import receiver +from django.core import serializers + + +class OrderConsumer(AsyncWebsocketConsumer): + async def connect(self): + restaurant_pk = self.scope['url_route']['kwargs']['restaurant_pk'] + self.restaurant = sync_to_async(Restaurant.get_user_restaurant_or_404)(restaurant_pk, self.scope['user']) + if not self.restaurant: + return + + self.room_name = str(restaurant_pk) + self.room_group_name = f'restaurant_{self.room_name}' + + # Join room group + await self.channel_layer.group_add( + self.room_group_name, + self.channel_name + ) + + await self.accept() + + async def disconnect(self, close_code): + raise StopConsumer + + async def new_order(self, event): + await self.send(event['data']) + + @staticmethod + @receiver(signals.post_save, sender=Order) + def order_observer(sender, instance, **kwargs): + if not instance.can_display: + return + + layer = channels.layers.get_channel_layer() + + async_to_sync(layer.group_send)(f'restaurant_{instance.restaurant.pk}', { + 'type': 'new.order', + 'data': serializers.serialize('json', (instance, )) + }) diff --git a/restaurant_orders/dashboard/forms.py b/restaurant_orders/dashboard/forms.py new file mode 100644 index 0000000..23937ed --- /dev/null +++ b/restaurant_orders/dashboard/forms.py @@ -0,0 +1,30 @@ +from django import forms + +from core.models import Order + + +FORM_TAILWIND_CLASSES = 'form-control block w-full px-3 py-1.5 text-base font-normal text-gray-700 bg-white bg-clip-padding border border-solid border-gray-300 rounded transition ease-in-out m-0 focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none' + +class OrderStatusForm(forms.ModelForm): + class Meta: + model = Order + fields = ('wp_status', ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['wp_status'].label = 'Przenies do:' + +class AddToBillForm(forms.Form): + send_mail = forms.BooleanField(label='Wyslij maila', initial=False, required=False) + send_sms = forms.BooleanField(label='Wyslij sms', initial=True, required=False) + + def __init__(self, pk, user, *args, **kwargs): + super().__init__(*args, **kwargs) + order = Order.get_order(pk, user) + + for item in order.line_items: + index = item['product_id'] + self.fields[index] = forms.IntegerField(required=False, label=item['name']) + + for index in self.fields.keys(): + self.fields[index].widget.attrs.update({'class': FORM_TAILWIND_CLASSES}) diff --git a/restaurant_orders/dashboard/templates/dashboard/dashboard.html b/restaurant_orders/dashboard/templates/dashboard/dashboard.html new file mode 100644 index 0000000..0d2bf11 --- /dev/null +++ b/restaurant_orders/dashboard/templates/dashboard/dashboard.html @@ -0,0 +1,152 @@ +{% extends "base.html" %} + +{% block title %}Dashboard{% endblock %} + +{% block content %} + {% include '_pagination.html' %} +
+ +
+ + + +
+ {% for object in object_list %} + + {% endfor %} +
+ + + + {% endblock %} diff --git a/restaurant_orders/dashboard/templates/dashboard/dashboard_order.html b/restaurant_orders/dashboard/templates/dashboard/dashboard_order.html new file mode 100644 index 0000000..f245843 --- /dev/null +++ b/restaurant_orders/dashboard/templates/dashboard/dashboard_order.html @@ -0,0 +1,89 @@ +{% extends "base.html" %} + +{% block title %}Order #{{order.wp_id}}{% endblock %} + +{% block content %} +
+ Wroc +

#{{ order.wp_id}} - {{ order.billing.first_name }} {{ order.billing.last_name }} - {{order.get_wp_status_display}}

+
+
+
+

Zamowienie

+ + + + + + + + + + + + + {% for item in order.line_items %} + + + + + + + + {% endfor %} + +
#ProduktCena za produktCena za produktyIlosc
{{ forloop.counter }}{{ item.name }}{{item.price}} zl{{item.subtotal}} zl{{item.quantity}}
+ +
    +
+
+
+ +
+
+

Adres dostawy

+
    +
  • + Imie i Nazwisko + {{order.billing.first_name}} {{order.billing.last_name}} +
  • +
  • + Numer stolika + {{order.billing.address_1}} +
  • +
  • + Telefon + {{order.billing.phone}} +
  • +
  • + Email + {{order.billing.email}} +
  • +
+
+
+ +
+
+

Doliczenie do zamowienia

+
+ {% csrf_token %} + {{addToBillForm}} + +
+
+
+ +
+
+

Akcje

+
+ {% csrf_token %} + {{orderStatusForm}} + +
+
+
+
+
+{% endblock %} diff --git a/restaurant_orders/dashboard/urls.py b/restaurant_orders/dashboard/urls.py new file mode 100644 index 0000000..cd67ce3 --- /dev/null +++ b/restaurant_orders/dashboard/urls.py @@ -0,0 +1,17 @@ +from django.urls import path +from dashboard.views import Home, DashboardView, DashboardOrderView, ChangeOrderStatusView, AddToBillView +from dashboard.consumers import OrderConsumer + +app_name="dashboard" + +urlpatterns = [ + path('', Home.as_view(), name="home"), + path('restaurant//', DashboardView.as_view(), name='restaurant_dashboard'), + path('restaurant/order//', DashboardOrderView.as_view(), name='order_dashboard'), + path('restaurant/order//change/status/', ChangeOrderStatusView.as_view(), name='order_status_change'), + path('restaurant/order//add_to_bill/', AddToBillView.as_view(), name='order_add_to_bill'), +] + +websocket_urlpatterns = [ + path('orders//', OrderConsumer.as_asgi()), +] diff --git a/restaurant_orders/dashboard/views.py b/restaurant_orders/dashboard/views.py new file mode 100644 index 0000000..cfbc757 --- /dev/null +++ b/restaurant_orders/dashboard/views.py @@ -0,0 +1,95 @@ +from django.shortcuts import render, redirect, reverse +from django.contrib.auth.mixins import LoginRequiredMixin +from django.views.generic.list import ListView, View +from django.views.generic.edit import UpdateView +from django.contrib.messages.views import SuccessMessageMixin +from django.core import serializers +from django.contrib import messages + + +from dashboard.forms import OrderStatusForm, AddToBillForm +from core.tasks import create_order_and_send_notification +from core.models import Restaurant, Order + +class Home(LoginRequiredMixin, View): + def get(self, request): + redirect_url = 'dashboard:restaurant_dashboard' + restaurants = Restaurant.get_user_restaurants(request.user) + + if len(restaurants) == 1: + return redirect(redirect_url, restaurant_pk=restaurants[0].pk) + + return render(request, template_name='restaurants_choice.html', context={ + 'title': 'Dashboard', + 'restaurants': restaurants, + 'redirect_url': redirect_url + }) + +class DashboardView(LoginRequiredMixin, ListView): + template_name = 'dashboard/dashboard.html' + model = Order + paginate_by = 4 + + def get_queryset(self, *args, **kwargs): + restaurant = Restaurant.get_user_restaurant_or_404(pk=self.kwargs.get('restaurant_pk'), + user=self.request.user) + + status = self.request.GET.get('status') + queryset = {} + if status: + queryset['wp_status'] = status + + obj = super().get_queryset(*args, **kwargs).filter( + restaurant=restaurant, + can_display=True, + **queryset + ).order_by('-wp_id') + + return obj + + +class DashboardOrderView(LoginRequiredMixin, View): + def get(self, request, pk): + order = Order.get_order(pk, request.user) + orderStatusForm = OrderStatusForm(instance=order) + addToBillForm = AddToBillForm(pk, request.user) + + return render(request, 'dashboard/dashboard_order.html', context={ + 'order': order, + 'orderStatusForm': orderStatusForm, + 'addToBillForm': addToBillForm + }) + + +class ChangeOrderStatusView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): + form_class = OrderStatusForm + model = Order + success_message = 'Zapisano!' + slug_field='order_pk' + + def get_queryset(self, *args, **kwargs): + return super().get_queryset(*args, **kwargs).filter( + pk=self.kwargs['pk'], + can_display=True, + restaurant__users=self.request.user.pk + ) + + def get_success_url(self): + return reverse('dashboard:order_dashboard', args=(self.kwargs['pk'], )) + +class AddToBillView(LoginRequiredMixin, View): + def post(self, request, pk, *args, **kwargs): + addToBillForm = AddToBillForm(pk, request.user, request.POST) + + if addToBillForm.is_valid(): + order = Order.get_order(pk, request.user) + order = serializers.serialize('json', (order, )) + email = True if addToBillForm.data.get('send_mail') else False + phone = True if addToBillForm.data.get('send_sms') else False + items = [(wp_pk, price) for wp_pk, price in request.POST.items() if price.isdigit()] + + # TODO: Za duzo tych jebanych argumentow ! + create_order_and_send_notification.delay(order, items, email, phone, request.user.pk) + + + return redirect('dashboard:order_dashboard', pk) -- cgit v1.2.3