shop_system_models 1.0.0.dev26932__tar.gz → 1.0.0.dev27178__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/PKG-INFO +1 -1
  2. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/pyproject.toml +1 -1
  3. shop_system_models-1.0.0.dev27178/shop_system_models/consts/languages.py +4 -0
  4. shop_system_models-1.0.0.dev27178/shop_system_models/consts/languages.pyi +4 -0
  5. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/authorization.py +6 -0
  6. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/deployment_api/request/processes.py +1 -0
  7. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/services.py +36 -0
  8. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/shop_categories.py +9 -0
  9. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/shop_content/blocks.py +21 -0
  10. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/shop_content/delivery_types.py +51 -0
  11. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/shop_content/payment_methods.py +32 -0
  12. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/shop_templates.py +18 -0
  13. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/shops.py +102 -0
  14. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/tasks.py +24 -0
  15. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/users.py +53 -0
  16. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/request/web_app_url.py +14 -0
  17. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/response/general.py +23 -0
  18. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/response/permissions.py +6 -0
  19. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/response/premium.py +15 -0
  20. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/response/shops.py +51 -0
  21. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/response/simple_responses.py +61 -0
  22. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/response/web_app_url.py +5 -0
  23. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/shared.pyi +34 -0
  24. shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/users.pyi +37 -0
  25. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/request/orders.py +1 -0
  26. shop_system_models-1.0.0.dev26932/shop_system_models/deployment_api/request/authorization.py +0 -1
  27. shop_system_models-1.0.0.dev26932/shop_system_models/deployment_api/request/services.py +0 -0
  28. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/README.md +0 -0
  29. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/__init__.py +0 -0
  30. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/__init__.pyi +0 -0
  31. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/consts/__init__.py +0 -0
  32. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/consts/__init__.pyi +0 -0
  33. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/consts/country_codes.py +0 -0
  34. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/consts/country_codes.pyi +0 -0
  35. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/consts/enums.py +0 -0
  36. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/consts/enums.pyi +0 -0
  37. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/consts/messages/admin.py +0 -0
  38. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/consts/messages/locales/en.json +0 -0
  39. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/consts/messages/locales/ru.json +0 -0
  40. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/consts/messages/mapping.py +0 -0
  41. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/deployment_api/__init__.py +0 -0
  42. /shop_system_models-1.0.0.dev26932/shop_system_models/deployment_api/request/servers.py → /shop_system_models-1.0.0.dev27178/shop_system_models/deployment_api/__init__.pyi +0 -0
  43. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/deployment_api/request/bot.py +0 -0
  44. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/deployment_api/request/nocodb.py +0 -0
  45. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/deployment_api/request/premium.py +0 -0
  46. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/deployment_api/shared.py +0 -0
  47. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/deployment_api/users.py +0 -0
  48. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/py.typed +0 -0
  49. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/__init__.py +0 -0
  50. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/__init__.pyi +0 -0
  51. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/bot/__init__.py +0 -0
  52. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/bot/request.py +0 -0
  53. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/bot/response.py +0 -0
  54. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/commands/__init__.py +0 -0
  55. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/commands/request.py +0 -0
  56. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/commands/response.py +0 -0
  57. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/links.py +0 -0
  58. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/processes/__init__.py +0 -0
  59. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/processes/request.py +0 -0
  60. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/processes/response.py +0 -0
  61. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shared.py +0 -0
  62. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/__init__.py +0 -0
  63. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/request/__init__.py +0 -0
  64. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/request/baskets.py +0 -0
  65. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/request/categories.py +0 -0
  66. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/request/coupons.py +0 -0
  67. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/request/details.py +0 -0
  68. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/request/payment_methods.py +0 -0
  69. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/request/products.py +0 -0
  70. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/request/review.py +0 -0
  71. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/request/shop.py +0 -0
  72. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/__init__.py +0 -0
  73. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/basic.py +0 -0
  74. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/baskets.py +0 -0
  75. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/categories.py +0 -0
  76. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/coupons.py +0 -0
  77. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/extra_product_options.py +0 -0
  78. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/initialization_data.py +0 -0
  79. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/orders.py +0 -0
  80. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/payment_methods.py +0 -0
  81. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/products.py +0 -0
  82. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/review.py +0 -0
  83. {shop_system_models-1.0.0.dev26932 → shop_system_models-1.0.0.dev27178}/shop_system_models/shop_api/shop/response/users.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: shop_system_models
3
- Version: 1.0.0.dev26932
3
+ Version: 1.0.0.dev27178
4
4
  Summary: Shared model definitions for shop system services
5
5
  Author: Pavel Mulin
6
6
  Author-email: pavel@tg-shops.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "shop_system_models"
3
- version = "v1.0.0.dev26932"
3
+ version = "v1.0.0.dev27178"
4
4
  description = "Shared model definitions for shop system services"
5
5
  authors = ["Pavel Mulin <pavel@tg-shops.com>"]
6
6
  readme = "README.md"
@@ -0,0 +1,4 @@
1
+ TG_LANGUAGES_MAPPING = {'ru': 'RU',
2
+ 'en': 'EN'}
3
+
4
+ LANGUAGES = {value: key for key, value in TG_LANGUAGES_MAPPING.items()} # reverse TG_LANGUAGES
@@ -0,0 +1,4 @@
1
+ from _typeshed import Incomplete
2
+
3
+ TG_LANGUAGES_MAPPING: Incomplete
4
+ LANGUAGES: Incomplete
@@ -0,0 +1,6 @@
1
+ from shop_system_models.deployment_api.request.users import User
2
+
3
+
4
+ class Token(User):
5
+ initData: str
6
+
@@ -12,3 +12,4 @@ class DeployVariables(BaseModel):
12
12
  contact_phone: Optional[str]
13
13
  bot_token: Optional[str]
14
14
  invite_user: bool = True
15
+
@@ -0,0 +1,36 @@
1
+ from typing import Optional
2
+
3
+ from shop_system_models.consts.enums import ServiceNames
4
+ from pydantic import BaseModel, computed_field
5
+
6
+
7
+ class ServiceConfig(BaseModel):
8
+ name: ServiceNames
9
+ version: Optional[str] = 'latest'
10
+
11
+ class Config:
12
+ use_enum_values = True
13
+
14
+
15
+ class ProjectConfiguration(BaseModel):
16
+ shop_name: str
17
+
18
+ # Константы для URL — будут задаваться в рантайме
19
+ SHOP_BOT_URL: str = ''
20
+ SHOP_API_URL: str = ''
21
+ SHOP_APP_URL: str = ''
22
+
23
+ @computed_field # type: ignore
24
+ @property
25
+ def shop_bot_url(self) -> str:
26
+ return f"{self.SHOP_BOT_URL}/{self.shop_name}"
27
+
28
+ @computed_field # type: ignore
29
+ @property
30
+ def shop_api_url(self) -> str:
31
+ return f"{self.SHOP_API_URL}/{self.shop_name}"
32
+
33
+ @computed_field # type: ignore
34
+ @property
35
+ def shop_url(self) -> str:
36
+ return f"{self.SHOP_APP_URL}/{self.shop_name}"
@@ -0,0 +1,9 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class ShopCategory(BaseModel):
7
+ name: str
8
+ description: Optional[str] = None
9
+ preview_url: Optional[str] = None
@@ -0,0 +1,21 @@
1
+ from typing import Optional
2
+
3
+ from fastapi import HTTPException
4
+ from pydantic import BaseModel, field_validator
5
+
6
+
7
+ def link_validation(link: str) -> str:
8
+ if not link.startswith('http://') and not link.startswith('https://'):
9
+ raise HTTPException(status_code=400, detail=f'Invalid link: {link}')
10
+ return link
11
+
12
+
13
+ class LinkBlocks(BaseModel):
14
+ contacts: Optional[str] = None
15
+ info: Optional[str] = None
16
+
17
+ @field_validator('contacts', 'info')
18
+ def link_validation(cls, value: str) -> str:
19
+ if value:
20
+ return link_validation(link=value)
21
+ return value
@@ -0,0 +1,51 @@
1
+ from typing import List, Optional
2
+
3
+ from fastapi import HTTPException
4
+ from pydantic import BaseModel, field_validator
5
+
6
+
7
+ class Coordinates(BaseModel):
8
+ latitude: float
9
+ longitude: float
10
+
11
+
12
+ class ExtraField(BaseModel):
13
+ name: str
14
+ description: str
15
+ is_required: bool
16
+
17
+
18
+ # class ExtraFieldPayload(BaseModel):
19
+ # name: str
20
+ # value: str
21
+
22
+
23
+ class DeliveryType(BaseModel):
24
+ name: str
25
+ amount: float = 0.0
26
+ is_address_required: bool = False
27
+ address_hint: Optional[str] = ''
28
+ extra_fields: List[ExtraField] = []
29
+ is_timepicker_required: bool = False
30
+ details: str = ''
31
+ country: Optional[str] = ''
32
+ country_code: Optional[str] = '' # ISO format, ex.: RU, KZ, BY...
33
+ city: Optional[str] = None
34
+ delivery_location: Optional[Coordinates] = None
35
+ delivery_radius: Optional[int] = None
36
+ delivery_min_hour: Optional[int] = None
37
+ delivery_max_hour: Optional[int] = None
38
+ delivery_minutes_interval: Optional[int] = None
39
+ delivery_min_day: Optional[int] = None
40
+ delivery_max_day: Optional[int] = None
41
+
42
+ @field_validator('name')
43
+ def name_validation(cls, name):
44
+ name = name.strip()
45
+ if len(name) <= 2:
46
+ raise HTTPException(status_code=400, detail=f'Invalid delivery name: {name}')
47
+ return name
48
+
49
+
50
+ class DeliveryTypeResponse(DeliveryType):
51
+ id: str
@@ -0,0 +1,32 @@
1
+ from enum import Enum
2
+ from typing import List, Optional
3
+
4
+ from pydantic import BaseModel
5
+
6
+
7
+ class PaymentTypes(str, Enum):
8
+ manual_payment_request = 'ManualPaymentRequest'
9
+ external_card_payment_provider = 'ExternalCardPaymentProvider'
10
+ crypto_ton = 'CryptoTON'
11
+ xtr = 'XTR'
12
+ life_pay = 'LifePay'
13
+ yookassa = "yookassa"
14
+ tkassa = "tkassa"
15
+
16
+ class Metadata(BaseModel):
17
+ key: str
18
+ value: List[str]
19
+
20
+
21
+ class PaymentMethod(BaseModel):
22
+ name: str
23
+ type: PaymentTypes
24
+ payment_data: str # payment_token, TON address etc....
25
+ meta: Optional[List[Metadata]] = []
26
+
27
+ class Config:
28
+ use_enum_values = True
29
+
30
+
31
+ class PaymentMethodResponse(PaymentMethod):
32
+ id: str
@@ -0,0 +1,18 @@
1
+ from typing import Optional
2
+
3
+ from fastapi import HTTPException
4
+ from pydantic import BaseModel, field_validator
5
+
6
+
7
+ class ShopTemplate(BaseModel):
8
+ template_id: str
9
+ name: str
10
+ description: Optional[str] = ''
11
+ bot_url: str
12
+ language: str
13
+
14
+ @field_validator('bot_url')
15
+ def url_validation(cls, bot_url):
16
+ if bot_url.startswith('http://') or bot_url.startswith('https://'):
17
+ return bot_url
18
+ raise HTTPException(status_code=400, detail=f'Invalid bot_url: {bot_url}')
@@ -0,0 +1,102 @@
1
+ import re
2
+ from datetime import datetime
3
+ from typing import Any, List, Optional, Union
4
+
5
+ from pydantic import BaseModel, ValidationError, computed_field, model_validator, Field
6
+ from transliterate import translit # type: ignore
7
+
8
+ from shop_system_models.consts.enums import ShopStatuses
9
+ from shop_system_models.deployment_api.request.nocodb import NocoDBConfig
10
+ from shop_system_models.deployment_api.request.services import ProjectConfiguration
11
+ from shop_system_models.deployment_api.request.tasks import Task
12
+ from shop_system_models.deployment_api.response.shops import ShopCategoryResponse
13
+
14
+
15
+ class Location(BaseModel):
16
+ latitude: float
17
+ longitude: float
18
+ address: str
19
+
20
+
21
+ class CreateShop(BaseModel):
22
+ name: str
23
+ categories: List[ShopCategoryResponse] = []
24
+ locations: Optional[List[Location]] = []
25
+ contact_email: str
26
+ template_id: str
27
+ orders_chat_id: int = 0
28
+ friendly_name: str = ''
29
+ contact_phone: Optional[str] = ''
30
+ bot_token: Optional[str] = ''
31
+ zone: Optional[int] = None
32
+
33
+ @model_validator(mode='before')
34
+ def set_friendly_name_and_format_name(cls, values: dict):
35
+ name = values.get('name', '')
36
+ if len(name) > 35:
37
+ raise ValueError('Shop name too long; must be less than 35 symbols')
38
+
39
+ if not values.get('friendly_name'):
40
+ values['friendly_name'] = name.strip().strip("-")
41
+
42
+ transliterated_name = translit(name, 'ru', reversed=True) if name else ''
43
+ no_whitespaces_and_underscores = transliterated_name.replace(' ', '-').replace('_', '-')
44
+ no_double_dashes = re.sub(r'-{2,}', '-', no_whitespaces_and_underscores)
45
+ to_lowercase = no_double_dashes.lower()
46
+ no_special_characters = re.sub(r'[^a-z0-9_-]', '', to_lowercase)
47
+ formatted_name = re.sub(r'^[^a-z0-9]+|[^a-z0-9]+$', '', no_special_characters)
48
+
49
+ values['name'] = formatted_name
50
+ return values
51
+
52
+
53
+ class Shop(CreateShop):
54
+ # КОНСТАНТЫ ИЗ CONFIG
55
+ WEB_APP_URL: str = ''
56
+ FRONTEND_HOST: str = ''
57
+
58
+ placeholder: Optional[Union[ShopStatuses, Any]] = ShopStatuses.deploying
59
+ tasks: List[Task] = []
60
+ language: str = 'RU'
61
+ nocodb_config: NocoDBConfig = NocoDBConfig()
62
+
63
+ search_enabled: Optional[bool] = False
64
+ warehouse_accounting: Optional[bool] = False
65
+ weekly_reports: Optional[bool] = True
66
+ orders_history_chat_id: Optional[int] = None
67
+ topic_chat_id: Optional[int] = None
68
+ premium_expiration_date: Optional[datetime] = None
69
+ broadcast_messages_count: Optional[int] = 0
70
+ web_app_url: str = Field(default_factory=lambda: Shop.WEB_APP_URL)
71
+
72
+ blocked: bool = False
73
+ block_reason: str = ""
74
+
75
+ @computed_field # type: ignore
76
+ @property
77
+ def sheet_link(self) -> Optional[str]:
78
+ if self.nocodb_config and self.nocodb_config.nocodb_project_id:
79
+ return f"{self.FRONTEND_HOST}/dashboard/#/nc/{self.nocodb_config.nocodb_project_id}"
80
+ return None
81
+
82
+
83
+ class ShopDB(Shop):
84
+ id: str
85
+ tg_admin_id: int = 0
86
+ is_changeable: Optional[bool] = True
87
+ order_process: str = "The-devs.Shop.CreateOrder"
88
+ nocodb_config: NocoDBConfig = NocoDBConfig()
89
+ preview_url: Optional[str] = None
90
+ views_id: List[str] = []
91
+
92
+ @computed_field # type: ignore
93
+ @property
94
+ def configuration(self) -> ProjectConfiguration:
95
+ return ProjectConfiguration(
96
+ shop_name=self.name
97
+ )
98
+
99
+
100
+ class UpdateFromProcess(BaseModel):
101
+ nocodb_config: NocoDBConfig
102
+ language: str
@@ -0,0 +1,24 @@
1
+ from typing import List
2
+
3
+ from shop_system_models.consts.enums import TaskStatuses
4
+ from pydantic import BaseModel
5
+
6
+
7
+ class Task(BaseModel):
8
+ title: str
9
+ assignee_role: List = []
10
+ shop_id: str
11
+ shop_name: str
12
+ submit_url: str = ''
13
+ variables: dict
14
+ element_id: str
15
+ form_json: dict
16
+ job_key: int
17
+ process_id: str
18
+ process_instance_key: int
19
+ process_monitoring_url: str
20
+ deadline: int
21
+ status: TaskStatuses = TaskStatuses.pending
22
+
23
+ class Config:
24
+ use_enum_values = True
@@ -0,0 +1,53 @@
1
+ from typing import List, Optional
2
+
3
+ from shop_system_models.consts.enums import UserRoles
4
+ from shop_system_models.consts.languages import TG_LANGUAGES_MAPPING
5
+ from pydantic import BaseModel, field_validator, model_validator, computed_field
6
+
7
+
8
+ class ReferralUser(BaseModel):
9
+ first_name: str
10
+ last_name: Optional[str] = ''
11
+ username: Optional[str] = ''
12
+ tg_id: int
13
+
14
+
15
+ class User(BaseModel):
16
+ first_name: str
17
+ last_name: Optional[str] = ''
18
+ username: Optional[str] = ''
19
+ tg_id: int
20
+ tg_language: str = '' # language_code from TG
21
+
22
+ @computed_field # type: ignore
23
+ @property
24
+ def language(self) -> str:
25
+ return TG_LANGUAGES_MAPPING.get(self.tg_language, 'EN')
26
+
27
+
28
+ class UserDB(User):
29
+ invited_by_id: Optional[str] = None
30
+ invited_by_user: Optional[ReferralUser] = None
31
+ cache_key: Optional[str] = None
32
+
33
+
34
+ class UserExtended(UserDB):
35
+ SHOPS_LIMIT: int = 0 # сюда потом в рантайме подставишь значение из конфига
36
+
37
+ roles: List[str] = [] # 'shop_admin:<shop_id>' or 'admin'
38
+ shops_available: int = SHOPS_LIMIT
39
+
40
+ @field_validator('roles')
41
+ def if_admin(cls, roles: list):
42
+ for role in roles:
43
+ if role == UserRoles.admin.value:
44
+ return [UserRoles.admin.value]
45
+ return roles
46
+
47
+ @field_validator('shops_available')
48
+ def admin_limit(cls, shops_available, model):
49
+ roles = model.data['roles']
50
+ for role in roles:
51
+ if role == UserRoles.admin.value:
52
+ return 10
53
+ return shops_available
@@ -0,0 +1,14 @@
1
+ import re
2
+
3
+ from pydantic import BaseModel, Field, field_validator
4
+
5
+
6
+ class WebAppUrlUpdateRequest(BaseModel):
7
+ web_app_url: str = Field(..., description="The URL of the telegram web app")
8
+
9
+ @field_validator("web_app_url")
10
+ def validate_web_app_url(cls, value):
11
+ pattern = r"^https://t\.me/[A-Za-z0-9_]+/[A-Za-z0-9_]+$"
12
+ if not re.match(pattern, value):
13
+ raise ValueError("web_app_url must follow the pattern: 'https://t.me/{bot_name}/{webapp_name}', where bot_name and webapp_name can vary.")
14
+ return value
@@ -0,0 +1,23 @@
1
+ import enum
2
+ from pydantic import BaseModel
3
+
4
+
5
+ class PageInfo(BaseModel):
6
+ total_rows: int
7
+ page: int
8
+ page_size: int
9
+ is_first_page: bool
10
+ is_last_page: bool
11
+
12
+
13
+ class ListResponseModel(BaseModel):
14
+ page_info: PageInfo
15
+
16
+
17
+ class ExtraOptionsModel(str, enum.Enum):
18
+ enabled = 'enabled'
19
+ disabled = 'disabled'
20
+
21
+
22
+ class ExtraOptionsStatusResponse(BaseModel):
23
+ status: ExtraOptionsModel
@@ -0,0 +1,6 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class InviteLinkResponse(BaseModel):
5
+ valid_until: int
6
+ link: str
@@ -0,0 +1,15 @@
1
+ from pydantic import BaseModel
2
+
3
+ from shop_system_models.deployment_api.request.premium import PremiumPlanTypes
4
+
5
+
6
+ class PremiumLinkResponseModel(BaseModel):
7
+ shop_name: str
8
+ premium_type: str
9
+ link: str
10
+
11
+
12
+ class PremiumPlanType(BaseModel):
13
+ price: int
14
+ final_price: int
15
+ type: PremiumPlanTypes
@@ -0,0 +1,51 @@
1
+ from datetime import datetime
2
+ from typing import List, Optional
3
+
4
+
5
+ from shop_system_models.deployment_api.request.nocodb import NocoDBConfig
6
+ from shop_system_models.deployment_api.request.shop_categories import ShopCategory
7
+ from shop_system_models.deployment_api.request.shop_content.blocks import LinkBlocks
8
+ from shop_system_models.deployment_api.request.shop_content.delivery_types import DeliveryTypeResponse
9
+ from shop_system_models.deployment_api.request.shop_content.payment_methods import PaymentMethodResponse
10
+ from pydantic import BaseModel, Field
11
+
12
+
13
+ class ContentDataResponseModel(BaseModel):
14
+ blocks: Optional[LinkBlocks]
15
+ delivery_types: Optional[List[DeliveryTypeResponse]]
16
+ payment_methods: Optional[List[PaymentMethodResponse]]
17
+
18
+
19
+ class ShopDetails(BaseModel):
20
+ shop_id: str
21
+ shop_name: str
22
+ friendly_name: str
23
+ shop_language: Optional[str] = 'RU'
24
+ shop_api_url: str
25
+ contact_phone: str
26
+ contact_email: str
27
+ orders_chat_id: int # orders_management_chat_id
28
+ orders_history_chat_id: Optional[int] = None
29
+ topic_chat_id: Optional[int] = None
30
+ bot_url: str
31
+ bot_token: str
32
+ placeholder: str
33
+ order_process: str
34
+ search_enabled: bool = False
35
+ warehouse_accounting: bool = False
36
+ nocodb_config: Optional[NocoDBConfig] = None
37
+ nocodb_project_id: Optional[str] = None
38
+ nocodb_categories_table: Optional[str] = None
39
+ nocodb_products_table: Optional[str] = None
40
+ nocodb_orders_table: Optional[str] = None
41
+ nocodb_status_table: Optional[str] = None
42
+ nocodb_bot_commands_table: Optional[str] = None
43
+ nocodb_options_table: Optional[str] = ""
44
+ nocodb_options_category_table: Optional[str] = ""
45
+ premium_expiration_date: Optional[datetime] = None
46
+ broadcast_messages_count: Optional[int] = 0
47
+ web_app_url: str
48
+
49
+
50
+ class ShopCategoryResponse(ShopCategory):
51
+ id: str
@@ -0,0 +1,61 @@
1
+ from typing import List, Optional
2
+
3
+
4
+ from shop_system_models.deployment_api.request.services import ServiceConfig
5
+ from shop_system_models.deployment_api.request.shop_templates import ShopTemplate
6
+ from shop_system_models.deployment_api.request.shops import CreateShop, Shop, ShopDB
7
+ from shop_system_models.deployment_api.request.tasks import Task
8
+ from shop_system_models.deployment_api.request.users import User, UserExtended
9
+ from pydantic import BaseModel
10
+
11
+ from shop_system_models.deployment_api.response.general import ListResponseModel
12
+
13
+
14
+ class BasicResponse(BaseModel):
15
+ message: str
16
+
17
+
18
+
19
+
20
+
21
+ class ServiceConfigResponse(ServiceConfig):
22
+ id: str
23
+
24
+
25
+ class CreateShopResponse(CreateShop):
26
+ id: str
27
+
28
+
29
+ class ShopResponse(Shop):
30
+ id: str
31
+ preview_url: Optional[str] = None
32
+
33
+
34
+ class ShopResponseId(ShopDB):
35
+ id: str
36
+
37
+
38
+ class ShopsListResponseModel(ListResponseModel):
39
+ shops: List[ShopResponseId]
40
+
41
+
42
+ class ShopDBResponse(ShopDB):
43
+ id: str
44
+
45
+
46
+ class TaskResponse(Task):
47
+ id: str
48
+
49
+
50
+ class UserResponse(UserExtended):
51
+ id: str
52
+ invited_users: Optional[List[User]] = None
53
+ cache_key: Optional[str] = None
54
+
55
+
56
+ class TokenResponse(BaseModel):
57
+ access_token: str
58
+
59
+
60
+ class ShopTemplateResponse(ShopTemplate):
61
+ id: str
@@ -0,0 +1,5 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class WebAppUrlResponse(BaseModel):
5
+ web_app_url: str
@@ -0,0 +1,34 @@
1
+ from datetime import datetime
2
+ from pydantic import BaseModel
3
+
4
+ class NocoDBConfig(BaseModel):
5
+ nocodb_project_id: str
6
+ nocodb_categories_table: str
7
+ nocodb_products_table: str
8
+ nocodb_orders_table: str
9
+ nocodb_status_table: str
10
+ nocodb_bot_commands_table: str
11
+ nocodb_options_table: str | None
12
+ nocodb_options_category_table: str | None
13
+
14
+ class ShopDetailsModel(BaseModel):
15
+ shop_id: str
16
+ shop_name: str
17
+ friendly_name: str
18
+ shop_language: str
19
+ shop_api_url: str
20
+ contact_phone: str | None
21
+ contact_email: str
22
+ orders_chat_id: int
23
+ orders_history_chat_id: int | None
24
+ search_enabled: bool | None
25
+ warehouse_accounting: bool
26
+ bot_url: str | None
27
+ bot_token: str
28
+ payment_token: str | None
29
+ placeholder: str
30
+ order_process: str
31
+ nocodb_config: NocoDBConfig | None
32
+ topic_chat_id: int | None
33
+ premium_expiration_date: datetime | None
34
+ web_app_url: str
@@ -0,0 +1,37 @@
1
+ from pydantic import BaseModel
2
+
3
+ class UserHeadersUpdatingModel(BaseModel):
4
+ tg_id: int
5
+ first_name: str | None
6
+ last_name: str | None
7
+ tg_language: str | None
8
+ username: str | None
9
+
10
+ class UserModel(UserHeadersUpdatingModel):
11
+ password: str | None
12
+ preview_url: str | None
13
+ rights: str
14
+ delivery_addresses: list[str] | None
15
+
16
+ class ReferralUser(BaseModel):
17
+ tg_id: int
18
+ first_name: str
19
+ last_name: str | None
20
+ username: str | None
21
+
22
+ class InvitedUser(ReferralUser):
23
+ tg_language: str | None
24
+ language: str | None
25
+
26
+ class UserDeploymentModel(BaseModel):
27
+ id: str
28
+ first_name: str
29
+ last_name: str | None
30
+ username: str | None
31
+ tg_id: int
32
+ tg_language: str
33
+ invited_by_id: str | None
34
+ invited_by_user: ReferralUser | None
35
+ roles: list[str] | None
36
+ shops_available: int
37
+ invited_users: list[InvitedUser] | None
@@ -89,6 +89,7 @@ class OrderPaymentDetails(BaseModel):
89
89
  expires_at: datetime
90
90
  link: str
91
91
 
92
+
92
93
  # This depends on UserBasketResponseModelV2 which we'll define in a separate file
93
94
  # For now, we'll create a placeholder class that can be updated later
94
95
  class OrderModel(CreateOrderModel):