def test_create_existing_booking_txn_with_txn_id(self): """ if the existing transaction is already associated with a paypal transaction_id, we do need to create a new transaction, with new invoice number with incremented counter """ user = mommy.make_recipe('flex_bookings.user', username="******") booking = mommy.make_recipe( 'flex_bookings.booking', user=user, event__name='test event' ) booking_txn = helpers.create_booking_paypal_transaction(user, booking) self.assertEqual(booking_txn.booking, booking) self.assertEqual( booking_txn.invoice_id, 'testuser-te-{}-inv#001'.format( booking.event.date.strftime("%d%m%y%H%M") ) ) self.assertEqual(PaypalBookingTransaction.objects.count(), 1) booking_txn.transaction_id = "123" booking_txn.save() new_booking_txn = helpers.create_booking_paypal_transaction(user, booking) self.assertEqual(PaypalBookingTransaction.objects.count(), 2) self.assertEqual( new_booking_txn.invoice_id, 'testuser-te-{}-inv#002'.format( booking.event.date.strftime("%d%m%y%H%M") ) )
def test_create_booking_with_duplicate_invoice_number(self): user = mommy.make_recipe('booking.user', username="******") booking = mommy.make_recipe('booking.booking', user=user, event__name='test event', event__date=datetime(2015, 2, 1, 10, 0, tzinfo=timezone.utc)) booking1 = mommy.make_recipe('booking.booking', user=user, event__name='test event1', event__date=datetime(2015, 2, 1, 10, 0, tzinfo=timezone.utc)) booking_txn = helpers.create_booking_paypal_transaction(user, booking) self.assertEqual(booking_txn.booking, booking) self.assertEqual( booking_txn.invoice_id, 'testuser-te-{}-inv#001'.format( booking.event.date.strftime("%d%m%y%H%M"))) booking1_txn = helpers.create_booking_paypal_transaction( user, booking1) self.assertEqual(booking1_txn.booking, booking1) self.assertNotEqual( booking1_txn.invoice_id, 'testuser-te-{}-inv#001'.format( booking1.event.date.strftime("%d%m%y%H%M"))) # to avoid duplication, the counter is set to 6 digits, the first 3 # random between 100 and 999 self.assertEqual(len(booking1_txn.invoice_id.split('#')[-1]), 6)
def test_paypal_notify_url_with_more_than_one_booking_trans_object_no_invoice( self, mock_postback ): mock_postback.return_value = b"VERIFIED" booking = mommy.make_recipe('flex_bookings.booking', paid=False) self.assertFalse(PayPalIPN.objects.exists()) self.assertFalse(PaypalBookingTransaction.objects.exists()) pptn = helpers.create_booking_paypal_transaction(booking.user, booking) pptn.invoice_id = 'invoice_1' pptn.save() pptn1 = helpers.create_booking_paypal_transaction(booking.user, booking) pptn1.invoice_id = 'invoice_2' pptn1.save() # if paypal ipn doesn't contain invoice number params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b'' } ) self.paypal_post(params) pptn1.refresh_from_db() self.assertEqual(b(pptn1.transaction_id), IPN_POST_PARAMS['txn_id']) booking.refresh_from_db() self.assertTrue(booking.paid) # 3 emails sent, to user and studio, and support b/c no invoice id self.assertEqual(len(mail.outbox), 3)
def test_create_booking_with_duplicate_invoice_number(self): user = mommy.make_recipe('flex_bookings.user', username="******") booking = mommy.make_recipe( 'flex_bookings.booking', user=user, event__name='test event', event__date=datetime(2015, 2, 1, 10, 0, tzinfo=timezone.utc) ) booking1 = mommy.make_recipe( 'flex_bookings.booking', user=user, event__name='test event1', event__date=datetime(2015, 2, 1, 10, 0, tzinfo=timezone.utc) ) booking_txn = helpers.create_booking_paypal_transaction(user, booking) self.assertEqual(booking_txn.booking, booking) self.assertEqual( booking_txn.invoice_id, 'testuser-te-{}-inv#001'.format( booking.event.date.strftime("%d%m%y%H%M") ) ) booking1_txn = helpers.create_booking_paypal_transaction(user, booking1) self.assertEqual(booking1_txn.booking, booking1) self.assertNotEqual( booking1_txn.invoice_id, 'testuser-te-{}-inv#001'.format( booking1.event.date.strftime("%d%m%y%H%M") ) ) # to avoid duplication, the counter is set to 6 digits, the first 3 # random between 100 and 999 self.assertEqual(len(booking1_txn.invoice_id.split('#')[-1]), 6)
def test_create_existing_booking_transaction(self): user = mommy.make_recipe("flex_bookings.user", username="******") booking = mommy.make_recipe("flex_bookings.booking", user=user, event__name="test event") booking_txn = helpers.create_booking_paypal_transaction(user, booking) self.assertEqual(booking_txn.booking, booking) self.assertEqual( booking_txn.invoice_id, "testuser-te-{}-inv#001".format(booking.event.date.strftime("%d%m%y%H%M")) ) self.assertEqual(PaypalBookingTransaction.objects.count(), 1) dp_booking_txn = helpers.create_booking_paypal_transaction(user, booking) self.assertEqual(PaypalBookingTransaction.objects.count(), 1) self.assertEqual(booking_txn, dp_booking_txn)
def test_paypal_notify_url_with_complete_status_no_invoice_number(self, mock_postback): mock_postback.return_value = b"VERIFIED" booking = mommy.make_recipe('flex_bookings.booking', payment_confirmed=False, paid=False) invoice_id = helpers.create_booking_paypal_transaction( booking.user, booking ).invoice_id self.assertFalse(PayPalIPN.objects.exists()) params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b'' } ) resp = self.paypal_post(params) booking.refresh_from_db() self.assertTrue(booking.payment_confirmed) self.assertTrue(booking.paid) # 3 emails sent - studio, user, support to notify about missing inv self.assertEqual(len(mail.outbox), 3) self.assertEqual( mail.outbox[2].subject, '{} No invoice number on paypal ipn for booking id {}'.format( settings.ACCOUNT_EMAIL_SUBJECT_PREFIX, booking.id ) )
def test_paypal_booking_admin_display(self): user = mommy.make_recipe( 'flex_bookings.user', first_name='Test', last_name='User') booking = mommy.make_recipe('flex_bookings.booking', user=user) pptrans = helpers.create_booking_paypal_transaction( booking.user, booking ) ppbooking_admin = PaypalBookingTransactionAdmin( PaypalBookingTransaction, AdminSite() ) ppbooking_query = ppbooking_admin.get_queryset(None)[0] self.assertEqual( ppbooking_admin.get_booking_id(ppbooking_query), booking.id ) self.assertEqual( ppbooking_admin.get_user(ppbooking_query), 'Test User' ) self.assertEqual( ppbooking_admin.get_event(ppbooking_query), booking.event ) self.assertEqual( ppbooking_admin.cost(ppbooking_query), u"\u00A3{}.00".format(booking.event.cost) )
def test_paypal_notify_only_updates_relevant_booking(self, mock_postback): mock_postback.return_value = b"VERIFIED" user = mommy.make_recipe('flex_bookings.user') booking = mommy.make_recipe('flex_bookings.booking', paid=False) mommy.make_recipe('flex_bookings.booking', paid=False, _quantity=5) invoice_id = helpers.create_booking_paypal_transaction( booking.user, booking ).invoice_id self.assertFalse(PayPalIPN.objects.exists()) params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b(invoice_id) } ) resp = self.paypal_post(params) self.assertEqual(resp.status_code, 200) self.assertEqual(PayPalIPN.objects.count(), 1) ppipn = PayPalIPN.objects.first() self.assertFalse(ppipn.flag) self.assertEqual(ppipn.flag_info, '') booking.refresh_from_db() self.assertTrue(booking.paid) # 2 emails sent, to user and studio self.assertEqual(len(mail.outbox), 2) for bkg in Booking.objects.all(): if bkg.id == booking.id: self.assertTrue(bkg.paid) else: self.assertFalse(bkg.paid)
def test_paypal_notify_url_with_refunded_status(self, mock_postback): """ when a paypal payment is refunded, it looks like it posts back to the notify url again (since the PayPalIPN is updated). Test that we can identify and process refunded payments. """ mock_postback.return_value = b"VERIFIED" booking = mommy.make_recipe('flex_bookings.booking', payment_confirmed=True, paid=True) pptrans = helpers.create_booking_paypal_transaction( booking.user, booking ) pptrans.transaction_id = "test_trans_id" pptrans.save() self.assertFalse(PayPalIPN.objects.exists()) params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b(pptrans.invoice_id), 'payment_status': b'Refunded' } ) self.paypal_post(params) booking.refresh_from_db() self.assertFalse(booking.payment_confirmed) self.assertFalse(booking.paid)
def test_create_existing_booking_transaction(self): user = mommy.make_recipe('booking.user', username="******") booking = mommy.make_recipe('booking.booking', user=user, event__name='test event') booking_txn = helpers.create_booking_paypal_transaction(user, booking) self.assertEqual(booking_txn.booking, booking) self.assertEqual( booking_txn.invoice_id, 'testuser-te-{}-inv#001'.format( booking.event.date.strftime("%d%m%y%H%M"))) self.assertEqual(PaypalBookingTransaction.objects.count(), 1) dp_booking_txn = helpers.create_booking_paypal_transaction( user, booking) self.assertEqual(PaypalBookingTransaction.objects.count(), 1) self.assertEqual(booking_txn, dp_booking_txn)
def test_paypal_notify_url_with_complete_status(self, mock_postback): mock_postback.return_value = b"VERIFIED" booking = mommy.make_recipe('flex_bookings.booking') pptrans = helpers.create_booking_paypal_transaction( booking.user, booking ) self.assertFalse(PayPalIPN.objects.exists()) params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b(pptrans.invoice_id), 'txn_id': b'test_txn_id' } ) self.assertIsNone(pptrans.transaction_id) resp = self.paypal_post(params) self.assertEqual(resp.status_code, 200) self.assertEqual(PayPalIPN.objects.count(), 1) ppipn = PayPalIPN.objects.first() self.assertFalse(ppipn.flag) self.assertEqual(ppipn.flag_info, '') # check paypal trans obj is updated pptrans.refresh_from_db() self.assertEqual(pptrans.transaction_id, 'test_txn_id') # 2 emails sent, to user and studio self.assertEqual(len(mail.outbox), 2)
def test_PayPalPaymentsListForm_renders_buy_it_now_button(self): booking = mommy.make_recipe('booking.booking') pptrans = helpers.create_booking_paypal_transaction( booking.user, booking) form = PayPalPaymentsListForm(initial=get_paypal_dict( 'http://example.com', booking.event.cost, booking.event, pptrans.invoice_id, '{} {}'.format('booking', booking.id))) self.assertIn('Buy it Now', form.render())
def test_create_booking_transaction(self): user = mommy.make_recipe('booking.user', username="******") booking = mommy.make_recipe('booking.booking', user=user, event__name='test event') booking_txn = helpers.create_booking_paypal_transaction(user, booking) self.assertEqual(booking_txn.booking, booking) self.assertEqual( booking_txn.invoice_id, 'testuser-te-{}-inv#001'.format( booking.event.date.strftime("%d%m%y%H%M"))) # str returns invoice id self.assertEqual(str(booking_txn), booking_txn.invoice_id)
def test_paypal_notify_url_with_more_than_one_booking_trans_object( self, mock_postback ): """ The PayPalBooking/Block/TicketBookingTransaction object is created and retrieved using the username and event name/date. If the user changes their username between booking and paying, a second Transaction object will be created. In this case, we use the Transaction object that has the invoice number that matches the paypal ipn; if the paypal ipn has no invoice associated, we use the latest one. """ mock_postback.return_value = b"VERIFIED" booking = mommy.make_recipe('flex_bookings.booking', paid=False) self.assertFalse(PayPalIPN.objects.exists()) self.assertFalse(PaypalBookingTransaction.objects.exists()) pptn = helpers.create_booking_paypal_transaction(booking.user, booking) pptn.invoice_id = 'invoice_1' pptn.save() pptn1 = helpers.create_booking_paypal_transaction(booking.user, booking) pptn1.invoice_id = 'invoice_2' pptn1.save() params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b'invoice_1' } ) self.paypal_post(params) pptn.refresh_from_db() self.assertEqual(b(pptn.transaction_id), IPN_POST_PARAMS['txn_id']) booking.refresh_from_db() self.assertTrue(booking.paid) # 2 emails sent, to user and studio self.assertEqual(len(mail.outbox), 2)
def test_PayPalPaymentsUpdateForm_renders_buy_it_now_button(self): booking = mommy.make_recipe('flex_bookings.booking') pptrans = helpers.create_booking_paypal_transaction( booking.user, booking ) form = PayPalPaymentsUpdateForm( initial=get_paypal_dict( 'http://example.com', booking.event.cost, booking.event, pptrans.invoice_id, '{} {}'.format('booking', booking.id) ) ) self.assertIn('Buy it Now', form.render())
def test_create_existing_booking_txn_with_txn_id(self): """ if the existing transaction is already associated with a paypal transaction_id, we do need to create a new transaction, with new invoice number with incremented counter """ user = mommy.make_recipe('booking.user', username="******") booking = mommy.make_recipe('booking.booking', user=user, event__name='test event') booking_txn = helpers.create_booking_paypal_transaction(user, booking) self.assertEqual(booking_txn.booking, booking) self.assertEqual( booking_txn.invoice_id, 'testuser-te-{}-inv#001'.format( booking.event.date.strftime("%d%m%y%H%M"))) self.assertEqual(PaypalBookingTransaction.objects.count(), 1) booking_txn.transaction_id = "123" booking_txn.save() new_booking_txn = helpers.create_booking_paypal_transaction( user, booking) self.assertEqual(PaypalBookingTransaction.objects.count(), 2) self.assertEqual( new_booking_txn.invoice_id, 'testuser-te-{}-inv#002'.format( booking.event.date.strftime("%d%m%y%H%M")))
def test_create_booking_transaction(self): user = mommy.make_recipe('flex_bookings.user', username="******") booking = mommy.make_recipe( 'flex_bookings.booking', user=user, event__name='test event' ) booking_txn = helpers.create_booking_paypal_transaction(user, booking) self.assertEqual(booking_txn.booking, booking) self.assertEqual( booking_txn.invoice_id, 'testuser-te-{}-inv#001'.format( booking.event.date.strftime("%d%m%y%H%M") ) ) # str returns invoice id self.assertEqual(str(booking_txn), booking_txn.invoice_id)
def get_context_data(self, **kwargs): # Call the base implementation first to get a context context = super(BookingUpdateView, self).get_context_data(**kwargs) invoice_id = create_booking_paypal_transaction( self.request.user, self.object ).invoice_id host = 'http://{}'.format(self.request.META.get('HTTP_HOST')) paypal_cost = self.object.event.cost voucher = kwargs.get('voucher', None) voucher_error = kwargs.get('voucher_error', None) code = kwargs.get('code', None) context['voucher_form'] = VoucherForm(initial={'code': code}) if voucher: valid = not bool(voucher_error) context['valid_voucher'] = valid if valid: paypal_cost = Decimal( float(paypal_cost) * ((100 - voucher.discount) / 100) ).quantize(Decimal('.05')) messages.info(self.request, 'Voucher has been applied') times_used = UsedEventVoucher.objects.filter( voucher=voucher, user=self.request.user ).count() context['times_voucher_used'] = times_used paypal_form = PayPalPaymentsUpdateForm( initial=context_helpers.get_paypal_dict( host, paypal_cost, '{}'.format(self.object.event), invoice_id, '{} {}{}'.format( 'booking', self.object.id, ' {}'.format(voucher.code) if voucher else '' ), paypal_email=self.object.event.paypal_email, ) ) context["paypalform"] = paypal_form context["paypal_cost"] = paypal_cost return context_helpers.get_booking_create_context( self.object.event, self.request, context )
def test_error_sending_emails_payment_received( self, mock_send_emails, mock_postback ): """ We send a warning email with the exception if anything else goes wrong during the payment processing; most likely to be something wrong with sending the emails """ mock_send_emails.side_effect = Exception('Error sending mail') mock_postback.return_value = b"VERIFIED" booking = mommy.make_recipe('flex_bookings.booking') pptrans = helpers.create_booking_paypal_transaction( booking.user, booking ) params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b(pptrans.invoice_id), 'txn_id': 'test_txn_id' } ) resp = self.paypal_post(params) booking.refresh_from_db() ppipn = PayPalIPN.objects.first() self.assertFalse(ppipn.flag) # even if the postback is verified, it is flagged and processed as # invalid self.assertEqual(len(mail.outbox), 1) self.assertEqual( mail.outbox[0].subject, '{} There was some problem processing payment for {} id {}'.format( settings.ACCOUNT_EMAIL_SUBJECT_PREFIX, 'booking', booking.id ), ) self.assertEqual( mail.outbox[0].body, 'Please check your booking and paypal records for invoice # {}, ' 'paypal transaction id test_txn_id.\n\nThe exception ' 'raised was "Error sending mail"'.format(pptrans.invoice_id) )
def test_paypal_booking_admin_display(self): user = mommy.make_recipe('booking.user', first_name='Test', last_name='User') booking = mommy.make_recipe('booking.booking', user=user) pptrans = helpers.create_booking_paypal_transaction( booking.user, booking) ppbooking_admin = admin.PaypalBookingTransactionAdmin( PaypalBookingTransaction, AdminSite()) ppbooking_query = ppbooking_admin.get_queryset(None)[0] self.assertEqual(ppbooking_admin.get_booking_id(ppbooking_query), booking.id) self.assertEqual(ppbooking_admin.get_user(ppbooking_query), 'Test User') self.assertEqual(ppbooking_admin.get_event(ppbooking_query), booking.event) self.assertEqual(ppbooking_admin.cost(ppbooking_query), u"\u00A3{}.00".format(booking.event.cost))
def test_successful_paypal_payment_updates_booking(self, mock_postback): mock_postback.return_value = b"VERIFIED" booking = mommy.make_recipe('flex_bookings.booking', payment_confirmed=False, paid=False) invoice_id = helpers.create_booking_paypal_transaction( booking.user, booking ).invoice_id self.assertFalse(PayPalIPN.objects.exists()) params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b(invoice_id) } ) resp = self.paypal_post(params) booking.refresh_from_db() self.assertTrue(booking.payment_confirmed) self.assertTrue(booking.paid)
def test_payment_received_with_duplicate_txn_flag(self, mock_postback): """ If we get a flagged completed payment, send a warning email. Most likely to happen with a duplicate transaction id """ mock_postback.return_value = b"VERIFIED" booking = mommy.make_recipe('flex_bookings.booking') pptrans = helpers.create_booking_paypal_transaction( booking.user, booking ) # make an existing completed paypal ipn mommy.make(PayPalIPN, txn_id='test_txn_id', payment_status='Completed') self.assertEqual(PayPalIPN.objects.count(), 1) params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b(pptrans.invoice_id), 'txn_id': 'test_txn_id' } ) resp = self.paypal_post(params) booking.refresh_from_db() ppipn = PayPalIPN.objects.all()[0] ppipn1 = PayPalIPN.objects.all()[1] self.assertFalse(ppipn.flag) self.assertTrue(ppipn1.flag) self.assertEqual(ppipn1.flag_info, 'Duplicate txn_id. (test_txn_id)') # even if the postback is verified, it is flagged and processed as # invalid self.assertEqual(len(mail.outbox), 1) self.assertEqual( mail.outbox[0].subject, 'WARNING! Invalid Payment Notification received from PayPal' )
def test_error_sending_emails_payment_not_received(self, mock_send_emails): """ We send a warning email with the exception if anything else goes wrong during the payment processing; most likely to be something wrong with sending the emails, so we need to check the logs """ mock_send_emails.side_effect = Exception('Error sending mail') payment_models_logger.warning = Mock() booking = mommy.make_recipe('flex_bookings.booking') pptrans = helpers.create_booking_paypal_transaction( booking.user, booking ) params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b(pptrans.invoice_id), 'txn_id': 'test_txn_id' } ) with self.assertRaises(Exception): resp = self.paypal_post(params) payment_models_logger.warning.assert_called_with( 'Problem processing payment_not_received for Booking {}; ' 'invoice_id {}, transaction id: test_txn_id. Exception: ' 'Error sending mail'.format(booking.id, pptrans.invoice) ) booking.refresh_from_db() ppipn = PayPalIPN.objects.first() self.assertTrue(ppipn.flag) self.assertEqual(ppipn.flag_info, 'Invalid postback. (INVALID)')
def test_successful_paypal_payment_sends_emails(self, mock_postback): mock_postback.return_value = b"VERIFIED" booking = mommy.make_recipe('flex_bookings.booking') invoice_id = helpers.create_booking_paypal_transaction( booking.user, booking ).invoice_id self.assertFalse(PayPalIPN.objects.exists()) params = dict(IPN_POST_PARAMS) params.update( { 'custom': b('booking {}'.format(booking.id)), 'invoice': b(invoice_id) } ) resp = self.paypal_post(params) self.assertEqual(resp.status_code, 200) self.assertEqual(PayPalIPN.objects.count(), 1) ppipn = PayPalIPN.objects.first() # 2 emails sent, to user and studio self.assertEqual(len(mail.outbox), 2) self.assertEqual(mail.outbox[0].to, [settings.DEFAULT_STUDIO_EMAIL]) self.assertEqual(mail.outbox[1].to, [booking.user.email])
def get_obj(ipn_obj): from payments import helpers additional_data = {} try: custom = ipn_obj.custom.split() obj_type = custom[0] obj_id = int(custom[1]) voucher_code = custom[2] if len(custom) == 3 and \ obj_type != 'test' else None except IndexError: # in case custom not included in paypal response raise PayPalTransactionError('Unknown object type for payment') if obj_type == 'paypal_test': # a test payment for paypal email # custom in a test payment is in form # 'test 0 <invoice_id> <paypal email being tested> <user's email>' obj = None paypal_trans = None additional_data['test_invoice'] = custom[2] additional_data['test_paypal_email'] = custom[3] additional_data['user_email'] = custom[4] elif obj_type == 'booking': try: obj = Booking.objects.get(id=obj_id) except Booking.DoesNotExist: raise PayPalTransactionError( 'Booking with id {} does not exist'.format(obj_id)) paypal_trans = PaypalBookingTransaction.objects.filter(booking=obj) if not paypal_trans: paypal_trans = helpers.create_booking_paypal_transaction( user=obj.user, booking=obj) elif paypal_trans.count() > 1: # we may have two ppb transactions created if user changed their # username between booking and paying (invoice_id is created and # retrieved using username) if ipn_obj.invoice: paypal_trans = PaypalBookingTransaction.objects.get( booking=obj, invoice_id=ipn_obj.invoice) else: paypal_trans = paypal_trans.latest('id') else: # we got one paypaltrans, as we should have paypal_trans = paypal_trans[0] elif obj_type == 'block': try: obj = Block.objects.get(id=obj_id) except Block.DoesNotExist: raise PayPalTransactionError( 'Block with id {} does not exist'.format(obj_id)) paypal_trans = PaypalBlockTransaction.objects.filter(block=obj) if not paypal_trans: paypal_trans = helpers.create_block_paypal_transaction( user=obj.user, block=obj) elif paypal_trans.count() > 1: # we may have two ppb transactions created if user changed their # username between booking block and paying (invoice_id is created and # retrieved using username) if ipn_obj.invoice: paypal_trans = PaypalBlockTransaction.objects.get( block=obj, invoice_id=ipn_obj.invoice) else: paypal_trans = paypal_trans.latest('id') else: # we got one paypaltrans, as we should have paypal_trans = paypal_trans[0] elif obj_type == 'ticket_booking': try: obj = TicketBooking.objects.get(id=obj_id) except TicketBooking.DoesNotExist: raise PayPalTransactionError( 'Ticket Booking with id {} does not exist'.format(obj_id)) paypal_trans = PaypalTicketBookingTransaction.objects.filter( ticket_booking=obj) if not paypal_trans: paypal_trans = helpers.create_ticket_booking_paypal_transaction( user=obj.user, ticket_booking=obj) elif paypal_trans.count() > 1: # we may have two ppb transactions created if user changed their # username between booking and paying (invoice_id is created and # retrieved using username) if ipn_obj.invoice: paypal_trans = PaypalTicketBookingTransaction.objects.get( ticket_booking=obj, invoice_id=ipn_obj.invoice) else: paypal_trans = paypal_trans.latest('id') else: # we got one paypaltrans, as we should have paypal_trans = paypal_trans[0] else: raise PayPalTransactionError('Unknown object type for payment') return { 'obj_type': obj_type, 'obj': obj, 'paypal_trans': paypal_trans, 'voucher_code': voucher_code, 'additional_data': additional_data }
def get_context_data(self, **kwargs): # Call the base implementation first to get a context context = super(BookingListView, self).get_context_data(**kwargs) user_blocks = self.request.user.blocks.all() active_block_event_types = [ block.block_type.event_type for block in user_blocks if block.active_block() ] bookingformlist = [] for booking in self.object_list: if booking.event.event_type not in active_block_event_types \ and booking.status == 'OPEN' and not booking.paid: # ONLY DO THIS IF PAYPAL BUTTON NEEDED invoice_id = create_booking_paypal_transaction( self.request.user, booking).invoice_id host = 'http://{}'.format(self.request.META.get('HTTP_HOST')) paypal_form = PayPalPaymentsListForm( initial=context_helpers.get_paypal_dict( host, booking.event.cost, booking.event, invoice_id, '{} {}'.format('booking', booking.id), paypal_email=booking.event.paypal_email, ) ) else: paypal_form = None try: WaitingListUser.objects.get(user=self.request.user, event=booking.event) on_waiting_list = True except WaitingListUser.DoesNotExist: on_waiting_list = False can_cancel = booking.event.allow_booking_cancellation and \ booking.event.can_cancel() and \ (booking.status == 'OPEN' and not booking.no_show) due_date_time = None if booking.event.advance_payment_required: uk_tz = pytz.timezone('Europe/London') if booking.event.payment_due_date: due_date_time = booking.event.payment_due_date elif booking.event.payment_time_allowed: last_booked = booking.date_rebooked if booking.date_rebooked else booking.date_booked due_date_time = last_booked + timedelta(hours=booking.event.payment_time_allowed) elif booking.event.cancellation_period: due_date_time = booking.event.date - timedelta( hours=booking.event.cancellation_period ) due_date_time = due_date_time.astimezone(uk_tz) bookingform = { 'booking_status': 'CANCELLED' if (booking.status == 'CANCELLED' or booking.no_show) else 'OPEN', 'ev_type': booking.event.event_type.event_type, 'booking': booking, 'paypalform': paypal_form, 'has_available_block': booking.event.event_type in active_block_event_types, 'can_cancel': can_cancel, 'on_waiting_list': on_waiting_list, 'due_date_time': due_date_time, } bookingformlist.append(bookingform) context['bookingformlist'] = bookingformlist return context
def get_obj(ipn_obj): from payments import helpers try: custom = ipn_obj.custom.split() obj_type = custom[0] obj_id = int(custom[-1]) except IndexError: # in case custom not included in paypal response raise PayPalTransactionError('Unknown object type for payment') if obj_type == 'booking': try: obj = Booking.objects.get(id=obj_id) except Booking.DoesNotExist: raise PayPalTransactionError( 'Booking with id {} does not exist'.format(obj_id) ) paypal_trans = PaypalBookingTransaction.objects.filter(booking=obj) if not paypal_trans: paypal_trans = helpers.create_booking_paypal_transaction( user=obj.user, booking=obj ) elif paypal_trans.count() > 1: # we may have two ppb transactions created if user changed their # username between booking and paying (invoice_id is created and # retrieved using username) if ipn_obj.invoice: paypal_trans = PaypalBookingTransaction.objects.get( booking=obj, invoice_id=ipn_obj.invoice ) else: paypal_trans = paypal_trans.latest('id') else: # we got one paypaltrans, as we should have paypal_trans = paypal_trans[0] elif obj_type == 'block': try: obj = Block.objects.get(id=obj_id) except Block.DoesNotExist: raise PayPalTransactionError( 'Block with id {} does not exist'.format(obj_id) ) paypal_trans = PaypalBlockTransaction.objects.filter(block=obj) if not paypal_trans: paypal_trans = helpers.create_block_paypal_transaction( user=obj.bookings.first().user, block=obj ) elif paypal_trans.count() > 1: # we may have two ppb transactions created if user changed their # username between booking block and paying (invoice_id is created and # retrieved using username) if ipn_obj.invoice: paypal_trans = PaypalBlockTransaction.objects.get( block=obj, invoice_id=ipn_obj.invoice ) else: paypal_trans = paypal_trans.latest('id') else: # we got one paypaltrans, as we should have paypal_trans = paypal_trans[0] else: raise PayPalTransactionError('Unknown object type for payment') return { 'obj_type': obj_type, 'obj': obj, 'paypal_trans': paypal_trans }
def get_obj(ipn_obj): from payments import helpers additional_data = {} try: custom = ipn_obj.custom.split() obj_type = custom[0] obj_id = int(custom[1]) voucher_code = custom[2] if len(custom) == 3 and \ obj_type != 'test' else None except IndexError: # in case custom not included in paypal response raise PayPalTransactionError('Unknown object type for payment') if obj_type == 'paypal_test': # a test payment for paypal email # custom in a test payment is in form # 'test 0 <invoice_id> <paypal email being tested> <user's email>' obj = None paypal_trans = None additional_data['test_invoice'] = custom[2] additional_data['test_paypal_email'] = custom[3] additional_data['user_email'] = custom[4] elif obj_type == 'booking': try: obj = Booking.objects.get(id=obj_id) except Booking.DoesNotExist: raise PayPalTransactionError( 'Booking with id {} does not exist'.format(obj_id) ) paypal_trans = PaypalBookingTransaction.objects.filter(booking=obj) if not paypal_trans: paypal_trans = helpers.create_booking_paypal_transaction( user=obj.user, booking=obj ) elif paypal_trans.count() > 1: # we may have two ppb transactions created if user changed their # username between booking and paying (invoice_id is created and # retrieved using username) if ipn_obj.invoice: paypal_trans = PaypalBookingTransaction.objects.get( booking=obj, invoice_id=ipn_obj.invoice ) else: paypal_trans = paypal_trans.latest('id') else: # we got one paypaltrans, as we should have paypal_trans = paypal_trans[0] elif obj_type == 'block': try: obj = Block.objects.get(id=obj_id) except Block.DoesNotExist: raise PayPalTransactionError( 'Block with id {} does not exist'.format(obj_id) ) paypal_trans = PaypalBlockTransaction.objects.filter(block=obj) if not paypal_trans: paypal_trans = helpers.create_block_paypal_transaction( user=obj.user, block=obj ) elif paypal_trans.count() > 1: # we may have two ppb transactions created if user changed their # username between booking block and paying (invoice_id is created and # retrieved using username) if ipn_obj.invoice: paypal_trans = PaypalBlockTransaction.objects.get( block=obj, invoice_id=ipn_obj.invoice ) else: paypal_trans = paypal_trans.latest('id') else: # we got one paypaltrans, as we should have paypal_trans = paypal_trans[0] elif obj_type == 'ticket_booking': try: obj = TicketBooking.objects.get(id=obj_id) except TicketBooking.DoesNotExist: raise PayPalTransactionError( 'Ticket Booking with id {} does not exist'.format(obj_id) ) paypal_trans = PaypalTicketBookingTransaction.objects.filter( ticket_booking=obj ) if not paypal_trans: paypal_trans = helpers.create_ticket_booking_paypal_transaction( user=obj.user, ticket_booking=obj ) elif paypal_trans.count() > 1: # we may have two ppb transactions created if user changed their # username between booking and paying (invoice_id is created and # retrieved using username) if ipn_obj.invoice: paypal_trans = PaypalTicketBookingTransaction.objects.get( ticket_booking=obj, invoice_id=ipn_obj.invoice ) else: paypal_trans = paypal_trans.latest('id') else: # we got one paypaltrans, as we should have paypal_trans = paypal_trans[0] else: raise PayPalTransactionError('Unknown object type for payment') return { 'obj_type': obj_type, 'obj': obj, 'paypal_trans': paypal_trans, 'voucher_code': voucher_code, 'additional_data': additional_data }
def payments_pending(request): unpaid_bookings = Booking.objects.filter( user=request.user, status='OPEN', paid=False ) unpaid_booked_events = [booking.event for booking in unpaid_bookings] blocks = [] unpaid_single_bookings = [] for booking in unpaid_bookings: if booking.event in unpaid_booked_events and booking.block: blocks.append(booking.block) else: invoice_id = create_booking_paypal_transaction( request.user, booking).invoice_id host = 'http://{}'.format(request.META.get('HTTP_HOST')) paypal_form = PayPalPaymentsListForm( initial=context_helpers.get_paypal_dict( host, booking.cost, booking.event, invoice_id, 'userid {} {} {}'.format( request.user.id, 'booking', booking.id ) ) ) unpaid_booking = { 'booking': booking, 'paypalform': paypal_form } unpaid_single_bookings.append(unpaid_booking) unpaid_blocks = [] for block in set(blocks): invoice_id = create_block_paypal_transaction( request.user, block).invoice_id host = 'http://{}'.format(request.META.get('HTTP_HOST')) paypal_form = PayPalPaymentsListForm( initial=context_helpers.get_paypal_dict( host, block.item_cost * block.events.count(), block.name, invoice_id, 'userid {} {} {}'.format(request.user.id, 'block', block.id) ) ) unpaid_block = { 'block': block, 'paypalform': paypal_form } unpaid_blocks.append(unpaid_block) context = { 'unpaid_blocks': unpaid_blocks, 'unpaid_bookings': unpaid_single_bookings } return TemplateResponse( request, 'flex_bookings/payments_pending.html', context )