Files
classifieds/app/services/reviews.py
T
2026-06-18 09:29:33 -04:00

49 lines
1.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Review business logic."""
from sqlalchemy.exc import IntegrityError
from app.extensions import db
from app.models.review import Review
class ReviewError(ValueError):
pass
def create_review(listing, author, rating: int, body: str | None = None):
"""Leave a review for a seller. Listing must be sold. Returns Review."""
from app.models.enums import ListingStatus
if listing.status != ListingStatus.sold:
raise ReviewError("can only review sold listings")
if listing.user_id == author.id:
raise ReviewError("cannot review your own listing")
if rating not in range(1, 6):
raise ReviewError("rating must be 15")
review = Review(
listing_id=listing.id,
author_id=author.id,
seller_id=listing.user_id,
rating=rating,
body=(body or "").strip() or None,
)
db.session.add(review)
try:
db.session.commit()
except IntegrityError:
db.session.rollback()
raise ReviewError("you have already reviewed this listing")
return review
def seller_rating(user_id) -> dict:
"""Return avg rating and count for a seller."""
from app.extensions import db
result = (db.session.query(
db.func.round(db.func.avg(Review.rating), 1).label("avg"),
db.func.count(Review.id).label("count"))
.filter(Review.seller_id == user_id)
.first())
return {
"avg": float(result.avg) if result.avg else None,
"count": result.count or 0,
}