django-edocs 0.1.0__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 (38) hide show
  1. django_edocs-0.1.0/LICENSE +21 -0
  2. django_edocs-0.1.0/MANIFEST.in +7 -0
  3. django_edocs-0.1.0/PKG-INFO +249 -0
  4. django_edocs-0.1.0/README.md +207 -0
  5. django_edocs-0.1.0/django_edocs.egg-info/PKG-INFO +249 -0
  6. django_edocs-0.1.0/django_edocs.egg-info/SOURCES.txt +36 -0
  7. django_edocs-0.1.0/django_edocs.egg-info/dependency_links.txt +1 -0
  8. django_edocs-0.1.0/django_edocs.egg-info/requires.txt +8 -0
  9. django_edocs-0.1.0/django_edocs.egg-info/top_level.txt +1 -0
  10. django_edocs-0.1.0/edocs/__init__.py +8 -0
  11. django_edocs-0.1.0/edocs/admin.py +76 -0
  12. django_edocs-0.1.0/edocs/api/__init__.py +3 -0
  13. django_edocs-0.1.0/edocs/api/serializers.py +64 -0
  14. django_edocs-0.1.0/edocs/api/urls.py +20 -0
  15. django_edocs-0.1.0/edocs/api/views.py +199 -0
  16. django_edocs-0.1.0/edocs/apps.py +12 -0
  17. django_edocs-0.1.0/edocs/conf.py +39 -0
  18. django_edocs-0.1.0/edocs/exceptions.py +18 -0
  19. django_edocs-0.1.0/edocs/models/__init__.py +11 -0
  20. django_edocs-0.1.0/edocs/models/base.py +127 -0
  21. django_edocs-0.1.0/edocs/models/document.py +157 -0
  22. django_edocs-0.1.0/edocs/models/signer.py +52 -0
  23. django_edocs-0.1.0/edocs/models/template.py +30 -0
  24. django_edocs-0.1.0/edocs/services/__init__.py +20 -0
  25. django_edocs-0.1.0/edocs/services/eimzo.py +66 -0
  26. django_edocs-0.1.0/edocs/services/engine.py +285 -0
  27. django_edocs-0.1.0/edocs/services/mock_extractor.py +141 -0
  28. django_edocs-0.1.0/edocs/services/qr.py +80 -0
  29. django_edocs-0.1.0/edocs/services/simulation.py +93 -0
  30. django_edocs-0.1.0/edocs/signals.py +16 -0
  31. django_edocs-0.1.0/edocs/static/edocs/js/eimzo-client.js +119 -0
  32. django_edocs-0.1.0/edocs/templates/edocs/verify.html +224 -0
  33. django_edocs-0.1.0/pyproject.toml +70 -0
  34. django_edocs-0.1.0/setup.cfg +4 -0
  35. django_edocs-0.1.0/tests/test_api.py +107 -0
  36. django_edocs-0.1.0/tests/test_engine.py +69 -0
  37. django_edocs-0.1.0/tests/test_mock_extractor.py +47 -0
  38. django_edocs-0.1.0/tests/test_models.py +72 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 django-edocs contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ include LICENSE
2
+ include README.md
3
+ include pyproject.toml
4
+ recursive-include edocs/templates *
5
+ recursive-include edocs/static *
6
+ recursive-exclude * __pycache__
7
+ recursive-exclude * *.py[co]
@@ -0,0 +1,249 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-edocs
3
+ Version: 0.1.0
4
+ Summary: Electronic document generation, Word (.docx) template engine, dynamic tables, PDF conversion, QR verification and E-IMZO signing workflow for Django.
5
+ Author: django-edocs contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Sniperat/django-edocs
8
+ Project-URL: Repository, https://github.com/Sniperat/django-edocs.git
9
+ Project-URL: Documentation, https://github.com/Sniperat/django-edocs#readme
10
+ Project-URL: Bug Tracker, https://github.com/Sniperat/django-edocs/issues
11
+ Keywords: django,edocs,e-imzo,document-generation,docx-template,pdf,qr-code,digital-signature,workflow,uzbekistan
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Web Environment
14
+ Classifier: Framework :: Django
15
+ Classifier: Framework :: Django :: 4.2
16
+ Classifier: Framework :: Django :: 5.0
17
+ Classifier: Framework :: Django :: 5.1
18
+ Classifier: Framework :: Django :: 5.2
19
+ Classifier: Intended Audience :: Developers
20
+ Classifier: Operating System :: OS Independent
21
+ Classifier: Programming Language :: Python
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Programming Language :: Python :: 3.9
24
+ Classifier: Programming Language :: Python :: 3.10
25
+ Classifier: Programming Language :: Python :: 3.11
26
+ Classifier: Programming Language :: Python :: 3.12
27
+ Classifier: Programming Language :: Python :: 3.13
28
+ Classifier: Topic :: Office/Business
29
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
30
+ Requires-Python: >=3.9
31
+ Description-Content-Type: text/markdown
32
+ License-File: LICENSE
33
+ Requires-Dist: Django>=4.2
34
+ Requires-Dist: djangorestframework>=3.12
35
+ Requires-Dist: python-docx>=1.1.0
36
+ Requires-Dist: docxtpl>=0.17.0
37
+ Requires-Dist: jinja2>=3.0.0
38
+ Requires-Dist: requests>=2.28.0
39
+ Requires-Dist: qrcode>=7.0
40
+ Requires-Dist: pillow>=9.0.0
41
+ Dynamic: license-file
42
+
43
+ # django-edocs
44
+
45
+ [![PyPI version](https://img.shields.io/pypi/v/django-edocs.svg)](https://pypi.org/project/django-edocs/)
46
+ [![Python](https://img.shields.io/pypi/pyversions/django-edocs.svg)](https://pypi.org/project/django-edocs/)
47
+ [![Django](https://img.shields.io/badge/django-4.2%20%7C%205.0%20%7C%205.1%20%7C%205.2-blue.svg)](https://www.djangoproject.com/)
48
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
49
+
50
+ **django-edocs** — Django loyihalari uchun professional elektron hujjat generatsiyasi, Word (`.docx`) shablon dvijogi, dinamik jadvallar, PDF konvertatsiyasi, QR-kodli tekshiruv va E-IMZO orqali ko'p tomonlama imzolash ish jarayoni (workflow) tizimi.
51
+
52
+ ---
53
+
54
+ ## 🌟 Asosiy Imkoniyatlar (Features)
55
+
56
+ 1. **Smart Word (.docx) Shablon Dvijogi**:
57
+ * Jinja2 (`{{ var }}`) hamda rasmiy davlat shartnomalaridagi dollar-skobka (`${var}`) sintaksislarini to'liq qo'llab-quvvatlaydi.
58
+ * Microsoft Word matnni bo'lib yuborgan holatlarda XML teglarni avtomatik tuzatadi va ulaydi.
59
+ * **Dinamik jadvallar (Auto Table Loops)**: Jadvaldagi `{{ items.name }}` yoki `${items.name}` o'zgaruvchilarini avtomatik aniqlab, qatorlarni takrorlanuvchi tsiklga o'raydi.
60
+ * `None` yoki `"null"` qiymatlarni avtomatik bo'sh qatorga (`""`) aylantiradi.
61
+
62
+ 2. **PDF Konvertatsiya va QR-Kodli Xavfsizlik**:
63
+ * Word fayllarini avtomatik tarzda yuqori sifatli PDF formatiga o'tkazadi (headless LibreOffice orqali).
64
+ * Har bir hujjatga takrorlanmas **4 xonali xavfsizlik kodi** va **SHA-256 hesh** biriktiriladi.
65
+ * Hujjatning pastki yoki burchak qismiga vertikal kodli dinamik **QR-kod** generatsiya qilinadi.
66
+
67
+ 3. **Ko'p Bosqichli E-IMZO Imzolash Ketma-ketligi**:
68
+ * Ketma-ket imzolash navbati (masalan: 1-tomon -> 2-tomon -> 3-tomon).
69
+ * Navbat kelmaguncha keyingi shaxs imzo qo'ya olmaydi.
70
+ * Hujjatni ko'rish, imzolash, **Rad etish** (izoh bilan) va **Bekor qilish** imkoniyati.
71
+
72
+ 4. **Tayyor REST API & Brauzer E-IMZO Mijozi**:
73
+ * Django REST Framework uchun tayyor Challenge, Sign, Reject, Cancel va PDF Preview endpointlari.
74
+ * Brauzerdagi mahalliy E-IMZO moduli (port 64443) bilan ishlovchi tayyor `eimzo-client.js` kutubxonasi.
75
+ * QR-kod skaner qilinganda mobil qurilmalarda ochiluvchi chiroyli ommaviy tekshiruv sahifasi.
76
+
77
+ ---
78
+
79
+ ## 📦 O'rnatish (Installation)
80
+
81
+ ```bash
82
+ pip install django-edocs
83
+ ```
84
+
85
+ Tizimda Word fayllarni PDF ga o'girish uchun LibreOffice o'rnatilgan bo'lishi kerak:
86
+ ```bash
87
+ # Ubuntu / Debian
88
+ sudo apt-get update && sudo apt-get install -y libreoffice fonts-dejavu
89
+
90
+ # Dockerfile uchun
91
+ RUN apt-get update && apt-get install -y libreoffice fonts-dejavu && rm -rf /var/lib/apt/lists/*
92
+ ```
93
+
94
+ ---
95
+
96
+ ## 🚀 Tezkor Boshlash (Quickstart)
97
+
98
+ ### 1. `settings.py` sozlamalari
99
+
100
+ `INSTALLED_APPS` ro'yxatiga `'edocs'` va `'rest_framework'` ni qo'shing:
101
+
102
+ ```python
103
+ INSTALLED_APPS = [
104
+ # ...
105
+ 'rest_framework',
106
+ 'edocs',
107
+ # ...
108
+ ]
109
+ ```
110
+
111
+ Ixtiyoriy sozlamalar:
112
+ ```python
113
+ # settings.py
114
+ EDOCS_VERIFY_FRONTEND_URL = "https://myportal.uz/edocs/verify" # QR kod skaner qilinganda yo'naltiriladigan URL
115
+ EDOCS_LIBREOFFICE_PATH = "libreoffice" # yoki "/usr/bin/libreoffice"
116
+ EDOCS_SIGNER_MODEL = "auth.User" # yoki o'zingizning maxsus xodim/rol modelingiz
117
+ ```
118
+
119
+ ### 2. Ma'lumotlar bazasini yangilang
120
+
121
+ ```bash
122
+ python manage.py migrate
123
+ ```
124
+
125
+ ### 3. URL marshrutlarini ulang
126
+
127
+ Loyiha `urls.py` fayliga:
128
+
129
+ ```python
130
+ from django.urls import path, include
131
+
132
+ urlpatterns = [
133
+ # ...
134
+ path("api/edocs/", include("edocs.api.urls")),
135
+ # ...
136
+ ]
137
+ ```
138
+
139
+ ### 4. O'z modelingizga hujjat biriktirish
140
+
141
+ Shartnoma, dalolatnoma yoki ma'lumotnoma modelingizni `AbstractDocumentBase` dan meros qilib oling:
142
+
143
+ ```python
144
+ from django.db import models
145
+ from edocs.models import AbstractDocumentBase
146
+
147
+ class Contract(AbstractDocumentBase):
148
+ number = models.CharField(max_length=50)
149
+ client_name = models.CharField(max_length=255)
150
+ total_amount = models.DecimalField(max_digits=12, decimal_places=2)
151
+
152
+ def __str__(self):
153
+ return f"Shartnoma #{self.number}"
154
+ ```
155
+
156
+ ### 5. Hujjat generatsiya qilish
157
+
158
+ ```python
159
+ from edocs.services import DocumentEngine
160
+ from myapp.models import Contract
161
+
162
+ # 1. Shartnomani saqlash
163
+ contract = Contract.objects.create(
164
+ number="12/2026",
165
+ client_name="Agro Tech MCHJ",
166
+ total_amount=50000000
167
+ )
168
+
169
+ # 2. Hujjatni Word shabloni asosida generatsiya qilish
170
+ document = DocumentEngine.generate_document(
171
+ template_code="standard_contract",
172
+ context_data={
173
+ "contract_number": contract.number,
174
+ "client_name": contract.client_name,
175
+ "total_amount": str(contract.total_amount),
176
+ "items": [
177
+ {"num": 1, "name": "Mahsulot A", "qty": 10, "price": "2000000"},
178
+ {"num": 2, "name": "Mahsulot B", "qty": 5, "price": "6000000"},
179
+ ]
180
+ },
181
+ related_object=contract,
182
+ signers=[
183
+ {"signer": user_director, "title": "Direktor", "tin": "123456789"},
184
+ {"signer": user_client, "title": "Haridor", "tin": "987654321"},
185
+ ]
186
+ )
187
+
188
+ # 3. Hujjatni shartnomaga biriktirish
189
+ contract.document = document
190
+ contract.save()
191
+ ```
192
+
193
+ ---
194
+
195
+ ## 🔑 Brauzerda E-IMZO bilan imzolash (Frontend)
196
+
197
+ Paket ichida tayyor `eimzo-client.js` mavjud:
198
+
199
+ ```html
200
+ <script src="/static/edocs/js/eimzo-client.js"></script>
201
+ <script>
202
+ // 1. E-IMZO moduli ochiqligini tekshirish
203
+ EImzoClient.checkAgent().then(isOnline => {
204
+ if (!isOnline) {
205
+ alert("Iltimos, E-IMZO dasturini ishga tushiring!");
206
+ return;
207
+ }
208
+
209
+ // 2. Sertifikatlar ro'yxatini olish
210
+ EImzoClient.listCertificates().then(certs => {
211
+ console.log("Mavjud kalitlar:", certs);
212
+
213
+ // 3. Tanlangan kalit bilan hujjatni imzolash
214
+ const chosenCert = certs[0];
215
+ EImzoClient.signDocument("DOCUMENT-GUID-HERE", chosenCert)
216
+ .then(res => {
217
+ alert("Hujjat muvaffaqiyatli imzolandi!");
218
+ window.location.reload();
219
+ })
220
+ .catch(err => alert("Xatolik: " + err.message));
221
+ });
222
+ });
223
+ </script>
224
+ ```
225
+
226
+ ---
227
+
228
+ ## 📡 Signallar (Signals)
229
+
230
+ Hujjat holati o'zgarganda bildirishnoma (Telegram bot, SMS, WebSocket) yuborish uchun Django signallaridan foydalaning:
231
+
232
+ ```python
233
+ from django.dispatch import receiver
234
+ from edocs.signals import document_fully_signed, document_rejected
235
+
236
+ @receiver(document_fully_signed)
237
+ def on_document_fully_signed(sender, document, related_object, **kwargs):
238
+ print(f"Hujjat to'liq imzolandi: {document.guid}, Obyekt: {related_object}")
239
+
240
+ @receiver(document_rejected)
241
+ def on_document_rejected(sender, document, signer, note, related_object, **kwargs):
242
+ print(f"Hujjat rad etildi! Sabab: {note}")
243
+ ```
244
+
245
+ ---
246
+
247
+ ## 📄 Litsenziya (License)
248
+
249
+ Ushbu kutubxona [MIT License](LICENSE) asosida ochiq manbali tarzda tarqatiladi.
@@ -0,0 +1,207 @@
1
+ # django-edocs
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/django-edocs.svg)](https://pypi.org/project/django-edocs/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/django-edocs.svg)](https://pypi.org/project/django-edocs/)
5
+ [![Django](https://img.shields.io/badge/django-4.2%20%7C%205.0%20%7C%205.1%20%7C%205.2-blue.svg)](https://www.djangoproject.com/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ **django-edocs** — Django loyihalari uchun professional elektron hujjat generatsiyasi, Word (`.docx`) shablon dvijogi, dinamik jadvallar, PDF konvertatsiyasi, QR-kodli tekshiruv va E-IMZO orqali ko'p tomonlama imzolash ish jarayoni (workflow) tizimi.
9
+
10
+ ---
11
+
12
+ ## 🌟 Asosiy Imkoniyatlar (Features)
13
+
14
+ 1. **Smart Word (.docx) Shablon Dvijogi**:
15
+ * Jinja2 (`{{ var }}`) hamda rasmiy davlat shartnomalaridagi dollar-skobka (`${var}`) sintaksislarini to'liq qo'llab-quvvatlaydi.
16
+ * Microsoft Word matnni bo'lib yuborgan holatlarda XML teglarni avtomatik tuzatadi va ulaydi.
17
+ * **Dinamik jadvallar (Auto Table Loops)**: Jadvaldagi `{{ items.name }}` yoki `${items.name}` o'zgaruvchilarini avtomatik aniqlab, qatorlarni takrorlanuvchi tsiklga o'raydi.
18
+ * `None` yoki `"null"` qiymatlarni avtomatik bo'sh qatorga (`""`) aylantiradi.
19
+
20
+ 2. **PDF Konvertatsiya va QR-Kodli Xavfsizlik**:
21
+ * Word fayllarini avtomatik tarzda yuqori sifatli PDF formatiga o'tkazadi (headless LibreOffice orqali).
22
+ * Har bir hujjatga takrorlanmas **4 xonali xavfsizlik kodi** va **SHA-256 hesh** biriktiriladi.
23
+ * Hujjatning pastki yoki burchak qismiga vertikal kodli dinamik **QR-kod** generatsiya qilinadi.
24
+
25
+ 3. **Ko'p Bosqichli E-IMZO Imzolash Ketma-ketligi**:
26
+ * Ketma-ket imzolash navbati (masalan: 1-tomon -> 2-tomon -> 3-tomon).
27
+ * Navbat kelmaguncha keyingi shaxs imzo qo'ya olmaydi.
28
+ * Hujjatni ko'rish, imzolash, **Rad etish** (izoh bilan) va **Bekor qilish** imkoniyati.
29
+
30
+ 4. **Tayyor REST API & Brauzer E-IMZO Mijozi**:
31
+ * Django REST Framework uchun tayyor Challenge, Sign, Reject, Cancel va PDF Preview endpointlari.
32
+ * Brauzerdagi mahalliy E-IMZO moduli (port 64443) bilan ishlovchi tayyor `eimzo-client.js` kutubxonasi.
33
+ * QR-kod skaner qilinganda mobil qurilmalarda ochiluvchi chiroyli ommaviy tekshiruv sahifasi.
34
+
35
+ ---
36
+
37
+ ## 📦 O'rnatish (Installation)
38
+
39
+ ```bash
40
+ pip install django-edocs
41
+ ```
42
+
43
+ Tizimda Word fayllarni PDF ga o'girish uchun LibreOffice o'rnatilgan bo'lishi kerak:
44
+ ```bash
45
+ # Ubuntu / Debian
46
+ sudo apt-get update && sudo apt-get install -y libreoffice fonts-dejavu
47
+
48
+ # Dockerfile uchun
49
+ RUN apt-get update && apt-get install -y libreoffice fonts-dejavu && rm -rf /var/lib/apt/lists/*
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 🚀 Tezkor Boshlash (Quickstart)
55
+
56
+ ### 1. `settings.py` sozlamalari
57
+
58
+ `INSTALLED_APPS` ro'yxatiga `'edocs'` va `'rest_framework'` ni qo'shing:
59
+
60
+ ```python
61
+ INSTALLED_APPS = [
62
+ # ...
63
+ 'rest_framework',
64
+ 'edocs',
65
+ # ...
66
+ ]
67
+ ```
68
+
69
+ Ixtiyoriy sozlamalar:
70
+ ```python
71
+ # settings.py
72
+ EDOCS_VERIFY_FRONTEND_URL = "https://myportal.uz/edocs/verify" # QR kod skaner qilinganda yo'naltiriladigan URL
73
+ EDOCS_LIBREOFFICE_PATH = "libreoffice" # yoki "/usr/bin/libreoffice"
74
+ EDOCS_SIGNER_MODEL = "auth.User" # yoki o'zingizning maxsus xodim/rol modelingiz
75
+ ```
76
+
77
+ ### 2. Ma'lumotlar bazasini yangilang
78
+
79
+ ```bash
80
+ python manage.py migrate
81
+ ```
82
+
83
+ ### 3. URL marshrutlarini ulang
84
+
85
+ Loyiha `urls.py` fayliga:
86
+
87
+ ```python
88
+ from django.urls import path, include
89
+
90
+ urlpatterns = [
91
+ # ...
92
+ path("api/edocs/", include("edocs.api.urls")),
93
+ # ...
94
+ ]
95
+ ```
96
+
97
+ ### 4. O'z modelingizga hujjat biriktirish
98
+
99
+ Shartnoma, dalolatnoma yoki ma'lumotnoma modelingizni `AbstractDocumentBase` dan meros qilib oling:
100
+
101
+ ```python
102
+ from django.db import models
103
+ from edocs.models import AbstractDocumentBase
104
+
105
+ class Contract(AbstractDocumentBase):
106
+ number = models.CharField(max_length=50)
107
+ client_name = models.CharField(max_length=255)
108
+ total_amount = models.DecimalField(max_digits=12, decimal_places=2)
109
+
110
+ def __str__(self):
111
+ return f"Shartnoma #{self.number}"
112
+ ```
113
+
114
+ ### 5. Hujjat generatsiya qilish
115
+
116
+ ```python
117
+ from edocs.services import DocumentEngine
118
+ from myapp.models import Contract
119
+
120
+ # 1. Shartnomani saqlash
121
+ contract = Contract.objects.create(
122
+ number="12/2026",
123
+ client_name="Agro Tech MCHJ",
124
+ total_amount=50000000
125
+ )
126
+
127
+ # 2. Hujjatni Word shabloni asosida generatsiya qilish
128
+ document = DocumentEngine.generate_document(
129
+ template_code="standard_contract",
130
+ context_data={
131
+ "contract_number": contract.number,
132
+ "client_name": contract.client_name,
133
+ "total_amount": str(contract.total_amount),
134
+ "items": [
135
+ {"num": 1, "name": "Mahsulot A", "qty": 10, "price": "2000000"},
136
+ {"num": 2, "name": "Mahsulot B", "qty": 5, "price": "6000000"},
137
+ ]
138
+ },
139
+ related_object=contract,
140
+ signers=[
141
+ {"signer": user_director, "title": "Direktor", "tin": "123456789"},
142
+ {"signer": user_client, "title": "Haridor", "tin": "987654321"},
143
+ ]
144
+ )
145
+
146
+ # 3. Hujjatni shartnomaga biriktirish
147
+ contract.document = document
148
+ contract.save()
149
+ ```
150
+
151
+ ---
152
+
153
+ ## 🔑 Brauzerda E-IMZO bilan imzolash (Frontend)
154
+
155
+ Paket ichida tayyor `eimzo-client.js` mavjud:
156
+
157
+ ```html
158
+ <script src="/static/edocs/js/eimzo-client.js"></script>
159
+ <script>
160
+ // 1. E-IMZO moduli ochiqligini tekshirish
161
+ EImzoClient.checkAgent().then(isOnline => {
162
+ if (!isOnline) {
163
+ alert("Iltimos, E-IMZO dasturini ishga tushiring!");
164
+ return;
165
+ }
166
+
167
+ // 2. Sertifikatlar ro'yxatini olish
168
+ EImzoClient.listCertificates().then(certs => {
169
+ console.log("Mavjud kalitlar:", certs);
170
+
171
+ // 3. Tanlangan kalit bilan hujjatni imzolash
172
+ const chosenCert = certs[0];
173
+ EImzoClient.signDocument("DOCUMENT-GUID-HERE", chosenCert)
174
+ .then(res => {
175
+ alert("Hujjat muvaffaqiyatli imzolandi!");
176
+ window.location.reload();
177
+ })
178
+ .catch(err => alert("Xatolik: " + err.message));
179
+ });
180
+ });
181
+ </script>
182
+ ```
183
+
184
+ ---
185
+
186
+ ## 📡 Signallar (Signals)
187
+
188
+ Hujjat holati o'zgarganda bildirishnoma (Telegram bot, SMS, WebSocket) yuborish uchun Django signallaridan foydalaning:
189
+
190
+ ```python
191
+ from django.dispatch import receiver
192
+ from edocs.signals import document_fully_signed, document_rejected
193
+
194
+ @receiver(document_fully_signed)
195
+ def on_document_fully_signed(sender, document, related_object, **kwargs):
196
+ print(f"Hujjat to'liq imzolandi: {document.guid}, Obyekt: {related_object}")
197
+
198
+ @receiver(document_rejected)
199
+ def on_document_rejected(sender, document, signer, note, related_object, **kwargs):
200
+ print(f"Hujjat rad etildi! Sabab: {note}")
201
+ ```
202
+
203
+ ---
204
+
205
+ ## 📄 Litsenziya (License)
206
+
207
+ Ushbu kutubxona [MIT License](LICENSE) asosida ochiq manbali tarzda tarqatiladi.