From f6b7fab5250dadfdf7bcc2b877c7974b1605ad33 Mon Sep 17 00:00:00 2001 From: Klaus-Uwe Mitterer Date: Wed, 24 Mar 2021 07:43:05 +0100 Subject: [PATCH] Creating custom admin model Modifying inquiry model and creating offer model Creating client profile views Fixing stars and hearts template tags --- auction/models.py | 22 ++++++++++++++++--- clients/urls.py | 10 +++++++++ localauth/admin.py | 5 +++++ partners/models.py | 3 ++- partners/templatetags/offeroptions.py | 8 +++---- payment/admin.py | 13 +++++------ payment/models.py | 31 +++++++++++++++++++++++++-- templates/clients/profile.html | 21 ++++++++++++++++++ templates/clients/signup.html | 23 ++++++++++++++++++++ templates/frontend/index.html | 2 ++ urlaubsauktion/admin.py | 15 +++++++++++++ urlaubsauktion/urls.py | 5 +++-- 12 files changed, 140 insertions(+), 18 deletions(-) create mode 100644 clients/urls.py create mode 100644 templates/clients/profile.html create mode 100644 templates/clients/signup.html create mode 100644 urlaubsauktion/admin.py diff --git a/auction/models.py b/auction/models.py index 4e69da5..4f7eb05 100644 --- a/auction/models.py +++ b/auction/models.py @@ -1,16 +1,32 @@ from django.contrib.gis.db import models -from localauth.models import User +from clients.models import ClientProfile +from partners.models import Establishment class Inquiry(models.Model): - user = models.ForeignKey(User, models.PROTECT) + client = models.ForeignKey(ClientProfile, models.PROTECT) destination_name = models.CharField(max_length=128) destination_coords = models.PointField() destination_radius = models.IntegerField() + arrival_from = models.DateTimeField() + departure_until = models.DateTimeField() budget = models.DecimalField(max_digits=10, decimal_places=2) adults = models.IntegerField() children = models.IntegerField() comment = models.TextField() + @property + def is_paid(self): + if not inquiry.invoice: + return False + + return inquiry.invoice.is_paid + def get_hotels(self): - pass \ No newline at end of file + pass + +class Offer(models.Model): + inquiry = models.ForeignKey(Inquiry, models.PROTECT) + establishment = models.ForeignKey(Establishment, models.PROTECT) + arrival = models.DateTimeField() + departure = models.DateTimeField() diff --git a/clients/urls.py b/clients/urls.py new file mode 100644 index 0000000..4ed5ae4 --- /dev/null +++ b/clients/urls.py @@ -0,0 +1,10 @@ +from django.urls import path + +from .views import ClientRegistrationView, ClientProfileView + +app_name = "clients" + +urlpatterns = [ + path('register/', ClientRegistrationView.as_view(), name="register"), + path('profile/', ClientProfileView.as_view(), name="profile"), +] \ No newline at end of file diff --git a/localauth/admin.py b/localauth/admin.py index e69de29..f6dc28d 100644 --- a/localauth/admin.py +++ b/localauth/admin.py @@ -0,0 +1,5 @@ +from urlaubsauktion.admin import joker_admin as admin + +from .models import User + +admin.register(User) \ No newline at end of file diff --git a/partners/models.py b/partners/models.py index b8c3b99..470cfa1 100644 --- a/partners/models.py +++ b/partners/models.py @@ -1,4 +1,4 @@ -from django.db import models +from django.contrib.gis.db import models from localauth.models import User, Profile @@ -16,6 +16,7 @@ class Establishment(models.Model): zip = models.CharField(max_length=16) state = models.CharField(max_length=64) country = CountryField() + coords = models.PointField() class RoomCategory(models.Model): establishment = models.ForeignKey(Establishment, models.CASCADE) diff --git a/partners/templatetags/offeroptions.py b/partners/templatetags/offeroptions.py index 4b69707..0a34cf5 100644 --- a/partners/templatetags/offeroptions.py +++ b/partners/templatetags/offeroptions.py @@ -3,7 +3,7 @@ from django import template register = template.Library() @register.simple_tag -def stars(number, classes=""): +def stars(number, color=""): number = int(number) if not 1 <= number <= 5: raise ValueError("Number of stars must be between 1 and 5.") @@ -11,12 +11,12 @@ def stars(number, classes=""): output = "" for i in range(5): - output += '' % (("" if i < number else "r"), classes) + output += '' % (("" if i < number else "r"), color) return output @register.simple_tag -def hearts(number, classes=""): +def hearts(number, color=""): number = int(number) if not 1 <= number <= 5: raise ValueError("Number of hearts must be between 1 and 5.") @@ -24,6 +24,6 @@ def hearts(number, classes=""): output = "" for i in range(5): - output += '' % (("" if i < number else "r"), classes) + output += '' % (("" if i < number else "r"), color) return output \ No newline at end of file diff --git a/payment/admin.py b/payment/admin.py index 3e92180..0e76722 100644 --- a/payment/admin.py +++ b/payment/admin.py @@ -1,13 +1,14 @@ -from django.contrib import admin +from urlaubsauktion.admin import joker_admin as admin -from .models import InvoicePayment, Invoice +from .models import InvoicePayment, Invoice, InvoiceItem from .paypal.models import PaypalInvoicePayment from .sepa.models import SepaInvoicePayment # Register your models here. -admin.site.register(InvoicePayment) -admin.site.register(Invoice) +admin.register(InvoicePayment) +admin.register(Invoice) +admin.register(InvoiceItem) -admin.site.register(PaypalInvoicePayment) -admin.site.register(SepaInvoicePayment) \ No newline at end of file +admin.register(PaypalInvoicePayment) +admin.register(SepaInvoicePayment) \ No newline at end of file diff --git a/payment/models.py b/payment/models.py index f107823..050d907 100644 --- a/payment/models.py +++ b/payment/models.py @@ -19,6 +19,8 @@ from dbsettings.functions import getValue from .functions import invoice_upload_path +from auction.models import Inquiry + class BillingAddress(models.Model): user = models.ForeignKey(get_user_model(), models.CASCADE) company = models.CharField(max_length=64, null=True, blank=True) @@ -37,6 +39,7 @@ class Invoice(models.Model): currency = models.CharField(max_length=3) tax_rate = models.DecimalField(max_digits=4, decimal_places=2) invoice = models.FileField(null=True, blank=True, upload_to=invoice_upload_path) + inquiry = models.OneToOneField(Inquiry, null=True, blank=True, on_delete=models.SET_NULL) @property def price_net(self): @@ -62,6 +65,17 @@ class Invoice(models.Model): @property def url(self): return False + + @property + def is_paid(self): + paid_amount = 0 + + for payment in self.invoicepayment_set().all(): + paid_amount += payment.amount + + if paid_amount >= price_gross: + return True + return False def generate_invoice(self): output = BytesIO() @@ -69,7 +83,7 @@ class Invoice(models.Model): pdfinfo = PDFInfo(title='Rechnung', author='Kumi Media Ltd.', subject='Rechnung') doc = SimpleInvoice(output, pdfinfo) - doc.is_paid = True + doc.is_paid = self.is_paid doc.invoice_info = InvoiceInfo("%s%i" % (getValue("billing.prefix", ""), self.id), timezone.now().date(), timezone.now().date()) @@ -93,7 +107,20 @@ class Invoice(models.Model): except: pass - doc.client_info = ClientInfo(email='invoice.user.email', country="Austria") + profile = self.user.clientprofile if self.inquiry else self.user.partnerprofile + + client_data = { key: value for key, value in { + "name": profile.full_name, + "street": profile.street, + "city": profile.city, + "state": profile.state, + "country": profile.country, + "post_code": profile.zip, + "vat_tax_number": profile.vat_id, + "email": self.user.email, + }.items() if value} + + doc.client_info = ClientInfo(**client_data) for item in self.invoiceitem_set().all(): doc.add_item(Item(item.name, item.description, item.count, item.net_each)) diff --git a/templates/clients/profile.html b/templates/clients/profile.html new file mode 100644 index 0000000..6e6d88a --- /dev/null +++ b/templates/clients/profile.html @@ -0,0 +1,21 @@ +{% extends "frontend/base.html" %} +{% load i18n %} +{% load bootstrap4 %} +{% block "content" %} + +
+
+
+
+
+

{% trans "Profildaten" %}

+
+ {% csrf_token %} + {% bootstrap_form form %} + +
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/clients/signup.html b/templates/clients/signup.html new file mode 100644 index 0000000..5a927ef --- /dev/null +++ b/templates/clients/signup.html @@ -0,0 +1,23 @@ +{% extends "frontend/base.html" %} +{% load i18n %} +{% load bootstrap4 %} +{% block "content" %} + +
+
+
+
+
+

{% trans "Profil anlegen" %}

+

Um eine Reise buchen zu können, brauchen wir zunächst ein paar Daten. Keine Sorge, das geht ganz schnell.

+ + + {% csrf_token %} + {% bootstrap_form form %} + +
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/frontend/index.html b/templates/frontend/index.html index 8fcc2a2..f53cbb2 100644 --- a/templates/frontend/index.html +++ b/templates/frontend/index.html @@ -436,6 +436,7 @@
  • 12|Buchungen diese Woche
  • {% autoescape off %}{% stars 5 "orange" %}{% endautoescape %} + {% autoescape off %}{% hearts 5 "red" %}{% endautoescape %}
  • @@ -535,6 +536,7 @@
    {{ t.text }}
    {% autoescape off %}{% stars t.stars %}{% endautoescape %} + {% autoescape off %}{% hearts t.hearts %}{% endautoescape %}
    {{ t.name }} diff --git a/urlaubsauktion/admin.py b/urlaubsauktion/admin.py new file mode 100644 index 0000000..58bc570 --- /dev/null +++ b/urlaubsauktion/admin.py @@ -0,0 +1,15 @@ +from django.contrib.admin import AdminSite +from django.utils.translation import ugettext_lazy +from django.contrib.auth import get_user_model + +class JokerAdmin(AdminSite): + # Text to put at the end of each page's . + site_title = ugettext_lazy('JourneyJoker Administration') + + # Text to put in each page's <h1> (and above login form). + site_header = ugettext_lazy('JourneyJoker Administration') + + # Text to put at the top of the admin index page. + index_title = ugettext_lazy('JourneyJoker Administration') + +joker_admin = JokerAdmin() diff --git a/urlaubsauktion/urls.py b/urlaubsauktion/urls.py index b678866..6c05096 100644 --- a/urlaubsauktion/urls.py +++ b/urlaubsauktion/urls.py @@ -13,14 +13,15 @@ Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ -from django.contrib import admin +from .admin import joker_admin from django.urls import path, include urlpatterns = [ - path('admin_area/', admin.site.urls), + path('admin_area/', joker_admin.urls), path('', include('public.urls'), name="frontend"), path('auth/', include('localauth.urls'), name="localauth"), path('auction/', include('auction.urls'), name="auction"), path('payment/', include('payment.urls'), name="payment"), path('partners/', include('partners.urls'), name="partners"), + path('clients/', include('clients.urls'), name="clients"), ]