schemas.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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. price_per_cm3: float
  16. available_colors: Optional[List[str]] = None
  17. is_active: bool
  18. class ServiceBase(BaseModel):
  19. id: int
  20. name_en: Optional[str] = None
  21. name_ru: Optional[str] = None
  22. name_ua: Optional[str] = None
  23. name_me: Optional[str] = None
  24. desc_en: Optional[str] = None
  25. desc_ru: Optional[str] = None
  26. desc_ua: Optional[str] = None
  27. desc_me: Optional[str] = None
  28. tech_type: Optional[str] = None
  29. is_active: bool
  30. # Management models
  31. class MaterialCreate(BaseModel):
  32. name_en: str
  33. name_ru: str
  34. name_ua: str
  35. name_me: str
  36. desc_en: str
  37. desc_ru: str
  38. desc_ua: str
  39. desc_me: str
  40. price_per_cm3: float
  41. available_colors: Optional[List[str]] = None
  42. is_active: bool = True
  43. class MaterialUpdate(BaseModel):
  44. name_en: Optional[str] = None
  45. name_ru: Optional[str] = None
  46. name_ua: Optional[str] = None
  47. name_me: Optional[str] = None
  48. desc_en: Optional[str] = None
  49. desc_ru: Optional[str] = None
  50. desc_ua: Optional[str] = None
  51. desc_me: Optional[str] = None
  52. price_per_cm3: Optional[float] = None
  53. available_colors: Optional[List[str]] = None
  54. is_active: Optional[bool] = None
  55. class ServiceCreate(BaseModel):
  56. name_en: str
  57. name_ru: str
  58. name_ua: str
  59. name_me: str
  60. desc_en: str
  61. desc_ru: str
  62. desc_ua: str
  63. desc_me: str
  64. tech_type: Optional[str] = None
  65. is_active: bool = True
  66. class ServiceUpdate(BaseModel):
  67. name_en: Optional[str] = None
  68. name_ru: Optional[str] = None
  69. name_ua: Optional[str] = None
  70. name_me: Optional[str] = None
  71. desc_en: Optional[str] = None
  72. desc_ru: Optional[str] = None
  73. desc_ua: Optional[str] = None
  74. desc_me: Optional[str] = None
  75. tech_type: Optional[str] = None
  76. is_active: Optional[bool] = None
  77. # Order creation models
  78. class OrderFileBase(BaseModel):
  79. filename: str
  80. file_size: Optional[int]
  81. class OrderCreate(BaseModel):
  82. first_name: str = Field(..., min_length=1)
  83. last_name: str = Field(..., min_length=1)
  84. phone: str = Field(..., min_length=5)
  85. email: EmailStr
  86. shipping_address: str = Field(..., min_length=10)
  87. model_link: Optional[str] = None
  88. quantity: int = Field(1, ge=1)
  89. notes: Optional[str] = None
  90. material_id: int
  91. color_name: Optional[str] = None
  92. # User models
  93. class UserCreate(BaseModel):
  94. email: EmailStr
  95. password: str = Field(..., min_length=6)
  96. first_name: Optional[str] = None
  97. last_name: Optional[str] = None
  98. phone: Optional[str] = None
  99. shipping_address: Optional[str] = None
  100. preferred_language: Optional[str] = "en"
  101. is_company: bool = False
  102. company_name: Optional[str] = None
  103. company_pib: Optional[str] = None
  104. company_address: Optional[str] = None
  105. class UserUpdate(BaseModel):
  106. first_name: Optional[str] = None
  107. last_name: Optional[str] = None
  108. phone: Optional[str] = None
  109. shipping_address: Optional[str] = None
  110. preferred_language: Optional[str] = None
  111. can_chat: Optional[bool] = None
  112. is_active: Optional[bool] = None
  113. is_company: Optional[bool] = None
  114. company_name: Optional[str] = None
  115. company_pib: Optional[str] = None
  116. company_address: Optional[str] = None
  117. class UserLogin(BaseModel):
  118. email: EmailStr
  119. password: str
  120. class UserResponse(BaseModel):
  121. id: int
  122. email: EmailStr
  123. first_name: Optional[str] = None
  124. last_name: Optional[str] = None
  125. phone: Optional[str] = None
  126. shipping_address: Optional[str] = None
  127. preferred_language: str = "en"
  128. role: str
  129. can_chat: bool
  130. is_active: bool
  131. is_company: bool
  132. company_name: Optional[str] = None
  133. company_pib: Optional[str] = None
  134. company_address: Optional[str] = None
  135. ip_address: Optional[str] = None
  136. created_at: datetime
  137. model_config = ConfigDict(from_attributes=True)
  138. class AdminOrderUpdate(BaseModel):
  139. status: Optional[str] = None
  140. total_price: Optional[float] = None
  141. material_id: Optional[int] = None
  142. material_name: Optional[str] = None
  143. color_name: Optional[str] = None
  144. quantity: Optional[int] = None
  145. send_notification: Optional[bool] = False
  146. class EstimateRequest(BaseModel):
  147. material_id: int
  148. file_sizes: List[int] # in bytes
  149. file_quantities: Optional[List[int]] = None
  150. # Possible to add density or other params later
  151. class Token(BaseModel):
  152. access_token: str
  153. token_type: str
  154. class SocialLogin(BaseModel):
  155. provider: str # 'google' or 'facebook'
  156. token: str
  157. email: EmailStr
  158. first_name: Optional[str] = None
  159. last_name: Optional[str] = None
  160. preferred_language: Optional[str] = "en"
  161. class ForgotPassword(BaseModel):
  162. email: EmailStr
  163. class ResetPassword(BaseModel):
  164. token: str
  165. new_password: str = Field(..., min_length=6)
  166. class PhotoUpdate(BaseModel):
  167. is_public: bool
  168. class OrderResponse(OrderCreate):
  169. id: int
  170. status: str
  171. total_price: Optional[float] = None
  172. estimated_price: Optional[float] = None
  173. material_name: Optional[str] = None
  174. material_price: Optional[float] = None
  175. material_id: Optional[int] = None
  176. color_name: Optional[str] = None
  177. original_params: Optional[str] = None
  178. created_at: datetime
  179. model_config = ConfigDict(from_attributes=True)
  180. class MessageCreate(BaseModel):
  181. message: str