-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maple - Stephanie & Ayaka #42
base: master
Are you sure you want to change the base?
Changes from all commits
658018b
9927276
0daf6f3
3c59c31
a997a41
4668b72
150530c
8a26d94
c1a800e
818526c
164a196
ce8d7e7
334c75b
8070c54
ab622b6
73c1f20
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,17 @@ | ||
from app import db | ||
|
||
class Customer(db.Model): | ||
id = db.Column(db.Integer, primary_key=True) | ||
id = db.Column(db.Integer, primary_key=True) | ||
name = db.Column(db.String(40)) | ||
postal_code = db.Column(db.String) | ||
phone = db.Column(db.String) | ||
register_at = db.Column(db.DateTime) | ||
videos = db.relationship("Video", secondary="rental", backref="customers") | ||
|
||
def to_dict(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 yay model methods! |
||
return { | ||
"id": self.id, | ||
"name": self.name, | ||
"phone": self.phone, | ||
"postal_code": self.postal_code | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,19 @@ | ||
from app import db | ||
from app.models.video import Video | ||
|
||
class Rental(db.Model): | ||
id = db.Column(db.Integer, primary_key=True) | ||
id = db.Column(db.Integer, primary_key=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
customer_id = db.Column(db.Integer, db.ForeignKey('customer.id')) | ||
video_id = db.Column(db.Integer, db.ForeignKey('video.id')) | ||
due_date = db.Column(db.DateTime) | ||
is_checked_in = db.Column(db.Boolean, default=False) | ||
|
||
def to_dict(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
video = Video.query.get(self.video_id) | ||
checked_out = Rental.query.filter_by(video_id = self.video_id, is_checked_in=False).all() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like how you both used queries to dynamically calculate your JSON data! |
||
return { | ||
"video_id": self.video_id, | ||
"customer_id": self.customer_id, | ||
"videos_checked_out_count": len(checked_out), | ||
"available_inventory": video.total_inventory - len(checked_out) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,20 @@ | ||
from app import db | ||
|
||
class Video(db.Model): | ||
id = db.Column(db.Integer, primary_key=True) | ||
id = db.Column(db.Integer, primary_key=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
title = db.Column(db.String) | ||
release_date = db.Column(db.DateTime) | ||
total_inventory = db.Column(db.Integer) | ||
|
||
def to_dict(self): | ||
return { | ||
"id": self.id, | ||
"title": self.title, | ||
"total_inventory": self.total_inventory | ||
} | ||
|
||
def to_dict_using_rentals(self): | ||
return { | ||
"title": self.title, | ||
"release_date": self.release_date | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .video_routes import videos_bp | ||
from .customer_routes import customers_bp | ||
from .rental_routes import rentals_bp |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,99 @@ | ||||||||
from app import db | ||||||||
from app.models.customer import Customer | ||||||||
from app.models.rental import Rental | ||||||||
from flask import Blueprint, request, jsonify | ||||||||
|
||||||||
customers_bp = Blueprint("customers", __name__, url_prefix="/customers") | ||||||||
|
||||||||
@customers_bp.route("", methods=["GET"]) | ||||||||
def get_all_customers(): | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||||
customers = Customer.query.all() | ||||||||
response_body = [customer.to_dict() for customer in customers] | ||||||||
return jsonify(response_body) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. solely for consistency's sake between all routes, don't forget to add a status code here
Suggested change
|
||||||||
|
||||||||
@customers_bp.route("", methods=["POST"]) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 I see you separated each method out into its own route! nice |
||||||||
def create_customer(): | ||||||||
request_body = request.get_json() | ||||||||
|
||||||||
error_message = validate_request(request_body) | ||||||||
if error_message: | ||||||||
return error_message | ||||||||
|
||||||||
new_customer = Customer( | ||||||||
name= request_body["name"], | ||||||||
phone= request_body["phone"], | ||||||||
postal_code= request_body["postal_code"] | ||||||||
) | ||||||||
|
||||||||
db.session.add(new_customer) | ||||||||
db.session.commit() | ||||||||
|
||||||||
return new_customer.to_dict(), 201 | ||||||||
|
||||||||
@customers_bp.route("/<customer_id>", methods=["GET"]) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||||
def get_customer(customer_id): | ||||||||
try: | ||||||||
customer = Customer.query.get(customer_id) | ||||||||
except: | ||||||||
return jsonify(None), 400 | ||||||||
|
||||||||
if customer is None: | ||||||||
return {"message": f"Customer {customer_id} was not found"}, 404 | ||||||||
|
||||||||
return customer.to_dict() | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
@customers_bp.route("/<customer_id>", methods=["DELETE"]) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||||
def delete_customer(customer_id): | ||||||||
customer = Customer.query.get(customer_id) | ||||||||
|
||||||||
if customer is None: | ||||||||
return {"message": f"Customer {customer_id} was not found"}, 404 | ||||||||
|
||||||||
db.session.delete(customer) | ||||||||
db.session.commit() | ||||||||
|
||||||||
return customer.to_dict() | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
@customers_bp.route("/<customer_id>", methods=["PUT"]) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||||
def update_customer(customer_id): | ||||||||
customer = Customer.query.get(customer_id) | ||||||||
request_body = request.get_json() | ||||||||
|
||||||||
if customer is None: | ||||||||
return {"message": f"Customer {customer_id} was not found"}, 404 | ||||||||
|
||||||||
error_message = validate_request(request_body) | ||||||||
if error_message: | ||||||||
return error_message | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
customer.name = request_body["name"] | ||||||||
customer.phone = request_body["phone"] | ||||||||
customer.postal_code = request_body["postal_code"] | ||||||||
|
||||||||
db.session.commit() | ||||||||
|
||||||||
return customer.to_dict() | ||||||||
|
||||||||
@customers_bp.route("/<customer_id>/rentals", methods=["GET"]) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||||
def get_rentals_by_customer(customer_id): | ||||||||
customer = Customer.query.get(customer_id) | ||||||||
|
||||||||
if not customer: | ||||||||
return {"message": f"Customer {customer_id} was not found"}, 404 | ||||||||
|
||||||||
videos= [] | ||||||||
for video in customer.videos: | ||||||||
rental = Rental.query.filter_by(customer_id = customer.id, video_id = video.id).first() | ||||||||
video = video.to_dict_using_rentals() | ||||||||
video["due_date"] = rental.due_date | ||||||||
videos.append(video) | ||||||||
|
||||||||
return jsonify(videos) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
def validate_request(request_body): | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 one thing we could do is create a separate file called |
||||||||
attributes = ["postal_code", "name", "phone"] | ||||||||
for attribute in attributes: | ||||||||
if attribute not in request_body: | ||||||||
return {"details": f"Request body must include {attribute}."}, 400 | ||||||||
|
||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,51 @@ | ||||||
from app import db | ||||||
from app.models.rental import Rental | ||||||
from app.models.customer import Customer | ||||||
from app.models.video import Video | ||||||
from flask import Blueprint, request, jsonify | ||||||
from datetime import datetime, timedelta | ||||||
|
||||||
rentals_bp = Blueprint("rentals", __name__, url_prefix="/rentals") | ||||||
|
||||||
@rentals_bp.route("/check-out", methods=["POST"]) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||
def check_out_video(): | ||||||
request_body = request.get_json() | ||||||
|
||||||
try: | ||||||
customer = Customer.query.get_or_404(request_body["customer_id"]) | ||||||
video = Video.query.get_or_404(request_body["video_id"]) | ||||||
except KeyError: | ||||||
return jsonify(None), 400 | ||||||
Comment on lines
+14
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since you are using I think sticking with |
||||||
|
||||||
if video.total_inventory - len(video.customers) == 0: | ||||||
return {"message": "Could not perform checkout"}, 400 | ||||||
|
||||||
new_rental = Rental( | ||||||
customer_id = customer.id, | ||||||
video_id = video.id, | ||||||
due_date = datetime.now() + timedelta(days=7) | ||||||
) | ||||||
|
||||||
db.session.add(new_rental) | ||||||
db.session.commit() | ||||||
|
||||||
return jsonify(new_rental.to_dict()) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
@rentals_bp.route("/check-in", methods=["POST"]) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||
def check_in_video(): | ||||||
request_body = request.get_json() | ||||||
|
||||||
try: | ||||||
customer = Customer.query.get_or_404(request_body["customer_id"]) | ||||||
video = Video.query.get_or_404(request_body["video_id"]) | ||||||
except KeyError: | ||||||
return jsonify(None), 400 | ||||||
Comment on lines
+38
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same idea as above! let's go with try/except and get method |
||||||
|
||||||
rental = Rental.query.filter_by(customer_id = customer.id, video_id = video.id).first() | ||||||
if not rental: | ||||||
return {"message": f"No outstanding rentals for customer {customer.id} and video {video.id}"}, 400 | ||||||
|
||||||
rental.is_checked_in = True | ||||||
db.session.commit() | ||||||
|
||||||
return jsonify(rental.to_dict()) |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,99 @@ | ||||||
from app import db | ||||||
from app.models.video import Video | ||||||
from app.models.rental import Rental | ||||||
from flask import Blueprint, request, jsonify | ||||||
|
||||||
videos_bp = Blueprint("videos", __name__, url_prefix="/videos") | ||||||
|
||||||
@videos_bp.route("", methods=["GET"]) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||
def get_all_videos(): | ||||||
videos = Video.query.all() | ||||||
response_body = [video.to_dict() for video in videos] | ||||||
return jsonify(response_body) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
@videos_bp.route("", methods=["POST"]) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||
def create_video(): | ||||||
request_body = request.get_json() | ||||||
|
||||||
error_message = validate_request(request_body) | ||||||
if error_message: | ||||||
return error_message | ||||||
|
||||||
new_video = Video( | ||||||
title= request_body["title"], | ||||||
release_date= request_body["release_date"], | ||||||
total_inventory= request_body["total_inventory"] | ||||||
) | ||||||
db.session.add(new_video) | ||||||
db.session.commit() | ||||||
|
||||||
return jsonify(new_video.to_dict()), 201 | ||||||
|
||||||
|
||||||
@videos_bp.route("/<video_id>", methods=["GET"]) | ||||||
def get_video(video_id): | ||||||
try: | ||||||
video = Video.query.get(video_id) | ||||||
except: | ||||||
return jsonify(None), 400 | ||||||
|
||||||
if video is None: | ||||||
return jsonify({"message": f"Video {video_id} was not found"}), 404 | ||||||
|
||||||
return video.to_dict() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
|
||||||
@videos_bp.route("/<video_id>", methods=["DELETE"]) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||
def delete_video(video_id): | ||||||
video = Video.query.get(video_id) | ||||||
|
||||||
if video is None: | ||||||
return {"message": f"Video {video_id} was not found"}, 404 | ||||||
|
||||||
db.session.delete(video) | ||||||
db.session.commit() | ||||||
|
||||||
return video.to_dict() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
@videos_bp.route("/<video_id>", methods=["PUT"]) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||
def update_video(video_id): | ||||||
request_body = request.get_json() | ||||||
video = Video.query.get(video_id) | ||||||
|
||||||
if video is None: | ||||||
return {"message": f"Video {video_id} was not found"}, 404 | ||||||
|
||||||
error_message = validate_request(request_body) | ||||||
if error_message: | ||||||
return error_message | ||||||
|
||||||
video.title = request_body["title"] | ||||||
video.total_inventory = request_body["total_inventory"] | ||||||
video.release_date = request_body["release_date"] | ||||||
|
||||||
db.session.commit() | ||||||
|
||||||
return video.to_dict() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
@videos_bp.route("/<video_id>/rentals", methods=["GET"]) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||
def get_rentals_by_video(video_id): | ||||||
video = Video.query.get(video_id) | ||||||
|
||||||
if video is None: | ||||||
return {"message": f"Video {video_id} was not found"}, 404 | ||||||
|
||||||
customers = [] | ||||||
for customer in video.customers: | ||||||
rental = Rental.query.filter_by(customer_id = customer.id, video_id = video_id).first() | ||||||
customer = customer.to_dict() | ||||||
customer["due_date"] = rental.due_date | ||||||
customers.append(customer) | ||||||
|
||||||
return jsonify(customers) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
def validate_request(request_body): | ||||||
attributes = ["title", "release_date", "total_inventory"] | ||||||
|
||||||
for attribute in attributes: | ||||||
if attribute not in request_body: | ||||||
return {"details": f"Request body must include {attribute}."}, 400 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Generic single-database configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍