Skip to content

Commit

Permalink
no_bid
Browse files Browse the repository at this point in the history
  • Loading branch information
= committed Aug 15, 2024
1 parent 4d35d99 commit 4d900d3
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 53 deletions.
44 changes: 22 additions & 22 deletions auctions/consumers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ def check_bidding_permissions(lot, user):
return "Bidding on this lot has ended"
if lot.user and lot.user.pk == user.pk:
return "You can't bid on your own lot"
if lot.auction:
tos = AuctionTOS.objects.filter(Q(user=user)|Q(email=user.email), auction=lot.auction).first()
if not tos:
return "You haven't joined this auction"
else:
if not tos.bidding_allowed:
return "This auction requires admin approval before you can bid"
return False

def check_chat_permissions(lot, user):
Expand All @@ -43,18 +50,12 @@ def check_chat_permissions(lot, user):

def check_all_permissions(lot, user):
"""Returns false if everything is OK, or a string error message"""
try:
ban = UserBan.objects.get(banned_user=user.pk, user=lot.user.pk)
if UserBan.objects.filter(banned_user=user.pk, user=lot.user.pk).first():
return "This user has banned you from bidding on their lots"
except:
pass
try:
ban = UserBan.objects.get(banned_user=user.pk, user=lot.auction.created_by.pk)
return "The owner of this auction has banned you from bidding"
except:
pass
if lot.banned:
return "This lot has been removed"
if lot.auction and UserBan.objects.filter(banned_user=user.pk, user=lot.auction.created_by.pk).first():
return "You don't have permission to bid in this auction"
return False

def reset_lot_end_time(lot):
Expand Down Expand Up @@ -102,15 +103,15 @@ def bid_on_lot(lot, user, amount):
if lot.bidding_error:
result['message'] = lot.bidding_error
return result
if lot.winner:
if lot.winner or lot.auctiontos_winner:
result['message'] = "This lot has already been sold"
return result
if lot.auction:
invoice = Invoice.objects.filter(auctiontos_user__user=user, auction=lot.auction).first()
if invoice:
if invoice.status != "DRAFT":
result['message'] = "Your invoice for this auction is not open. An administrator can reopen it and allow you to bid."
return result
if invoice and invoice.status != "DRAFT":
result['message'] = "Your invoice for this auction is not open. An administrator can reopen it and allow you to bid."
return result

originalHighBidder = lot.high_bidder
originalBid = lot.high_bid
originalMaxBid = lot.max_bid
Expand Down Expand Up @@ -396,14 +397,13 @@ def receive(self, text_data):
try:
error = check_all_permissions(self.lot, self.user)
if error:
if error:
async_to_sync(self.channel_layer.group_send)(
self.user_room_name,
{
'type': 'error_message',
'error': error
}
)
async_to_sync(self.channel_layer.group_send)(
self.user_room_name,
{
'type': 'error_message',
'error': error
}
)
else:
try:
message = text_data_json['message']
Expand Down
4 changes: 3 additions & 1 deletion auctions/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def generic(self, qs, value):
['frank','franklin','frankie'],
['fred','frederick','freddy'],
['gary','gareth'],
['george','georgie'],
['george','georgie', 'geo'],
['greg','gregory','gregg'],
['hank','henry'],
['jack','jackson','jackie'],
Expand Down Expand Up @@ -143,6 +143,8 @@ def generic(self, qs, value):
'club owes': {'auctiontos__calculated_total__gt': 0},
'seen': {'auctiontos__opened': True},
'unseen': {'auctiontos__opened': False},
'no bid': {'bidding_allowed': False},
'no sell': {'selling_allowed': False},
}

# Apply filters based on patterns
Expand Down
24 changes: 17 additions & 7 deletions auctions/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,7 @@ def __init__(self, is_edit_form, auctiontos, auction, *args, **kwargs):
'address',
'pickup_location',
'selling_allowed',
'bidding_allowed',
Div(
Div('is_club_member',css_class='col-sm-6',),
Div('is_admin',css_class='col-sm-6',),
Expand Down Expand Up @@ -694,9 +695,15 @@ def __init__(self, is_edit_form, auctiontos, auction, *args, **kwargs):
self.fields['is_admin'].initial = self.auctiontos.is_admin
self.fields['is_club_member'].initial = self.auctiontos.is_club_member
self.fields['selling_allowed'].initial = self.auctiontos.selling_allowed
self.fields['bidding_allowed'].initial = self.auctiontos.bidding_allowed
if not auction.allow_bidding_on_lots and not self.auctiontos:
self.fields['bidding_allowed'].widget = HiddenInput()
if not auction.allow_bidding_on_lots and self.auctiontos and self.auctiontos.bidding_allowed:
self.fields['bidding_allowed'].widget = HiddenInput()
else:
# special rule: default to the default location
self.fields['is_admin'].widget = HiddenInput()
self.fields['bidding_allowed'].widget = HiddenInput()
# special rule: default to the default location
if auction.location_qs.count() == 1:
self.fields['pickup_location'].initial = auction.location_qs.first()
if auction.location_qs.count() == 1:
Expand Down Expand Up @@ -728,6 +735,7 @@ class Meta:
'phone_number',
'address',
'selling_allowed',
'bidding_allowed',
'is_club_member',
'memo',
]
Expand Down Expand Up @@ -1213,9 +1221,9 @@ class Meta:
model = Auction
fields = ['notes', 'lot_entry_fee','unsold_lot_fee','winning_bid_percent_to_club', 'date_start', 'date_end', 'lot_submission_start_date',\
'lot_submission_end_date', 'sealed_bid','use_categories', 'promote_this_auction', 'max_lots_per_user', 'allow_additional_lots_as_donation',
'email_users_when_invoices_ready', 'pre_register_lot_discount_percent', 'only_approved_sellers',
'email_users_when_invoices_ready', 'pre_register_lot_discount_percent', 'only_approved_sellers', 'only_approved_bidders',
'invoice_payment_instructions', 'minimum_bid', 'winning_bid_percent_to_club_for_club_members', 'lot_entry_fee_for_club_members', 'require_phone_number',
'reserve_price', 'buy_now', 'tax', 'allow_bidding_on_lots',
'reserve_price', 'buy_now', 'tax',
]
widgets = {
'date_start': DateTimePickerInput(),
Expand All @@ -1241,14 +1249,15 @@ def __init__(self, *args, **kwargs):
#self.fields['notes'].help_text = "Foo"
if self.instance.is_online:
self.fields['lot_submission_end_date'].help_text = "This should be 1-24 hours before the end of your auction"
self.fields['allow_bidding_on_lots'].help_text = "Leave this checked or people won't be able to bid!"
self.fields['allow_bidding_on_lots'].widget=forms.HiddenInput()
#self.fields['allow_bidding_on_lots'].help_text = "Leave this checked or people won't be able to bid!"
#self.fields['allow_bidding_on_lots'].widget=forms.HiddenInput()
#self.fields['pre_register_lot_entry_fee_discount'].widget=forms.HiddenInput()
self.fields['pre_register_lot_discount_percent'].widget=forms.HiddenInput()
#self.fields['set_lot_winners_url'].widget=forms.HiddenInput()
else:
self.fields['only_approved_bidders'].widget=forms.HiddenInput()
self.fields['unsold_lot_fee'].widget=forms.HiddenInput()
self.fields['allow_bidding_on_lots'].help_text = "Allow people to place bids online. You should probably leave this unchecked."
#self.fields['allow_bidding_on_lots'].help_text = "Allow people to place bids online. You should probably leave this unchecked."
self.fields['date_end'].help_text = "You should probably leave this blank so that you can manually set winners. This field has been indefinitely set to hidden - see https://github.com/iragm/fishauctions/issues/116"
self.fields['date_end'].widget=forms.HiddenInput()
self.fields['lot_submission_end_date'].help_text = 'This should probably be before bidding starts. Admins (you) can add more lots at any time, this only restricts users.'
Expand Down Expand Up @@ -1321,7 +1330,8 @@ def __init__(self, *args, **kwargs):
Div('max_lots_per_user', css_class='col-md-3',),
Div('allow_additional_lots_as_donation', css_class='col-md-3',),
Div('only_approved_sellers',css_class='col-md-3',),
Div('allow_bidding_on_lots', css_class='col-md-3',),
Div('only_approved_bidders',css_class='col-md-3',),
#Div('allow_bidding_on_lots', css_class='col-md-3',),
css_class='row',
),

Expand Down
20 changes: 18 additions & 2 deletions auctions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ class Auction(models.Model):
only_approved_sellers = models.BooleanField(default=False)
only_approved_sellers.help_text = "Require admin approval before users can add lots. This will not change permissions for users that have already joined."
only_approved_bidders = models.BooleanField(default=False)
only_approved_bidders.help_text = "Require admin approval before users can bid. This will not change permissions for users that have already joined."
only_approved_bidders.help_text = "Require admin approval before users can bid. This only applies to new users: Users that you manually add and users who have a paid invoice in a past auctions will be allowed to bid."
require_phone_number = models.BooleanField(default=False)
require_phone_number.help_text = "Require users to have entered a phone number before they can join this auction"
email_users_when_invoices_ready = models.BooleanField(default=True)
Expand Down Expand Up @@ -1098,7 +1098,11 @@ def phone_as_string(self):
def bulk_add_link_html(self):
"""Link to add multiple lots at once for this user"""
url = reverse("bulk_add_lots", kwargs = {'bidder_number':self.bidder_number, 'slug':self.auction.slug})
return html.format_html(f"<a href='{url}' hx-noget><i class='bi bi-calendar-plus me-1'></i>Add lots</a>")
if not self.selling_allowed:
icon = '<i class="text-danger me-1 bi bi-cash-coin" title="Selling not allowed"></i>'
else:
icon = "<i class='bi bi-calendar-plus me-1'></i>"
return html.format_html(f"<a href='{url}' hx-noget>{icon} Add lots</a>")

@property
def bought_lots_qs(self):
Expand Down Expand Up @@ -1191,6 +1195,18 @@ def check_number_in_auction(number):
#print("new instance of auctionTOS")
if self.auction.only_approved_sellers:
self.selling_allowed = False
if self.auction.only_approved_bidders:
# default
self.bidding_allowed = False
if self.manually_added:
# anyone manually added can bid
self.bidding_allowed = True
else:
if self.user:
auction_admins = AuctionTOS.objects.filter(is_admin=True, auction=self.auction).values_list('user__pk', flat=True)
user_has_participated_before = AuctionTOS.objects.filter(user=self.user, auction__created_by__pk__in=auction_admins, auctiontos__status='PAID').first()
if user_has_participated_before:
self.bidding_allowed = True
# no emails for in-person auctions, thankyouverymuch
if not self.auction.is_online:
pass
Expand Down
8 changes: 6 additions & 2 deletions auctions/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ def render_name(self, value, record):
# as a link, looks better
result = f"<a href='' hx-noget hx-get='/api/auctiontos/{record.pk}' hx-target='#modals-here' hx-trigger='click'><i class='bi bi-person-fill-gear me-1'></i>{value}</a>"
if record.is_club_member:
return mark_safe(f'{result} <span class="badge bg-info">Member</span>')
result += '<span class="badge bg-info ms-1 me-1" title="Alternate selling fees will be applied">Member</span>'
if not record.bidding_allowed:
result += '<i class="text-danger bi bi-exclamation-octagon-fill" title="Bidding not allowed"></i>'
# if not record.bidding_allowed:
# result += '<i class="text-danger ms-1 bi bi-cash-coin" title="Selling not allowed"></i>'
return mark_safe(result)

def render_email(self, value, record):
email_string = f'<a href="mailto:{value}">{value}</a>'
#email_string = value
if record.user:
email_string += ""
email_string += "<i class='bi bi-check me-1' title='Verified email'></i>"
return mark_safe(email_string)

class Meta:
Expand Down
8 changes: 8 additions & 0 deletions auctions/templates/auction_users.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@
<i class="bi bi-filter"></i> Filters
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
{% if auction.is_online %}
<label class="dropdown-item ">
<input type="checkbox" class="invoice_filter" id="checkbox_no_bid"> <i class="bi bi-exclamation-octagon-fill"></i> Can't bid
</label>
{% endif %}
<label class="dropdown-item ">
<input type="checkbox" class="invoice_filter" id="checkbox_no_sell"> <i class="bi bi-exclamation-octagon-fill"></i> Can't sell
</label>
<span class="text-muted dropdown-item"><small>Users with an invoice that is:</small></span>
<label class="dropdown-item ">
<input type="checkbox" class="invoice_filter" id="checkbox_open"> <i class="bi bi-bag"></i> Open
Expand Down
6 changes: 3 additions & 3 deletions auctions/templates/auctions/auctiontos_confirm_delete.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block title %} Delete user {% endblock %}
{% block title %} Remove user {% endblock %}
{% load static %}
{% block extra_js %}
<script>
Expand Down Expand Up @@ -29,8 +29,8 @@
</script>
{% endblock %}
{% block content %}
<h4>Delete user</h4>
<p>Are you sure you want to delete {{ auctiontos.name }}?</p>
<h4>Remove {{ auctiontos.name }}</h4>
<p>Are you sure you want to remove {{ auctiontos.name }} from {{ auctiontos.auction }}?</p>
<span class="text-warning">This cannot be undone!</span><br><br>
{% crispy form form.helper %}
{% endblock %}
2 changes: 1 addition & 1 deletion auctions/templates/invoice_buttons.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{# invoice status buttons #}
{% if invoice %}
<div class="btn-group" id='invoice-buttons' role="group" aria-label="Invoice status selection">
<div class="btn-group ms-1 me-1" id='invoice-buttons' role="group" aria-label="Invoice status selection">
<button type="button" id="{{invoice.pk}}_DRAFT" hx-post="/api/payinvoice/{{ invoice.pk }}/DRAFT" hx-target="#invoice-buttons" hx-swap="outerHTML" class="btn {% if invoice.status == 'DRAFT'%}btn-info{% else %}btn-secondary{% endif %}"><i class="bi bi-bag"></i> Open</button>
<button type="button" id="{{invoice.pk}}_UNPAID" hx-post="/api/payinvoice/{{ invoice.pk }}/UNPAID" hx-target="#invoice-buttons" hx-swap="outerHTML" class="btn {% if invoice.status == 'UNPAID'%}btn-info{% else %}btn-secondary{% endif %}"><i class="bi bi-bag-plus"></i> Ready</button>
<button type="button" id="{{invoice.pk}}_PAID" hx-post="/api/payinvoice/{{ invoice.pk }}/PAID" hx-target="#invoice-buttons" hx-swap="outerHTML" class="btn {% if invoice.status == 'PAID'%}btn-success{% else %}btn-secondary{% endif %}"><i class="bi bi-bag-heart"></i> Paid</button>
Expand Down
15 changes: 4 additions & 11 deletions auctions/templates/view_lot_images.html
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ <h3>{{ lot.lot_name }}</h3>
<span id="your_bid">{% if viewer_bid %}Your max bid is $<span id='your_bid_price'>{{ viewer_bid }}</span>{% endif %}</span>
</span>
{% else %}
$<span id="price">{{ lot.reserve_price }} {% if lot.buy_now_price and not lot.bidding_error %}<button type="button" class='btn btn-sm btn-info' id="buy-now">Buy now: ${{lot.buy_now_price}}</button>{% endif %}</span> <span id="high_bidder_name"></span><span id="your_bid"></span>
$<span id="price">{{ lot.reserve_price }} {% if lot.buy_now_price and not lot.bidding_error %}<button type="button" class='btn btn-sm btn-success text-black' id="buy-now">Buy now: ${{lot.buy_now_price}}</button>{% endif %}</span> <span id="high_bidder_name"></span><span id="your_bid"></span>
{% endif %}
{% endif %}
{% endif %}
Expand Down Expand Up @@ -487,19 +487,12 @@ <h5 class="modal-title" id="label">Confirm bid</h5>
<div class="modal fade" id="bidError" tabindex="-1" role="dialog" aria-labelledby="label" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-danger">
<h5 class="modal-title" id="label">Bid failed!</h5>
<div class="modal-header">
<h5 class="modal-title text-danger" id="label"><i class="bi bi-exclamation-circle-fill"></i> Bid failed!</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div id='confirmDialogText' class="modal-body">
{% if not user.is_authenticated %}
You have to <a href='/login/?next={{ lot.lot_link }}'>sign in</a> to place bids.
{% elif not user_tos %}
This lot is part of <b>{{ lot.auction }}</b>. Please <a href='/auctions/{{lot.auction.slug}}/?next=/lots/{{ lot.pk }}/#join'>read the auction's rules and confirm your pickup location</a> to bid<br>
{% elif lot.user.pk == request.user.id %} You can't bid on your own lot.
{% else %}
An unknown error occurred.
{% endif %}
{{ user_specific_bidding_error|safe }}
</div>
<div class="modal-footer">
{% if not user.is_authenticated %}
Expand Down
Loading

0 comments on commit 4d900d3

Please sign in to comment.