def load_anonymous_order(request, order): """ Try to load an anonymous order. If none is found then return the given (user) order. If an anonymous order is found then close the existing order for that user and migrate the anonymous one to the authenticated user. """ from django.utils.importlib import import_module from django.conf import settings engine = import_module(settings.SESSION_ENGINE) session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None) bb_session = engine.SessionStore(session_key) if anon_order_id_session_key in bb_session: try: anon_current_order = Order.objects.get(id=bb_session.pop(anon_order_id_session_key)) if anon_current_order.status == OrderStatuses.current: try: # Close old order by this user. order.status = OrderStatuses.closed order.save() # Cancel the payments on the closed order. if order.payments.count() > 0: for payment in anon_current_order.payments.all(): if payment.status != PaymentStatuses.new: try: payments.cancel_payment(payment) except(NotImplementedError, PaymentException) as e: logger.warn("Problem cancelling payment on closed user Order {0}: {1}".format( order.id, e)) except Order.DoesNotExist: # There isn't a current order so we don't need to close it. pass else: return order # Assign the anon order to this user. anon_current_order.user = order.user anon_current_order.save() # Move all donations to this user too. for donation in anon_current_order.donations.all(): donation.save() return anon_current_order except Order.DoesNotExist: return order else: return order
def _update_payment(self, order): """ Create a payment if we need one and update the order total. """ def create_new_payment(cancelled_payment=None): """ Creates and new payment and copies over the the payment profile from the cancelled payment.""" # TODO See if we can use something like Django-lazy-user so that the payment profile can always be set with data from the user model. payment = DocDataPaymentOrder() if cancelled_payment: payment.email = cancelled_payment.email payment.first_name = cancelled_payment.first_name payment.last_name = cancelled_payment.last_name payment.address = cancelled_payment.address payment.postal_code = cancelled_payment.postal_code payment.city = cancelled_payment.city payment.country = cancelled_payment.country payment.order = order payment.save() # Create a payment if we need one. # We're currently only using DocData so we can directly connect the DocData payment order to the order. # In the future, we can create the payment at a later stage in the order process using cowry's # 'factory.create_new_payment(amount, currency)'. latest_payment = order.latest_payment if not latest_payment: create_new_payment() latest_payment = order.latest_payment elif latest_payment.status != PaymentStatuses.new: if latest_payment.status == PaymentStatuses.in_progress: # FIXME: This is not a great way to handle payment cancel failures because they user won't be notified. # FIXME: Move to RESTful API for payment cancel / order. try: payments.cancel_payment(latest_payment) except(NotImplementedError, PaymentException) as e: order.status = OrderStatuses.closed order.save() else: create_new_payment(latest_payment) latest_payment = order.latest_payment else: # TODO Deal with this error somehow. logger.error("CurrentOrder retrieved when latest payment has status: {0}".format(latest_payment.status)) # Update the payment total. latest_payment.amount = order.total latest_payment.currency = 'EUR' # The default currency for now. latest_payment.save()
def adjust_anonymous_current_order(sender, request, user, **kwargs): if anon_order_id_session_key in request.session: try: anon_current_order = Order.objects.get(id=request.session.pop(anon_order_id_session_key)) if anon_current_order.status == OrderStatuses.current: try: user_current_order = Order.objects.get(user=user, recurring=False, status=OrderStatuses.current) # Close old order by this user. user_current_order.status = OrderStatuses.closed user_current_order.save() # Cancel the payments on the closed order. if user_current_order.payments.count() > 0: for payment in anon_current_order.payments.all(): if payment.status != PaymentStatuses.new: try: payments.cancel_payment(payment) except(NotImplementedError, PaymentException) as e: logger.warn("Problem cancelling payment on closed user Order {0}: {1}".format( user_current_order.id, e)) except Order.DoesNotExist: # There isn't a current order so we don't need to close it. pass # Assign the anon order to this user. anon_current_order.user = user anon_current_order.save() # Move all donations to this user too. for donation in anon_current_order.donations.all(): donation.user = user donation.save() except Order.DoesNotExist: pass