def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error(request, _('A refund cannot be applied for yet. Please try again later. ' 'If this error persists contact [email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % contribution.pk) return redirect('account.purchases') if contribution.is_instant_refund(): try: paypal.refund(contribution.paykey) except PaypalError, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error(request, _('There was an error with your instant ' 'refund.')) contribution.record_failed_refund(e) return redirect('account.purchases') refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) return redirect('account.purchases')
def refund_reason(request, contribution, wizard): if not contribution.can_we_refund(): return http.HttpResponseForbidden() addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error(request, _('A refund cannot be applied for yet. Please try again later. ' 'If this error persists contact [email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % contribution.pk) return redirect('account.purchases') if contribution.is_instant_refund(): try: paypal.refund(contribution.paykey) except PaypalError: paypal_log.error('Paypal error with refund', exc_info=True) messages.error(request, _('There was an error with your instant ' 'refund.')) return redirect('account.purchases') refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) return redirect('account.purchases') form = forms.ContactForm(request.POST or None) if request.method == 'POST' and form.is_valid(): reason = form.cleaned_data['text'] template = jingo.render_to_string(request, wizard.tpl('emails/refund-request.txt'), context={'product': addon, 'form': form, 'user': request.amo_user, 'contribution': contribution, 'refund_url': contribution.get_absolute_refund_url(), 'refund_reason': reason}) log.info('Refund request sent by user: %s for addon: %s' % (request.amo_user.pk, addon.pk)) # L10n: %s is the app name. support_mail(_(u'New Refund Request for %s' % addon.name), template, sender=settings.NOBODY_EMAIL, recipients=[smart_str(addon.support_email)]) # Add this refund request to the queue. contribution.enqueue_refund(amo.REFUND_PENDING, reason) return redirect(reverse('support', args=[contribution.pk, 'refund-sent'])) return wizard.render(request, wizard.tpl('refund.html'), {'product': addon, 'contribution': contribution, 'form': form, 'title': _('Request Refund')})
def bango_portal_from_package(request, package_id): response = _redirect_to_bango_portal(package_id, "package_id: %s" % package_id) if "Location" in response: return HttpResponseRedirect(response["Location"]) else: message = json.loads(response.content).get("__all__", response.content)[0] messages.error(request, message) return HttpResponseRedirect(reverse("lookup.home"))
def bango_portal_from_package(request, package_id): response = _redirect_to_bango_portal(int(package_id), 'package_id: %s' % package_id) if 'Location' in response: return HttpResponseRedirect(response['Location']) else: message = (json.loads(response.content) .get('__all__', response.content)[0]) messages.error(request, message) return HttpResponseRedirect(reverse('lookup.home'))
def app_review(request, addon): version = addon.latest_version resp = None try: resp = _review(request, addon, version) except SigningError, exc: transaction.rollback() messages.error(request, "Signing Error: %s" % exc) transaction.commit() return redirect(reverse("reviewers.apps.review", args=[addon.app_slug]))
def bango_portal_from_package(request, package_id): response = _redirect_to_bango_portal(package_id, 'package_id: %s' % package_id) if 'Location' in response: return HttpResponseRedirect(response['Location']) else: message = (json.loads(response.content).get('__all__', response.content)[0]) messages.error(request, message) return HttpResponseRedirect(reverse('lookup.home'))
def app_review(request, addon): version = addon.latest_version resp = None try: resp = _review(request, addon, version) except SigningError, exc: transaction.rollback() messages.error(request, 'Signing Error: %s' % exc) transaction.commit() return redirect(reverse('reviewers.apps.review', args=[addon.app_slug]))
def user_delete(request, user_id): delete_form = DeleteUserForm(request.POST) if not delete_form.is_valid(): messages.error(request, delete_form.errors) return HttpResponseRedirect(reverse('lookup.user_summary', args=[user_id])) user = get_object_or_404(UserProfile, pk=user_id) user.deleted = True user.save() # Must call the save function to delete user. amo.log(amo.LOG.DELETE_USER_LOOKUP, user, details={'reason': delete_form.cleaned_data['delete_reason']}, user=request.amo_user) return HttpResponseRedirect(reverse('lookup.user_summary', args=[user_id]))
def transaction_refund(request, uuid): contrib = get_object_or_404(Contribution, uuid=uuid, type=amo.CONTRIB_PURCHASE) if contrib.has_refund(): messages.error(request, _('A refund has already been processed.')) return redirect(reverse('lookup.transaction_summary', args=[uuid])) form = TransactionRefundForm(request.POST) if not form.is_valid(): messages.error(request, str(form.errors)) return redirect(reverse('lookup.transaction_summary', args=[uuid])) try: res = client.api.bango.refund.post({'uuid': contrib.transaction_id}) except (HttpClientError, HttpServerError): # Either doing something not supposed to or Solitude had an issue. log.exception('Refund error: %s' % uuid) messages.error( request, _('You cannot make a refund request for this transaction.')) return redirect(reverse('lookup.transaction_summary', args=[uuid])) if res['status'] == STATUS_PENDING: # Create pending Refund. contrib.enqueue_refund( status=amo.REFUND_PENDING, refund_reason=form.cleaned_data['refund_reason'], user=request.amo_user) log.info('Refund pending: %s' % uuid) email_buyer_refund_pending(contrib) messages.success( request, _('Refund for this transaction now pending.')) elif res['status'] == STATUS_COMPLETED: # Create approved Refund. contrib.enqueue_refund( status=amo.REFUND_APPROVED, refund_reason=form.cleaned_data['refund_reason'], user=request.amo_user) log.info('Refund approved: %s' % uuid) email_buyer_refund_approved(contrib) messages.success( request, _('Refund for this transaction successfully approved.')) elif res['status'] == STATUS_FAILED: # Bango no like. log.error('Refund failed: %s' % uuid) messages.error( request, _('Refund request for this transaction failed.')) return redirect(reverse('lookup.transaction_summary', args=[uuid]))
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error( request, _('A refund cannot be applied for yet. Please try again later. ' 'If this error persists contact [email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % contribution.pk) return redirect('account.purchases') if contribution.is_refunded(): messages.error(request, _('This has already been refunded.')) paypal_log.info('Already refunded: %s' % contribution.pk) return redirect('account.purchases') if contribution.is_instant_refund(): if waffle.flag_is_active(request, 'solitude-payments'): try: client.post_refund(data={'uuid': contribution.transaction_id}) except client.Error, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error( request, _('There was an error with your ' 'instant refund.')) contribution.record_failed_refund(e, request.amo_user) return redirect('account.purchases') else: # TODO(solitude): remove this. try: paypal.refund(contribution.paykey) except PaypalError, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error( request, _('There was an error with your ' 'instant refund.')) contribution.record_failed_refund(e, request.amo_user) return redirect('account.purchases')
def refund_reason(request, contribution, wizard): addon = contribution.addon if not "request" in wizard.get_progress(): return redirect("support", contribution.pk, "request") if contribution.transaction_id is None: messages.error( request, _( "A refund cannot be applied for yet. Please try again later. " "If this error persists contact [email protected]." ), ) paypal_log.info("Refund requested for contribution with no " "transaction_id: %r" % contribution.pk) return redirect("account.purchases") if contribution.is_refunded(): messages.error(request, _("This has already been refunded.")) paypal_log.info("Already refunded: %s" % contribution.pk) return redirect("account.purchases") if contribution.is_instant_refund(): if waffle.flag_is_active(request, "solitude-payments"): try: client.post_refund(data={"uuid": contribution.transaction_id}) except client.Error, e: paypal_log.error("Paypal error with refund", exc_info=True) messages.error(request, _("There was an error with your " "instant refund.")) contribution.record_failed_refund(e) return redirect("account.purchases") else: # TODO(solitude): remove this. try: paypal.refund(contribution.paykey) except PaypalError, e: paypal_log.error("Paypal error with refund", exc_info=True) messages.error(request, _("There was an error with your " "instant refund.")) contribution.record_failed_refund(e) return redirect("account.purchases")
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error(request, _('A refund cannot be applied for yet. Please try again later. ' 'If this error persists contact [email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % contribution.pk) return redirect('account.purchases') if contribution.is_refunded(): messages.error(request, _('This has already been refunded.')) paypal_log.info('Already refunded: %s' % contribution.pk) return redirect('account.purchases') if contribution.is_instant_refund(): if waffle.flag_is_active(request, 'solitude-payments'): try: client.post_refund(data={'uuid': contribution.transaction_id}) except client.Error, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error(request, _('There was an error with your ' 'instant refund.')) contribution.record_failed_refund(e, request.amo_user) return redirect('account.purchases') else: # TODO(solitude): remove this. try: paypal.refund(contribution.paykey) except PaypalError, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error(request, _('There was an error with your ' 'instant refund.')) contribution.record_failed_refund(e, request.amo_user) return redirect('account.purchases')
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error(request, _('A refund cannot be applied for yet. Please try again later. ' 'If this error persists contact [email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % contribution.pk) return redirect('account.purchases') if contribution.is_refunded(): messages.error(request, _('This has already been refunded.')) paypal_log.info('Already refunded: %s' % contribution.pk) return redirect('account.purchases') if contribution.is_instant_refund(): try: paypal.refund(contribution.paykey) except PaypalError, e: paypal_log.error('Paypal error with refund', exc_info=True) messages.error(request, _('There was an error with your instant ' 'refund.')) contribution.record_failed_refund(e) return redirect('account.purchases') refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) amo.log(amo.LOG.REFUND_INSTANT, addon) return redirect('account.purchases')
def refund_reason(request, contribution, wizard): if not contribution.can_we_refund(): return http.HttpResponseForbidden() addon = contribution.addon if not "request" in wizard.get_progress(): return redirect("support", contribution.pk, "request") if contribution.transaction_id is None: messages.error( request, _( "A refund cannot be applied for yet. Please try again later. " "If this error persists contact [email protected]." ), ) paypal_log.info("Refund requested for contribution with no " "transaction_id: %r" % contribution.pk) return redirect("account.purchases") if contribution.is_instant_refund(): paypal.refund(contribution.paykey) # TODO: Consider requiring a refund reason for instant refunds. refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info("Refund %r issued for contribution %r" % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _("Refund is being processed.")) return redirect("account.purchases") form = forms.ContactForm(request.POST or None) if request.method == "POST" and form.is_valid(): reason = form.cleaned_data["text"] template = jingo.render_to_string( request, wizard.tpl("emails/refund-request.txt"), context={ "product": addon, "form": form, "user": request.amo_user, "contribution": contribution, "refund_url": contribution.get_absolute_refund_url(), "refund_reason": reason, }, ) log.info("Refund request sent by user: %s for addon: %s" % (request.amo_user.pk, addon.pk)) # L10n: %s is the app name. support_mail( _(u"New Refund Request for %s" % addon.name), template, sender=settings.NOBODY_EMAIL, recipients=[smart_str(addon.support_email)], ) # Add this refund request to the queue. contribution.enqueue_refund(amo.REFUND_PENDING, reason) return redirect(reverse("support", args=[contribution.pk, "refund-sent"])) return wizard.render( request, wizard.tpl("refund.html"), {"product": addon, "contribution": contribution, "form": form, "title": _("Request Refund")}, )
def transaction_refund(request, tx_uuid): contrib = get_object_or_404(Contribution, uuid=tx_uuid, type=amo.CONTRIB_PURCHASE) refund_contribs = contrib.get_refund_contribs() refund_contrib = refund_contribs[0] if refund_contribs.exists() else None if refund_contrib: messages.error(request, _("A refund has already been processed.")) return redirect(reverse("lookup.transaction_summary", args=[tx_uuid])) form = TransactionRefundForm(request.POST) if not form.is_valid(): return jingo.render( request, "lookup/transaction_summary.html", dict( {"uuid": tx_uuid, "tx_refund_form": form, "tx_form": TransactionSearchForm()}.items() + _transaction_summary(tx_uuid).items() ), ) data = {"uuid": contrib.transaction_id, "manual": form.cleaned_data["manual"]} if settings.BANGO_FAKE_REFUNDS: data["fake_response_status"] = {"responseCode": form.cleaned_data["fake"]} try: res = client.api.bango.refund.post(data) except (HttpClientError, HttpServerError): # Either doing something not supposed to or Solitude had an issue. log.exception("Refund error: %s" % tx_uuid) messages.error(request, _("You cannot make a refund request for this transaction.")) return redirect(reverse("lookup.transaction_summary", args=[tx_uuid])) if res["status"] in [PENDING, COMPLETED]: # Create refund Contribution by cloning the payment Contribution. refund_contrib = Contribution.objects.get(id=contrib.id) refund_contrib.id = None refund_contrib.save() refund_contrib.update( type=amo.CONTRIB_REFUND, related=contrib, uuid=hashlib.md5(str(uuid.uuid4())).hexdigest(), amount=-refund_contrib.amount if refund_contrib.amount else None, transaction_id=res["uuid"], ) if res["status"] == PENDING: # Create pending Refund. refund_contrib.enqueue_refund( amo.REFUND_PENDING, request.amo_user, refund_reason=form.cleaned_data["refund_reason"] ) log.info("Refund pending: %s" % tx_uuid) email_buyer_refund_pending(contrib) messages.success(request, _("Refund for this transaction now pending.")) elif res["status"] == COMPLETED: # Create approved Refund. refund_contrib.enqueue_refund( amo.REFUND_APPROVED, request.amo_user, refund_reason=form.cleaned_data["refund_reason"] ) log.info("Refund approved: %s" % tx_uuid) email_buyer_refund_approved(contrib) messages.success(request, _("Refund for this transaction successfully approved.")) elif res["status"] == FAILED: # Bango no like. log.error("Refund failed: %s" % tx_uuid) messages.error(request, _("Refund request for this transaction failed.")) return redirect(reverse("lookup.transaction_summary", args=[tx_uuid]))
def transaction_refund(request, tx_uuid): contrib = get_object_or_404(Contribution, uuid=tx_uuid, type=amo.CONTRIB_PURCHASE) refund_contribs = contrib.get_refund_contribs() refund_contrib = refund_contribs[0] if refund_contribs.exists() else None if refund_contrib: messages.error(request, _('A refund has already been processed.')) return redirect(reverse('lookup.transaction_summary', args=[tx_uuid])) form = TransactionRefundForm(request.POST) if not form.is_valid(): return jingo.render( request, 'lookup/transaction_summary.html', dict({ 'uuid': tx_uuid, 'tx_refund_form': form, 'tx_form': TransactionSearchForm() }.items() + _transaction_summary(tx_uuid).items())) try: res = client.api.bango.refund.post({'uuid': contrib.transaction_id}) except (HttpClientError, HttpServerError): # Either doing something not supposed to or Solitude had an issue. log.exception('Refund error: %s' % tx_uuid) messages.error( request, _('You cannot make a refund request for this transaction.')) return redirect(reverse('lookup.transaction_summary', args=[tx_uuid])) if res['status'] in [PENDING, COMPLETED]: # Create refund Contribution by cloning the payment Contribution. refund_contrib = Contribution.objects.get(id=contrib.id) refund_contrib.id = None refund_contrib.save() refund_contrib.update( type=amo.CONTRIB_REFUND, related=contrib, uuid=hashlib.md5(str(uuid.uuid4())).hexdigest(), amount=-refund_contrib.amount if refund_contrib.amount else None, transaction_id=client.get(res['transaction'])['uuid']) if res['status'] == PENDING: # Create pending Refund. refund_contrib.enqueue_refund( amo.REFUND_PENDING, request.amo_user, refund_reason=form.cleaned_data['refund_reason']) log.info('Refund pending: %s' % tx_uuid) email_buyer_refund_pending(contrib) messages.success(request, _('Refund for this transaction now pending.')) elif res['status'] == COMPLETED: # Create approved Refund. refund_contrib.enqueue_refund( amo.REFUND_APPROVED, request.amo_user, refund_reason=form.cleaned_data['refund_reason']) log.info('Refund approved: %s' % tx_uuid) email_buyer_refund_approved(contrib) messages.success( request, _('Refund for this transaction successfully approved.')) elif res['status'] == FAILED: # Bango no like. log.error('Refund failed: %s' % tx_uuid) messages.error(request, _('Refund request for this transaction failed.')) return redirect(reverse('lookup.transaction_summary', args=[tx_uuid]))
def transaction_refund(request, tx_uuid): contrib = get_object_or_404(Contribution, uuid=tx_uuid, type=amo.CONTRIB_PURCHASE) refund_contribs = contrib.get_refund_contribs() refund_contrib = refund_contribs[0] if refund_contribs.exists() else None if refund_contrib: messages.error(request, _('A refund has already been processed.')) return redirect(reverse('lookup.transaction_summary', args=[tx_uuid])) form = TransactionRefundForm(request.POST) if not form.is_valid(): messages.error(request, str(form.errors)) return redirect(reverse('lookup.transaction_summary', args=[tx_uuid])) try: res = client.api.bango.refund.post({'uuid': contrib.transaction_id}) except (HttpClientError, HttpServerError): # Either doing something not supposed to or Solitude had an issue. log.exception('Refund error: %s' % tx_uuid) messages.error( request, _('You cannot make a refund request for this transaction.')) return redirect(reverse('lookup.transaction_summary', args=[tx_uuid])) if res['status'] in [PENDING, COMPLETED]: # Create refund Contribution by cloning the payment Contribution. refund_contrib = Contribution.objects.get(id=contrib.id) refund_contrib.id = None refund_contrib.save() refund_contrib.update( type=amo.CONTRIB_REFUND, related=contrib, uuid=hashlib.md5(str(uuid.uuid4())).hexdigest(), amount=-refund_contrib.amount if refund_contrib.amount else None, transaction_id=client.get(res['transaction'])['uuid']) if res['status'] == PENDING: # Create pending Refund. refund_contrib.enqueue_refund( amo.REFUND_PENDING, request.amo_user, refund_reason=form.cleaned_data['refund_reason']) log.info('Refund pending: %s' % tx_uuid) email_buyer_refund_pending(contrib) messages.success( request, _('Refund for this transaction now pending.')) elif res['status'] == COMPLETED: # Create approved Refund. refund_contrib.enqueue_refund( amo.REFUND_APPROVED, request.amo_user, refund_reason=form.cleaned_data['refund_reason']) log.info('Refund approved: %s' % tx_uuid) email_buyer_refund_approved(contrib) messages.success( request, _('Refund for this transaction successfully approved.')) elif res['status'] == FAILED: # Bango no like. log.error('Refund failed: %s' % tx_uuid) messages.error( request, _('Refund request for this transaction failed.')) return redirect(reverse('lookup.transaction_summary', args=[tx_uuid]))