product_app.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import typing
  2. import sqlalchemy
  3. import sqlalchemy.engine.base
  4. from .app_route import app_route_database
  5. from .product import product
  6. from .product import product_factory
  7. from .product_loader import product_loader
  8. from .product_response import product_response
  9. from .product_builder import product_builder
  10. from .exception import bad_request_exception
  11. from .exception import not_found_exception
  12. from .exception import access_denied_exception
  13. from .users_collection import users_collection
  14. class product_app(app_route_database):
  15. def __init__(
  16. self,
  17. connection: sqlalchemy.engine.base.Engine,
  18. users: users_collection
  19. ) -> None:
  20. super().__init__(connection)
  21. self.__users_collection = users
  22. def all(self) -> dict:
  23. try:
  24. with self.__products_database as loader:
  25. return self.__collection(loader.load_all())
  26. except Exception as error:
  27. return self._fail(str(error))
  28. def get_barcode(self, target: str) -> dict:
  29. try:
  30. with self.__products_database as loader:
  31. return self.__single(loader.get_by_barcode(target))
  32. except Exception as error:
  33. return self._fail(str(error))
  34. def get_name(self, target: str) -> dict:
  35. try:
  36. with self.__products_database as loader:
  37. return self.__single(loader.get_by_name(target))
  38. except Exception as error:
  39. return self._fail(str(error))
  40. def search_name(self, target: str) -> dict:
  41. try:
  42. with self.__products_database as loader:
  43. return self.__collection(loader.search_by_name(target))
  44. except Exception as error:
  45. return self._fail(str(error))
  46. def search_author(self, target: str) -> dict:
  47. try:
  48. with self.__products_database as loader:
  49. return self.__collection(loader.search_by_author(target))
  50. except Exception as error:
  51. return self._fail(str(error))
  52. def check_barcode(self, target: str) -> dict:
  53. try:
  54. with self.__products_database as loader:
  55. return self.__exists(loader.barcode_in_use(target))
  56. except Exception as error:
  57. return self._fail(str(error))
  58. def check_name(self, target: str) -> dict:
  59. try:
  60. with self.__products_database as loader:
  61. return self.__exists(loader.name_in_use(target))
  62. except Exception as error:
  63. return self._fail(str(error))
  64. def create(self, send: dict) -> dict:
  65. try:
  66. if not self.__logged_in(send):
  67. raise access_denied_exception()
  68. with self.__products_database as loader:
  69. target = product_builder().modify(send).result
  70. result = loader.store(target)
  71. return self.__modify(result, "Can nod create product.")
  72. except Exception as error:
  73. return self._fail(str(error))
  74. def __logged_in(self, send: dict) -> bool:
  75. if not "apikey" in send:
  76. return False
  77. return self.__users.get(send["apikey"]) is not None
  78. def __select_by_sended(
  79. self,
  80. send: dict,
  81. loader: product_loader
  82. ) -> product | None:
  83. barcode = None
  84. name = None
  85. if "target_barcode" in send:
  86. barcode = send["target_barcode"]
  87. if "target_name" in send:
  88. name = send["target_name"]
  89. if barcode is not None and name is not None:
  90. content = "Give only one, target_name or target_barcode"
  91. raise bad_request_exception(content)
  92. if barcode is None and name is None:
  93. content = "Give target_barcode or target_name"
  94. raise bad_request_exception(content)
  95. result = None
  96. if barcode is not None:
  97. result = loader.get_by_barcode(barcode)
  98. if name is not None:
  99. result = loader.get_by_name(name)
  100. if result is None:
  101. raise not_found_exception()
  102. return result
  103. def update(self, send: dict) -> dict:
  104. try:
  105. if not self.__logged_in(send):
  106. raise access_denied_exception()
  107. with self.__products_database as loader:
  108. target = self.__select_by_sended(send, loader)
  109. updated = product_builder(target).modify(send).result
  110. result = loader.store(updated)
  111. return self.__modify(result, "Can not update product.")
  112. except Exception as error:
  113. return self._fail(str(error))
  114. def delete(self, send: dict) -> dict:
  115. try:
  116. if not self.__logged_in(send):
  117. raise access_denied_exception()
  118. with self.__products_database as loader:
  119. target = self.__select_by_sended(send, loader)
  120. result = loader.drop(target)
  121. return self.__modify(result, "Can not delete product.")
  122. except Exception as error:
  123. return self._fail(str(error))
  124. def __modify(self, result: bool, cause: str) -> dict:
  125. if result:
  126. return self._success()
  127. else:
  128. return self._fail(cause)
  129. def __exists(self, result: bool) -> dict:
  130. return self._success(exists = result)
  131. def __single(self, target: product) -> dict:
  132. if target is None:
  133. return self._fail("Can not found product in database.")
  134. return self._success(product = product_response(target))
  135. def __collection(self, target: typing.Iterable[product]) -> dict:
  136. return self._success(collection = product_response(target))
  137. @property
  138. def __users(self) -> users_collection:
  139. return self.__users_collection
  140. @property
  141. def __products_database(self) -> product_loader:
  142. return product_loader(self._connection)