Skip to content
Snippets Groups Projects
Commit ca0872aa authored by MikaelKrats's avatar MikaelKrats
Browse files

Merge branch 'main' into localization-multicurrency-2

Fixed Conflicts:
#	src/tjts5901/templates/addItem.html
#	src/tjts5901/views.py
parents a8c97f26 d1a98bb9
No related branches found
No related tags found
1 merge request!60Multicurrency
Pipeline #15952 passed
......@@ -6,6 +6,7 @@ flask==2.2.2
python-dotenv
flask-login
flask_babel
datetime
flask-mongoengine==1.0
Pillow
......
......@@ -221,6 +221,8 @@ def profile(email):
for item in items:
item.current_price = get_item_price(item)
item.created_at = item.created_at.strftime("%Y-%m-%d %H:%M:%S")
item.closes_at = item.closes_at.strftime("%Y-%m-%d %H:%M:%S")
item.image_base64 = base64.b64encode(item.image.read()).decode('utf-8')
return render_template('auth/profile.html', user=user, items=items)
......
......@@ -67,6 +67,8 @@ class Item(db.Document):
meta = {"indexes": [
{"fields": [
"closes_at",
"closed_processed",
"seller_informed_about_result"
]}
]}
......@@ -82,6 +84,14 @@ class Item(db.Document):
closes_at = DateTimeField()
closed_processed = BooleanField(required=True, default=False)
"Flag indicating if closing of auction was already processed"
seller_informed_about_result = BooleanField(required=True, default=False)
"Flag indicating if seller has already been informed about the result of the auction"
image = FileField()
def save(self, *args, **kwargs):
......@@ -113,6 +123,9 @@ class Bid(db.Document):
"amount",
"item",
"created_at",
"auction_end_processed",
"winning_bid",
"bidder_informed"
]}
]}
......@@ -128,6 +141,15 @@ class Bid(db.Document):
created_at = DateTimeField(required=True, default=datetime.utcnow)
"Date and time that the bid was placed."
auction_end_processed = BooleanField(required=True, default=False)
"Flag indicating, that closed auction has been processes"
winning_bid = BooleanField(required=True, default=False)
"Flag indicating, whether the bid was the winning bid of the auction"
bidder_informed = BooleanField(required=True, default=False)
"Flag indicating, whether the bidder has been informed about the result of the auction"
class AccessToken(db.Document):
......
......@@ -27,11 +27,18 @@
<input type="number" class="form-control" id="sPrice" name="sPrice" min="0" max="100000000">
</div>
<div class="mb-3">
<label for="currency" class="form-label">Currency</label>
<select name="currency" id="currency" class="form-control">
{% for code, name in currencies.items() %}
<option value="{{ code }}" {% if code == default_currency %}selected{% endif %}>{{ name }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
</select>
<label for="closing" class="form-label">Duration of auction in hours and minutes</label>
<input type="time" id="duration" name="duration" step="60">
</select>
</div>
<div class="mb-3">
<label for="image" class="form-label">Image (Please add image in .jpg format)</label>
......
......@@ -41,6 +41,8 @@
<p class="card-text">{{ auction.description }}</p>
<p class="card-text">Starting Bid: {{ auction.starting_bid }} €</p>
<p class="card-text">Current Price: {{ auction.current_price }} €</p>
<p class="card-text">Starting Time: {{ auction.created_at }} </p>
<p class="card-text">Closing Time: {{ auction.closes_at }} </p>
</div>
<div class="card-footer">
</div>
......
......@@ -36,7 +36,7 @@
<ul class="navbar-nav">
{% if current_user.is_authenticated %}
<li class="nav-item"><span>{{current_user['email'] }}</span></li>
<li class="nav-item"><a href="{{ url_for('auth.profile', email='me') }}" class="nav-link">My pro</a></li>
<li class="nav-item"><a href="{{ url_for('auth.profile', email='me') }}" class="nav-link">My Profile</a></li>
<li class="nav-item"><a href="{{ url_for('auth.logout') }}" class="nav-link">Log Out</a></li>
{% else %}
<li class="nav-item"><a href="{{ url_for('auth.register') }}" class="nav-link">Register</a>
......
......@@ -7,8 +7,9 @@ import base64
import logging
from typing import Optional
from datetime import datetime, timedelta
from mongoengine.queryset.visitor import Q
from flask import Blueprint, flash, redirect, render_template, request, url_for, jsonify
from .models import Item, User, Bid
from .models import Item, Bid
from .auth import login_required, current_user
from flask_babel import _, get_locale
......@@ -78,6 +79,66 @@ def get_item_price(item: Item) -> int:
return winning_bid.amount
else:
return item.starting_bid
def check_auction_ends():
"""
Check if all previously not processed auctions have ended now
Get all closed items, check if they belong to the current user and inform about
the ending of the auction.
Then process all bids on these items and check if they won
"""
items = Item.objects.filter(Q(closes_at=datetime.utcnow()) & Q(closed_processed=False)) \
.order_by('-closes_at')
for item in items:
item.update(closed_processed = True)
message = None
if item.seller == current_user:
message = "The auction of your item \'{}\' has ended. ".format(item.title)
item.update(seller_informed_about_result = True)
# Get (potential) bids for the item and process them
bids = Bid.objects(item=item).order_by('-amount')
if len(bids) >= 1:
# Set winning_bid = True for winning bid
bids[0].update(winning_bid = True)
bids[0].update(auction_end_processed = True)
# Set winning_bid = False for all other bids
for bid in bids[1:]:
bid.update(winning_bid = False)
bid.update(auction_end_processed = True)
# Inform seller if this is current user
if item.seller == current_user:
message += "Congrats! It was sold for {}.".format(bids[0].amount)
# Inform current user if no one bid on the item
else:
if item.seller == current_user:
message += "No one bid on your item. Try again!"
#Display message if not None
if message is not None:
flash((message))
def check_bids_ended():
"""
Method for checking all bids of current user, marked as auction_end_processed
and inform bidder if neccessary
"""
bids = Bid.objects.filter(Q(bidder=current_user) & Q(auction_end_processed=True) & Q(bidder_informed=False))
if len(bids) >= 1:
for bid in bids:
if bid.winning_bid == True:
flash(("Congrats! You won the auction of '{}' with your bid over {}.".format(bid.item.title, bid.amount)))
else:
flash(("Pity! You were not successfull with the auction of '{}' with your bid over {}.".format(bid.item.title, bid.amount)))
bid.update(bidder_informed = True)
@bp.route("/test")
......@@ -97,6 +158,7 @@ def test_item_adding():
item.starting_bid = 100
item.seller = current_user
item.image = image
item.closes_at = datetime.utcnow() + timedelta(days=1)
item.save()
......@@ -115,11 +177,16 @@ def add_item():
currency = request.form.get('currency', REF_CURRENCY)
starting_price = convert_from_currency(request.form['sPrice'], currency)
image = request.files['image']
duration = request.form.get('duration')
error = None
if not nItem:
error = 'Item name is required.'
if not starting_price or starting_price < 1:
error = Markup(_("Starting bid must be greater than %(amount)s.", amount=format_converted_currency(1, currency)))
if not duration:
error = 'Duration is required.'
print(duration, type(duration))
if error is None:
try:
......@@ -128,7 +195,7 @@ def add_item():
description=description,
starting_bid=starting_price,
seller=current_user,
closes_at=datetime.utcnow() + timedelta(days=1),
closes_at=datetime.utcnow() + timedelta(hours=int(duration[:2]), minutes=int(duration[-2:])),
image=image
)
......@@ -157,15 +224,18 @@ def add_item():
@login_required
def list_bid():
"""
page that lists all items currently on auction
page that lists all items currently on auction and checks for notification
"""
check_auction_ends()
check_bids_ended()
# only on sale items are shown
items = Item.objects.filter(closes_at__gt=datetime.utcnow()) \
.order_by('-closes_at')
for item in items:
item.image_base64 = base64.b64encode(item.image.read()).decode('utf-8')
item.created_at = item.created_at.strftime("%Y-%m-%d %H:%M:%S")
item.current_price = get_item_price(item)
html = render_template("listBid.html", items=items)
......@@ -335,10 +405,7 @@ def page_bid(id):
local_min_bid = convert_currency(min_bid, local_currency)
item.image_base64 = base64.b64encode(item.image.read()).decode('utf-8')
# Dark pattern to show enticing message to user
#if item.closes_at < datetime.utcnow() + timedelta(hours=1):
# flash("This item is closing soon! Act now! Now! Now!")
item.created_at = item.created_at.strftime("%Y-%m-%d %H:%M:%S")
return render_template('view.html',
item=item, min_bid=min_bid,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment