feat(pets): implements adoption
This commit is contained in:
@@ -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)
|
||||||
@@ -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")
|
|
||||||
@@ -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)
|
||||||
@@ -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/")
|
||||||
@@ -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')
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
6
app/utils/adoption_status.py
Normal file
6
app/utils/adoption_status.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
class AdoptionStatusEnum(Enum):
|
||||||
|
APPROVED = "approved"
|
||||||
|
PENDING = "pending"
|
||||||
|
REJECTED = "rejected"
|
||||||
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user