Just checking in.
This commit is contained in:
parent
54e84be36a
commit
4ca76378df
21 changed files with 200 additions and 35 deletions
|
@ -1,11 +1,7 @@
|
|||
from django.db import models
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
class Profile(models.Model):
|
||||
user = models.ForeignKey(get_user_model(), models.CASCADE)
|
||||
from localauth.models import Profile
|
||||
|
||||
class ClientProfile(Profile):
|
||||
pass
|
||||
|
||||
class PartnerProfile(Profile):
|
||||
pass
|
|
@ -1,4 +1,10 @@
|
|||
class SuperUserRequiredMixin(object):
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.shortcuts import redirect
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.conf import settings
|
||||
|
||||
class SuperUserRequiredMixin:
|
||||
"""
|
||||
View mixin which requires that the authenticated user is a super user
|
||||
(i.e. `is_superuser` is True).
|
||||
|
@ -12,5 +18,17 @@ class SuperUserRequiredMixin(object):
|
|||
'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)
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
class LoginRequiredMixin:
|
||||
"""
|
||||
View mixin which verifies that the user has authenticated.
|
||||
|
||||
NOTE:
|
||||
This should be the left-most mixin of a view.
|
||||
"""
|
||||
|
||||
@method_decorator(login_required)
|
||||
def dispatch(self, *args, **kwargs):
|
||||
return super().dispatch(*args, **kwargs)
|
|
@ -3,6 +3,8 @@ from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
|
|||
from django.contrib.auth import get_user_model
|
||||
from django.utils import timezone
|
||||
|
||||
from django_countries.fields import CountryField
|
||||
|
||||
class UserManager(BaseUserManager):
|
||||
use_in_migrations = True
|
||||
|
||||
|
@ -56,4 +58,19 @@ class User(AbstractBaseUser):
|
|||
return self.is_superuser
|
||||
|
||||
has_module_perms = has_permission
|
||||
has_perm = has_permission
|
||||
has_perm = has_permission
|
||||
|
||||
class Profile(models.Model):
|
||||
user = models.OneToOneField(User, models.CASCADE)
|
||||
company = models.CharField(max_length=64, null=True, blank=True)
|
||||
vat_id = models.CharField(max_length=32, null=True, blank=True)
|
||||
first_name = models.CharField(max_length=64)
|
||||
last_name = models.CharField(max_length=64)
|
||||
street = models.CharField(max_length=64)
|
||||
city = models.CharField(max_length=64)
|
||||
zip = models.CharField(max_length=16)
|
||||
state = models.CharField(max_length=64)
|
||||
country = CountryField()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
|
@ -1,6 +1,8 @@
|
|||
from django.contrib.auth.views import LoginView as Login, LogoutView as Logout
|
||||
from django.http.response import HttpResponseRedirect
|
||||
from django.contrib.auth import login
|
||||
from django.shortcuts import resolve_url
|
||||
from django.conf import settings
|
||||
|
||||
from .forms import RegistrationForm
|
||||
from .models import User
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
from localauth.models import User, Profile
|
||||
|
||||
from django_countries.fields import CountryField
|
||||
|
||||
class PartnerProfile(Profile):
|
||||
pass
|
||||
|
||||
class Establishment(models.Model):
|
||||
owner = models.ForeignKey(PartnerProfile, models.CASCADE)
|
||||
name = models.CharField(max_length=64)
|
||||
stars = models.IntegerField(null=True, blank=True)
|
||||
street = models.CharField(max_length=64)
|
||||
city = models.CharField(max_length=64)
|
||||
zip = models.CharField(max_length=16)
|
||||
state = models.CharField(max_length=64)
|
||||
country = CountryField()
|
||||
|
||||
class RoomCategory(models.Model):
|
||||
establishment = models.ForeignKey(Establishment, models.CASCADE)
|
||||
name = models.CharField(max_length=64)
|
|
@ -3,6 +3,27 @@ from django import template
|
|||
register = template.Library()
|
||||
|
||||
@register.simple_tag
|
||||
def stars(count, color="yellow"):
|
||||
return """
|
||||
"""
|
||||
def stars(number, classes=""):
|
||||
number = int(number)
|
||||
if not 1 <= number <= 5:
|
||||
raise ValueError("Number of stars must be between 1 and 5.")
|
||||
|
||||
output = ""
|
||||
|
||||
for i in range(5):
|
||||
output += '<span><i class="fa%s fa-star %s"></i></span>' % (("" if i < number else "r"), classes)
|
||||
|
||||
return output
|
||||
|
||||
@register.simple_tag
|
||||
def hearts(number, classes=""):
|
||||
number = int(number)
|
||||
if not 1 <= number <= 5:
|
||||
raise ValueError("Number of hearts must be between 1 and 5.")
|
||||
|
||||
output = ""
|
||||
|
||||
for i in range(5):
|
||||
output += '<span><i class="fa%s fa-heart %s"></i></span>' % (("" if i < number else "r"), classes)
|
||||
|
||||
return output
|
|
@ -1,3 +1,9 @@
|
|||
from django.shortcuts import render
|
||||
from django.views.generic import CreateView
|
||||
|
||||
# Create your views here.
|
||||
from .models import PartnerProfile
|
||||
|
||||
from localauth.mixins import LoginRequiredMixin
|
||||
|
||||
class PartnerRegistrationView(LoginRequiredMixin, CreateView):
|
||||
model = PartnerProfile
|
||||
exclude = ["user"]
|
|
@ -21,6 +21,8 @@ from .functions import invoice_upload_path
|
|||
|
||||
class BillingAddress(models.Model):
|
||||
user = models.ForeignKey(get_user_model(), models.CASCADE)
|
||||
company = models.CharField(max_length=64, null=True, blank=True)
|
||||
vat_id = models.CharField(max_length=32, null=True, blank=True)
|
||||
first_name = models.CharField(max_length=64)
|
||||
last_name = models.CharField(max_length=64)
|
||||
street = models.CharField(max_length=128)
|
||||
|
@ -129,6 +131,6 @@ class InvoicePayment(PolymorphicModel):
|
|||
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))
|
||||
@classmethod
|
||||
def initiate(cls, invoice):
|
||||
raise NotImplementedError("%s does not implement initiate()" % cls.__name__)
|
||||
|
|
|
@ -11,6 +11,9 @@ class SepaPaymentReference(models.Model):
|
|||
invoice = models.ForeignKey(Invoice, models.CASCADE)
|
||||
reference = models.IntegerField(default=generate_reference)
|
||||
|
||||
def create_payment(self, amount):
|
||||
return SepaInvoicePayment.objects.create(invoice=self.invoice, gateway_id=self.reference, amount=amount)
|
||||
|
||||
class SepaInvoicePayment(InvoicePayment):
|
||||
@property
|
||||
def gateway(self):
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
from django.urls import path
|
||||
|
||||
from .views import SepaApplyPaymentView
|
||||
|
||||
urlpatterns = [
|
||||
path('apply/', SepaApplyPaymentView.as_view(), name="superuser_apply"),
|
||||
]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from django.views.generic import FormView
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.contrib import messages
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
from localauth.mixins import SuperUserRequiredMixin
|
||||
|
||||
|
@ -8,15 +9,14 @@ from .forms import SepaApplyPaymentForm
|
|||
from .models import SepaPaymentReference, SepaInvoicePayment
|
||||
|
||||
class SepaApplyPaymentView(SuperUserRequiredMixin, FormView):
|
||||
template_name = "payment/sepa/apply.html"
|
||||
form_class = SepaApplyPaymentForm
|
||||
success_url = '/'
|
||||
success_url = reverse_lazy("sepa:apply")
|
||||
|
||||
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"])
|
||||
pr.create_payment(form.cleaned_data["amount"])
|
||||
|
||||
messages.success(self.request, "Zahlung angewendet.")
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django.urls import path, include
|
||||
|
||||
urlpatterns = [
|
||||
path('gateways/paypal/', include("payment.paypal.urls")),
|
||||
path('gateways/sepa/', include("payment.sepa.urls")),
|
||||
path('gateways/paypal/', include("payment.paypal.urls"), name="paypal"),
|
||||
path('gateways/sepa/', include("payment.sepa.urls"), name="sepa"),
|
||||
]
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
from django.db import models
|
||||
from django.conf import settings
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class Testimonial(models.Model):
|
||||
name = models.CharField(max_length=128)
|
||||
text = models.TextField()
|
||||
stars = models.PositiveIntegerField(
|
||||
validators=[
|
||||
MaxValueValidator(5),
|
||||
MinValueValidator(1)
|
||||
])
|
||||
language = models.CharField(max_length=12, choices=settings.LANGUAGES)
|
||||
public = models.BooleanField(default=False)
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
from django import template
|
||||
|
||||
from random import SystemRandom
|
||||
|
||||
from public.models import Testimonial
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.simple_tag
|
||||
def testimonials():
|
||||
return """
|
||||
"""
|
||||
def testimonials(count=5, language="de"):
|
||||
objects = list(Testimonial.objects.filter(language=language)) # pylint: disable=no-member
|
||||
SystemRandom().shuffle(objects)
|
||||
return objects[:min(count, len(objects))]
|
||||
|
|
|
@ -5,4 +5,5 @@ dbsettings
|
|||
django-bootstrap4
|
||||
pyinvoice
|
||||
django-countries
|
||||
paypal-checkout-serversdk
|
||||
paypal-checkout-serversdk
|
||||
python-dateutil
|
1
static/frontend/css/toastr.min.css
vendored
Normal file
1
static/frontend/css/toastr.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
static/frontend/js/toastr.min.js
vendored
Normal file
7
static/frontend/js/toastr.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -10,7 +10,7 @@
|
|||
<link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon">
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Lato:300,300i,400,400i,700,700i,900,900i%7CMerriweather:300,300i,400,400i,700,700i,900,900i" rel="stylesheet">
|
||||
<link href="https://fontproxy.kumi.systems/css?family=Lato:300,300i,400,400i,700,700i,900,900i%7CMerriweather:300,300i,400,400i,700,700i,900,900i" rel="stylesheet">
|
||||
|
||||
<!-- Bootstrap Stylesheet -->
|
||||
<link rel="stylesheet" href="{% static "frontend/css/bootstrap.min4.2.1.css" %}">
|
||||
|
@ -40,6 +40,9 @@
|
|||
<!-- Magnific Gallery -->
|
||||
<link rel="stylesheet" href="{% static "frontend/css/magnific-popup.css" %}">
|
||||
|
||||
<!-- Toastr -->
|
||||
<link rel="stylesheet" href="{% static "frontend/css/toastr.min.css" %}">
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
|
@ -175,7 +178,15 @@
|
|||
<li><a class="dropdown-item" href="/">{% trans "Impressum" %}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-item search-btn">
|
||||
{% if request.user.is_superuser %}
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link" data-toggle="dropdown">Admin<span><i class="fa fa-angle-down"></i></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="{% url "payment:sepa:apply" %}">{% trans "SEPA-Zahlung anwenden" %}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="dropdown-item search-btn" style="display: none;">
|
||||
<a href="#" class="search-button" onClick="openSearch()"><span><i class="fa fa-search"></i></span></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -520,6 +531,7 @@
|
|||
<script src="{% static "frontend/js/bootstrap.min4.2.1.js" %}"></script>
|
||||
<script src="{% static "frontend/js/jquery.flexslider.js" %}"></script>
|
||||
<script src="{% static "frontend/js/bootstrap-datepicker.js" %}"></script>
|
||||
<script src="{% static "frontend/js/toastr.min.js" %}"></script>
|
||||
<script src="{% static "frontend/js/owl.carousel.min.js" %}"></script>
|
||||
<script src="{% static "frontend/js/custom-navigation.js" %}"></script>
|
||||
<script src="{% static "frontend/js/custom-flex.js" %}"></script>
|
||||
|
@ -528,6 +540,21 @@
|
|||
<script src="{% static "frontend/js/custom-video.js" %}"></script>
|
||||
<script src="{% static "frontend/js/popup-ad.js" %}"></script>
|
||||
<script src="{% static "frontend/js/autocomplete.js" %}"></script>
|
||||
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
{% if message.tags == 'success'%}
|
||||
<script type=text/javascript>toastr.{{ message.tags }}('{{ message }}')</script>
|
||||
{% elif message.tags == 'info' %}
|
||||
<script type=text/javascript>toastr.{{ message.tags }}('{{ message }}')</script>
|
||||
{% elif message.tags == 'warning' %}
|
||||
<script type=text/javascript>toastr.{{ message.tags }}('{{ message }}')</script>
|
||||
{% elif message.tags == 'error' %}
|
||||
<script type=text/javascript>toastr.{{ message.tags }}('{{ message }}')</script>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% block "scripts" %}
|
||||
{% endblock %}
|
||||
<!-- Page Scripts Ends -->
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% load i18n %}
|
||||
<html>
|
||||
<head>
|
||||
<title>Urlaubsauktion - {% trans "Weiterleitung" %}</title>
|
||||
<title>JourneyJoker - {% trans "Weiterleitung" %}</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>{% trans "Sie werden zu unserem Zahlungsdienstleister weitergeleitet. Wir bitten um einen Augenblick Geduld." %}</p>
|
||||
|
|
24
templates/payment/sepa/apply.html
Normal file
24
templates/payment/sepa/apply.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
{% 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">
|
||||
<div class="payment-success-text">
|
||||
<h2>{% trans "SEPA-Zahlung anwenden" %}</h2>
|
||||
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
<button class="btn btn-orange btn-block">{% trans "Anwenden" %}</button>
|
||||
</div>
|
||||
</div><!-- end columns -->
|
||||
</div><!-- end row -->
|
||||
</div><!-- end container -->
|
||||
</div><!-- end coming-soon-text -->
|
||||
</section><!-- end innerpage-wrapper -->
|
||||
{% endblock %}
|
|
@ -18,8 +18,8 @@ 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')),
|
||||
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"),
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue