catalog.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. from fastapi import APIRouter, Depends, HTTPException
  2. from typing import List, Optional
  3. import db
  4. import schemas
  5. import auth_utils
  6. import json
  7. router = APIRouter(tags=["catalog"])
  8. @router.get("/materials", response_model=List[schemas.MaterialBase])
  9. async def get_materials():
  10. rows = db.execute_query("SELECT * FROM materials WHERE is_active = TRUE")
  11. for r in rows:
  12. if r.get('available_colors') and isinstance(r['available_colors'], str):
  13. try: r['available_colors'] = json.loads(r['available_colors'])
  14. except: r['available_colors'] = []
  15. return rows
  16. @router.get("/services", response_model=List[schemas.ServiceBase])
  17. async def get_services():
  18. return db.execute_query("SELECT * FROM services WHERE is_active = TRUE")
  19. @router.get("/admin/materials")
  20. async def admin_get_materials(token: str = Depends(auth_utils.oauth2_scheme)):
  21. payload = auth_utils.decode_token(token)
  22. if not payload or payload.get("role") != 'admin':
  23. raise HTTPException(status_code=403, detail="Admin role required")
  24. rows = db.execute_query("SELECT * FROM materials ORDER BY id DESC")
  25. for r in rows:
  26. if r.get('available_colors') and isinstance(r['available_colors'], str):
  27. try: r['available_colors'] = json.loads(r['available_colors'])
  28. except: r['available_colors'] = []
  29. return rows
  30. @router.post("/admin/materials")
  31. async def admin_create_material(data: schemas.MaterialCreate, token: str = Depends(auth_utils.oauth2_scheme)):
  32. payload = auth_utils.decode_token(token)
  33. if not payload or payload.get("role") != 'admin':
  34. raise HTTPException(status_code=403, detail="Admin role required")
  35. colors_json = json.dumps(data.available_colors) if data.available_colors else None
  36. query = "INSERT INTO materials (name_en, name_ru, name_ua, name_me, desc_en, desc_ru, desc_ua, desc_me, price_per_cm3, available_colors, is_active) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
  37. params = (data.name_en, data.name_ru, data.name_ua, data.name_me, data.desc_en, data.desc_ru, data.desc_ua, data.desc_me, data.price_per_cm3, colors_json, data.is_active)
  38. mat_id = db.execute_commit(query, params)
  39. return {"id": mat_id}
  40. @router.patch("/admin/materials/{mat_id}")
  41. async def admin_update_material(mat_id: int, data: schemas.MaterialUpdate, token: str = Depends(auth_utils.oauth2_scheme)):
  42. payload = auth_utils.decode_token(token)
  43. if not payload or payload.get("role") != 'admin':
  44. raise HTTPException(status_code=403, detail="Admin role required")
  45. update_fields = []
  46. params = []
  47. for field, value in data.dict(exclude_unset=True).items():
  48. update_fields.append(f"{field} = %s")
  49. if isinstance(value, list):
  50. params.append(json.dumps(value))
  51. else:
  52. params.append(value)
  53. if update_fields:
  54. query = f"UPDATE materials SET {', '.join(update_fields)} WHERE id = %s"
  55. params.append(mat_id)
  56. db.execute_commit(query, tuple(params))
  57. return {"id": mat_id}
  58. @router.delete("/admin/materials/{mat_id}")
  59. async def admin_delete_material(mat_id: int, token: str = Depends(auth_utils.oauth2_scheme)):
  60. payload = auth_utils.decode_token(token)
  61. if not payload or payload.get("role") != 'admin':
  62. raise HTTPException(status_code=403, detail="Admin role required")
  63. db.execute_commit("DELETE FROM materials WHERE id = %s", (mat_id,))
  64. return {"id": mat_id, "status": "deleted"}
  65. @router.get("/admin/services")
  66. async def admin_get_services(token: str = Depends(auth_utils.oauth2_scheme)):
  67. payload = auth_utils.decode_token(token)
  68. if not payload or payload.get("role") != 'admin':
  69. raise HTTPException(status_code=403, detail="Admin role required")
  70. return db.execute_query("SELECT * FROM services ORDER BY id DESC")
  71. @router.post("/admin/services")
  72. async def admin_create_service(data: schemas.ServiceCreate, token: str = Depends(auth_utils.oauth2_scheme)):
  73. payload = auth_utils.decode_token(token)
  74. if not payload or payload.get("role") != 'admin':
  75. raise HTTPException(status_code=403, detail="Admin role required")
  76. query = "INSERT INTO services (name_en, name_ru, name_ua, name_me, desc_en, desc_ru, desc_ua, desc_me, tech_type, is_active) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
  77. srv_id = db.execute_commit(query, (data.name_en, data.name_ru, data.name_ua, data.name_me, data.desc_en, data.desc_ru, data.desc_ua, data.desc_me, data.tech_type, data.is_active))
  78. return {"id": srv_id}
  79. @router.patch("/admin/services/{srv_id}")
  80. async def admin_update_service(srv_id: int, data: schemas.ServiceUpdate, token: str = Depends(auth_utils.oauth2_scheme)):
  81. payload = auth_utils.decode_token(token)
  82. if not payload or payload.get("role") != 'admin':
  83. raise HTTPException(status_code=403, detail="Admin role required")
  84. update_fields = []
  85. params = []
  86. for field, value in data.dict(exclude_unset=True).items():
  87. update_fields.append(f"{field} = %s")
  88. if isinstance(value, list):
  89. params.append(json.dumps(value))
  90. else:
  91. params.append(value)
  92. if update_fields:
  93. query = f"UPDATE services SET {', '.join(update_fields)} WHERE id = %s"
  94. params.append(srv_id)
  95. db.execute_commit(query, tuple(params))
  96. return {"id": srv_id}
  97. @router.delete("/admin/services/{srv_id}")
  98. async def admin_delete_service(srv_id: int, token: str = Depends(auth_utils.oauth2_scheme)):
  99. payload = auth_utils.decode_token(token)
  100. if not payload or payload.get("role") != 'admin':
  101. raise HTTPException(status_code=403, detail="Admin role required")
  102. db.execute_commit("DELETE FROM services WHERE id = %s", (srv_id,))
  103. return {"id": srv_id, "status": "deleted"}