Implement login system

Copy over payment system from kumi.xxx
Add missing requirements
Other stuff
This commit is contained in:
Kumi 2021-03-21 16:50:50 +01:00
parent b31ebc4818
commit 54e84be36a
47 changed files with 564 additions and 88 deletions

5
auction/apps.py Normal file
View file

@ -0,0 +1,5 @@
from django.apps import AppConfig
class AuctionConfig(AppConfig):
name = 'auction'

16
auction/models.py Normal file
View file

@ -0,0 +1,16 @@
from django.contrib.gis.db import models
from localauth.models import User
class Inquiry(models.Model):
user = models.ForeignKey(User, models.PROTECT)
destination_name = models.CharField(max_length=128)
destination_coords = models.PointField()
destination_radius = models.IntegerField()
budget = models.DecimalField(max_digits=10, decimal_places=2)
adults = models.IntegerField()
children = models.IntegerField()
comment = models.TextField()
def get_hotels(self):
pass

10
auction/urls.py Normal file
View file

@ -0,0 +1,10 @@
from django.urls import path
from public.views import HomeView
app_name = "auction"
urlpatterns = [
path('create_inquiry/', HomeView.as_view(), name="create_inquiry"),
path('process_inquiry/<slug:uuid>/', HomeView.as_view(), name="process_inquiry"),
]

View file

@ -1,3 +1,4 @@
libpq-dev
build-essential
libpython3-dev
postgis

View file

@ -1,5 +0,0 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import Account
admin.site.register(Account, UserAdmin)

12
localauth/forms.py Normal file
View file

@ -0,0 +1,12 @@
from django.contrib.auth.forms import UserCreationForm
from .models import User
class RegistrationForm(UserCreationForm):
def __init__(self, *args, **kwargs):
kwargs.pop("request")
super().__init__(*args, **kwargs)
class Meta:
model = User
fields = ["email", "password1", "password2"]

16
localauth/mixins.py Normal file
View file

@ -0,0 +1,16 @@
class SuperUserRequiredMixin(object):
"""
View mixin which requires that the authenticated user is a super user
(i.e. `is_superuser` is True).
"""
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
if not request.user.is_superuser:
messages.error(
request,
'You do not have the permission required to perform the '
'requested operation.')
return redirect(settings.LOGIN_URL)
return super(SuperUserRequiredMixin, self).dispatch(request,
*args, **kwargs)

View file

@ -1,58 +1,46 @@
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.utils import timezone
from django.contrib.auth import get_user_model
from polymorphic.models import PolymorphicModel
class Profile:
account = models.ForeignKey(get_user_model(), models.CASCADE)
from django.utils import timezone
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, email, password, **extra_fields):
now = timezone.now()
if not username:
raise ValueError('The given username must be set')
def _create_user(self, email, display_name, password, **extra_fields):
values = [email, display_name]
field_value_map = dict(zip(self.model.REQUIRED_FIELDS, values))
for field_name, value in field_value_map.items():
if not value:
raise ValueError('The {} value must be set'.format(field_name))
email = self.normalize_email(email)
user = self.model(username=username, email=email,
is_staff=is_staff, is_active=True,
is_superuser=is_superuser,
date_joined=now, **extra_fields)
user = self.model(
email=email,
display_name=display_name,
**extra_fields
)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username, email=None, password=None, **extra_fields):
return self._create_user(username, email, password, False, False,
**extra_fields)
def create_user(self, email, display_name, password=None, **extra_fields):
return self._create_user(email, display_name, password, **extra_fields)
def create_superuser(self, username, email, password, **extra_fields):
return self._create_user(username, email, p
def create_superuser(self, email, display_name, password=None, **extra_fields):
extra_fields.setdefault('is_superuser', True)
return self._create_user(email, display_name, password, **extra_fields)
class Account(AbstractBaseUser):
email = models.EmailField(_('username'), max_length=30, unique=True,
help_text=_('Required. 30 characters or fewer. Letters, digits and '
'@/./+/-/_ only.'),
validators=[
validators.RegexValidator(r'^[\w.@+-]+$',
_('Enter a valid username. '
'This value may contain only letters, numbers '
'and @/./+/-/_ characters.'), 'invalid'),
],
error_messages={
'unique': _("A user with that username already exists."),
})
class User(AbstractBaseUser):
email = models.EmailField(unique=True)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now)
last_login = models.DateTimeField(null=True)
is_superuser = models.BooleanField(default=False)
objects = AccountManager()
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
class Meta:
verbose_name = _('account')
verbose_name_plural = _('accounts')
REQUIRED_FIELDS = ['display_name']
def get_full_name(self):
return self.email
@ -60,5 +48,12 @@ class Account(AbstractBaseUser):
def get_short_name(self):
return self.email
def email_user(self, subject, message, from_email=None, **kwargs):
send_mail(subject, message, from_email, [self.email], **kwargs)
def has_permission(self, *args, **kwargs):
return self.is_superuser
@property
def is_staff(self):
return self.is_superuser
has_module_perms = has_permission
has_perm = has_permission

11
localauth/urls.py Normal file
View file

@ -0,0 +1,11 @@
from django.urls import path
from .views import LoginView, LogoutView, RegistrationView
app_name = "localauth"
urlpatterns = [
path('login/', LoginView.as_view(), name="login"),
path('logout/', LogoutView.as_view(), name="logout"),
path('register/', RegistrationView.as_view(), name="register"),
]

View file

@ -1,3 +1,24 @@
from django.shortcuts import render
from django.contrib.auth.views import LoginView as Login, LogoutView as Logout
from django.http.response import HttpResponseRedirect
from django.contrib.auth import login
# Create your views here.
from .forms import RegistrationForm
from .models import User
class LoginView(Login):
template_name = "localauth/register.html"
class LogoutView(Logout):
next_page = "/"
class RegistrationView(Login):
form_class = RegistrationForm
template_name = "localauth/register.html"
def form_valid(self, form):
user = User.objects.create_user(form.cleaned_data["email"], form.cleaned_data["password1"])
login(self.request, user)
return HttpResponseRedirect(self.get_success_url())
def get_default_redirect_url(self):
return resolve_url(self.next_page or settings.REGISTER_REDIRECT_URL)

View file

View file

@ -0,0 +1,8 @@
from django import template
register = template.Library()
@register.simple_tag
def stars(count, color="yellow"):
return """
"""

0
payment/__init__.py Normal file
View file

13
payment/admin.py Normal file
View file

@ -0,0 +1,13 @@
from django.contrib import admin
from .models import InvoicePayment, Invoice
from .paypal.models import PaypalInvoicePayment
from .sepa.models import SepaInvoicePayment
# Register your models here.
admin.site.register(InvoicePayment)
admin.site.register(Invoice)
admin.site.register(PaypalInvoicePayment)
admin.site.register(SepaInvoicePayment)

5
payment/apps.py Normal file
View file

@ -0,0 +1,5 @@
from django.apps import AppConfig
class PaymentConfig(AppConfig):
name = 'payment'

4
payment/functions.py Normal file
View file

@ -0,0 +1,4 @@
import uuid
def invoice_upload_path(instance, filename):
return "/".join(["userfiles", str(instance.user.id), str(uuid.uuid4()), filename])

134
payment/models.py Normal file
View file

@ -0,0 +1,134 @@
from django.db import models
from django.contrib.auth import get_user_model
from django.core.files.base import ContentFile
from django.utils import timezone
from dateutil.relativedelta import relativedelta
from pyinvoice.models import InvoiceInfo, ServiceProviderInfo, ClientInfo, Item, Transaction, PDFInfo
from pyinvoice.templates import SimpleInvoice
from polymorphic.models import PolymorphicModel
from django_countries.fields import CountryField
from io import BytesIO
import urllib.request
from dbsettings.functions import getValue
from .functions import invoice_upload_path
class BillingAddress(models.Model):
user = models.ForeignKey(get_user_model(), models.CASCADE)
first_name = models.CharField(max_length=64)
last_name = models.CharField(max_length=64)
street = models.CharField(max_length=128)
city = models.CharField(max_length=64)
zip = models.CharField(max_length=16)
state = models.CharField(max_length=32, null=True, blank=True)
country = CountryField()
class Invoice(models.Model):
user = models.ForeignKey(get_user_model(), models.PROTECT)
billing_address = models.ForeignKey(BillingAddress, models.PROTECT)
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)
@property
def price_net(self):
price = 0
for item in self.invoiceitem_set().all():
price += item.net_total
return price
@property
def tax(self):
return round(self.price_net * self.tax_rate / 100, 2)
@property
def price_gross(self):
return self.price_net + self.tax
@property
def payment_instructions(self):
return "Alle Preise in %s." % self.currency
@property
def url(self):
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.invoice_info = InvoiceInfo("%s%i" % (getValue("billing.prefix", ""), self.id), timezone.now().date(), timezone.now().date())
provider_data = { key: value for key, value in {
"name": getValue("billing.provider.name", False),
"street": getValue("billing.provider.street", False),
"city": getValue("billing.provider.city", False),
"state": getValue("billing.provider.state", False),
"country": getValue("billing.provider.country", False),
"post_code": getValue("billing.provider.zip", False),
"vat_tax_number": getValue("billing.provider.vat_id", False)
}.items() if value}
doc.service_provider_info = ServiceProviderInfo(**provider_data)
logo_url = getValue("billing.logo_url", False)
if logo_url:
try:
logo = BytesIO(urllib.request.urlopen(logo_url).read())
doc.logo(logo)
except:
pass
doc.client_info = ClientInfo(email='invoice.user.email', country="Austria")
for item in self.invoiceitem_set().all():
doc.add_item(Item(item.name, item.description, item.count, item.net_each))
doc.set_item_tax_rate(self.tax_rate)
for payment in self.invoicepayment_set().all():
doc.add_transaction(Transaction(payment.gateway, payment.gateway_id, payment.timestamp, payment.amount))
bottom_tip = (f"{ self.payment_instructions }<br /><br />" if self.payment_instructions else "") + getValue("billing.bottom_tip", "")
bottom_tip += "<br /><br />" if bottom_tip else ""
bottom_tip += "Rechnung erstellt: %s" % str(timezone.now())
doc.set_bottom_tip(bottom_tip)
doc.finish()
self.invoice = ContentFile(output.getvalue(), "invoice.pdf")
self.save()
class InvoiceItem(models.Model):
invoice = models.ForeignKey(Invoice, models.CASCADE)
name = models.CharField(max_length=64)
description = models.CharField(max_length=256, null=True, blank=True)
count = models.IntegerField()
net_each = models.DecimalField(max_digits=11, decimal_places=2)
class InvoicePayment(PolymorphicModel):
invoice = models.ForeignKey(Invoice, models.PROTECT)
amount = models.DecimalField(max_digits=9, decimal_places=2)
gateway_id = models.CharField(max_length=256)
timestamp = models.DateTimeField(default=timezone.now)
@property
def gateway(self):
raise NotImplementedError("%s does not implement gateway" % type(self))
@staticmethod
def initiate(invoice):
raise NotImplementedError("%s does not implement initiate()" % type(self))

View file

9
payment/paypal/api.py Normal file
View file

@ -0,0 +1,9 @@
from paypalcheckoutsdk.core import PayPalHttpClient, SandboxEnvironment, LiveEnvironment
from dbsettings.functions import getValue
class PaypalAPI:
def __init__(self, client_id=None, client_secret=None, mode=None):
mode = SandboxEnvironment if (client_secret == "sandbox" or getValue("paypal.mode") == "sandbox") else LiveEnvironment
environment = mode(client_id=(client_id or getValue("paypal.client_id")), client_secret=(client_secret or getValue("paypal.client_secret")))
self.client = PayPalHttpClient(environment)

64
payment/paypal/models.py Normal file
View file

@ -0,0 +1,64 @@
from payment.models import InvoicePayment, Invoice
from .api import PaypalAPI
from paypalcheckoutsdk.orders import OrdersCreateRequest
from paypalhttp import HttpError
from django.db import models
from django.urls import reverse_lazy
from dbsettings.functions import getValue
import logging
logger = logging.getLogger(__name__)
class PaypalOrder(models.Model):
invoice = models.ForeignKey(Invoice, models.CASCADE)
order_id = models.CharField(max_length=64)
class PaypalInvoicePayment(InvoicePayment):
@property
def gateway(self):
return "Paypal"
@staticmethod
def initiate(invoice):
request = OrdersCreateRequest()
request.prefer('return=representation')
request.request_body (
{
"intent": "CAPTURE",
"purchase_units": [
{
"amount": {
"currency_code": invoice.currency,
"value": float(invoice.price_gross)
}
}
],
"application_context": {
"return_url": getValue("application.base_url") + reverse_lazy("this_sucks"),
"cancel_url": getValue("application.base_url"),
"brand_name": getValue("application.name", "JourneyJoker"),
"landing_page": "BILLING",
"user_action": "CONTINUE"
},
}
)
try:
client = PaypalAPI().client
response = client.execute(request)
PaypalOrder.objects.create(subscription=subscription, order_id=response.result.id)
for link in response.result.links:
if link.rel == "approve":
return link.href
except IOError as ioe:
logger.error(ioe)
if isinstance(ioe, HttpError):
logger.error(ioe.status_code)

4
payment/paypal/urls.py Normal file
View file

@ -0,0 +1,4 @@
from django.urls import path
urlpatterns = [
]

0
payment/sepa/__init__.py Normal file
View file

5
payment/sepa/forms.py Normal file
View file

@ -0,0 +1,5 @@
from django import forms
class SepaApplyPaymentForm(forms.Form):
reference = forms.CharField()
amount = forms.DecimalField(max_digits=11, decimal_places=2)

59
payment/sepa/functions.py Normal file
View file

@ -0,0 +1,59 @@
import string
import re
import random
from dbsettings.functions import getValue
import qrcode
QRCODE_CONTENT = """
BCD
002
1
SCT
%s
%s
%s
%s%s
%s
%s
%s
%s
""".strip()
def generate_rf(reference):
reference = str(reference).upper().zfill(21) + "RF00"
pattern = re.compile("[A-Z0-9]+")
if not pattern.fullmatch(reference):
raise ValueError("Not a valid reference: %s may only contain 0-9 and A-Z!")
code = ""
chars = string.digits + string.ascii_uppercase
for char in reference:
code += str(chars.index(char))
remainder = int(code) % 97
checksum = 98 - remainder
return "RF%i%s" % (checksum, reference[:-4])
def generate_reference(length=21):
return "".join([random.SystemRandom().choice(string.digits + string.ascii_uppercase) for i in range(length)])
def generate_qrcode(amount, iban="", recipient="", bic="", reference="", currency="EUR", message="", purpose="", notice=""):
content = QRCODE_CONTENT % (
bic or getValue("sepa.bic", ""),
recipient or getValue("sepa.account_holder", ""),
iban or getValue("sepa.iban"),
currency,
"{:0.2f}".format(float(amount)).rstrip("0"),
purpose,
reference if (not reference) or str(reference).startswith("RF") or len(str(reference)) > 21 else generate_rf(reference),
message,
notice
)
return qrcode.make(content)

21
payment/sepa/models.py Normal file
View file

@ -0,0 +1,21 @@
from payment.models import InvoicePayment, Invoice
from django.db import models
import random
import string
from .functions import generate_reference
class SepaPaymentReference(models.Model):
invoice = models.ForeignKey(Invoice, models.CASCADE)
reference = models.IntegerField(default=generate_reference)
class SepaInvoicePayment(InvoicePayment):
@property
def gateway(self):
return "Bank Transfer"
@staticmethod
def initiate(subscription):
SepaPaymentReference.objects.get_or_create(subscription=subscription)

4
payment/sepa/urls.py Normal file
View file

@ -0,0 +1,4 @@
from django.urls import path
urlpatterns = [
]

23
payment/sepa/views.py Normal file
View file

@ -0,0 +1,23 @@
from django.views.generic import FormView
from django.shortcuts import get_object_or_404
from django.contrib import messages
from localauth.mixins import SuperUserRequiredMixin
from .forms import SepaApplyPaymentForm
from .models import SepaPaymentReference, SepaInvoicePayment
class SepaApplyPaymentView(SuperUserRequiredMixin, FormView):
form_class = SepaApplyPaymentForm
success_url = '/'
def form_valid(self, form):
reference = form.cleaned_data["reference"]
pr = get_object_or_404(SepaPaymentReference, reference=reference)
invoice = pr.invoice
SepaInvoicePayment.objects.create(invoice=invoice, amount=form.cleaned_data["amount"])
messages.success(self.request, "Zahlung angewendet.")
return super().form_valid(form)

3
payment/tests.py Normal file
View file

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

6
payment/urls.py Normal file
View file

@ -0,0 +1,6 @@
from django.urls import path, include
urlpatterns = [
path('gateways/paypal/', include("payment.paypal.urls")),
path('gateways/sepa/', include("payment.sepa.urls")),
]

0
payment/views.py Normal file
View file

View file

@ -1,5 +0,0 @@
from django.apps import AppConfig
class PaymentsConfig(AppConfig):
name = 'payments'

View file

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View file

View file

@ -0,0 +1,8 @@
from django import template
register = template.Library()
@register.simple_tag
def testimonials():
return """
"""

9
public/urls.py Normal file
View file

@ -0,0 +1,9 @@
from django.urls import path
from .views import HomeView
app_name = "frontend"
urlpatterns = [
path('', HomeView.as_view(), name="home"),
]

View file

@ -1,3 +1,4 @@
from django.shortcuts import render
from django.views.generic import TemplateView
# Create your views here.
class HomeView(TemplateView):
template_name = "frontend/index.html"

View file

@ -1,3 +1,8 @@
Django
django-polymorphic
psycopg2
dbsettings
django-bootstrap4
pyinvoice
django-countries
paypal-checkout-serversdk

View file

@ -4,7 +4,7 @@
<!doctype html>
<html lang="en">
<head>
<title>Urlaubsauktion - {{ title }}</title>
<title>JourneyJoker{% if title %} - {{ title }}{% endif %}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon">
@ -84,11 +84,11 @@
<div id="links">
<ul class="list-unstyled list-inline">
{% if request.user.is_authenticated %}
<li class="list-inline-item">{% trans "Eingeloggt als:" %} {{ request.user.username }}</li>
<li class="list-inline-item"><a href="{% url "profiles:logout" %}"><span><i class="fa fa-lock"></i></span>{% trans "Logout" %}</a></li>
<li class="list-inline-item">{% trans "Eingeloggt als:" %} {{ request.user.email }} | </li>
<li class="list-inline-item"><a href="{% url "localauth:logout" %}"><span><i class="fa fa-lock"></i></span>{% trans "Logout" %}</a></li>
{% else %}
<li class="list-inline-item"><a href="{% url "profiles:login" %}?next={{ request.path }}"><span><i class="fa fa-lock"></i></span>{% trans "Login" %}</a></li>
<li class="list-inline-item"><a href="{% url "profiles:register" %}?next={{ request.path }}"><span><i class="fa fa-plus"></i></span>{% trans "Registrieren" %}</a></li>
<li class="list-inline-item"><a href="{% url "localauth:login" %}?next={{ request.path }}"><span><i class="fa fa-lock"></i></span>{% trans "Login" %}</a></li>
<li class="list-inline-item"><a href="{% url "localauth:register" %}?next={{ request.path }}"><span><i class="fa fa-plus"></i></span>{% trans "Registrieren" %}</a></li>
{% endif %}
<li class="list-inline-item">
<form>
@ -126,7 +126,7 @@
<nav class="navbar navbar-expand-xl sticky-top navbar-custom main-navbar p-1" id="mynavbar-1">
<div class="container">
<a href="{% url "frontend:index" %}" class="navbar-brand py-1 m-0"><span><i class="fa fa-plane"></i>URLAUBS</span>AUKTION</a>
<a href="{% url "frontend:home" %}" class="navbar-brand py-1 m-0"><span><i class="fa fa-plane"></i>JOURNEY</span>JOKER</a>
<div class="header-search d-xl-none my-auto ml-auto py-1">
<a href="#" class="search-button" onClick="openSearch()"><span><i class="fa fa-search"></i></span></a>
</div>
@ -139,30 +139,28 @@
<li class="nav-item active">
<a href="/" class="nav-link" id="navbarDropdown" role="button">{% trans "Home" %}</a>
</li>
{% if request.user.clientprofile or not request.user.partnerprofile %}
<li class="nav-item dropdown">
<a href="#" class="nav-link" data-toggle="dropdown">{% trans "Meine Urlaubsauktion" %}<span><i class="fa fa-angle-down"></i></span></a>
<a href="#" class="nav-link" data-toggle="dropdown">{% trans "Mein&nbsp;Urlaub" %}<span><i class="fa fa-angle-down"></i></span></a>
<ul class="dropdown-menu">
{% if request.user.is_authenticated %}
<li><a class="dropdown-item" href="/">{% trans "Gestellte Anfragen" %}</a></li>
<li><a class="dropdown-item" href="/">{% trans "Gebuchte Reisen" %}</a></li>
{% else %}
<li><a class="dropdown-item" href="{% url "profiles:login" %}?next={{ request.path }}">{% trans "Login" %}</a></li>
<li><a class="dropdown-item" href="{% url "profiles:register" %}?next={{ request.path }}">{% trans "Registrieren" %}</a></li>
<li><a class="dropdown-item" href="{% url "localauth:login" %}?next={{ request.path }}">{% trans "Login" %}</a></li>
<li><a class="dropdown-item" href="{% url "localauth:register" %}?next={{ request.path }}">{% trans "Registrieren" %}</a></li>
{% endif %}
</ul>
</li>
{% endif %}
{% if request.user.partnerprofile %}
<li class="nav-item dropdown">
<a href="#" class="nav-link" data-toggle="dropdown">B2B<span><i class="fa fa-angle-down"></i></span></a>
<ul class="dropdown-menu">
<ul class="dropdown-menu">
{% if not request.user.partnerprofile %}
<li><a class="dropdown-item" href="/">{% trans "Als Anbieter anmelden" %}</a></li>
{% else %}
<li><a class="dropdown-item" href="/">{% trans "Bieten" %}</a></li>
<li><a class="dropdown-item" href="/">{% trans "Buchungen verwalten" %}</a></li>
{% endif %}
{% endif %}
</ul>
</li>
{% endif %}
@ -452,7 +450,7 @@
<div class="col-12 col-md-6 col-lg-3 col-xl-3 footer-widget ftr-contact">
<h3 class="footer-heading">Kontakt</h3>
<ul class="list-unstyled">
<li><span><i class="fa fa-map-marker"></i></span>Think:Put Die Agentur für Denken & Tun, Kolingasse 10/10, 1090 Wien</li>
<li><span><i class="fa fa-map-marker"></i></span>Think:Put<br>Die Agentur für Denken & Tun<br>Kolingasse 10/10<br>1090 Wien</li>
<!--<li><span><i class="fa fa-phone"></i></span>+43 800 093004</li>
<li><span><i class="fa fa-envelope"></i></span>office@kumi.systems</li>-->
</ul>
@ -466,7 +464,7 @@
</div><!-- end columns -->
<div class="col-12 col-md-6 col-lg-3 col-xl-3 footer-widget ftr-links ftr-pad-left">
<h3 class="footer-heading">Urlaubsauktion</h3>
<h3 class="footer-heading">JourneyJoker</h3>
<ul class="list-unstyled">
<li><a href="#">Impressum</a></li>
<li><a href="#">Kontakt</a></li>
@ -477,7 +475,7 @@
<div class="col-12 col-md-6 col-lg-4 col-xl-4 footer-widget ftr-about">
<h3 class="footer-heading">Über uns</h3>
<p>Die Urlaubsauktion ist ur leiwand. Oida.</p>
<p>Der Joker ist ur leiwand. Oida.</p>
<ul class="social-links list-inline list-unstyled">
<li class="list-inline-item"><a href="#"><span><i class="fab fa-facebook"></i></span></a></li>
<li class="list-inline-item"><a href="#"><span><i class="fab fa-twitter"></i></span></a></li>
@ -497,7 +495,7 @@
<div class="container">
<div class="row">
<div class="col-12 col-md-6 col-lg-6 col-xl-6" id="copyright">
<p>© 2020 <a href="https://thinkput.at/">Think:Put Die Agentur für Denken & Tun</a> Web-Entwicklung: <a href="https://">Kumi Systems e.U.</a></p>
<p>© 2020 2021 <a href="https://thinkput.at/">Think:Put Die Agentur für Denken & Tun</a></p><p>Entwicklung: <a href="https://kumi.systems/">Kumi Systems e.U.</a> <a href="https://kumi.media">Kumi Media Ltd.</a></p>
</div><!-- end columns -->
<div class="col-12 col-md-6 col-lg-6 col-xl-6" id="terms">

View file

@ -15,9 +15,9 @@
height:100%;">
<div class=" meta">
<div class="container">
<h2>{% trans "Willkommen zur großen" %}</h2>
<h1>{% trans "Urlaubs-Umkehrauktion" %}</h1>
<a href="#" class="btn btn-default">{% trans "Was bedeutet das?" %}</a>
<h2>{% trans "Willkommen bei JourneyJoker" %}</h2>
<h1>{% trans "Mein Urlaub nach Maß" %}</h1>
<a href="#" class="btn btn-default">{% trans "Wie geht das?" %}</a>
</div><!-- end container -->
</div><!-- end meta -->
</li><!-- end item-1 -->

View file

@ -1,10 +1,10 @@
{% load static %}
{% load i18n %}
{% load bootstrap %}
{% load bootstrap4 %}
<!doctype html>
<html lang="en">
<head>
<title>Urlaubsauktion - {{ title }}</title>
<title>JourneyJoker - {{ title }}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon">
@ -44,14 +44,14 @@
<div class="col-md-12">
<div class="full-page-title">
<a href="{% url "frontend:index" %}"><h3 class="company-name"><span><i class="fa fa-plane"></i>Urlaubs</span>Auktion</h3></a>
<a href="{% url "frontend:home" %}"><h3 class="company-name"><span><i class="fa fa-plane"></i>Journey</span>Joker</h3></a>
</div><!-- end full-page-title -->
<div class="custom-form custom-form-fields">
<h3>{{ title }}</h3>
<form method="POST">
{% csrf_token %}
{{ form|bootstrap }}
{% bootstrap_form form %}
<button class="btn btn-orange btn-block">{% trans "Login" %}</button>
</form>
@ -61,7 +61,7 @@
</div><!-- end other-links -->
</div><!-- end custom-form -->
<p class="full-page-copyright">© 2020 <a href="https://kumi.systems/">Kumi Systems e.U.</a> All rights reserved.</p>
<p class="full-page-copyright">© 2020 2021 <a href="https://kumi.systems/">Kumi Systems e.U.</a> All rights reserved.</p>
</div><!-- end columns -->
</div><!-- end row -->
</div><!-- end container -->

View file

@ -15,6 +15,14 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'localauth',
'public',
'partners',
'payment',
'clients',
'dbsettings',
'auction',
'bootstrap4',
'django_countries',
]
MIDDLEWARE = [
@ -32,7 +40,7 @@ ROOT_URLCONF = 'urlaubsauktion.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [BASE_DIR / "templates"],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
@ -53,7 +61,7 @@ WSGI_APPLICATION = 'urlaubsauktion.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': DB_NAME,
'USER': DB_USER,
'PASSWORD': DB_PASS,
@ -101,4 +109,11 @@ USE_TZ = True
STATIC_URL = '/static/'
AUTH_USER_MODEL = "localauth.Account"
STATICFILES_DIRS = [
BASE_DIR / "static",
]
AUTH_USER_MODEL = "localauth.User"
REGISTER_REDIRECT_URL = "/"
LOGIN_REDIRECT_URL = "/"

View file

@ -14,8 +14,12 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('public.urls')),
path('auth/', include('localauth.urls')),
path('auction/', include('auction.urls')),
path('payment/', include('payment.urls')),
]