fudo.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. import math
  2. import requests
  3. from rich import print
  4. import os
  5. api_token = os.getenv('FUDO_API_KEY')
  6. api_secret = os.getenv('FUDO_API_SECRET')
  7. def get_token():
  8. url = 'https://auth.fu.do/api'
  9. data = {
  10. "apiKey": api_token,
  11. "apiSecret": api_secret
  12. }
  13. r = requests.post(url, data=data)
  14. return r.json()['token']
  15. def get_categorys():
  16. """
  17. {
  18. "data": [
  19. {
  20. "id": "1",
  21. "type": "ProductCategory",
  22. "attributes": {
  23. "enableOnlineMenu": true,
  24. "name": "Drinks",
  25. "preparationTime": 0,
  26. "position": 50
  27. },
  28. "relationships": {
  29. "kitchen": {
  30. "data": {
  31. "id": "1",
  32. "type": "Kitchen"
  33. }
  34. },
  35. "parentCategory": {
  36. "data": {
  37. "id": "1",
  38. "type": "ProductCategory"
  39. }
  40. }
  41. }
  42. }
  43. ]
  44. }"""
  45. token = get_token()
  46. url = 'https://api.fu.do/v1alpha1/product-categories'
  47. headers = {
  48. 'Authorization': 'Bearer ' + token
  49. }
  50. r = requests.get(url, headers=headers)
  51. return r.json()
  52. def get_product(id_category:int):
  53. """
  54. Response Example:
  55. [{
  56. 'type': 'Product',
  57. 'id': '206',
  58. 'attributes': {
  59. 'active': True,
  60. 'code': None,
  61. 'cost': 364.0,
  62. 'description': '',
  63. 'enableOnlineMenu': None,
  64. 'enableQrMenu': None,
  65. 'favourite': False,
  66. 'imageUrl': None,
  67. 'name': 'Pollo 70 g',
  68. 'position': 28800000,
  69. 'preparationTime': None,
  70. 'price': 1500.0,
  71. 'sellAlone': True,
  72. 'stock': None,
  73. 'stockControl': False
  74. },
  75. 'relationships': {'kitchen': {'data': {'type': 'Kitchen', 'id': '4'}}, 'productCategory': {'data': {'type': 'ProductCategory', 'id': '28'}}, 'productModifiersGroups': {'data': []}, 'productProportions': {'data': []}}
  76. }]
  77. """
  78. url = 'https://api.fu.do/v1alpha1/products/{}'.format(id_category)
  79. token = get_token()
  80. headers = {
  81. 'Authorization': 'Bearer ' + token
  82. }
  83. r = requests.get(url, headers=headers)
  84. return r.json()
  85. def get_products():
  86. """
  87. Response Example:{
  88. 'type': 'Product',
  89. 'id': '206',
  90. 'attributes': {
  91. 'active': True,
  92. 'code': None,
  93. 'cost': 364.0,
  94. 'description': '',
  95. 'enableOnlineMenu': None,
  96. 'enableQrMenu': None,
  97. 'favourite': False,
  98. 'imageUrl': None,
  99. 'name': 'Pollo 70 g',
  100. 'position': 28800000,
  101. 'preparationTime': None,
  102. 'price': 1500.0,
  103. 'sellAlone': True,
  104. 'stock': None,
  105. 'stockControl': False
  106. },
  107. 'relationships': {'kitchen': {'data': {'type': 'Kitchen', 'id': '4'}}, 'productCategory': {'data': {'type': 'ProductCategory', 'id': '28'}}, 'productModifiersGroups': {'data': []}, 'productProportions': {'data': []}}
  108. }
  109. """
  110. url = 'https://api.fu.do/v1alpha1/products'
  111. token = get_token()
  112. headers = {
  113. 'Authorization': 'Bearer ' + token
  114. }
  115. r = requests.get(url, headers=headers)
  116. return list(filter(lambda x: x['relationships']['productCategory']['data']['id'] == '1', r.json()['data']))
  117. def get_table(number:int):
  118. n_per_page = 10
  119. page = math.ceil(number / n_per_page)
  120. url = 'https://api.fu.do/v1alpha1/tables?page[number]={}&page[size]={}&include=activeSales&sort=number'.format(page, n_per_page)
  121. token = get_token()
  122. headers = {
  123. 'Authorization': 'Bearer ' + token
  124. }
  125. r = requests.get(url, headers=headers)
  126. if r.status_code != 200:
  127. print('Error al obtener tablas:' + str(r.json()['errors']))
  128. return None
  129. try:
  130. return list(filter(lambda x: x['attributes']['number'] == number, r.json()['data']))[0]
  131. except:
  132. print('Error al obtener tabla')
  133. print(r.json())
  134. return None
  135. def get_sale(sale_id:int):
  136. url = 'https://api.fu.do/v1alpha1/sales/{}'.format(sale_id)
  137. token = get_token()
  138. headers = {
  139. 'Authorization': 'Bearer ' + token
  140. }
  141. r = requests.get(url, headers=headers)
  142. if r.status_code != 200:
  143. print('Error al obtener tablas:' + str(r.json()['errors']))
  144. return None
  145. return r.json()
  146. def create_sale(table_id:int):
  147. url = 'https://api.fu.do/v1alpha1/sales'
  148. token = get_token()
  149. headers = {
  150. 'Authorization': 'Bearer ' + token
  151. }
  152. data = {
  153. "data": {
  154. "type": "Sale",
  155. "attributes": {
  156. "people": 1,
  157. "saleType": "EAT-IN",
  158. "comment": "Pedido desde la app pedidos express"
  159. },
  160. "relationships": {
  161. "table": {
  162. "data": {
  163. "id": str(table_id),
  164. "type": "Table"
  165. }
  166. },
  167. "waiter": {
  168. "data": {
  169. "type": "User",
  170. "id": "76"
  171. }
  172. }
  173. }
  174. }
  175. }
  176. r = requests.post(url, headers=headers, json=data)
  177. if r.status_code != 201:
  178. print('Error al crear la venta:', r.json())
  179. return None
  180. return r.json()["data"]
  181. def create_item(product_id:int, quantity:int, sale_id:int, comment:str|None = None):
  182. url = 'https://api.fu.do/v1alpha1/items'
  183. token = get_token()
  184. headers = {
  185. 'Authorization': 'Bearer ' + token
  186. }
  187. data = {
  188. "quantity": quantity,
  189. "origin": "MOBILE",
  190. "comment": "[DESARROLLO NO SACAR]Pedido desde pedidos express" + (f" - {comment}" if comment else ""),
  191. }
  192. data = {
  193. "data":{
  194. "type": "Item",
  195. "attributes": data,
  196. "relationships": {
  197. "product": {
  198. "data": {
  199. "type": "Product",
  200. "id": str(product_id)
  201. }
  202. },
  203. "sale": {
  204. "data": {
  205. "type": "Sale",
  206. "id": str(sale_id)
  207. }
  208. }
  209. },
  210. }
  211. }
  212. r = requests.post(url, headers=headers, json=data)
  213. if r.status_code != 201:
  214. print(r.json())
  215. return None
  216. return r.json()["data"]
  217. def get_active_sale(table):
  218. data = table['relationships']['activeSales']['data']
  219. if len(data) == 0:
  220. return None
  221. return data[0]
  222. if __name__ == "__main__":
  223. table = get_table(107)
  224. if table is None:
  225. print('No se pudo obtener la mesa')
  226. exit()
  227. activeSale = get_active_sale(table)
  228. if not activeSale:
  229. print('No hay una venta activa para la mesa')
  230. activeSale = create_sale(table['id'])
  231. if activeSale is None:
  232. print('No se pudo crear la venta')
  233. exit()
  234. else:
  235. activeSale = activeSale[0]
  236. print('Venta activa:', activeSale['id'])
  237. """
  238. Intrucciones para hacer un pedido:
  239. 1. Obtener el token de autenticación con `get_token()`.
  240. 2. obtener la mesa con `get_table(numero_de_mesa)`.
  241. 3. ver si tiene una activeSale, en caso contrario crear una con `create_sale(id_mesa)`.
  242. 4. agregar los items a la venta con `create_item(id_producto, cantidad, id_venta, comentario)`.
  243. """