OrangeDataPack 0.0.1__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.
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.3
2
+ Name: OrangeDataPack
3
+ Version: 0.0.1
4
+ Summary: Package for OrangeData API service
5
+ Requires-Dist: cryptography>=50.0.1
6
+ Requires-Dist: phonenumbers>=9.0.40
7
+ Requires-Dist: pydantic>=2.13.5
8
+ Requires-Dist: pydantic-extra-types>=2.11.1
9
+ Requires-Dist: requests>=2.34.2
10
+ Requires-Python: >=3.14.3
11
+ Description-Content-Type: text/markdown
12
+
13
+ # orange-data
@@ -0,0 +1 @@
1
+ # orange-data
File without changes
@@ -0,0 +1,133 @@
1
+ import base64
2
+ import json
3
+ from urllib.parse import urljoin
4
+
5
+ import requests
6
+ from cryptography.hazmat.primitives import hashes
7
+ from cryptography.hazmat.primitives.asymmetric import padding
8
+ from cryptography.hazmat.primitives.serialization import load_pem_private_key
9
+ from pydantic import BaseModel, validate_call
10
+
11
+ from orangedatatools.schemas import (
12
+ Correction12Schema,
13
+ CorrectionSchema,
14
+ DocumentSchema,
15
+ ItemCodeSchema,
16
+ )
17
+ from orangedatatools.schemas.client_args import ClientArgs
18
+ from orangedatatools.utils.endpoints import OrangeEndpoints as ENDS
19
+
20
+
21
+ class OrangeDataClient:
22
+ @validate_call
23
+ def __init__(
24
+ self,
25
+ org_params: ClientArgs,
26
+ api_url: str,
27
+ key_private_path: str,
28
+ client_key_path: str,
29
+ client_cert_path: str,
30
+ ):
31
+ """Initializes the client with the passed parameters.
32
+
33
+ Args:
34
+ org_params (Client Args): Organization parameters.
35
+ api_url (str): The URL of the API for sending requests.
36
+ key_private_path (str): The path to the private key for signing.
37
+ client_key_path (str): The path to the client's private key.
38
+ client_cert_path (str): The path to the client SSL certificate.
39
+ """
40
+ self.org_params = org_params
41
+ self.api_url = api_url.rstrip("/")
42
+ self.key_private_path = key_private_path
43
+ self.client_key_path = client_key_path
44
+ self.client_cert_path = client_cert_path
45
+
46
+ def __combineData(self, data: BaseModel) -> dict:
47
+ """Merging organization parameters and receipt data
48
+
49
+ Args:
50
+ data (BaseModel): Pydantic data schema
51
+ """
52
+
53
+ return {
54
+ **self.org_params.model_dump(),
55
+ **data.model_dump(exclude_none=True, mode="json"),
56
+ }
57
+
58
+ def __computeSignature(self, data: bytes) -> base64:
59
+ """Creating a signature based on a private pem key"""
60
+
61
+ with open(self.key_private_path, "rb") as pem_in:
62
+ pemlines = pem_in.read()
63
+ private_key = load_pem_private_key(pemlines, password=None)
64
+ signature = private_key.sign(data, padding.PKCS1v15(), hashes.SHA256())
65
+
66
+ return base64.b64encode(signature).decode("utf-8")
67
+
68
+ def __signPost(self, params: BaseModel, path: str) -> tuple[str, int]:
69
+ data = self.__combineData(params)
70
+ bytes_data = json.dumps(data, ensure_ascii=False).encode("utf-8")
71
+ sign = self.__computeSignature(bytes_data)
72
+
73
+ headers = {
74
+ "Accept": "application/json",
75
+ "Content-Type": "application/json",
76
+ "X-Signature": sign,
77
+ }
78
+
79
+ url_path = urljoin(self.api_url, path)
80
+
81
+ r = requests.post(
82
+ url=url_path,
83
+ headers=headers,
84
+ json=data,
85
+ cert=(self.client_cert_path, self.client_key_path),
86
+ verify=False,
87
+ )
88
+
89
+ return r.text, r.status_code
90
+
91
+ def __Get(self, path: str) -> tuple[str, int]:
92
+ url_path = urljoin(self.api_url, path)
93
+ r = requests.get(url=url_path)
94
+
95
+ return r.text, r.status_code
96
+
97
+ @validate_call
98
+ def create_receipt(self, order_params: DocumentSchema) -> tuple[str, int]:
99
+ return self.__signPost(order_params, ENDS.document())
100
+
101
+ def check_receipt(self, document_id: str) -> tuple[str, int]:
102
+ path = ENDS.document_status(self.org_params.inn, document_id)
103
+
104
+ return self.__Get(path)
105
+
106
+ @validate_call
107
+ def create_correction(self, correction_params: CorrectionSchema) -> tuple[str, int]:
108
+ return self.__signPost(correction_params, ENDS.corrections())
109
+
110
+ def check_correction(self, correction_id: str) -> tuple[str, int]:
111
+ path = ENDS.corrections_status(self.org_params.inn, correction_id)
112
+
113
+ return self.__Get(path)
114
+
115
+ @validate_call
116
+ def create_correction12(
117
+ self, correction_params: Correction12Schema
118
+ ) -> tuple[str, int]:
119
+ return self.__signPost(correction_params, ENDS.corrections12())
120
+
121
+ def check_correction12(self, correction_id: str) -> tuple[str, int]:
122
+ path = ENDS.correction12_status(self.org_params.inn, correction_id)
123
+
124
+ return self.__Get(path)
125
+
126
+ @validate_call
127
+ def create_itemcode(self, itemcode_params: ItemCodeSchema) -> tuple[str, int]:
128
+ return self.__signPost(itemcode_params, ENDS.itemcode())
129
+
130
+ def check_itemcode(self, itemcode_id: str) -> tuple[str, int]:
131
+ path = ENDS.itemcode_status(self.org_params.inn, itemcode_id)
132
+
133
+ return self.__Get(path)
@@ -0,0 +1,6 @@
1
+ from .correction12_args import Correction12Schema
2
+ from .correction_args import CorrectionSchema
3
+ from .fiscal_args import DocumentSchema
4
+ from .itemcode_args import ItemCodeSchema
5
+
6
+ __all__ = ["CorrectionSchema", "Correction12Schema", "DocumentSchema", "ItemCodeSchema"]
@@ -0,0 +1,34 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class ReqBodyBase(BaseModel):
7
+ id: str = Field(max_length=64)
8
+ callbackUrl: Optional[str] = Field(default=None, max_length=1024)
9
+ callbackApiKey: Optional[str] = Field(default=None, max_length=3072)
10
+ meta: Optional[str] = Field(default=None, max_length=128)
11
+
12
+
13
+ class _IgnoreItemCodeCheckMixin(BaseModel):
14
+ """Mixin with the common flag ignoreItemCodeCheck."""
15
+
16
+ ignoreItemCodeCheck: Optional[bool] = Field(default=None)
17
+
18
+
19
+ class ReqBodyBaseFiscal(ReqBodyBase, _IgnoreItemCodeCheckMixin):
20
+ """Base schema for fiscal documents."""
21
+
22
+ pass
23
+
24
+
25
+ class ReqBodyBaseCorrection(ReqBodyBase):
26
+ """Base schema for correction receipts."""
27
+
28
+ pass
29
+
30
+
31
+ class ReqBodyBaseCorrection12(ReqBodyBase, _IgnoreItemCodeCheckMixin):
32
+ """Base schema for correction receipts (format 1.2)."""
33
+
34
+ pass
@@ -0,0 +1,18 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class ClientArgs(BaseModel):
7
+ inn: str = Field(min_length=10, max_length=12)
8
+ group: Optional[str] = Field(
9
+ default=None,
10
+ max_length=32,
11
+ description=(
12
+ "Название ключа, который должен быть использован для проверки подписи. "
13
+ "Для клиентов используется их ИНН, для новых клиентов с 01.02.25 ИНН_ID "
14
+ "(ID - идентификационный номер пользователя в системе). Для партнеров "
15
+ "и платежных агентов код с маской 301****, для вендинга 401****."
16
+ ),
17
+ )
18
+ key: str = Field(max_length=32)
@@ -0,0 +1,230 @@
1
+ from decimal import Decimal
2
+ from enum import IntEnum
3
+ from typing import Annotated, Optional
4
+
5
+ from pydantic import BaseModel, Field, PlainSerializer
6
+ from pydantic_extra_types.phone_numbers import PhoneNumber
7
+
8
+ DecimalField = Annotated[
9
+ Decimal,
10
+ PlainSerializer(lambda x: float(x), return_type=float, when_used="json"),
11
+ ]
12
+
13
+
14
+ class TaxSystem(IntEnum):
15
+ osn = 0
16
+ usn_income = 1
17
+ usn_profit = 2
18
+ envd = 3
19
+ esn = 4
20
+ patent = 5
21
+
22
+
23
+ class CalcIndicator(IntEnum):
24
+ income = 1
25
+ income_return = 2
26
+ expense = 3
27
+ expense_return = 4
28
+
29
+
30
+ class VatRate(IntEnum):
31
+ vat_20 = 1
32
+ vat_10 = 2
33
+ vat_20_120 = 3
34
+ vat_10_110 = 4
35
+ vat_0 = 5
36
+ vat_none = 6
37
+ vat_5 = 7
38
+ vat_7 = 8
39
+ vat_5_105 = 9
40
+ vat_7_107 = 10
41
+
42
+
43
+ class PaymentMethod(IntEnum):
44
+ prepayment_full = 1
45
+ prepayment_partial = 2
46
+ advance = 3
47
+ full_payment = 4
48
+ partial_credit = 5
49
+ credit = 6
50
+ credit_payment = 7
51
+
52
+
53
+ class SettlementSubject(IntEnum):
54
+ product = 1
55
+ excisable = 2
56
+ work = 3
57
+ service = 4
58
+ gambling_bet = 5
59
+ gambling_win = 6
60
+ lottery_ticket = 7
61
+ lottery_win = 8
62
+ ip_rights = 9
63
+ advance = 10
64
+ agent_fee = 11
65
+ payout = 12
66
+ other_subject = 13
67
+ property_right = 14
68
+ non_op_income = 15
69
+ other_payments = 16
70
+ trading_fee = 17
71
+ tourist_tax = 18
72
+ deposit = 19
73
+ expense = 20
74
+ pension_ip = 21
75
+ pension = 22
76
+ medical_ip = 23
77
+ medical = 24
78
+ social = 25
79
+ casino = 26
80
+ cash_out = 27
81
+ unmarked_atnm = 30
82
+ marked_atm = 31
83
+ tnm = 32
84
+ tm = 33
85
+
86
+
87
+ class Contact(PhoneNumber):
88
+ phone_format = "E164"
89
+
90
+
91
+ class FractionalQuantityMarkedProductSchema(BaseModel):
92
+ Numerator: Optional[int] = Field(default=None)
93
+ Denominator: Optional[int] = Field(default=None)
94
+
95
+
96
+ class BarcodesCalculationItem(BaseModel):
97
+ ean8: Optional[str] = Field(default=None, max_length=8)
98
+ ean13: Optional[str] = Field(default=None, max_length=13)
99
+ itf14: Optional[str] = Field(default=None, max_length=14)
100
+ gs1: Optional[str] = Field(default=None, max_length=38)
101
+ mi: Optional[str] = Field(default=None, max_length=20)
102
+ egais20: Optional[str] = Field(default=None, max_length=23)
103
+ egais30: Optional[str] = Field(default=None, max_length=14)
104
+ f1: Optional[str] = Field(default=None, max_length=32)
105
+ f2: Optional[str] = Field(default=None, max_length=32)
106
+ f3: Optional[str] = Field(default=None, max_length=32)
107
+ f4: Optional[str] = Field(default=None, max_length=32)
108
+ f5: Optional[str] = Field(default=None, max_length=32)
109
+ f6: Optional[str] = Field(default=None, max_length=32)
110
+
111
+
112
+ class OperationalDetailsSchema(BaseModel):
113
+ date: Optional[str] = Field(default=None)
114
+ id: Optional[int] = Field(default=None, le=255)
115
+ value: Optional[str] = Field(default=None, max_length=64)
116
+
117
+
118
+ class InformationBuyerSchema(BaseModel):
119
+ name: Optional[str] = Field(default=None, max_length=239)
120
+ inn: Optional[str] = Field(default=None, min_length=10, max_length=12)
121
+ birthDate: Optional[str] = Field(default=None, max_length=10)
122
+ citizenship: Optional[str] = Field(default=None, max_length=3)
123
+ identityDocumentCode: Optional[str] = Field(default=None, max_length=2)
124
+ identityDocumentData: Optional[str] = Field(default=None, max_length=64)
125
+ address: Optional[str] = Field(default=None, max_length=239)
126
+
127
+
128
+ class AgentDataSchema(BaseModel):
129
+ paymentTransferOperatorPhoneNumbers: list[str]
130
+ paymentAgentOperation: str = Field(max_length=24)
131
+ paymentAgentPhoneNumbers: list[str]
132
+ paymentOperatorName: str = Field(max_length=64)
133
+ paymentOperatorAddress: str = Field(max_length=243)
134
+ paymentOperatorINN: str = Field(min_length=10, max_length=12)
135
+
136
+
137
+ class SupplierInfoSchema(BaseModel):
138
+ phoneNumbers: list[Contact]
139
+ name: str = Field(max_length=239)
140
+
141
+
142
+ class AdditionalUserDetailsSchema(BaseModel):
143
+ name: str = Field(max_length=64)
144
+ value: str = Field(max_length=234)
145
+
146
+
147
+ class PaymentSchema(BaseModel):
148
+ type: int = Field(ge=1, le=16)
149
+ amount: DecimalField = Field(decimal_places=2)
150
+
151
+
152
+ class PaymentInfo(BaseModel):
153
+ amount: DecimalField = Field(decimal_places=2)
154
+ type: int = Field(le=255)
155
+ id: str = Field(max_length=256)
156
+ additionalInfo: str = Field(max_length=256)
157
+
158
+
159
+ class PaymentsInfo(BaseModel):
160
+ payments: list[PaymentInfo]
161
+
162
+
163
+ class ReceiptClosingParametersSchema(BaseModel):
164
+ payments: list[PaymentSchema]
165
+ taxationSystem: TaxSystem
166
+ electronicPaymentsInfo: PaymentsInfo
167
+
168
+
169
+ class PostionSchema(BaseModel):
170
+ quantity: DecimalField = Field(decimal_places=6)
171
+ price: DecimalField = Field(decimal_places=2)
172
+ tax: VatRate
173
+ taxSum: Optional[Decimal] = Field(default=None, decimal_places=2)
174
+ text: str = Field(max_length=128)
175
+ paymentMethodType: Optional[PaymentMethod] = Field(
176
+ default=PaymentMethod.full_payment
177
+ )
178
+ paymentSubjectType: Optional[SettlementSubject] = Field(
179
+ default=SettlementSubject.product
180
+ )
181
+ nomenclatureCode: Optional[bytes] = Field(default=None, min_length=8, max_length=32)
182
+ itemCode: Optional[str] = Field(default=None, max_length=233)
183
+ plannedStatus: Optional[int] = Field(default=None, le=256)
184
+ supplierInfo: Optional[SupplierInfoSchema] = Field(default=None)
185
+ supplierINN: Optional[str] = Field(default=None, min_length=10, max_length=12)
186
+ agentType: Optional[int] = Field(default=None, ge=1, le=127)
187
+ agentInfo: Optional[AgentDataSchema] = Field(default=None)
188
+ unitOfMeasurement: Optional[str] = Field(default=None, max_length=16)
189
+ quantityMeasurementUnit: Optional[int] = Field(default=None, le=255)
190
+ additionalAttribute: Optional[str] = Field(default=None, max_length=64)
191
+ manufacturerCountryCode: Optional[str] = Field(default=None, max_length=3)
192
+ customsDeclarationNumber: Optional[str] = Field(default=None, max_length=32)
193
+ excise: Optional[Decimal] = Field(default=None, decimal_places=2)
194
+ unitTaxSum: Optional[Decimal] = Field(default=None, decimal_places=2)
195
+ fractionalQuantity: Optional[FractionalQuantityMarkedProductSchema] = Field(
196
+ default=None
197
+ )
198
+ barcodes: Optional[BarcodesCalculationItem] = Field(default=None)
199
+ assignedStatus: Optional[int] = Field(default=None)
200
+
201
+
202
+ class BaseContent(BaseModel):
203
+ ffdVersion: Optional[int] = Field(default=2)
204
+ type: CalcIndicator
205
+ positions: list[PostionSchema]
206
+ checkClose: ReceiptClosingParametersSchema
207
+ customerContact: str = Field(max_length=64)
208
+ additionalUserAttribute: Optional[AdditionalUserDetailsSchema] = Field(default=None)
209
+ additionalAttribute: Optional[str] = Field(default=None, max_length=16)
210
+ automatNumber: Optional[str] = Field(default=None, max_length=20)
211
+ settlementAddress: Optional[str] = Field(default=None, max_length=243)
212
+ settlementPlace: Optional[str] = Field(default=None, max_length=243)
213
+ cashier: Optional[str] = Field(default=None, max_length=64)
214
+ cashierINN: Optional[str] = Field(default=None, min_length=12)
215
+ senderEmail: Optional[str] = Field(default=None, max_length=64)
216
+ totalSum: Optional[Decimal] = Field(default=None, decimal_places=2)
217
+ vat1Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
218
+ vat2Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
219
+ vat3Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
220
+ vat4Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
221
+ vat5Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
222
+ vat6Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
223
+ vat7Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
224
+ vat8Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
225
+ vat9Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
226
+ vat10Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
227
+ operationalAttribute: Optional[OperationalDetailsSchema] = Field(default=None)
228
+ timeZone: Optional[int] = Field(default=None, ge=1, le=11)
229
+ isInternetStore: Optional[bool] = Field(default=None)
230
+ useTax20: Optional[bool] = Field(default=None)
@@ -0,0 +1,14 @@
1
+ from pydantic import Field
2
+
3
+ from .base_args import ReqBodyBaseCorrection12
4
+ from .common import BaseContent
5
+
6
+
7
+ class Correction12SchemaContent(BaseContent):
8
+ correctionType: str
9
+ causeDocumentDate: str
10
+ causeDocumentNumber: str
11
+
12
+
13
+ class Correction12Schema(ReqBodyBaseCorrection12):
14
+ content: Correction12SchemaContent
@@ -0,0 +1,55 @@
1
+ from decimal import Decimal
2
+ from enum import IntEnum
3
+ from typing import Optional
4
+
5
+ from pydantic import BaseModel, Field
6
+
7
+ from .base_args import ReqBodyBaseCorrection
8
+ from .common import DecimalField, TaxSystem
9
+
10
+
11
+ class CorrectionTypes(IntEnum):
12
+ self_selected = 0 # выбрана самостоятельно
13
+ prescribed = 1 # предписана (обязательна)
14
+
15
+
16
+ class CorrectionCalcIndicator(IntEnum):
17
+ """Calculation indicator for a correction receipt (income/expense only)."""
18
+
19
+ income = 1
20
+ expense = 3
21
+
22
+
23
+ class CorrectionSchemaContent(BaseModel):
24
+ correctionType: CorrectionTypes
25
+ type: CorrectionCalcIndicator
26
+ causeDocumentDate: str
27
+ causeDocumentNumber: Optional[str] = Field(default=None, max_length=32)
28
+ totalSum: DecimalField = Field(decimal_places=2)
29
+ cashSum: Optional[Decimal] = Field(default=None, decimal_places=2)
30
+ eCashSum: Optional[Decimal] = Field(default=None, decimal_places=2)
31
+ prepaymentSum: Optional[Decimal] = Field(default=None, decimal_places=2)
32
+ postpaymentSum: Optional[Decimal] = Field(default=None, decimal_places=2)
33
+ otherPaymentTypeSum: Optional[Decimal] = Field(default=None, decimal_places=2)
34
+ tax1Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
35
+ tax2Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
36
+ tax3Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
37
+ tax4Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
38
+ tax5Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
39
+ tax6Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
40
+ tax7Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
41
+ tax8Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
42
+ tax9Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
43
+ tax10Sum: Optional[Decimal] = Field(default=None, decimal_places=2)
44
+ taxationSystem: TaxSystem
45
+ automatNumber: Optional[str] = Field(default=None, max_length=20)
46
+ settlementAddress: Optional[str] = Field(default=None, max_length=243)
47
+ settlementPlace: Optional[str] = Field(default=None, max_length=243)
48
+ customerContact: str = Field(max_length=64)
49
+ senderEmail: Optional[str] = Field(default=None, max_length=64)
50
+ isInternetStore: Optional[bool] = Field(default=None)
51
+ useTax20: Optional[bool] = Field(default=None)
52
+
53
+
54
+ class CorrectionSchema(ReqBodyBaseCorrection):
55
+ content: CorrectionSchemaContent
@@ -0,0 +1,27 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import Field
4
+
5
+ from .base_args import ReqBodyBaseFiscal
6
+ from .common import BaseContent, Contact, InformationBuyerSchema
7
+
8
+
9
+ class DocumentSchemaContent(BaseContent):
10
+ agentType: Optional[int] = Field(default=None, le=127)
11
+ paymentTransferOperatorPhoneNumbers: Optional[list[Contact]] = Field(default=None)
12
+ paymentAgentOperation: Optional[str] = Field(default=None, max_length=24)
13
+ paymentAgentPhoneNumbers: Optional[list[Contact]] = Field(default=None)
14
+ paymentOperatorPhoneNumbers: Optional[list[Contact]] = Field(default=None)
15
+ paymentOperatorName: Optional[str] = Field(default=None, max_length=64)
16
+ paymentOperatorAddress: Optional[str] = Field(default=None, max_length=243)
17
+ paymentOperatorINN: Optional[str] = Field(
18
+ default=None, min_length=10, max_length=12
19
+ )
20
+ supplierPhoneNumbers: Optional[list[Contact]] = Field(default=None)
21
+ customer: Optional[str] = Field(default=None, max_length=243)
22
+ customerINN: Optional[str] = Field(default=None, min_length=10, max_length=12)
23
+ customerInfo: Optional[InformationBuyerSchema] = Field(default=None)
24
+
25
+
26
+ class DocumentSchema(ReqBodyBaseFiscal):
27
+ content: DocumentSchemaContent
@@ -0,0 +1,18 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+ from .base_args import ReqBodyBaseFiscal
6
+ from .common import DecimalField, FractionalQuantityMarkedProductSchema
7
+
8
+
9
+ class ItemCodeSchemaContent(BaseModel):
10
+ plannedStatus: int = Field(le=256)
11
+ itemCode: int = Field(ge=1, le=223)
12
+ quantityMeasurementUnit: Optional[int] = Field(le=255, default=None)
13
+ quantity: Optional[DecimalField]
14
+ fractionalQuantity: Optional[FractionalQuantityMarkedProductSchema]
15
+
16
+
17
+ class ItemCodeSchema(ReqBodyBaseFiscal):
18
+ content: ItemCodeSchemaContent
File without changes
@@ -0,0 +1,65 @@
1
+ class OrangeEndpoints:
2
+ BASE = "/api/v2"
3
+
4
+ @classmethod
5
+ def check(cls) -> str:
6
+ """
7
+ GET-method
8
+ """
9
+ return f"{cls.BASE}/"
10
+
11
+ @classmethod
12
+ def document(cls) -> str:
13
+ """
14
+ POST-method
15
+ """
16
+ return f"{cls.BASE}/documents"
17
+
18
+ @classmethod
19
+ def corrections12(cls) -> str:
20
+ """
21
+ POST-method
22
+ """
23
+ return f"{cls.BASE}/correction12"
24
+
25
+ @classmethod
26
+ def itemcode(cls) -> str:
27
+ """
28
+ POST-method
29
+ """
30
+ return f"{cls.BASE}/itemcode"
31
+
32
+ @classmethod
33
+ def corrections(cls) -> str:
34
+ """
35
+ POST-method
36
+ """
37
+ return f"{cls.BASE}/corrections"
38
+
39
+ @classmethod
40
+ def document_status(cls, inn: str, document_id: str) -> str:
41
+ """
42
+ GET-method
43
+ """
44
+ return f"{cls.document()}/{inn}/status/{document_id}"
45
+
46
+ @classmethod
47
+ def itemcode_status(cls, inn: str, itemcode: str) -> str:
48
+ """
49
+ GET-method
50
+ """
51
+ return f"{cls.itemcode()}/{inn}/status/{itemcode}"
52
+
53
+ @classmethod
54
+ def corrections_status(cls, inn: str, correction_id: str) -> str:
55
+ """
56
+ GET-method
57
+ """
58
+ return f"{cls.corrections()}/{inn}/status/{correction_id}"
59
+
60
+ @classmethod
61
+ def correction12_status(cls, inn: str, correction_id: str) -> str:
62
+ """
63
+ GET-method
64
+ """
65
+ return f"{cls.correction12()}/{inn}/status/{correction_id}"
@@ -0,0 +1,27 @@
1
+ [project]
2
+ name = "OrangeDataPack"
3
+ version = "0.0.1"
4
+ description = "Package for OrangeData API service"
5
+ readme = "README.md"
6
+ requires-python = ">=3.14.3"
7
+ dependencies = [
8
+ "cryptography>=50.0.1",
9
+ "phonenumbers>=9.0.40",
10
+ "pydantic>=2.13.5",
11
+ "pydantic-extra-types>=2.11.1",
12
+ "requests>=2.34.2",
13
+ ]
14
+
15
+ [build-system]
16
+ requires = ["uv_build>=0.12.17"]
17
+ build-backend = "uv_build"
18
+
19
+ [tool.uv.build-backend]
20
+ module-name = "orangedatatools"
21
+ module-root = ""
22
+
23
+ [dependency-groups]
24
+ dev = [
25
+ "pre-commit>=4.6.2",
26
+ "uv-build>=0.12.19",
27
+ ]
@@ -0,0 +1,26 @@
1
+ [project]
2
+ name = "OrangeDataPack"
3
+ version = "0.0.1"
4
+ description = "Package for OrangeData API service"
5
+ readme = "README.md"
6
+ requires-python = ">=3.14.3"
7
+ dependencies = [
8
+ "cryptography>=50.0.1",
9
+ "phonenumbers>=9.0.40",
10
+ "pydantic>=2.13.5",
11
+ "pydantic-extra-types>=2.11.1",
12
+ "requests>=2.34.2",
13
+ ]
14
+ [build-system]
15
+ requires = ["uv_build>=0.12.17"]
16
+ build-backend = "uv_build"
17
+
18
+ [tool.uv.build-backend]
19
+ module-name = "orangedatatools"
20
+ module-root = ""
21
+
22
+ [dependency-groups]
23
+ dev = [
24
+ "pre-commit>=4.6.2",
25
+ "uv-build>=0.12.19",
26
+ ]