Creating custom admin model
Modifying inquiry model and creating offer model Creating client profile views Fixing stars and hearts template tags
This commit is contained in:
parent
5b0f2e4adb
commit
f6b7fab525
12 changed files with 140 additions and 18 deletions
|
@ -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
|
||||
|
||||
class Offer(models.Model):
|
||||
inquiry = models.ForeignKey(Inquiry, models.PROTECT)
|
||||
establishment = models.ForeignKey(Establishment, models.PROTECT)
|
||||
arrival = models.DateTimeField()
|
||||
departure = models.DateTimeField()
|
||||
|
|
10
clients/urls.py
Normal file
10
clients/urls.py
Normal file
|
@ -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"),
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
from urlaubsauktion.admin import joker_admin as admin
|
||||
|
||||
from .models import User
|
||||
|
||||
admin.register(User)
|
|
@ -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)
|
||||
|
|
|
@ -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 += '<span><i class="fa%s fa-star %s"></i></span>' % (("" if i < number else "r"), classes)
|
||||
output += '<span><i class="fa%s fa-star" style="color:%s;"></i></span>' % (("" 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 += '<span><i class="fa%s fa-heart %s"></i></span>' % (("" if i < number else "r"), classes)
|
||||
output += '<span><i class="fa%s fa-heart" style="color:%s;"></i></span>' % (("" if i < number else "r"), color)
|
||||
|
||||
return output
|
|
@ -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)
|
||||
admin.register(PaypalInvoicePayment)
|
||||
admin.register(SepaInvoicePayment)
|
|
@ -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):
|
||||
|
@ -63,13 +66,24 @@ class Invoice(models.Model):
|
|||
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()
|
||||
|
||||
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))
|
||||
|
|
21
templates/clients/profile.html
Normal file
21
templates/clients/profile.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
{% extends "frontend/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap4 %}
|
||||
{% block "content" %}
|
||||
<!--===== INNERPAGE-WRAPPER ====-->
|
||||
<section class="innerpage-wrapper">
|
||||
<div id="payment-success" class="section-padding">
|
||||
<div class="container text-center">
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="col-md-12 col-lg-8 col-lg-offset-2">
|
||||
<h2>{% trans "Profildaten" %}</h2>
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
<button class="btn btn-orange btn-block">{% trans "Anwenden" %}</button>
|
||||
</div><!-- end columns -->
|
||||
</div><!-- end row -->
|
||||
</div><!-- end container -->
|
||||
</div><!-- end coming-soon-text -->
|
||||
</section><!-- end innerpage-wrapper -->
|
||||
{% endblock %}
|
23
templates/clients/signup.html
Normal file
23
templates/clients/signup.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
{% extends "frontend/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap4 %}
|
||||
{% block "content" %}
|
||||
<!--===== INNERPAGE-WRAPPER ====-->
|
||||
<section class="innerpage-wrapper">
|
||||
<div id="payment-success" class="section-padding">
|
||||
<div class="container text-center">
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="col-md-12 col-lg-8 col-lg-offset-2">
|
||||
<h2>{% trans "Profil anlegen" %}</h2>
|
||||
<p>Um eine Reise buchen zu können, brauchen wir zunächst ein paar Daten. Keine Sorge, das geht ganz schnell.</p>
|
||||
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
<button class="btn btn-orange btn-block">{% trans "Anwenden" %}</button>
|
||||
</div><!-- end columns -->
|
||||
</div><!-- end row -->
|
||||
</div><!-- end container -->
|
||||
</div><!-- end coming-soon-text -->
|
||||
</section><!-- end innerpage-wrapper -->
|
||||
{% endblock %}
|
|
@ -436,6 +436,7 @@
|
|||
<li class="list-inline-item price">12<span class="divider">|</span><span class="pkg">Buchungen diese Woche</span></li>
|
||||
<li class="list-inline-item rating">
|
||||
{% autoescape off %}{% stars 5 "orange" %}{% endautoescape %}
|
||||
{% autoescape off %}{% hearts 5 "red" %}{% endautoescape %}
|
||||
</li>
|
||||
</ul>
|
||||
</div><!-- end main-mask -->
|
||||
|
@ -535,6 +536,7 @@
|
|||
<blockquote>{{ t.text }}</blockquote>
|
||||
<div class="rating">
|
||||
{% autoescape off %}{% stars t.stars %}{% endautoescape %}
|
||||
{% autoescape off %}{% hearts t.hearts %}{% endautoescape %}
|
||||
</div>
|
||||
<small>{{ t.name }}</small>
|
||||
</div><!-- end item -->
|
||||
|
|
15
urlaubsauktion/admin.py
Normal file
15
urlaubsauktion/admin.py
Normal file
|
@ -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 <title>.
|
||||
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()
|
|
@ -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"),
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue