Skip to content

Commit d92c003

Browse files
author
=
committedSep 8, 2024
fix #191
1 parent e57c38a commit d92c003

10 files changed

+154
-48
lines changed
 

‎auctions/consumers.py

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ def bid_on_lot(lot, user, amount):
138138
bid, created = Bid.objects.get_or_create(
139139
user=user,
140140
lot_number=lot,
141+
is_deleted=False,
141142
defaults={"amount": amount},
142143
)
143144
# also update category interest, max one per bid

‎auctions/forms.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,7 @@ class Meta:
15461546
"allow_bidding_on_lots", # it's back...for now
15471547
"date_online_bidding_ends",
15481548
"date_online_bidding_starts",
1549+
"allow_deleting_bids",
15491550
]
15501551
widgets = {
15511552
"date_start": DateTimePickerInput(),
@@ -1702,15 +1703,19 @@ def __init__(self, *args, **kwargs):
17021703
Div(
17031704
Div(
17041705
"allow_bidding_on_lots",
1705-
css_class="col-md-4",
1706+
css_class="col-md-3",
17061707
),
17071708
Div(
17081709
"date_online_bidding_starts",
1709-
css_class="col-md-4",
1710+
css_class="col-md-3",
17101711
),
17111712
Div(
17121713
"date_online_bidding_ends",
1713-
css_class="col-md-4",
1714+
css_class="col-md-3",
1715+
),
1716+
Div(
1717+
"allow_deleting_bids",
1718+
css_class="col-md-3",
17141719
),
17151720
css_class="row",
17161721
),

‎auctions/management/commands/update_user_interest.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ def handle(self, *args, **options):
2222
self.stdout.write("Creating userdata")
2323
users = User.objects.all()
2424
for user in users:
25-
allBids = Bid.objects.select_related("lot_number__species_category").filter(user=user)
25+
allBids = (
26+
Bid.objects.exclude(is_deleted=True).select_related("lot_number__species_category").filter(user=user)
27+
)
2628
pageViews = PageView.objects.select_related("lot_number__species_category").filter(user=user)
2729
# remove all user interests
2830
UserInterestCategory.objects.filter(user=user).delete()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Generated by Django 5.0.8 on 2024-09-08 18:40
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("auctions", "0144_auction_date_online_bidding_ends_and_more"),
9+
]
10+
11+
operations = [
12+
migrations.AddField(
13+
model_name="auction",
14+
name="allow_deleting_bids",
15+
field=models.BooleanField(
16+
blank=True, default=False, help_text="Allow users to delete their own bids until the auction ends"
17+
),
18+
),
19+
migrations.AddField(
20+
model_name="bid",
21+
name="is_deleted",
22+
field=models.BooleanField(default=False),
23+
),
24+
migrations.AlterField(
25+
model_name="lothistory",
26+
name="changed_price",
27+
field=models.BooleanField(
28+
default=False,
29+
help_text="Was this a bid that changed the price? If False, this lot will show up in the admin chat system",
30+
),
31+
),
32+
]

‎auctions/models.py

+41-14
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ def add_tos_info(qs):
243243
return qs.annotate(
244244
lots_bid_actual=Coalesce(
245245
Subquery(
246-
Bid.objects.filter(user=OuterRef("user"), lot_number__auction=OuterRef("auction"))
246+
Bid.objects.exclude(is_deleted=True)
247+
.filter(user=OuterRef("user"), lot_number__auction=OuterRef("auction"))
247248
.values("user")
248249
.annotate(count=Count("pk", distinct=True))
249250
.values("count"),
@@ -624,6 +625,8 @@ class Auction(models.Model):
624625
advanced_lot_adding.help_text = "Show lot number, quantity and description fields when bulk adding lots"
625626
extra_promo_text = models.CharField(max_length=50, default="", blank=True, null=True)
626627
extra_promo_link = models.URLField(blank=True, null=True)
628+
allow_deleting_bids = models.BooleanField(default=False, blank=True)
629+
allow_deleting_bids.help_text = "Allow users to delete their own bids until the auction ends"
627630

628631
def __str__(self):
629632
result = self.title
@@ -2412,6 +2415,13 @@ def bids_can_be_removed(self):
24122415
return True
24132416
if self.ended:
24142417
return False
2418+
if (
2419+
not self.auction.is_online
2420+
and self.auction.date_online_bidding_ends
2421+
and self.auction.allow_bidding_on_lots
2422+
and timezone.now() > self.auction.date_online_bidding_ends
2423+
):
2424+
return False
24152425
return True
24162426

24172427
@property
@@ -2614,11 +2624,15 @@ def price(self):
26142624
@property
26152625
def max_bid(self):
26162626
"""returns the highest bid amount for this lot - this number should not be visible to the public"""
2617-
allBids = Bid.objects.filter(
2618-
lot_number=self.lot_number,
2619-
last_bid_time__lte=self.calculated_end,
2620-
amount__gte=self.reserve_price,
2621-
).order_by("-amount", "last_bid_time")[:2]
2627+
allBids = (
2628+
Bid.objects.exclude(is_deleted=True)
2629+
.filter(
2630+
lot_number=self.lot_number,
2631+
last_bid_time__lte=self.calculated_end,
2632+
amount__gte=self.reserve_price,
2633+
)
2634+
.order_by("-amount", "last_bid_time")[:2]
2635+
)
26222636
try:
26232637
# $1 more than the second highest bid
26242638
bidPrice = allBids[0].amount
@@ -2631,11 +2645,15 @@ def max_bid(self):
26312645
def bids(self):
26322646
"""Get all bids for this lot, highest bid first"""
26332647
# bids = Bid.objects.filter(lot_number=self.lot_number, last_bid_time__lte=self.calculated_end, amount__gte=self.reserve_price).order_by('-amount', 'last_bid_time')
2634-
bids = Bid.objects.filter(
2635-
lot_number=self.lot_number,
2636-
last_bid_time__lte=self.calculated_end,
2637-
amount__gte=self.reserve_price,
2638-
).order_by("-amount", "last_bid_time")
2648+
bids = (
2649+
Bid.objects.exclude(is_deleted=True)
2650+
.filter(
2651+
lot_number=self.lot_number,
2652+
last_bid_time__lte=self.calculated_end,
2653+
amount__gte=self.reserve_price,
2654+
)
2655+
.order_by("-amount", "last_bid_time")
2656+
)
26392657
return bids
26402658

26412659
@property
@@ -2695,7 +2713,7 @@ def page_views(self):
26952713
@property
26962714
def number_of_bids(self):
26972715
"""How many users placed bids on this lot?"""
2698-
bids = Bid.objects.filter(
2716+
bids = Bid.objects.exclude(is_deleted=True).filter(
26992717
lot_number=self.lot_number,
27002718
bid_time__lte=self.calculated_end,
27012719
amount__gte=self.reserve_price,
@@ -2838,7 +2856,11 @@ def seller_ip(self):
28382856
@property
28392857
def bidder_ip_same_as_seller(self):
28402858
if self.seller_ip:
2841-
bids = Bid.objects.filter(lot_number__pk=self.pk, user__userdata__last_ip_address=self.seller_ip).count()
2859+
bids = (
2860+
Bid.objects.exclude(is_deleted=True)
2861+
.filter(lot_number__pk=self.pk, user__userdata__last_ip_address=self.seller_ip)
2862+
.count()
2863+
)
28422864
if bids:
28432865
return bids
28442866
return None
@@ -3207,13 +3229,18 @@ class Bid(models.Model):
32073229
last_bid_time = models.DateTimeField(auto_now_add=True, blank=True)
32083230
amount = models.PositiveIntegerField(validators=[MinValueValidator(1)])
32093231
was_high_bid = models.BooleanField(default=False)
3232+
is_deleted = models.BooleanField(default=False)
32103233
# note: there is not AuctionTOS field here - this means that bids can only be placed by Users
32113234
# AuctionTOSs CAN be declared the winners of lots without placing a single bid
32123235
# time will tell if this is a mistake or not
32133236

32143237
def __str__(self):
32153238
return str(self.user) + " bid " + str(self.amount) + " on lot " + str(self.lot_number)
32163239

3240+
def delete(self, *args, **kwargs):
3241+
self.is_deleted = True
3242+
self.save()
3243+
32173244

32183245
class Watch(models.Model):
32193246
"""
@@ -3572,7 +3599,7 @@ def calc_total_volume(self):
35723599
def total_bids(self):
35733600
"""Total number of successful bids this user has placed (max one per lot)"""
35743601
# return len(Bid.objects.filter(user=self.user, was_high_bid=True))
3575-
return len(Bid.objects.filter(user=self.user))
3602+
return len(Bid.objects.exclude(is_deleted=True).filter(user=self.user))
35763603

35773604
@property
35783605
def lots_viewed(self):

‎auctions/templates/auction_edit_form.html

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
$('#div_id_date_online_bidding_starts').show();
3434
$('#div_id_date_online_bidding_ends').show();
3535
$('#div_id_only_approved_bidders').show();
36+
$('#div_id_allow_deleting_bids').show();
3637
{% if not auction.is_online %}
3738
$('#div_id_date_start label').html('In-person bidding opens<span class="asteriskField">*</span>');
3839
$('#id_date_start_helptext').html('Does not change online bidding');
@@ -41,6 +42,7 @@
4142
$('#div_id_date_online_bidding_starts').hide();
4243
$('#div_id_date_online_bidding_ends').hide();
4344
$('#div_id_only_approved_bidders').hide();
45+
$('#div_id_allow_deleting_bids').hide();
4446
{% if not auction.is_online %}
4547
$('#div_id_date_start label').html('Bidding opens<span class="asteriskField">*</span>');
4648
$('#id_date_start_helptext').html('When the auction actually starts');
@@ -50,6 +52,7 @@
5052
{% if auction.is_online %}
5153
$(document).ready(function() {
5254
$('#div_id_only_approved_bidders').show();
55+
$('#div_id_allow_deleting_bids').show();
5356
});
5457
{% endif %}
5558
</script>

‎auctions/templates/auctions/bid_confirm_delete.html

+11-7
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
{% block title %} Delete bid {% endblock %}
44
{% load static %}
55
{% block content %}
6-
<form method="post">{% csrf_token %}
7-
<p>Are you sure you want to delete {{ object.user }}'s bid on {{object.lot_number.lot_name }}?</p>
8-
<p>Note: this will only remove {{ object.user }}'s bid on <b>this</b> lot. If {{ object.user }} is causing trouble, you can <a href="{% url 'userpage' slug=object.user %}">ban them here</a>, which will remove all their bids from all lots.
9-
</p>
10-
<input type="submit" class='btn btn-danger' value="Delete">
11-
<a href="{{object.lot_number.lot_link}}" class='btn btn-secondary'>Cancel</a>
12-
</form>
6+
<form method="post">{% csrf_token %}
7+
{% if removing_own_bid %}
8+
<p>Remove your bid on {{object.lot_number.lot_name }}?</p>
9+
{% else %}
10+
<p>Are you sure you want to delete {{ object.user }}'s bid on {{object.lot_number.lot_name }}?</p>
11+
<p>Note: this will only remove {{ object.user }}'s bid on <b>this</b> lot. If {{ object.user }} is causing trouble, you can <a href="{% url 'userpage' slug=object.user %}">ban them here</a>, which will remove all their bids from all lots.
12+
{% endif %}
13+
</p>
14+
<input type="submit" class='btn btn-danger' value="Delete">
15+
<a href="{{object.lot_number.lot_link}}" class='btn btn-secondary'>Cancel</a>
16+
</form>
1317
{% endblock %}

‎auctions/templates/view_lot_images.html

+9-3
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,13 @@ <h3>{{ lot.lot_name }}</h3>
260260
{% else %}
261261
<span id="high_bidder_name">{% if lot.high_bidder.userdata.username_visible %}<a href="{% url 'userpage' slug=lot.high_bidder %}">{{ lot.high_bidder }}</a>{% else %}Anonymous{%endif%}</span>
262262
{% endif %}
263-
<span id="your_bid">{% if viewer_bid %}Your max bid is $<span id='your_bid_price'>{{ viewer_bid }}</span>{% endif %}</span>
263+
<span id="your_bid">
264+
{% if viewer_bid %}
265+
Your max bid is $<span id='your_bid_price'>{{ viewer_bid }}</span>
266+
{% if lot.bids_can_be_removed and lot.auction.allow_deleting_bids %}
267+
<a href="{% url 'delete_bid' pk=viewer_bid_pk %}" class='btn btn-danger btn-sm'>Remove your bid</a>
268+
{% endif %}
269+
{% endif %}</span>
264270
{% if is_auction_admin %}{{ lot.auction_show_high_bidder_template }}{% endif %}
265271
</span>
266272
{% else %}
@@ -402,7 +408,7 @@ <h5>Exchange info</h5>
402408
{% if force_buy_now %}
403409
var dialogText = "Buy {{ lot.lot_name }} now for $" + bid + "?<br><br><small>All sales are final</small>";
404410
{% else %}
405-
var dialogText = "Bid $" + bid + " on {{ lot.lot_name }}<br><br><small>All bids are final</small>";
411+
var dialogText = "Bid $" + bid + " on {{ lot.lot_name }}<br><br><small>{% if not lot.auction.allow_deleting_bids %}All bids are final{% endif %}</small>";
406412
{% endif %}
407413
{% if not lot.auction %}
408414
dialogText += "<br><div>This lot is sold directly by {{ lot.user }}. Make sure to check the user's feedback.</div>";
@@ -459,7 +465,7 @@ <h5>Exchange info</h5>
459465
{% if bids %}
460466
<h5>Remove bids</h5>
461467
{% for bid in bids %}
462-
<a href="/bids/delete/{{ bid.pk }}/" class='btn btn-danger mt-1 mr-1'>Remove {{bid.user.first_name}} {{bid.user.last_name}} ({{ bid.user }})'s bid</a><br>
468+
<a href="{% url 'delete_bid' pk=bid.pk %}" class='btn btn-danger mt-1 mr-1'>Remove {{bid.user.first_name}} {{bid.user.last_name}} ({{ bid.user }})'s bid</a><br>
463469
{% endfor %}
464470
{% endif %}
465471

‎auctions/urls.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
path("lots/user/", views.LotsByUser.as_view(), name="user_lots"),
114114
path("lots/<int:pk>/<slug:slug>/", views.ViewLot.as_view()),
115115
path("bids/", login_required(views.MyBids.as_view()), name="my_bids"),
116-
path("bids/delete/<int:pk>/", views.BidDelete.as_view()),
116+
path("bids/delete/<int:pk>/", views.BidDelete.as_view(), name="delete_bid"),
117117
path("", views.toDefaultLandingPage),
118118
path("old_about/", views.aboutSite, name="about"),
119119
path("about/", views.PromoSite.as_view(), name="promo"),

0 commit comments

Comments
 (0)