mirror of
https://github.com/pretix/pretix.git
synced 2026-05-04 15:04:03 +00:00
Refactor mark_paid out of models
This commit is contained in:
@@ -1,134 +0,0 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
from django.utils.translation import ugettext as _
|
||||
from django import forms
|
||||
|
||||
from pretix.base.models import (
|
||||
User, Organizer, OrganizerPermission, Event, EventPermission,
|
||||
Property, PropertyValue, Item, ItemVariation, ItemCategory
|
||||
)
|
||||
|
||||
|
||||
class PretixUserCreationForm(forms.ModelForm):
|
||||
|
||||
"""
|
||||
A form that creates a user, with no privileges, from the given username and
|
||||
password.
|
||||
"""
|
||||
error_messages = {
|
||||
'password_mismatch': _("The two password fields didn't match."),
|
||||
}
|
||||
password1 = forms.CharField(label=_("Password"),
|
||||
widget=forms.PasswordInput)
|
||||
password2 = forms.CharField(label=_("Password confirmation"),
|
||||
widget=forms.PasswordInput,
|
||||
help_text=_("Enter the same password as above, for verification."))
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ("email", "username", "event")
|
||||
|
||||
def clean_password2(self):
|
||||
password1 = self.cleaned_data.get("password1")
|
||||
password2 = self.cleaned_data.get("password2")
|
||||
if password1 and password2 and password1 != password2:
|
||||
raise forms.ValidationError(
|
||||
self.error_messages['password_mismatch'],
|
||||
code='password_mismatch',
|
||||
)
|
||||
return password2
|
||||
|
||||
def save(self, commit=True):
|
||||
user = super(PretixUserCreationForm, self).save(commit=False)
|
||||
user.set_password(self.cleaned_data["password1"])
|
||||
if commit:
|
||||
user.save()
|
||||
return user
|
||||
|
||||
|
||||
class PretixUserAdmin(UserAdmin):
|
||||
|
||||
fieldsets = (
|
||||
(None, {'fields': ('identifier', 'event', 'username', 'password')}),
|
||||
(_('Personal info'), {'fields': ('familyname', 'givenname', 'email')}),
|
||||
(_('Locale'), {'fields': ('locale', 'timezone')}),
|
||||
(_('Permissions'), {'fields': ('is_active', 'is_staff',
|
||||
'groups', 'user_permissions')}),
|
||||
)
|
||||
list_display = ('identifier', 'event', 'username', 'email', 'givenname', 'familyname', 'is_staff')
|
||||
search_fields = ('identifier', 'username', 'givenname', 'familyname', 'email')
|
||||
ordering = ('identifier',)
|
||||
list_filter = ('is_staff', 'is_active', 'groups')
|
||||
add_form = PretixUserCreationForm
|
||||
|
||||
|
||||
class OrganizerPermissionInline(admin.TabularInline):
|
||||
|
||||
model = OrganizerPermission
|
||||
extra = 2
|
||||
|
||||
|
||||
class OrganizerAdmin(admin.ModelAdmin):
|
||||
|
||||
model = Organizer
|
||||
inlines = [OrganizerPermissionInline]
|
||||
list_display = ('name', 'slug')
|
||||
search_fields = ('name', 'slug')
|
||||
|
||||
|
||||
class EventPermissionInline(admin.TabularInline):
|
||||
|
||||
model = EventPermission
|
||||
extra = 2
|
||||
|
||||
|
||||
class EventAdmin(admin.ModelAdmin):
|
||||
|
||||
model = Event
|
||||
inlines = [EventPermissionInline]
|
||||
list_display = ('name', 'slug', 'organizer', 'date_from')
|
||||
search_fields = ('name', 'slug')
|
||||
list_filter = ('date_from', 'currency')
|
||||
|
||||
|
||||
class PropertyValueInline(admin.StackedInline):
|
||||
|
||||
model = PropertyValue
|
||||
extra = 4
|
||||
|
||||
|
||||
class PropertyAdmin(admin.ModelAdmin):
|
||||
|
||||
model = Property
|
||||
inlines = [PropertyValueInline]
|
||||
list_display = ('name', 'event')
|
||||
search_fields = ('name', 'event')
|
||||
|
||||
|
||||
class ItemCategoryAdmin(admin.ModelAdmin):
|
||||
|
||||
model = ItemCategory
|
||||
list_display = ('name', 'event')
|
||||
search_fields = ('name', 'event')
|
||||
|
||||
|
||||
class ItemVariationInline(admin.TabularInline):
|
||||
|
||||
model = ItemVariation
|
||||
extra = 4
|
||||
|
||||
|
||||
class ItemAdmin(admin.ModelAdmin):
|
||||
|
||||
model = Item
|
||||
inlines = [ItemVariationInline]
|
||||
list_display = ('name', 'event', 'category')
|
||||
search_fields = ('name', 'event', 'category', 'short_description')
|
||||
|
||||
|
||||
admin.site.register(User, PretixUserAdmin)
|
||||
admin.site.register(Organizer, OrganizerAdmin)
|
||||
admin.site.register(Event, EventAdmin)
|
||||
admin.site.register(Property, PropertyAdmin)
|
||||
admin.site.register(Item, ItemAdmin)
|
||||
admin.site.register(ItemCategory, ItemCategoryAdmin)
|
||||
@@ -5,7 +5,6 @@ import uuid
|
||||
import random
|
||||
import time
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
|
||||
@@ -1660,58 +1659,6 @@ class Order(Versionable):
|
||||
quota.release()
|
||||
return True, quotas_locked
|
||||
|
||||
def mark_paid(self, provider=None, info=None, date=None, manual=None, force=False):
|
||||
"""
|
||||
Mark this order as paid. This clones the order object, sets the payment provider,
|
||||
info and date and returns the cloned order object.
|
||||
|
||||
:param provider: The payment provider that marked this as paid
|
||||
:type provider: str
|
||||
:param info: The information to store in order.payment_info
|
||||
:type info: str
|
||||
:param date: The date the payment was received (if you pass ``None``, the current
|
||||
time will be used).
|
||||
:type date: datetime
|
||||
:param force: Whether this payment should be marked as paid even if no remaining
|
||||
quota is available (default: ``False``).
|
||||
:type force: boolean
|
||||
:raises Quota.QuotaExceededException: if the quota is exceeded and ``force`` is ``False``
|
||||
"""
|
||||
can_be_paid, quotas_locked = self._can_be_paid(keep_locked=True)
|
||||
if not force and can_be_paid is not True:
|
||||
raise Quota.QuotaExceededException(can_be_paid)
|
||||
order = self.clone()
|
||||
order.payment_provider = provider or order.payment_provider
|
||||
order.payment_info = info or order.payment_info
|
||||
order.payment_date = date or now()
|
||||
if manual is not None:
|
||||
order.payment_manual = manual
|
||||
order.status = Order.STATUS_PAID
|
||||
order.save()
|
||||
|
||||
if quotas_locked:
|
||||
for quota in quotas_locked:
|
||||
quota.release()
|
||||
|
||||
from pretix.base.mail import mail
|
||||
mail(
|
||||
order.user, _('Payment received for your order: %(code)s') % {'code': order.code},
|
||||
'pretixpresale/email/order_paid.txt',
|
||||
{
|
||||
'user': order.user,
|
||||
'order': order,
|
||||
'event': order.event,
|
||||
'url': settings.SITE_URL + reverse('presale:event.order', kwargs={
|
||||
'event': order.event.slug,
|
||||
'organizer': order.event.organizer.slug,
|
||||
'order': order.code
|
||||
}),
|
||||
'downloads': order.event.settings.get('ticket_download', as_type=bool)
|
||||
},
|
||||
order.event
|
||||
)
|
||||
return order
|
||||
|
||||
|
||||
class QuestionAnswer(Versionable):
|
||||
"""
|
||||
|
||||
@@ -244,11 +244,11 @@ class BasePaymentProvider:
|
||||
containing an URL the user will be redirected to. If you are done with your process
|
||||
you should return the user to the order's detail page.
|
||||
|
||||
If the payment is completed, you should call ``order.mark_paid(provider, info)``
|
||||
If the payment is completed, you should call ``pretix.bsae.services.orders.mark_order_paid(order, provider, info)``
|
||||
with ``provider`` being your :py:attr:`identifier` and ``info`` being any string
|
||||
you might want to store for later usage. Please note, that if you want to store
|
||||
something inside ``order.payment_info``, please do it after the ``mark_paid`` call,
|
||||
as this call does a object clone for you. Please also note that ``mark_paid`` might
|
||||
something inside ``order.payment_info``, please do it after the ``mark_order_paid`` call,
|
||||
as this call does a object clone for you. Please also note that ``mark_order_paid`` might
|
||||
raise a ``Quota.QuotaExceededException`` if (and only if) the payment term of this
|
||||
order is over and some of the items are sold out. You should use the exception message
|
||||
to display a meaningful error to the user.
|
||||
|
||||
58
src/pretix/base/services/orders.py
Normal file
58
src/pretix/base/services/orders.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.timezone import now
|
||||
from pretix.base.models import Order, Quota
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
def mark_order_paid(order, provider=None, info=None, date=None, manual=None, force=False):
|
||||
"""
|
||||
Marks an order as paid. This clones the order object, sets the payment provider,
|
||||
info and date and returns the cloned order object.
|
||||
|
||||
:param provider: The payment provider that marked this as paid
|
||||
:type provider: str
|
||||
:param info: The information to store in order.payment_info
|
||||
:type info: str
|
||||
:param date: The date the payment was received (if you pass ``None``, the current
|
||||
time will be used).
|
||||
:type date: datetime
|
||||
:param force: Whether this payment should be marked as paid even if no remaining
|
||||
quota is available (default: ``False``).
|
||||
:type force: boolean
|
||||
:raises Quota.QuotaExceededException: if the quota is exceeded and ``force`` is ``False``
|
||||
"""
|
||||
can_be_paid, quotas_locked = order._can_be_paid(keep_locked=True)
|
||||
if not force and can_be_paid is not True:
|
||||
raise Quota.QuotaExceededException(can_be_paid)
|
||||
order = order.clone()
|
||||
order.payment_provider = provider or order.payment_provider
|
||||
order.payment_info = info or order.payment_info
|
||||
order.payment_date = date or now()
|
||||
if manual is not None:
|
||||
order.payment_manual = manual
|
||||
order.status = Order.STATUS_PAID
|
||||
order.save()
|
||||
|
||||
if quotas_locked:
|
||||
for quota in quotas_locked:
|
||||
quota.release()
|
||||
|
||||
from pretix.base.mail import mail
|
||||
mail(
|
||||
order.user, _('Payment received for your order: %(code)s') % {'code': order.code},
|
||||
'pretixpresale/email/order_paid.txt',
|
||||
{
|
||||
'user': order.user,
|
||||
'order': order,
|
||||
'event': order.event,
|
||||
'url': settings.SITE_URL + reverse('presale:event.order', kwargs={
|
||||
'event': order.event.slug,
|
||||
'organizer': order.event.organizer.slug,
|
||||
'order': order.code
|
||||
}),
|
||||
'downloads': order.event.settings.get('ticket_download', as_type=bool)
|
||||
},
|
||||
order.event
|
||||
)
|
||||
return order
|
||||
Reference in New Issue
Block a user