schemas.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. from pydantic import BaseModel, EmailStr, Field, ConfigDict
  2. from typing import Optional, List
  3. from datetime import datetime
  4. # Response models
  5. class MaterialBase(BaseModel):
  6. id: int
  7. name_en: Optional[str] = None
  8. name_ru: Optional[str] = None
  9. name_ua: Optional[str] = None
  10. name_me: Optional[str] = None
  11. desc_en: Optional[str] = None
  12. desc_ru: Optional[str] = None
  13. desc_ua: Optional[str] = None
  14. desc_me: Optional[str] = None
  15. long_desc_en: Optional[str] = None
  16. long_desc_ru: Optional[str] = None
  17. long_desc_ua: Optional[str] = None
  18. long_desc_me: Optional[str] = None
  19. price_per_cm3: float
  20. available_colors: Optional[List[str]] = None
  21. is_active: bool
  22. class ServiceBase(BaseModel):
  23. id: int
  24. name_en: Optional[str] = None
  25. name_ru: Optional[str] = None
  26. name_ua: Optional[str] = None
  27. name_me: Optional[str] = None
  28. desc_en: Optional[str] = None
  29. desc_ru: Optional[str] = None
  30. desc_ua: Optional[str] = None
  31. desc_me: Optional[str] = None
  32. tech_type: Optional[str] = None
  33. is_active: bool
  34. # Management models
  35. class MaterialCreate(BaseModel):
  36. name_en: str
  37. name_ru: str
  38. name_ua: str
  39. name_me: str
  40. desc_en: str
  41. desc_ru: str
  42. desc_ua: str
  43. desc_me: str
  44. long_desc_en: Optional[str] = ""
  45. long_desc_ru: Optional[str] = ""
  46. long_desc_ua: Optional[str] = ""
  47. long_desc_me: Optional[str] = ""
  48. price_per_cm3: float
  49. available_colors: Optional[List[str]] = None
  50. is_active: bool = True
  51. class MaterialUpdate(BaseModel):
  52. name_en: Optional[str] = None
  53. name_ru: Optional[str] = None
  54. name_ua: Optional[str] = None
  55. name_me: Optional[str] = None
  56. desc_en: Optional[str] = None
  57. desc_ru: Optional[str] = None
  58. desc_ua: Optional[str] = None
  59. desc_me: Optional[str] = None
  60. long_desc_en: Optional[str] = None
  61. long_desc_ru: Optional[str] = None
  62. long_desc_ua: Optional[str] = None
  63. long_desc_me: Optional[str] = None
  64. price_per_cm3: Optional[float] = None
  65. available_colors: Optional[List[str]] = None
  66. is_active: Optional[bool] = None
  67. class ServiceCreate(BaseModel):
  68. name_en: str
  69. name_ru: str
  70. name_ua: str
  71. name_me: str
  72. desc_en: str
  73. desc_ru: str
  74. desc_ua: str
  75. desc_me: str
  76. tech_type: Optional[str] = None
  77. is_active: bool = True
  78. class ServiceUpdate(BaseModel):
  79. name_en: Optional[str] = None
  80. name_ru: Optional[str] = None
  81. name_ua: Optional[str] = None
  82. name_me: Optional[str] = None
  83. desc_en: Optional[str] = None
  84. desc_ru: Optional[str] = None
  85. desc_ua: Optional[str] = None
  86. desc_me: Optional[str] = None
  87. tech_type: Optional[str] = None
  88. is_active: Optional[bool] = None
  89. # Order creation models
  90. class OrderFileBase(BaseModel):
  91. filename: str
  92. file_size: Optional[int]
  93. class OrderCreate(BaseModel):
  94. first_name: str = Field(..., min_length=1)
  95. last_name: str = Field(..., min_length=1)
  96. phone: str = Field(..., min_length=5)
  97. email: EmailStr
  98. shipping_address: str = Field(..., min_length=10)
  99. model_link: Optional[str] = None
  100. quantity: int = Field(1, ge=1)
  101. notes: Optional[str] = None
  102. material_id: int
  103. color_name: Optional[str] = None
  104. # User models
  105. class UserCreate(BaseModel):
  106. email: EmailStr
  107. password: str = Field(..., min_length=6)
  108. first_name: Optional[str] = None
  109. last_name: Optional[str] = None
  110. phone: Optional[str] = None
  111. shipping_address: Optional[str] = None
  112. preferred_language: Optional[str] = "en"
  113. is_company: bool = False
  114. company_name: Optional[str] = None
  115. company_pib: Optional[str] = None
  116. company_address: Optional[str] = None
  117. class UserUpdate(BaseModel):
  118. first_name: Optional[str] = None
  119. last_name: Optional[str] = None
  120. phone: Optional[str] = None
  121. shipping_address: Optional[str] = None
  122. preferred_language: Optional[str] = None
  123. can_chat: Optional[bool] = None
  124. is_active: Optional[bool] = None
  125. is_company: Optional[bool] = None
  126. company_name: Optional[str] = None
  127. company_pib: Optional[str] = None
  128. company_address: Optional[str] = None
  129. class AdminUserUpdate(UserUpdate):
  130. role: Optional[str] = None
  131. password: Optional[str] = Field(None, min_length=6)
  132. class UserLogin(BaseModel):
  133. email: EmailStr
  134. password: str
  135. captcha_token: Optional[str] = None
  136. class UserResponse(BaseModel):
  137. id: int
  138. email: EmailStr
  139. first_name: Optional[str] = None
  140. last_name: Optional[str] = None
  141. phone: Optional[str] = None
  142. shipping_address: Optional[str] = None
  143. preferred_language: str = "en"
  144. role: str
  145. can_chat: bool
  146. is_active: bool
  147. is_company: bool
  148. company_name: Optional[str] = None
  149. company_pib: Optional[str] = None
  150. company_address: Optional[str] = None
  151. ip_address: Optional[str] = None
  152. created_at: datetime
  153. model_config = ConfigDict(from_attributes=True)
  154. class AdminOrderUpdate(BaseModel):
  155. status: Optional[str] = None
  156. total_price: Optional[float] = None
  157. material_id: Optional[int] = None
  158. material_name: Optional[str] = None
  159. color_name: Optional[str] = None
  160. quantity: Optional[int] = None
  161. send_notification: Optional[bool] = False
  162. fiscal_qr_url: Optional[str] = None
  163. ikof: Optional[str] = None
  164. jikr: Optional[str] = None
  165. class EstimateRequest(BaseModel):
  166. material_id: int
  167. file_sizes: List[int] # in bytes
  168. file_quantities: Optional[List[int]] = None
  169. # Possible to add density or other params later
  170. class Token(BaseModel):
  171. access_token: str
  172. token_type: str
  173. from typing import Optional, List, Any
  174. class SocialLogin(BaseModel):
  175. provider: str # 'google'
  176. token: str
  177. email: Any = None
  178. first_name: Any = None
  179. last_name: Any = None
  180. preferred_language: Any = "en"
  181. class ForgotPassword(BaseModel):
  182. email: EmailStr
  183. class ResetPassword(BaseModel):
  184. token: str
  185. new_password: str = Field(..., min_length=6)
  186. class PhotoUpdate(BaseModel):
  187. is_public: bool
  188. class OrderResponse(OrderCreate):
  189. id: int
  190. status: str
  191. total_price: Optional[float] = None
  192. estimated_price: Optional[float] = None
  193. material_name: Optional[str] = None
  194. material_price: Optional[float] = None
  195. material_id: Optional[int] = None
  196. color_name: Optional[str] = None
  197. original_params: Optional[str] = None
  198. created_at: datetime
  199. # Review fields
  200. review_text: Optional[str] = None
  201. rating: Optional[int] = 0
  202. review_approved: bool = False
  203. model_config = ConfigDict(from_attributes=True)
  204. class OrderReview(BaseModel):
  205. rating: int = Field(..., ge=1, le=5)
  206. review_text: str = Field(..., min_length=2)
  207. class PublicReview(BaseModel):
  208. first_name: str
  209. rating: Optional[int] = 0
  210. review_text: Optional[str] = None
  211. class MessageCreate(BaseModel):
  212. message: str
  213. class ContactRequest(BaseModel):
  214. name: str = Field(..., min_length=1)
  215. email: EmailStr
  216. subject: str = Field(..., min_length=1)
  217. message: str = Field(..., min_length=1)
  218. class TokenVerify(BaseModel):
  219. token: str