forked from CGM_Public/pretix_original
Mark order as paid immediately
This commit is contained in:
@@ -1159,7 +1159,7 @@ class OrderPayment(models.Model):
|
|||||||
self.order.log_action('pretix.event.order.overpaid', {}, user=user, auth=auth)
|
self.order.log_action('pretix.event.order.overpaid', {}, user=user, auth=auth)
|
||||||
order_paid.send(self.order.event, order=self.order)
|
order_paid.send(self.order.event, order=self.order)
|
||||||
|
|
||||||
def confirm(self, count_waitinglist=True, send_mail=True, force=False, user=None, auth=None, mail_text=''):
|
def confirm(self, count_waitinglist=True, send_mail=True, force=False, user=None, auth=None, mail_text='', lock=True):
|
||||||
"""
|
"""
|
||||||
Marks the payment as complete. If possible, this also marks the order as paid if no further
|
Marks the payment as complete. If possible, this also marks the order as paid if no further
|
||||||
payment is required
|
payment is required
|
||||||
@@ -1218,7 +1218,7 @@ class OrderPayment(models.Model):
|
|||||||
if payment_sum - refund_sum < self.order.total:
|
if payment_sum - refund_sum < self.order.total:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.order.status == Order.STATUS_PENDING and self.order.expires > now() + timedelta(hours=12):
|
if (self.order.status == Order.STATUS_PENDING and self.order.expires > now() + timedelta(hours=12)) or not lock:
|
||||||
# Performance optimization. In this case, there's really no reason to lock everything and an atomic
|
# Performance optimization. In this case, there's really no reason to lock everything and an atomic
|
||||||
# database transaction is more than enough.
|
# database transaction is more than enough.
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
|
|||||||
@@ -567,6 +567,7 @@ def _create_order(event: Event, email: str, positions: List[CartPosition], now_d
|
|||||||
meta_info: dict=None, sales_channel: str='web'):
|
meta_info: dict=None, sales_channel: str='web'):
|
||||||
fees, pf = _get_fees(positions, payment_provider, address, meta_info, event)
|
fees, pf = _get_fees(positions, payment_provider, address, meta_info, event)
|
||||||
total = sum([c.price for c in positions]) + sum([c.value for c in fees])
|
total = sum([c.price for c in positions]) + sum([c.value for c in fees])
|
||||||
|
p = None
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
order = Order(
|
order = Order(
|
||||||
@@ -600,7 +601,7 @@ def _create_order(event: Event, email: str, positions: List[CartPosition], now_d
|
|||||||
fee.save()
|
fee.save()
|
||||||
|
|
||||||
if payment_provider and not order.require_approval:
|
if payment_provider and not order.require_approval:
|
||||||
order.payments.create(
|
p = order.payments.create(
|
||||||
state=OrderPayment.PAYMENT_STATE_CREATED,
|
state=OrderPayment.PAYMENT_STATE_CREATED,
|
||||||
provider=payment_provider.identifier,
|
provider=payment_provider.identifier,
|
||||||
amount=total,
|
amount=total,
|
||||||
@@ -616,7 +617,7 @@ def _create_order(event: Event, email: str, positions: List[CartPosition], now_d
|
|||||||
order.log_action('pretix.event.order.consent', data={'msg': msg})
|
order.log_action('pretix.event.order.consent', data={'msg': msg})
|
||||||
|
|
||||||
order_placed.send(event, order=order)
|
order_placed.send(event, order=order)
|
||||||
return order
|
return order, p
|
||||||
|
|
||||||
|
|
||||||
def _perform_order(event: str, payment_provider: str, position_ids: List[str],
|
def _perform_order(event: str, payment_provider: str, position_ids: List[str],
|
||||||
@@ -648,8 +649,12 @@ def _perform_order(event: str, payment_provider: str, position_ids: List[str],
|
|||||||
if len(position_ids) != len(positions):
|
if len(position_ids) != len(positions):
|
||||||
raise OrderError(error_messages['internal'])
|
raise OrderError(error_messages['internal'])
|
||||||
_check_positions(event, now_dt, positions, address=addr)
|
_check_positions(event, now_dt, positions, address=addr)
|
||||||
order = _create_order(event, email, positions, now_dt, pprov,
|
order, payment = _create_order(event, email, positions, now_dt, pprov,
|
||||||
locale=locale, address=addr, meta_info=meta_info, sales_channel=sales_channel)
|
locale=locale, address=addr, meta_info=meta_info, sales_channel=sales_channel)
|
||||||
|
|
||||||
|
free_order_flow = payment and payment_provider == 'free' and order.total == Decimal('0.00')
|
||||||
|
if free_order_flow:
|
||||||
|
payment.confirm(send_mail=False, lock=False)
|
||||||
|
|
||||||
invoice = order.invoices.last() # Might be generated by plugin already
|
invoice = order.invoices.last() # Might be generated by plugin already
|
||||||
if event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
|
if event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
|
||||||
@@ -664,7 +669,7 @@ def _perform_order(event: str, payment_provider: str, position_ids: List[str],
|
|||||||
if order.require_approval:
|
if order.require_approval:
|
||||||
email_template = event.settings.mail_text_order_placed_require_approval
|
email_template = event.settings.mail_text_order_placed_require_approval
|
||||||
log_entry = 'pretix.event.order.email.order_placed_require_approval'
|
log_entry = 'pretix.event.order.email.order_placed_require_approval'
|
||||||
elif payment_provider == 'free':
|
elif free_order_flow:
|
||||||
email_template = event.settings.mail_text_order_free
|
email_template = event.settings.mail_text_order_free
|
||||||
log_entry = 'pretix.event.order.email.order_free'
|
log_entry = 'pretix.event.order.email.order_free'
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from django.utils.translation import (
|
|||||||
from django.views.generic.base import TemplateResponseMixin
|
from django.views.generic.base import TemplateResponseMixin
|
||||||
|
|
||||||
from pretix.base.models import Order
|
from pretix.base.models import Order
|
||||||
from pretix.base.models.orders import InvoiceAddress
|
from pretix.base.models.orders import InvoiceAddress, OrderPayment
|
||||||
from pretix.base.services.cart import (
|
from pretix.base.services.cart import (
|
||||||
get_fees, set_cart_addons, update_tax_rates,
|
get_fees, set_cart_addons, update_tax_rates,
|
||||||
)
|
)
|
||||||
@@ -721,7 +721,7 @@ class ConfirmStep(CartMixin, AsyncAction, TemplateFlowStep):
|
|||||||
return self.get_step_url(self.request)
|
return self.get_step_url(self.request)
|
||||||
|
|
||||||
def get_order_url(self, order):
|
def get_order_url(self, order):
|
||||||
payment = order.payments.first()
|
payment = order.payments.filter(state__in=[OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING]).first()
|
||||||
if not payment:
|
if not payment:
|
||||||
return eventreverse(self.request.event, 'presale:event.order', kwargs={
|
return eventreverse(self.request.event, 'presale:event.order', kwargs={
|
||||||
'order': order.code,
|
'order': order.code,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ def test_expiry_days(event):
|
|||||||
event.settings.set('payment_term_weekdays', False)
|
event.settings.set('payment_term_weekdays', False)
|
||||||
order = _create_order(event, email='dummy@example.org', positions=[],
|
order = _create_order(event, email='dummy@example.org', positions=[],
|
||||||
now_dt=today, payment_provider=FreeOrderProvider(event),
|
now_dt=today, payment_provider=FreeOrderProvider(event),
|
||||||
locale='de')
|
locale='de')[0]
|
||||||
assert (order.expires - today).days == 5
|
assert (order.expires - today).days == 5
|
||||||
|
|
||||||
|
|
||||||
@@ -52,14 +52,14 @@ def test_expiry_weekdays(event):
|
|||||||
event.settings.set('payment_term_weekdays', True)
|
event.settings.set('payment_term_weekdays', True)
|
||||||
order = _create_order(event, email='dummy@example.org', positions=[],
|
order = _create_order(event, email='dummy@example.org', positions=[],
|
||||||
now_dt=today, payment_provider=FreeOrderProvider(event),
|
now_dt=today, payment_provider=FreeOrderProvider(event),
|
||||||
locale='de')
|
locale='de')[0]
|
||||||
assert (order.expires - today).days == 6
|
assert (order.expires - today).days == 6
|
||||||
assert order.expires.weekday() == 0
|
assert order.expires.weekday() == 0
|
||||||
|
|
||||||
today = make_aware(datetime(2016, 9, 19, 15, 0, 0, 0))
|
today = make_aware(datetime(2016, 9, 19, 15, 0, 0, 0))
|
||||||
order = _create_order(event, email='dummy@example.org', positions=[],
|
order = _create_order(event, email='dummy@example.org', positions=[],
|
||||||
now_dt=today, payment_provider=FreeOrderProvider(event),
|
now_dt=today, payment_provider=FreeOrderProvider(event),
|
||||||
locale='de')
|
locale='de')[0]
|
||||||
assert (order.expires - today).days == 7
|
assert (order.expires - today).days == 7
|
||||||
assert order.expires.weekday() == 0
|
assert order.expires.weekday() == 0
|
||||||
|
|
||||||
@@ -72,12 +72,12 @@ def test_expiry_last(event):
|
|||||||
event.settings.set('payment_term_last', now() + timedelta(days=3))
|
event.settings.set('payment_term_last', now() + timedelta(days=3))
|
||||||
order = _create_order(event, email='dummy@example.org', positions=[],
|
order = _create_order(event, email='dummy@example.org', positions=[],
|
||||||
now_dt=today, payment_provider=FreeOrderProvider(event),
|
now_dt=today, payment_provider=FreeOrderProvider(event),
|
||||||
locale='de')
|
locale='de')[0]
|
||||||
assert (order.expires - today).days == 3
|
assert (order.expires - today).days == 3
|
||||||
event.settings.set('payment_term_last', now() + timedelta(days=7))
|
event.settings.set('payment_term_last', now() + timedelta(days=7))
|
||||||
order = _create_order(event, email='dummy@example.org', positions=[],
|
order = _create_order(event, email='dummy@example.org', positions=[],
|
||||||
now_dt=today, payment_provider=FreeOrderProvider(event),
|
now_dt=today, payment_provider=FreeOrderProvider(event),
|
||||||
locale='de')
|
locale='de')[0]
|
||||||
assert (order.expires - today).days == 5
|
assert (order.expires - today).days == 5
|
||||||
|
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ def test_expiry_last_relative(event):
|
|||||||
))
|
))
|
||||||
order = _create_order(event, email='dummy@example.org', positions=[],
|
order = _create_order(event, email='dummy@example.org', positions=[],
|
||||||
now_dt=today, payment_provider=FreeOrderProvider(event),
|
now_dt=today, payment_provider=FreeOrderProvider(event),
|
||||||
locale='de')
|
locale='de')[0]
|
||||||
assert (order.expires - today).days == 3
|
assert (order.expires - today).days == 3
|
||||||
|
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ def test_expiry_last_relative_subevents(event):
|
|||||||
))
|
))
|
||||||
order = _create_order(event, email='dummy@example.org', positions=[cp1, cp2],
|
order = _create_order(event, email='dummy@example.org', positions=[cp1, cp2],
|
||||||
now_dt=today, payment_provider=FreeOrderProvider(event),
|
now_dt=today, payment_provider=FreeOrderProvider(event),
|
||||||
locale='de')
|
locale='de')[0]
|
||||||
assert (order.expires - today).days == 6
|
assert (order.expires - today).days == 6
|
||||||
|
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ def test_expiry_dst(event):
|
|||||||
today = tz.localize(datetime(2016, 10, 29, 12, 0, 0)).astimezone(utc)
|
today = tz.localize(datetime(2016, 10, 29, 12, 0, 0)).astimezone(utc)
|
||||||
order = _create_order(event, email='dummy@example.org', positions=[],
|
order = _create_order(event, email='dummy@example.org', positions=[],
|
||||||
now_dt=today, payment_provider=FreeOrderProvider(event),
|
now_dt=today, payment_provider=FreeOrderProvider(event),
|
||||||
locale='de')
|
locale='de')[0]
|
||||||
localex = order.expires.astimezone(tz)
|
localex = order.expires.astimezone(tz)
|
||||||
assert (localex.hour, localex.minute) == (23, 59)
|
assert (localex.hour, localex.minute) == (23, 59)
|
||||||
|
|
||||||
|
|||||||
@@ -907,6 +907,24 @@ class CheckoutTestCase(BaseCheckoutTestCase, TestCase):
|
|||||||
self.assertEqual(OrderPosition.objects.count(), 1)
|
self.assertEqual(OrderPosition.objects.count(), 1)
|
||||||
self.assertEqual(OrderPosition.objects.first().price, 42)
|
self.assertEqual(OrderPosition.objects.first().price, 42)
|
||||||
|
|
||||||
|
def test_free_order(self):
|
||||||
|
self.ticket.free_price = True
|
||||||
|
self.ticket.save()
|
||||||
|
cr1 = CartPosition.objects.create(
|
||||||
|
event=self.event, cart_id=self.session_key, item=self.ticket,
|
||||||
|
price=0, expires=now() + timedelta(minutes=10)
|
||||||
|
)
|
||||||
|
self._set_session('payment', 'free')
|
||||||
|
|
||||||
|
response = self.client.post('/%s/%s/checkout/confirm/' % (self.orga.slug, self.event.slug), follow=True)
|
||||||
|
doc = BeautifulSoup(response.rendered_content, "lxml")
|
||||||
|
self.assertEqual(len(doc.select(".thank-you")), 1)
|
||||||
|
self.assertFalse(CartPosition.objects.filter(id=cr1.id).exists())
|
||||||
|
self.assertEqual(Order.objects.count(), 1)
|
||||||
|
self.assertEqual(OrderPosition.objects.count(), 1)
|
||||||
|
self.assertEqual(OrderPosition.objects.first().price, 0)
|
||||||
|
self.assertEqual(Order.objects.first().status, Order.STATUS_PAID)
|
||||||
|
|
||||||
def test_confirm_in_time(self):
|
def test_confirm_in_time(self):
|
||||||
cr1 = CartPosition.objects.create(
|
cr1 = CartPosition.objects.create(
|
||||||
event=self.event, cart_id=self.session_key, item=self.ticket,
|
event=self.event, cart_id=self.session_key, item=self.ticket,
|
||||||
@@ -920,6 +938,7 @@ class CheckoutTestCase(BaseCheckoutTestCase, TestCase):
|
|||||||
self.assertFalse(CartPosition.objects.filter(id=cr1.id).exists())
|
self.assertFalse(CartPosition.objects.filter(id=cr1.id).exists())
|
||||||
self.assertEqual(Order.objects.count(), 1)
|
self.assertEqual(Order.objects.count(), 1)
|
||||||
self.assertEqual(OrderPosition.objects.count(), 1)
|
self.assertEqual(OrderPosition.objects.count(), 1)
|
||||||
|
self.assertEqual(Order.objects.first().status, Order.STATUS_PENDING)
|
||||||
|
|
||||||
def test_subevent_confirm_expired_available(self):
|
def test_subevent_confirm_expired_available(self):
|
||||||
self.event.has_subevents = True
|
self.event.has_subevents = True
|
||||||
|
|||||||
Reference in New Issue
Block a user