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

View file

@ -4,7 +4,7 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<title>Urlaubsauktion - {{ title }}</title> <title>JourneyJoker{% if title %} - {{ title }}{% endif %}</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon"> <link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon">
@ -84,11 +84,11 @@
<div id="links"> <div id="links">
<ul class="list-unstyled list-inline"> <ul class="list-unstyled list-inline">
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<li class="list-inline-item">{% trans "Eingeloggt als:" %} {{ request.user.username }}</li> <li class="list-inline-item">{% trans "Eingeloggt als:" %} {{ request.user.email }} | </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"><a href="{% url "localauth:logout" %}"><span><i class="fa fa-lock"></i></span>{% trans "Logout" %}</a></li>
{% else %} {% 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 "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 "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:register" %}?next={{ request.path }}"><span><i class="fa fa-plus"></i></span>{% trans "Registrieren" %}</a></li>
{% endif %} {% endif %}
<li class="list-inline-item"> <li class="list-inline-item">
<form> <form>
@ -126,7 +126,7 @@
<nav class="navbar navbar-expand-xl sticky-top navbar-custom main-navbar p-1" id="mynavbar-1"> <nav class="navbar navbar-expand-xl sticky-top navbar-custom main-navbar p-1" id="mynavbar-1">
<div class="container"> <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"> <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> <a href="#" class="search-button" onClick="openSearch()"><span><i class="fa fa-search"></i></span></a>
</div> </div>
@ -139,30 +139,28 @@
<li class="nav-item active"> <li class="nav-item active">
<a href="/" class="nav-link" id="navbarDropdown" role="button">{% trans "Home" %}</a> <a href="/" class="nav-link" id="navbarDropdown" role="button">{% trans "Home" %}</a>
</li> </li>
{% if request.user.clientprofile or not request.user.partnerprofile %}
<li class="nav-item dropdown"> <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"> <ul class="dropdown-menu">
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<li><a class="dropdown-item" href="/">{% trans "Gestellte Anfragen" %}</a></li> <li><a class="dropdown-item" href="/">{% trans "Gestellte Anfragen" %}</a></li>
<li><a class="dropdown-item" href="/">{% trans "Gebuchte Reisen" %}</a></li> <li><a class="dropdown-item" href="/">{% trans "Gebuchte Reisen" %}</a></li>
{% else %} {% else %}
<li><a class="dropdown-item" href="{% url "profiles:login" %}?next={{ request.path }}">{% trans "Login" %}</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 "profiles:register" %}?next={{ request.path }}">{% trans "Registrieren" %}</a></li> <li><a class="dropdown-item" href="{% url "localauth:register" %}?next={{ request.path }}">{% trans "Registrieren" %}</a></li>
{% endif %} {% endif %}
</ul> </ul>
</li> </li>
{% endif %}
{% if request.user.partnerprofile %} {% if request.user.partnerprofile %}
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a href="#" class="nav-link" data-toggle="dropdown">B2B<span><i class="fa fa-angle-down"></i></span></a> <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 %} {% if not request.user.partnerprofile %}
<li><a class="dropdown-item" href="/">{% trans "Als Anbieter anmelden" %}</a></li> <li><a class="dropdown-item" href="/">{% trans "Als Anbieter anmelden" %}</a></li>
{% else %} {% else %}
<li><a class="dropdown-item" href="/">{% trans "Bieten" %}</a></li> <li><a class="dropdown-item" href="/">{% trans "Bieten" %}</a></li>
<li><a class="dropdown-item" href="/">{% trans "Buchungen verwalten" %}</a></li> <li><a class="dropdown-item" href="/">{% trans "Buchungen verwalten" %}</a></li>
{% endif %} {% endif %}
</ul> </ul>
</li> </li>
{% endif %} {% endif %}
@ -452,7 +450,7 @@
<div class="col-12 col-md-6 col-lg-3 col-xl-3 footer-widget ftr-contact"> <div class="col-12 col-md-6 col-lg-3 col-xl-3 footer-widget ftr-contact">
<h3 class="footer-heading">Kontakt</h3> <h3 class="footer-heading">Kontakt</h3>
<ul class="list-unstyled"> <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-phone"></i></span>+43 800 093004</li>
<li><span><i class="fa fa-envelope"></i></span>office@kumi.systems</li>--> <li><span><i class="fa fa-envelope"></i></span>office@kumi.systems</li>-->
</ul> </ul>
@ -466,7 +464,7 @@
</div><!-- end columns --> </div><!-- end columns -->
<div class="col-12 col-md-6 col-lg-3 col-xl-3 footer-widget ftr-links ftr-pad-left"> <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"> <ul class="list-unstyled">
<li><a href="#">Impressum</a></li> <li><a href="#">Impressum</a></li>
<li><a href="#">Kontakt</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"> <div class="col-12 col-md-6 col-lg-4 col-xl-4 footer-widget ftr-about">
<h3 class="footer-heading">Über uns</h3> <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"> <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-facebook"></i></span></a></li>
<li class="list-inline-item"><a href="#"><span><i class="fab fa-twitter"></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="container">
<div class="row"> <div class="row">
<div class="col-12 col-md-6 col-lg-6 col-xl-6" id="copyright"> <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><!-- end columns -->
<div class="col-12 col-md-6 col-lg-6 col-xl-6" id="terms"> <div class="col-12 col-md-6 col-lg-6 col-xl-6" id="terms">

View file

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

View file

@ -1,10 +1,10 @@
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
{% load bootstrap %} {% load bootstrap4 %}
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<title>Urlaubsauktion - {{ title }}</title> <title>JourneyJoker - {{ title }}</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon"> <link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon">
@ -44,14 +44,14 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="full-page-title"> <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><!-- end full-page-title -->
<div class="custom-form custom-form-fields"> <div class="custom-form custom-form-fields">
<h3>{{ title }}</h3> <h3>{{ title }}</h3>
<form method="POST"> <form method="POST">
{% csrf_token %} {% csrf_token %}
{{ form|bootstrap }} {% bootstrap_form form %}
<button class="btn btn-orange btn-block">{% trans "Login" %}</button> <button class="btn btn-orange btn-block">{% trans "Login" %}</button>
</form> </form>
@ -61,7 +61,7 @@
</div><!-- end other-links --> </div><!-- end other-links -->
</div><!-- end custom-form --> </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 columns -->
</div><!-- end row --> </div><!-- end row -->
</div><!-- end container --> </div><!-- end container -->

View file

@ -15,6 +15,14 @@ INSTALLED_APPS = [
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'localauth', 'localauth',
'public',
'partners',
'payment',
'clients',
'dbsettings',
'auction',
'bootstrap4',
'django_countries',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -32,7 +40,7 @@ ROOT_URLCONF = 'urlaubsauktion.urls'
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [], 'DIRS': [BASE_DIR / "templates"],
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
@ -53,7 +61,7 @@ WSGI_APPLICATION = 'urlaubsauktion.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': DB_NAME, 'NAME': DB_NAME,
'USER': DB_USER, 'USER': DB_USER,
'PASSWORD': DB_PASS, 'PASSWORD': DB_PASS,
@ -101,4 +109,11 @@ USE_TZ = True
STATIC_URL = '/static/' 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')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.contrib import admin from django.contrib import admin
from django.urls import path from django.urls import path, include
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('', include('public.urls')),
path('auth/', include('localauth.urls')),
path('auction/', include('auction.urls')),
path('payment/', include('payment.urls')),
] ]