Skip to content

Commit

Permalink
Merge pull request #213 from iragm/allow-deleting-bids
Browse files Browse the repository at this point in the history
fix #191
  • Loading branch information
iragm authored Sep 8, 2024
2 parents e57c38a + d92c003 commit 2f55cc4
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 48 deletions.
1 change: 1 addition & 0 deletions auctions/consumers.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ def bid_on_lot(lot, user, amount):
bid, created = Bid.objects.get_or_create(
user=user,
lot_number=lot,
is_deleted=False,
defaults={"amount": amount},
)
# also update category interest, max one per bid
Expand Down
11 changes: 8 additions & 3 deletions auctions/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,7 @@ class Meta:
"allow_bidding_on_lots", # it's back...for now
"date_online_bidding_ends",
"date_online_bidding_starts",
"allow_deleting_bids",
]
widgets = {
"date_start": DateTimePickerInput(),
Expand Down Expand Up @@ -1702,15 +1703,19 @@ def __init__(self, *args, **kwargs):
Div(
Div(
"allow_bidding_on_lots",
css_class="col-md-4",
css_class="col-md-3",
),
Div(
"date_online_bidding_starts",
css_class="col-md-4",
css_class="col-md-3",
),
Div(
"date_online_bidding_ends",
css_class="col-md-4",
css_class="col-md-3",
),
Div(
"allow_deleting_bids",
css_class="col-md-3",
),
css_class="row",
),
Expand Down
4 changes: 3 additions & 1 deletion auctions/management/commands/update_user_interest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ def handle(self, *args, **options):
self.stdout.write("Creating userdata")
users = User.objects.all()
for user in users:
allBids = Bid.objects.select_related("lot_number__species_category").filter(user=user)
allBids = (
Bid.objects.exclude(is_deleted=True).select_related("lot_number__species_category").filter(user=user)
)
pageViews = PageView.objects.select_related("lot_number__species_category").filter(user=user)
# remove all user interests
UserInterestCategory.objects.filter(user=user).delete()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 5.0.8 on 2024-09-08 18:40

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("auctions", "0144_auction_date_online_bidding_ends_and_more"),
]

operations = [
migrations.AddField(
model_name="auction",
name="allow_deleting_bids",
field=models.BooleanField(
blank=True, default=False, help_text="Allow users to delete their own bids until the auction ends"
),
),
migrations.AddField(
model_name="bid",
name="is_deleted",
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name="lothistory",
name="changed_price",
field=models.BooleanField(
default=False,
help_text="Was this a bid that changed the price? If False, this lot will show up in the admin chat system",
),
),
]
55 changes: 41 additions & 14 deletions auctions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ def add_tos_info(qs):
return qs.annotate(
lots_bid_actual=Coalesce(
Subquery(
Bid.objects.filter(user=OuterRef("user"), lot_number__auction=OuterRef("auction"))
Bid.objects.exclude(is_deleted=True)
.filter(user=OuterRef("user"), lot_number__auction=OuterRef("auction"))
.values("user")
.annotate(count=Count("pk", distinct=True))
.values("count"),
Expand Down Expand Up @@ -624,6 +625,8 @@ class Auction(models.Model):
advanced_lot_adding.help_text = "Show lot number, quantity and description fields when bulk adding lots"
extra_promo_text = models.CharField(max_length=50, default="", blank=True, null=True)
extra_promo_link = models.URLField(blank=True, null=True)
allow_deleting_bids = models.BooleanField(default=False, blank=True)
allow_deleting_bids.help_text = "Allow users to delete their own bids until the auction ends"

def __str__(self):
result = self.title
Expand Down Expand Up @@ -2412,6 +2415,13 @@ def bids_can_be_removed(self):
return True
if self.ended:
return False
if (
not self.auction.is_online
and self.auction.date_online_bidding_ends
and self.auction.allow_bidding_on_lots
and timezone.now() > self.auction.date_online_bidding_ends
):
return False
return True

@property
Expand Down Expand Up @@ -2614,11 +2624,15 @@ def price(self):
@property
def max_bid(self):
"""returns the highest bid amount for this lot - this number should not be visible to the public"""
allBids = 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")[:2]
allBids = (
Bid.objects.exclude(is_deleted=True)
.filter(
lot_number=self.lot_number,
last_bid_time__lte=self.calculated_end,
amount__gte=self.reserve_price,
)
.order_by("-amount", "last_bid_time")[:2]
)
try:
# $1 more than the second highest bid
bidPrice = allBids[0].amount
Expand All @@ -2631,11 +2645,15 @@ def max_bid(self):
def bids(self):
"""Get all bids for this lot, highest bid first"""
# 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')
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")
bids = (
Bid.objects.exclude(is_deleted=True)
.filter(
lot_number=self.lot_number,
last_bid_time__lte=self.calculated_end,
amount__gte=self.reserve_price,
)
.order_by("-amount", "last_bid_time")
)
return bids

@property
Expand Down Expand Up @@ -2695,7 +2713,7 @@ def page_views(self):
@property
def number_of_bids(self):
"""How many users placed bids on this lot?"""
bids = Bid.objects.filter(
bids = Bid.objects.exclude(is_deleted=True).filter(
lot_number=self.lot_number,
bid_time__lte=self.calculated_end,
amount__gte=self.reserve_price,
Expand Down Expand Up @@ -2838,7 +2856,11 @@ def seller_ip(self):
@property
def bidder_ip_same_as_seller(self):
if self.seller_ip:
bids = Bid.objects.filter(lot_number__pk=self.pk, user__userdata__last_ip_address=self.seller_ip).count()
bids = (
Bid.objects.exclude(is_deleted=True)
.filter(lot_number__pk=self.pk, user__userdata__last_ip_address=self.seller_ip)
.count()
)
if bids:
return bids
return None
Expand Down Expand Up @@ -3207,13 +3229,18 @@ class Bid(models.Model):
last_bid_time = models.DateTimeField(auto_now_add=True, blank=True)
amount = models.PositiveIntegerField(validators=[MinValueValidator(1)])
was_high_bid = models.BooleanField(default=False)
is_deleted = models.BooleanField(default=False)
# note: there is not AuctionTOS field here - this means that bids can only be placed by Users
# AuctionTOSs CAN be declared the winners of lots without placing a single bid
# time will tell if this is a mistake or not

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

def delete(self, *args, **kwargs):
self.is_deleted = True
self.save()


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

@property
def lots_viewed(self):
Expand Down
3 changes: 3 additions & 0 deletions auctions/templates/auction_edit_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
$('#div_id_date_online_bidding_starts').show();
$('#div_id_date_online_bidding_ends').show();
$('#div_id_only_approved_bidders').show();
$('#div_id_allow_deleting_bids').show();
{% if not auction.is_online %}
$('#div_id_date_start label').html('In-person bidding opens<span class="asteriskField">*</span>');
$('#id_date_start_helptext').html('Does not change online bidding');
Expand All @@ -41,6 +42,7 @@
$('#div_id_date_online_bidding_starts').hide();
$('#div_id_date_online_bidding_ends').hide();
$('#div_id_only_approved_bidders').hide();
$('#div_id_allow_deleting_bids').hide();
{% if not auction.is_online %}
$('#div_id_date_start label').html('Bidding opens<span class="asteriskField">*</span>');
$('#id_date_start_helptext').html('When the auction actually starts');
Expand All @@ -50,6 +52,7 @@
{% if auction.is_online %}
$(document).ready(function() {
$('#div_id_only_approved_bidders').show();
$('#div_id_allow_deleting_bids').show();
});
{% endif %}
</script>
Expand Down
18 changes: 11 additions & 7 deletions auctions/templates/auctions/bid_confirm_delete.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
{% block title %} Delete bid {% endblock %}
{% load static %}
{% block content %}
<form method="post">{% csrf_token %}
<p>Are you sure you want to delete {{ object.user }}'s bid on {{object.lot_number.lot_name }}?</p>
<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.
</p>
<input type="submit" class='btn btn-danger' value="Delete">
<a href="{{object.lot_number.lot_link}}" class='btn btn-secondary'>Cancel</a>
</form>
<form method="post">{% csrf_token %}
{% if removing_own_bid %}
<p>Remove your bid on {{object.lot_number.lot_name }}?</p>
{% else %}
<p>Are you sure you want to delete {{ object.user }}'s bid on {{object.lot_number.lot_name }}?</p>
<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.
{% endif %}
</p>
<input type="submit" class='btn btn-danger' value="Delete">
<a href="{{object.lot_number.lot_link}}" class='btn btn-secondary'>Cancel</a>
</form>
{% endblock %}
12 changes: 9 additions & 3 deletions auctions/templates/view_lot_images.html
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,13 @@ <h3>{{ lot.lot_name }}</h3>
{% else %}
<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>
{% endif %}
<span id="your_bid">{% if viewer_bid %}Your max bid is $<span id='your_bid_price'>{{ viewer_bid }}</span>{% endif %}</span>
<span id="your_bid">
{% if viewer_bid %}
Your max bid is $<span id='your_bid_price'>{{ viewer_bid }}</span>
{% if lot.bids_can_be_removed and lot.auction.allow_deleting_bids %}
<a href="{% url 'delete_bid' pk=viewer_bid_pk %}" class='btn btn-danger btn-sm'>Remove your bid</a>
{% endif %}
{% endif %}</span>
{% if is_auction_admin %}{{ lot.auction_show_high_bidder_template }}{% endif %}
</span>
{% else %}
Expand Down Expand Up @@ -402,7 +408,7 @@ <h5>Exchange info</h5>
{% if force_buy_now %}
var dialogText = "Buy {{ lot.lot_name }} now for $" + bid + "?<br><br><small>All sales are final</small>";
{% else %}
var dialogText = "Bid $" + bid + " on {{ lot.lot_name }}<br><br><small>All bids are final</small>";
var dialogText = "Bid $" + bid + " on {{ lot.lot_name }}<br><br><small>{% if not lot.auction.allow_deleting_bids %}All bids are final{% endif %}</small>";
{% endif %}
{% if not lot.auction %}
dialogText += "<br><div>This lot is sold directly by {{ lot.user }}. Make sure to check the user's feedback.</div>";
Expand Down Expand Up @@ -459,7 +465,7 @@ <h5>Exchange info</h5>
{% if bids %}
<h5>Remove bids</h5>
{% for bid in bids %}
<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>
<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>
{% endfor %}
{% endif %}

Expand Down
2 changes: 1 addition & 1 deletion auctions/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
path("lots/user/", views.LotsByUser.as_view(), name="user_lots"),
path("lots/<int:pk>/<slug:slug>/", views.ViewLot.as_view()),
path("bids/", login_required(views.MyBids.as_view()), name="my_bids"),
path("bids/delete/<int:pk>/", views.BidDelete.as_view()),
path("bids/delete/<int:pk>/", views.BidDelete.as_view(), name="delete_bid"),
path("", views.toDefaultLandingPage),
path("old_about/", views.aboutSite, name="about"),
path("about/", views.PromoSite.as_view(), name="promo"),
Expand Down
Loading

0 comments on commit 2f55cc4

Please sign in to comment.