| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- import typing
- import sqlalchemy
- import sqlalchemy.engine.base
- from .app_route import app_route_database
- from .product import product
- from .product_loader import product_loader
- from .exception import bad_request_exception
- from .exception import not_found_exception
- from .exception import access_denied_exception
- from .exception import database_exception
- from .exception import incorrect_target_exception
- from .users_collection import users_collection
- from .reservation import reservation
- from .reservation import reservation_factory
- from .reservation_loader import reservation_loader
- from .deep_request import deep_request
- from .reservations_collection import reservations_collection
- from .reservations_response import reservations_response
- class reservation_deep_request(deep_request):
- @property
- def has_product(self) -> bool:
- return self.target_barcode is not None or self.target_name is not None
- @property
- def has_email(self) -> bool:
- return self.email is not None
- @property
- def has_phone_number(self) -> bool:
- return self.phone_number is not None
- @property
- def has_apikey(self) -> bool:
- return self.apikey is not None
- class reservation_app(app_route_database):
- def __init__(
- self,
- connection: sqlalchemy.engine.base.Engine,
- users: users_collection
- ) -> None:
- super().__init__(connection)
- self.__users_collection = users
- def get_by_user(self, params: dict) -> dict:
- request = reservation_deep_request(params)
-
- try:
- with self.__reservation_loader as loader:
- collection = self.__load_by_user(request, loader)
- self.__reservation_user_filter(collection, request)
- reservations_list = reservations_response() \
- .collection(collection.results())
- return self._success(reservations = reservations_list)
-
- except Exception as error:
- return self.__catch(error)
- def get_by_product(self, params: dict) -> dict:
- request = reservation_deep_request(params)
- try:
- self.__login(request)
- item = self.__load_product(request)
-
- with self.__reservation_loader as loader:
- collection = loader.get_by_target(item)
- self.__reservation_user_filter(collection, request)
-
- reservations_list = reservations_response() \
- .collection(collection.results())
- return self._success(reservations = reservations_list)
-
- except Exception as error:
- return self.__catch(error)
- def rent_product(self, params: dict) -> dict:
- request = reservation_deep_request(params)
-
- try:
- self.__login(request)
- item = self.__load_product(request)
- rent = self.__create_factory(request).target(item).result()
-
- with self.__reservation_loader as loader:
- if not self.__product_avairable(item):
- raise bad_request_exception("Item already not avairable")
- if not loader.store(rent):
- raise database_exception()
- return self._success()
- except Exception as error:
- return self.__catch(error)
- def give_back_product(self, params: dict) -> dict:
- request = reservation_deep_request(params)
- try:
- self.__login(request)
- target = self.__get_reservation(request)
- with self.__reservation_loader as loader:
- if loader.drop(target):
- return self._success()
-
- raise database_exception()
-
- except Exception as error:
- return self.__catch(error)
- def __reservation_user_filter(
- self,
- collection: reservations_collection,
- request: deep_request
- ) -> bool:
- if not request.has_email and not request.has_phone_number:
- return False
- if request.has_email:
- collection.by_email(request.email)
- if request.has_phone_number:
- collection.by_phone_number(request.phone_number)
- return True
- def __reservation_product_filter(
- self,
- collection: reservations_collection,
- request: deep_request
- ) -> bool:
- if not request.has_product:
- return False
- item = self.__load_product(request)
- collection.by_target(item)
- return True
- def __get_reservation(self, request: deep_request) -> reservation:
- with self.__reservation_loader as loader:
- item = self.__load_product(request)
- collection = loader.get_by_target(item)
-
- if not self.__reservation_user_filter(collection, request):
- raise bad_request_exception("Not contaim email or phone")
- result = collection.results()
- if len(result) == 0:
- raise not_found_exception()
-
- if len(result) > 1:
- raise incorrect_target_exception("Found too much targets.")
- return result[0]
- def __load_by_user(
- self,
- request: deep_request,
- loader: reservation_loader
- ) -> reservations_collection:
- if request.has_email:
- return loader.get_by_email(request.email)
- if request.has_phone_number:
- return loader.get_by_phone_number(request.phone_number)
- raise bad_request_exception("Has no email or phone number")
- def __create_factory(self, request: deep_request) -> reservation_factory:
- if not request.has_email and not request.has_phone_number:
- raise bad_request_exception("Not contain email or/and phone")
- factory = reservation_factory()
- if request.has_email:
- factory.email(request.email)
- if request.has_phone_number:
- factory.phone_number(request.phone_number)
- return factory
- def __login(self, request: deep_request) -> None:
- if not request.has_apikey:
- raise access_denied_exception()
- if self.__users_collection.get(request.apikey):
- return
- raise access_denied_exception()
- def __load_product(self, request: deep_request) -> product:
- if request.target_barcode is not None:
- return self.__product_by_barcode(request)
- if request.target_name is not None:
- return self.__product_by_name(request)
- raise bad_request_exception("Not contain barcode or name")
- def __product_by_barcode(self, request: deep_request) -> product:
- with self.__product_loader as loader:
- product = loader.get_by_barcode(request.target_barcode)
- if product is not None:
- return product
- raise not_found_exception()
- def __product_avairable(self, target: product) -> bool:
- with self.__product_loader as loader:
- return loader.get_by_barcode(target.barcode).on_stock > 0
- def __product_by_name(self, request: deep_request) -> product:
- with self.__product_loader as loader:
- product = loader.get_by_name(request.target_name)
- if product is not None:
- product.on_stock
- return product
-
- raise not_found_exception()
- def __catch(self, error: Exception) -> dict:
- return self._fail(str(error))
- @property
- def __reservation_loader(self):
- return reservation_loader(self._connection)
- @property
- def __product_loader(self):
- return product_loader(self._connection)
-
|