# Path: auth.py
# class Auth:
#     def login_required(*args, **kwargs):
#     def current_user(self):
#     def init_app(app):
# def load_user(user_id):
# def load_user_from_request(request):
# 
# Path: models.py
# ENVIRONMENT = os.getenv('ENVIRONMENT', 'dev')
# class BaseModel(Model):
#     class Meta:
# class Item(BaseModel):
# class Picture(BaseModel):
# class User(BaseModel, UserMixin):
# class Address(BaseModel):
# class Order(BaseModel):
#     class Meta:
# class OrderItem(BaseModel):
# class Favorite(BaseModel):
#     def save(self, *args, **kwargs):
#     def json_list(cls, objs_list):
#     def json(self, include_data=[]):
#     def validate_input(cls, data, partial=False):
#     def search(cls, query, dataset, limit=-1,
#                attributes=None, weights=None,
#                threshold=search.config.THRESHOLD):
#     def __str__(self):
#     def is_favorite(self, item):
# def on_delete_item_handler(model_class, instance):
#     def filename(self):
#     def __str__(self):
# def on_delete_picture_handler(model_class, instance):
#     def exists(email):
#     def hash_password(password):
#     def verify_password(self, password):
#     def add_favorite(user, item):
#     def delete_favorite(self, obj):
#     def order_items(self):
#     def empty_order(self):
#     def create_order(user, address, items):
#     def update_items(self, items, update_total=True, new_address=None):
#     def edit_items_quantity(self, items):
#     def delete_items(self, items):
#     def create_items(self, items):
#     def add_item(self, item, quantity=1):
#     def remove_item(self, item, quantity=1):
#     def add_item(self, quantity=1):
#     def remove_item(self, quantity=1):
#     def _calculate_subtotal(self):
# 
# Path: notifications.py
# def notify_new_order(address, user):
#     body = render_template('new_order.html', address=address, user=user)
#     send_email("Nuovo Ordine", body)
# 
# Path: utils.py
# def generate_response(data, status, mimetype='application/vnd.api+json'):
#     """
#     Given a resource model that extends from `BaseModel` generate a Reponse
#     object to be returned from the application endpoints'
#     """
#     return Response(
#         response=data,
#         status=status,
#         mimetype=mimetype
#     )
# 
# Path: exceptions.py
# class InsufficientAvailabilityException(Exception):
# 
#     def __init__(self, item, requested_quantity):
#         super(Exception, self).__init__(
#             "Item availability {}, requested {}".format(
#                 item.availability,
#                 requested_quantity))
# 
#         self.item = item
#         self.requested_quantity = requested_quantity


from http.client import (BAD_REQUEST, CREATED, NO_CONTENT, NOT_FOUND, OK,
                         UNAUTHORIZED)
from flask import abort, request
from flask_restful import Resource
from auth import auth
from models import database, Address, Order, Item, User
from notifications import notify_new_order
from utils import generate_response
from exceptions import InsufficientAvailabilityException
            if req_address:
                try:
                    address = Address.get(Address.uuid == req_address['data']['id'])
                except Address.DoesNotExist:
                    abort(BAD_REQUEST)
                order.delivery_address = address

            # get the user from the flask.g global object registered inside the
            # auth.py::verify() function, called by @auth.login_required decorator
            # and match it against the found user.
            # This is to prevent uses from modify other users' order.
            if auth.current_user != order.user and auth.current_user.admin is False:
                return ({'message': "You can't delete another user's order"},
                        UNAUTHORIZED)

            # Generate the dict of {<Item>: <int:quantity>} to call Order.update_items
            items_uuids = [e['id'] for e in req_items.get('data', [])]
            items = list(Item.select().where(Item.uuid << items_uuids))
            if len(items) != len(items_uuids):
                abort(BAD_REQUEST)
            items_to_add = {
                item: req_item['quantity']
                for item in items for req_item in req_items.get('data', [])
                if str(item.uuid) == req_item['id']
            }
            try:
                order.update_items(items_to_add, new_address=address)
            except InsufficientAvailabilityException:
                abort(BAD_REQUEST)


# Path: auth.py
# class Auth:
#     def login_required(*args, **kwargs):
#     def current_user(self):
#     def init_app(app):
# def load_user(user_id):
# def load_user_from_request(request):
# 
# Path: models.py
# ENVIRONMENT = os.getenv('ENVIRONMENT', 'dev')
# class BaseModel(Model):
#     class Meta:
# class Item(BaseModel):
# class Picture(BaseModel):
# class User(BaseModel, UserMixin):
# class Address(BaseModel):
# class Order(BaseModel):
#     class Meta:
# class OrderItem(BaseModel):
# class Favorite(BaseModel):
#     def save(self, *args, **kwargs):
#     def json_list(cls, objs_list):
#     def json(self, include_data=[]):
#     def validate_input(cls, data, partial=False):
#     def search(cls, query, dataset, limit=-1,
#                attributes=None, weights=None,
#                threshold=search.config.THRESHOLD):
#     def __str__(self):
#     def is_favorite(self, item):
# def on_delete_item_handler(model_class, instance):
#     def filename(self):
#     def __str__(self):
# def on_delete_picture_handler(model_class, instance):
#     def exists(email):
#     def hash_password(password):
#     def verify_password(self, password):
#     def add_favorite(user, item):
#     def delete_favorite(self, obj):
#     def order_items(self):
#     def empty_order(self):
#     def create_order(user, address, items):
#     def update_items(self, items, update_total=True, new_address=None):
#     def edit_items_quantity(self, items):
#     def delete_items(self, items):
#     def create_items(self, items):
#     def add_item(self, item, quantity=1):
#     def remove_item(self, item, quantity=1):
#     def add_item(self, quantity=1):
#     def remove_item(self, quantity=1):
#     def _calculate_subtotal(self):
# 
# Path: notifications.py
# def notify_new_order(address, user):
#     body = render_template('new_order.html', address=address, user=user)
#     send_email("Nuovo Ordine", body)
# 
# Path: utils.py
# def generate_response(data, status, mimetype='application/vnd.api+json'):
#     """
#     Given a resource model that extends from `BaseModel` generate a Reponse
#     object to be returned from the application endpoints'
#     """
#     return Response(
#         response=data,
#         status=status,
#         mimetype=mimetype
#     )
# 
# Path: exceptions.py
# class InsufficientAvailabilityException(Exception):
# 
#     def __init__(self, item, requested_quantity):
#         super(Exception, self).__init__(
#             "Item availability {}, requested {}".format(
#                 item.availability,
#                 requested_quantity))
# 
#         self.item = item
#         self.requested_quantity = requested_quantity


# Path: views/orders.py
from http.client import (BAD_REQUEST, CREATED, NO_CONTENT, NOT_FOUND, OK,
                         UNAUTHORIZED)
from flask import abort, request
from flask_restful import Resource
from auth import auth
from models import database, Address, Order, Item, User
from notifications import notify_new_order
from utils import generate_response
from exceptions import InsufficientAvailabilityException

            if req_address:
                try:
                    address = Address.get(Address.uuid == req_address['data']['id'])
                except Address.DoesNotExist:
                    abort(BAD_REQUEST)
                order.delivery_address = address

            # get the user from the flask.g global object registered inside the
            # auth.py::verify() function, called by @auth.login_required decorator
            # and match it against the found user.
            # This is to prevent uses from modify other users' order.
            if auth.current_user != order.user and auth.current_user.admin is False:
                return ({'message': "You can't delete another user's order"},
                        UNAUTHORIZED)

            # Generate the dict of {<Item>: <int:quantity>} to call Order.update_items
            items_uuids = [e['id'] for e in req_items.get('data', [])]
            items = list(Item.select().where(Item.uuid << items_uuids))
            if len(items) != len(items_uuids):
                abort(BAD_REQUEST)
            items_to_add = {
                item: req_item['quantity']
                for item in items for req_item in req_items.get('data', [])
                if str(item.uuid) == req_item['id']
            }
            try:
                order.update_items(items_to_add, new_address=address)
            except InsufficientAvailabilityException:
                abort(BAD_REQUEST)


        return generate_response(order.json(), OK)