alter purchases to cope with multiple purchases, add in free and remove date paid sorting for now (bug 696509)
This commit is contained in:
Родитель
ff656a8be9
Коммит
8f2403e5a5
|
@ -15,8 +15,7 @@
|
|||
{{ impala_addon_listing_header(url_base, filter.opts, sorting, filter.extras) }}
|
||||
{% endif %}
|
||||
<div class="items">
|
||||
{% for contribution in purchases.object_list %}
|
||||
{% with addon=contribution.addon %}
|
||||
{% for addon in addons.object_list %}
|
||||
<div class="item addon ignore-compatibility">
|
||||
<div class="info">
|
||||
<h3>
|
||||
|
@ -25,13 +24,17 @@
|
|||
</h3>
|
||||
<p class="desc">{{ addon.description|truncate(250)|nl2br }}</p>
|
||||
<div class="vitals c">
|
||||
{% trans date=addon.created, amt=contribution.get_amount_locale(), url=url('users.support', contribution.pk) %}
|
||||
<div>Purchased {{ date }} for {{ amt }} - <a href="{{ url }}">Request Support</a></div>
|
||||
{% for contribution in contributions.get(addon.pk, []) %}
|
||||
<div class="purchase-byline">
|
||||
{% trans date=addon.created, amt=contribution.get_amount_locale() %}
|
||||
Purchased {{ date }} for {{ amt }}
|
||||
{% endtrans %}
|
||||
· <a href="{{ url('users.support', contribution.pk) }}">{{ _('Request Support') }}</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
<p>You have no purchases.</p>
|
||||
{% endfor %}
|
||||
|
|
|
@ -31,6 +31,7 @@ from stats.models import Contribution
|
|||
from users.models import BlacklistedPassword, UserProfile, UserNotification
|
||||
import users.notifications as email
|
||||
from users.utils import EmailResetCode, UnsubscribeCode
|
||||
from webapps.models import Installed
|
||||
|
||||
|
||||
class UserViewBase(amo.tests.TestCase):
|
||||
|
@ -879,6 +880,7 @@ class TestPurchases(amo.tests.TestCase):
|
|||
self.client.login(username='regular@mozilla.com', password='password')
|
||||
self.user = User.objects.get(email='regular@mozilla.com')
|
||||
|
||||
self.addon, self.con = None, None
|
||||
for x in range(1, 5):
|
||||
addon = Addon.objects.create(type=amo.ADDON_EXTENSION,
|
||||
name='t%s' % x)
|
||||
|
@ -887,9 +889,8 @@ class TestPurchases(amo.tests.TestCase):
|
|||
type=amo.CONTRIB_PURCHASE)
|
||||
con.created = datetime.now() - timedelta(days=10 - x)
|
||||
con.save()
|
||||
|
||||
self.con = con
|
||||
self.addon = addon
|
||||
if not self.addon and not self.con:
|
||||
self.addon, self.con = addon, con
|
||||
|
||||
def test_in_menu(self):
|
||||
doc = pq(self.client.get(self.url).content)
|
||||
|
@ -912,31 +913,30 @@ class TestPurchases(amo.tests.TestCase):
|
|||
def test_purchase_list(self):
|
||||
res = self.client.get(self.url)
|
||||
eq_(res.status_code, 200)
|
||||
eq_(len(res.context['purchases'].object_list), 4)
|
||||
eq_(len(res.context['addons'].object_list), 4)
|
||||
|
||||
def get_order(self, order):
|
||||
res = self.client.get('%s?sort=%s' % (self.url, order))
|
||||
return [str(c.addon.name) for c in
|
||||
res.context['purchases'].object_list]
|
||||
return [str(c.name) for c in
|
||||
res.context['addons'].object_list]
|
||||
|
||||
def test_ordering(self):
|
||||
eq_(self.get_order('name'), ['t1', 't2', 't3', 't4'])
|
||||
eq_(self.get_order('price'), ['t1', 't2', 't3', 't4'])
|
||||
eq_(self.get_order('date'), ['t4', 't3', 't2', 't1'])
|
||||
|
||||
def test_price(self):
|
||||
res = self.client.get(self.url)
|
||||
assert '$4.00' in pq(res.content)('div.vitals').eq(0).text()
|
||||
assert '$1.00' in pq(res.content)('div.vitals').eq(0).text()
|
||||
|
||||
def test_price_locale(self):
|
||||
res = self.client.get(self.url.replace('/en-US', '/fr'))
|
||||
assert u'4,00' in pq(res.content)('div.vitals').eq(0).text()
|
||||
assert u'1,00' in pq(res.content)('div.vitals').eq(0).text()
|
||||
|
||||
def test_receipt(self):
|
||||
res = self.client.get(reverse('users.purchases.receipt',
|
||||
args=[self.addon.pk]))
|
||||
eq_(len(res.context['purchases'].object_list), 1)
|
||||
eq_(res.context['purchases'].object_list[0].addon.pk, self.addon.pk)
|
||||
eq_(len(res.context['addons'].object_list), 1)
|
||||
eq_(res.context['addons'].object_list[0].pk, self.addon.pk)
|
||||
|
||||
def test_receipt_404(self):
|
||||
url = reverse('users.purchases.receipt', args=[545])
|
||||
|
@ -1057,7 +1057,7 @@ class TestPurchases(amo.tests.TestCase):
|
|||
email = mail.outbox[0]
|
||||
eq_(email.to, ['a@a.com'])
|
||||
eq_(email.from_email, 'regular@mozilla.com')
|
||||
assert '$4.00' in email.body
|
||||
assert '$1.00' in email.body
|
||||
|
||||
def test_request_fails(self):
|
||||
self.addon.support_email = 'a@a.com'
|
||||
|
@ -1066,3 +1066,23 @@ class TestPurchases(amo.tests.TestCase):
|
|||
self.client.post(self.get_url('request'), {'remove': 1})
|
||||
res = self.client.post(self.get_url('reason'), {})
|
||||
eq_(res.status_code, 200)
|
||||
|
||||
def test_free_shows_up(self):
|
||||
Contribution.objects.all().delete()
|
||||
res = self.client.get(self.url)
|
||||
eq_(res.context['addons'][0].pk, self.addon.pk)
|
||||
|
||||
def test_others_free_dont(self):
|
||||
Contribution.objects.all().delete()
|
||||
other = UserProfile.objects.get(pk=10482)
|
||||
Installed.objects.all()[0].update(user=other)
|
||||
res = self.client.get(self.url)
|
||||
eq_(len(res.context['addons']), 3)
|
||||
|
||||
def test_purchase_multiple(self):
|
||||
Contribution.objects.create(user=self.user.get_profile(),
|
||||
addon=self.addon, amount='1.00',
|
||||
type=amo.CONTRIB_PURCHASE)
|
||||
res = self.client.get(self.url)
|
||||
addon_vitals = pq(res.content)('div.vitals').eq(0)
|
||||
eq_(len(addon_vitals('div.purchase-byline')), 2)
|
||||
|
|
|
@ -569,19 +569,16 @@ def unsubscribe(request, hash=None, token=None, perm_setting=None):
|
|||
{'unsubscribed': unsubscribed, 'perm_settings': perm_settings})
|
||||
|
||||
|
||||
class ContributionsFilter(BaseFilter):
|
||||
opts = (('date', _lazy(u'Purchase Date')),
|
||||
('price', _lazy(u'Price')),
|
||||
class AddonsFilter(BaseFilter):
|
||||
opts = (('price', _lazy(u'Price')),
|
||||
('name', _lazy(u'Name')))
|
||||
|
||||
def filter(self, field):
|
||||
qs = self.base_queryset
|
||||
if field == 'date':
|
||||
return qs.order_by('-created')
|
||||
elif field == 'price':
|
||||
return qs.order_by('amount')
|
||||
if field == 'price':
|
||||
return qs.order_by('addonpremium__price')
|
||||
elif field == 'name':
|
||||
return qs.order_by('addon__name')
|
||||
return qs.order_by('name')
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -590,21 +587,39 @@ def purchases(request, addon_id=None):
|
|||
if not waffle.switch_is_active('marketplace'):
|
||||
raise http.Http404
|
||||
|
||||
# First get all the contributions.
|
||||
# TODO(ashort): this is where we'll need to get cunning about refunds.
|
||||
cs = Contribution.objects.filter(user=request.amo_user,
|
||||
type=amo.CONTRIB_PURCHASE)
|
||||
if addon_id:
|
||||
cs = cs.filter(addon=addon_id)
|
||||
|
||||
filter = ContributionsFilter(request, cs, key='sort', default='date')
|
||||
purchases = amo.utils.paginate(request, filter.qs)
|
||||
contributions = {}
|
||||
for c in cs:
|
||||
contributions.setdefault(c.addon_id, []).append(c)
|
||||
|
||||
if addon_id and not purchases.object_list:
|
||||
# If you are asking for a receipt for just one item, only show that.
|
||||
# Otherwise, we'll show all addons that have a contribution or are free.
|
||||
if addon_id:
|
||||
ids = [addon_id]
|
||||
else:
|
||||
free = (request.amo_user.installed_set
|
||||
.exclude(addon__in=contributions.keys())
|
||||
.values_list('addon_id', flat=True))
|
||||
ids = contributions.keys() + list(free)
|
||||
|
||||
filter = AddonsFilter(request, Addon.objects.filter(id__in=ids),
|
||||
key='sort', default='name')
|
||||
|
||||
if addon_id and not filter.qs:
|
||||
# User has requested a receipt for an addon they don't have.
|
||||
raise http.Http404
|
||||
|
||||
return jingo.render(request, 'users/purchases.html',
|
||||
{'purchases': purchases, 'filter': filter,
|
||||
{'addons': amo.utils.paginate(request, filter.qs),
|
||||
'filter': filter,
|
||||
'url_base': reverse('users.purchases'),
|
||||
'contributions': contributions,
|
||||
'single': bool(addon_id)})
|
||||
|
||||
|
||||
|
|
|
@ -246,6 +246,9 @@
|
|||
color: @note-gray;
|
||||
content: '\00B7';
|
||||
}
|
||||
&.purchase-byline {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
span.price {
|
||||
color: @green;
|
||||
|
|
Загрузка…
Ссылка в новой задаче