feat(pets): implements adoption

This commit is contained in:
2024-12-09 23:23:36 -03:00
parent 053eefe939
commit eff1c8b1b6
9 changed files with 82 additions and 11 deletions

View File

@@ -2,4 +2,4 @@ from app.extensions import db
class AdoptionStatus(db.Model): class AdoptionStatus(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
status = db.Column(db.String(255), nullable=False) name = db.Column(db.String(255), nullable=False)

View File

@@ -1,13 +1,10 @@
from app.extensions import db from app.extensions import db
import datetime
from sqlalchemy.orm import relationship, mapped_column from sqlalchemy.orm import relationship, mapped_column
class Adoptions(db.Model) : class Adoptions(db.Model) :
id = mapped_column(db.Integer, primary_key=True) id = mapped_column(db.Integer, primary_key=True)
publisher_id = mapped_column(db.Integer, db.ForeignKey('user.id'), nullable=False) adopter_id = mapped_column(db.Integer, db.ForeignKey('user.id'), nullable=False)
pet_id = mapped_column(db.Integer, db.ForeignKey('pet.id'), nullable=False) pet_id = mapped_column(db.Integer, db.ForeignKey('pet.id'), nullable=False)
publish_date = mapped_column(db.DateTime, default=datetime.datetime.utcnow, nullable=False)
status_id = mapped_column(db.Integer, db.ForeignKey('adoption_status.id'), nullable=False) status_id = mapped_column(db.Integer, db.ForeignKey('adoption_status.id'), nullable=False)
publisher = relationship("User") adopter = relationship("User")
pet = relationship("Pet") status = relationship("AdoptionStatus", uselist=False)
status = relationship("AdoptionStatus")

View File

@@ -14,5 +14,6 @@ class Pet(db.Model):
height = mapped_column(db.Float, default=0, nullable=False) height = mapped_column(db.Float, default=0, nullable=False)
registrar_id = mapped_column(db.Integer, db.ForeignKey('user.id'), nullable=False) registrar_id = mapped_column(db.Integer, db.ForeignKey('user.id'), nullable=False)
registration_date = mapped_column(db.DateTime, default=datetime.datetime.utcnow, nullable=False) registration_date = mapped_column(db.DateTime, default=datetime.datetime.utcnow, nullable=False)
adoption = relationship("Adoptions",uselist=False)
kind = relationship("PetKind") kind = relationship("PetKind")
registrar = relationship("User") registrar = relationship("User",uselist=False)

View File

@@ -23,3 +23,10 @@ def register():
flash(FlashMessage("Pet added!", AlertType.SUCCESS.value )) flash(FlashMessage("Pet added!", AlertType.SUCCESS.value ))
types = PetService.get_pets_kind() types = PetService.get_pets_kind()
return render_template("pets/register.html", types=types) return render_template("pets/register.html", types=types)
@bp.route('adopt')
@login_required
def adopt():
if not PetService.adopt_pet(request):
return redirect("/users/login")
return redirect("/pets/")

View File

@@ -2,9 +2,13 @@ import cloudinary
import cloudinary.uploader import cloudinary.uploader
import os import os
from flask import flash, Request, session from flask import flash, Request, session
from sqlalchemy import Row, ScalarResult
from app.extensions import db from app.extensions import db
from app.models.adoptions import Adoptions
from app.models.adoption_status import AdoptionStatus
from app.models.pet import Pet from app.models.pet import Pet
from app.models.pet_kind import PetKind from app.models.pet_kind import PetKind
from app.utils.adoption_status import AdoptionStatusEnum
from app.utils.alert_type import AlertType from app.utils.alert_type import AlertType
from app.utils.errors.pets.pet_register_errors import PetRegisterError from app.utils.errors.pets.pet_register_errors import PetRegisterError
from app.utils.flash_message import FlashMessage from app.utils.flash_message import FlashMessage
@@ -12,6 +16,35 @@ from app.utils.helpers import pet_sex_id_to_str
from app.utils.validators.pet_validators import PetValidators from app.utils.validators.pet_validators import PetValidators
class PetService: class PetService:
@staticmethod
def adopt_pet(request: Request):
pet_id = request.args.get('id')
user_id = session.get('id')
if user_id is None:
session.clear()
return False
pet = PetValidators.is_valid_pet_id(pet_id)
if pet is not None:
if pet[0].registrar_id != user_id:
if db.session.execute(db.select(Adoptions).filter_by(pet_id=pet_id)).one_or_none() == None:
adoption_statuses: ScalarResult[AdoptionStatus] = db.session.execute(db.select(AdoptionStatus)).scalars();
pending_status_id = None
for adoption_status in adoption_statuses:
if adoption_status.name == AdoptionStatusEnum.PENDING.value:
pending_status_id = adoption_status.id
if pending_status_id is not None:
adoption = Adoptions(
adopter_id=user_id,
pet_id=pet_id,
status_id=pending_status_id
)
db.session.add(adoption)
db.session.commit()
db.session.flush()
return True
@staticmethod @staticmethod
def register_pet(request: Request): def register_pet(request: Request):
user_id = session.get('id') user_id = session.get('id')

View File

@@ -38,6 +38,14 @@
background-color: #fd0d99; background-color: #fd0d99;
} }
.fliping-card__side--front-adopted {
filter: grayscale(1);
}
.fliping-card__side--back a {
color: white;
}
.fliping-card:hover .fliping-card__side--back { .fliping-card:hover .fliping-card__side--back {
transform: rotateY(0); transform: rotateY(0);
} }

View File

@@ -7,6 +7,9 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="pets container"> <div class="pets container">
<div class="row px-2">
{% include 'message.html' %}
</div>
<div class="row px-2"> <div class="row px-2">
<div class="card py-4 mb-3 mb-md-0 mt-4"> <div class="card py-4 mb-3 mb-md-0 mt-4">
<div class="col-12"> <div class="col-12">
@@ -74,7 +77,11 @@
{% for pet in pagination_result.items %} {% for pet in pagination_result.items %}
<div class="col-6 col-sm-4 col-md-4 col-lg-3 mt-3 mt-md-5"> <div class="col-6 col-sm-4 col-md-4 col-lg-3 mt-3 mt-md-5">
<div class="fliping-card img-fluid mx-auto"> <div class="fliping-card img-fluid mx-auto">
<div class="fliping-card__side fliping-card__side--front"> <div class="fliping-card__side fliping-card__side--front
{%if pet.adoption != none and pet.adoption.status.name != 'rejected' %}
{{'fliping-card__side--front-adopted'}}
{% endif %}
">
<img alt="pet" width="200" height="200" src="{{ pet.img_src }}" class="img-fluid"> <img alt="pet" width="200" height="200" src="{{ pet.img_src }}" class="img-fluid">
</div> </div>
<div class="fliping-card__side fliping-card__side--back <div class="fliping-card__side fliping-card__side--back
@@ -89,7 +96,11 @@
<li>Age: {{pet.age}}, Sex: {{pet.sex}}</li> <li>Age: {{pet.age}}, Sex: {{pet.sex}}</li>
<li>W: {{pet.weight}}lbs., H: {{pet.height}}ft.</li> <li>W: {{pet.weight}}lbs., H: {{pet.height}}ft.</li>
<li>Location: {{pet.location}}</li> <li>Location: {{pet.location}}</li>
<li>Ask for adoption!</li> {%if pet.adoption != none and pet.adoption.status.name != 'rejected' %}
<li>This pet is currently in an adoption process.</li>
{% else %}
<li><a href="{% if session['id'] %} {{'/pets/adopt?id=' ~ pet.id}} {% else %} {{'/users/login'}}{% endif %}">Ask for adoption!</a></li>
{% endif %}
</ul> </ul>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,6 @@
from enum import Enum
class AdoptionStatusEnum(Enum):
APPROVED = "approved"
PENDING = "pending"
REJECTED = "rejected"

View File

@@ -4,6 +4,7 @@ from app.models.pet import Pet
from app.models.pet_kind import PetKind from app.models.pet_kind import PetKind
from app.models.adoptions import Adoptions from app.models.adoptions import Adoptions
from app.models.adoption_status import AdoptionStatus from app.models.adoption_status import AdoptionStatus
from app.utils.adoption_status import AdoptionStatusEnum
from datetime import date from datetime import date
from random import randrange from random import randrange
from werkzeug.security import generate_password_hash from werkzeug.security import generate_password_hash
@@ -34,6 +35,13 @@ class DBUtils():
db.session.add_all([dog,cat]) db.session.add_all([dog,cat])
db.session.commit() db.session.commit()
"""Adoption statuses"""
adoption_pending = AdoptionStatus(name=AdoptionStatusEnum.PENDING.value)
adoption_approved = AdoptionStatus(name=AdoptionStatusEnum.APPROVED.value)
adoption_rejected = AdoptionStatus(name=AdoptionStatusEnum.REJECTED.value)
db.session.add_all([adoption_pending,adoption_approved,adoption_rejected])
db.session.commit()
"""Pets""" """Pets"""
pets = [] pets = []
for i in range(40): for i in range(40):