fiscguy 0.1.2__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. fiscguy-0.1.2/LICENSE +21 -0
  2. fiscguy-0.1.2/MANIFEST.in +16 -0
  3. fiscguy-0.1.2/PKG-INFO +407 -0
  4. fiscguy-0.1.2/README.md +364 -0
  5. fiscguy-0.1.2/fiscguy/__init__.py +35 -0
  6. fiscguy-0.1.2/fiscguy/admin.py +19 -0
  7. fiscguy-0.1.2/fiscguy/api.py +235 -0
  8. fiscguy-0.1.2/fiscguy/apps.py +5 -0
  9. fiscguy-0.1.2/fiscguy/management/__init__.py +0 -0
  10. fiscguy-0.1.2/fiscguy/management/commands/__init__.py +0 -0
  11. fiscguy-0.1.2/fiscguy/management/commands/init_device.py +354 -0
  12. fiscguy-0.1.2/fiscguy/migrations/0001_initial.py +269 -0
  13. fiscguy-0.1.2/fiscguy/migrations/__init__.py +0 -0
  14. fiscguy-0.1.2/fiscguy/models.py +236 -0
  15. fiscguy-0.1.2/fiscguy/serializers.py +176 -0
  16. fiscguy-0.1.2/fiscguy/services/closing_day_service.py +282 -0
  17. fiscguy-0.1.2/fiscguy/services/configuration_service.py +60 -0
  18. fiscguy-0.1.2/fiscguy/services/receipt_service.py +74 -0
  19. fiscguy-0.1.2/fiscguy/tests/__init__.py +3 -0
  20. fiscguy-0.1.2/fiscguy/tests/__initt__.py +0 -0
  21. fiscguy-0.1.2/fiscguy/tests/test_api.py +547 -0
  22. fiscguy-0.1.2/fiscguy/tests.py +3 -0
  23. fiscguy-0.1.2/fiscguy/urls.py +21 -0
  24. fiscguy-0.1.2/fiscguy/utils/cert_temp_manager.py +38 -0
  25. fiscguy-0.1.2/fiscguy/utils/datetime_now.py +15 -0
  26. fiscguy-0.1.2/fiscguy/views.py +139 -0
  27. fiscguy-0.1.2/fiscguy/zimra_base.py +182 -0
  28. fiscguy-0.1.2/fiscguy/zimra_crypto.py +313 -0
  29. fiscguy-0.1.2/fiscguy/zimra_receipt_handler.py +500 -0
  30. fiscguy-0.1.2/fiscguy.egg-info/PKG-INFO +407 -0
  31. fiscguy-0.1.2/fiscguy.egg-info/SOURCES.txt +36 -0
  32. fiscguy-0.1.2/fiscguy.egg-info/dependency_links.txt +1 -0
  33. fiscguy-0.1.2/fiscguy.egg-info/requires.txt +19 -0
  34. fiscguy-0.1.2/fiscguy.egg-info/top_level.txt +1 -0
  35. fiscguy-0.1.2/pyproject.toml +158 -0
  36. fiscguy-0.1.2/requirements-dev.txt +20 -0
  37. fiscguy-0.1.2/requirements.txt +10 -0
  38. fiscguy-0.1.2/setup.cfg +4 -0
fiscguy-0.1.2/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Casper Moyo
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,16 @@
1
+ include README.md
2
+ include LICENSE
3
+ include pyproject.toml
4
+ include requirements.txt
5
+ include requirements-dev.txt
6
+
7
+ recursive-include fiscguy *.py
8
+ recursive-include fiscguy *.sql
9
+ recursive-include fiscguy/migrations *.py
10
+ recursive-include fiscguy/management *.py
11
+ recursive-include fiscguy/tests *.py
12
+
13
+ global-exclude __pycache__
14
+ global-exclude *.pyc
15
+ global-exclude *.pyo
16
+ global-exclude .DS_Store
fiscguy-0.1.2/PKG-INFO ADDED
@@ -0,0 +1,407 @@
1
+ Metadata-Version: 2.4
2
+ Name: fiscguy
3
+ Version: 0.1.2
4
+ Summary: ZIMRA Fiscal Device Integration Library - Simple and Pythonic API for ZIMRA fiscal device operations
5
+ Author-email: Casper MoyO <cassymyo@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/cassymyo-spec/zimra
8
+ Project-URL: Documentation, https://github.com/cassymyo-spec/zimra#readme
9
+ Project-URL: Repository, https://github.com/cassymyo-spec/zimra.git
10
+ Project-URL: Issues, https://github.com/cassymyo-spec/zimra/issues
11
+ Keywords: zimra,fiscal,device,receipt,invoicing,zimbabwe
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.11
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: Django>=4.2
25
+ Requires-Dist: djangorestframework>=3.14
26
+ Requires-Dist: loguru>=0.7
27
+ Requires-Dist: requests>=2.28
28
+ Requires-Dist: cryptography>=38.0
29
+ Requires-Dist: qrcode>=7.4
30
+ Requires-Dist: Pillow>=9.0
31
+ Requires-Dist: python-dotenv>=0.19
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=7.0; extra == "dev"
34
+ Requires-Dist: pytest-django>=4.5; extra == "dev"
35
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
36
+ Requires-Dist: black>=22.0; extra == "dev"
37
+ Requires-Dist: isort>=5.11; extra == "dev"
38
+ Requires-Dist: flake8>=4.0; extra == "dev"
39
+ Requires-Dist: pylint>=2.15; extra == "dev"
40
+ Requires-Dist: mypy>=0.990; extra == "dev"
41
+ Requires-Dist: django-stubs>=1.12; extra == "dev"
42
+ Dynamic: license-file
43
+
44
+ # Fiscguy
45
+
46
+ A Python library for integrating with ZIMRA (Zimbabwe Revenue Authority) fiscal devices. Provides a simple, Pythonic API for managing fiscal operations including device registration, receipt generation, and fiscal day management.
47
+
48
+ ## Features
49
+
50
+ - Secure Device Integration - Certificate-based authentication with ZIMRA FDMS
51
+ - Receipt Management - Create and submit receipts with multiple tax types
52
+ - Fiscal Day Operations - Open and close fiscal days with automatic counter management
53
+ - Device Status - Query device status and configuration
54
+ - Configuration Management - Fetch and manage device configuration
55
+ - Tax Support - Supports standard, zero-rated, exempt, and withholding taxes
56
+ - Fully Tested - Comprehensive unit tests with 90%+ code coverage
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ pip install fiscguy
62
+ ```
63
+
64
+ Or from source:
65
+
66
+ ```bash
67
+ git clone https://github.com/cassymyo-spec/zimra.git
68
+ cd zimra
69
+ pip install -e .
70
+ ```
71
+
72
+ ## Quick Start
73
+
74
+ ### Important: Register a Device First
75
+
76
+ Before using Fiscguy, you must register and initialize a fiscal device:
77
+
78
+ ```bash
79
+ python manage.py init_device
80
+ ```
81
+
82
+ This interactive command will guide you through:
83
+ - Device information entry
84
+ - Certificate generation
85
+ - Device registration with ZIMRA
86
+ - Configuration and tax synchronization
87
+
88
+ ### Important: Environment Switching
89
+
90
+ When running `python manage.py init_device`:
91
+
92
+ **If switching FROM TEST TO PRODUCTION:**
93
+ - **Safe to proceed** - All test data will be automatically deleted
94
+ - The command will warn you and require confirmation (`YES`)
95
+ - **All the following test data will be permanently deleted:**
96
+ - Fiscal Days
97
+ - Fiscal Counters
98
+ - Receipts & Receipt Lines
99
+ - Device Configuration
100
+ - Certificates
101
+ - Device record itself
102
+ - Taxes
103
+
104
+ **If switching FROM PRODUCTION TO TEST:**
105
+ - **NOT ADVISABLE** - This will delete your production records
106
+ - Only do this if you're absolutely sure you want to lose all production data
107
+ - The command will warn you and require confirmation (`YES`)
108
+
109
+ **How to switch safely:**
110
+ 1. Run `python manage.py init_device`
111
+ 2. Answer the environment question (yes=production, no=test)
112
+ 3. If different from current environment, you'll see a warning
113
+ 4. Review the warning carefully
114
+ 5. Type `YES` to confirm deletion and switch
115
+
116
+ ### Using the Library
117
+
118
+ Once your device is registered, you can use the library:
119
+
120
+ ```python
121
+ from fiscguy import (
122
+ open_day,
123
+ close_day,
124
+ submit_receipt,
125
+ get_status,
126
+ get_configuration,
127
+ get_taxes,
128
+ )
129
+
130
+ # Check device status
131
+ status = get_status()
132
+ print(f"Device: {status['device_id']}, Counter: {status['counter']}")
133
+
134
+ # Open a fiscal day
135
+ result = open_day()
136
+ print(f"Day opened: {result['fiscal_day_number']}")
137
+
138
+ # Submit a receipt
139
+ receipt_data = {
140
+ "receipt_type": "fiscalinvoice",
141
+ "currency": "USD",
142
+ "total_amount": "100.00",
143
+ "payment_terms": "cash",
144
+ "lines": [
145
+ {
146
+ "product": "Test Item",
147
+ "quantity": "1",
148
+ "unit_price": "100.00",
149
+ "line_total": "100.00",
150
+ "tax_amount": "15.50",
151
+ "tax_name": "standard rated 15.5%",
152
+ }
153
+ ],
154
+ "buyer": 1,
155
+ }
156
+
157
+ result = submit_receipt(receipt_data)
158
+ print(f"Receipt submitted: {result['receiptID']}")
159
+
160
+ # Close the fiscal day
161
+ result = close_day()
162
+ print(f"Day closed, signature: {result['signature'][:20]}...")
163
+ ```
164
+
165
+ ## API Reference
166
+
167
+ ### `open_day() -> Dict[str, Any]`
168
+
169
+ Open a new fiscal day.
170
+
171
+ **Returns:**
172
+ - `fiscal_day_number`: The fiscal day number
173
+ - `fiscal_day_date`: The date the day was opened (ISO format)
174
+ - `message`: Status message (if day already open)
175
+
176
+ **Raises:**
177
+ - `RuntimeError`: If no device is registered
178
+
179
+ ### `close_day() -> Dict[str, Any]`
180
+
181
+ Close the currently open fiscal day.
182
+
183
+ **Returns:**
184
+ - `signature`: Device signature for the fiscal day
185
+ - `closing_string`: Raw closing day string
186
+
187
+ **Raises:**
188
+ - `RuntimeError`: If no device or no open fiscal day exists
189
+
190
+ ### `submit_receipt(receipt_data: Dict[str, Any]) -> Dict[str, Any]`
191
+
192
+ Create and submit a receipt to ZIMRA.
193
+
194
+ **Parameters:**
195
+ - `receipt_data`: Receipt dictionary with required fields:
196
+ - `receipt_type`: "fiscalinvoice" or "creditnote"
197
+ - `currency`: "USD", "ZWL", etc.
198
+ - `total_amount`: Total amount (string or Decimal)
199
+ - `payment_terms`: "cash", "cheque", "card", etc.
200
+ - `lines`: List of line items
201
+ - `buyer`: Buyer ID (integer)
202
+
203
+ **Line Item Structure:**
204
+ ```python
205
+ {
206
+ "product": "Product name",
207
+ "quantity": "1",
208
+ "unit_price": "100.00",
209
+ "line_total": "100.00",
210
+ "tax_amount": "15.50",
211
+ "tax_name": "standard rated 15.5%",
212
+ }
213
+ ```
214
+
215
+ **Returns:**
216
+ - `receiptID`: ZIMRA receipt ID
217
+ - `receipt_data`: Full receipt data
218
+
219
+ **Raises:**
220
+ - `ValidationError`: If tax_name doesn't match any database tax
221
+ - `RuntimeError`: If submission to ZIMRA fails
222
+
223
+ ### `get_status() -> Dict[str, Any]`
224
+
225
+ Get current device and fiscal status.
226
+
227
+ **Returns:**
228
+ - `device_id`: Device identifier
229
+ - `counter`: Global receipt counter
230
+ - `fiscal_day`: Current fiscal day number (or null if none open)
231
+ - `fiscal_day_status`: Status of fiscal day
232
+
233
+ ### `get_configuration() -> Dict[str, Any]`
234
+
235
+ Fetch device configuration from the database.
236
+
237
+ **Returns:**
238
+ - Dictionary with configuration fields
239
+ - Empty dict if no configuration exists
240
+
241
+ ### `get_taxes() -> List[Dict[str, Any]]`
242
+
243
+ Fetch all configured tax types.
244
+
245
+ **Returns:**
246
+ - List of tax dictionaries with fields: `code`, `name`, `percent`, `tax_id`
247
+
248
+ ## Django Integration
249
+
250
+ Fiscguy is built on Django ORM. To use in a Django project:
251
+
252
+ 1. Add to `INSTALLED_APPS` in settings:
253
+
254
+ ```python
255
+ INSTALLED_APPS = [
256
+ ...
257
+ "fiscguy",
258
+ "rest_framework",
259
+ ]
260
+ ```
261
+
262
+ 2. Run migrations:
263
+
264
+ ```bash
265
+ python manage.py migrate fiscguy
266
+ ```
267
+
268
+ 3. Initialize a device:
269
+
270
+ ```bash
271
+ python manage.py init_device
272
+ ```
273
+
274
+ 4. Use the library:
275
+
276
+ ```python
277
+ from fiscguy import open_day, submit_receipt
278
+ ```
279
+
280
+ ## Models
281
+
282
+ Fiscguy provides Django ORM models for:
283
+
284
+ - Device - Fiscal device information
285
+ - FiscalDay - Fiscal day records
286
+ - FiscalCounter - Receipt counters for fiscal days
287
+ - Receipt - Receipt records
288
+ - ReceiptLine - Individual receipt line items
289
+ - Taxes - Tax type definitions
290
+ - Configuration - Device configuration
291
+ - Certs - Device certificates and keys
292
+ - Buyer - Buyer/customer information
293
+
294
+ ## Error Handling
295
+
296
+ ```python
297
+ from fiscguy import submit_receipt
298
+ from rest_framework.exceptions import ValidationError
299
+
300
+ try:
301
+ result = submit_receipt(receipt_data)
302
+ except ValidationError as e:
303
+ print(f"Validation error: {e.detail}")
304
+ except RuntimeError as e:
305
+ print(f"Runtime error: {e}")
306
+ ```
307
+
308
+ ## Testing
309
+
310
+ ```bash
311
+ # All tests
312
+ pytest
313
+
314
+ # With coverage
315
+ pytest --cov=fiscguy
316
+
317
+ # Specific test
318
+ pytest fiscguy/tests/test_api.py::SubmitReceiptTest::test_submit_receipt_success
319
+ ```
320
+
321
+ ## Development
322
+
323
+ ```bash
324
+ # Clone and setup
325
+ git clone https://github.com/cassymyo-spec/zimra.git
326
+ cd zimra
327
+ python -m venv venv
328
+ source venv/bin/activate
329
+ pip install -e ".[dev]"
330
+
331
+ # Run tests
332
+ pytest
333
+
334
+ # Code formatting
335
+ black fiscguy
336
+ isort fiscguy
337
+
338
+ # Linting
339
+ flake8 fiscguy
340
+ pylint fiscguy
341
+
342
+ # Type checking
343
+ mypy fiscguy
344
+ ```
345
+
346
+ ## Architecture
347
+
348
+ ```
349
+ Public API (api.py)
350
+ - open_day, close_day, submit_receipt, etc.
351
+ |
352
+ Services Layer
353
+ - ReceiptService
354
+ - ClosingDayService
355
+ |
356
+ Handler Layer
357
+ - ZIMRAReceiptHandler
358
+ |
359
+ Client Layer
360
+ - ZIMRAClient (FDMS API)
361
+ - ZIMRACrypto (Signing)
362
+ ```
363
+
364
+ ## Key Components
365
+
366
+ - fiscguy/api.py - Public library interface (6 functions)
367
+ - fiscguy/services/ - Business logic (ReceiptService, ClosingDayService)
368
+ - fiscguy/zimra_base.py - ZIMRA FDMS HTTP client
369
+ - fiscguy/zimra_receipt_handler.py - Receipt formatting and signing
370
+ - fiscguy/zimra_crypto.py - Cryptographic operations
371
+ - fiscguy/models.py - Django ORM models
372
+ - fiscguy/serializers.py - DRF serializers
373
+ - fiscguy/tests/ - Unit tests (22+ tests)
374
+
375
+ ## Contributing
376
+
377
+ 1. Fork the repository
378
+ 2. Create a feature branch
379
+ 3. Add/adjust tests
380
+ 4. Submit a PR
381
+
382
+ See CONTRIBUTING.md for detailed guidelines.
383
+
384
+ ## License
385
+
386
+ MIT License
387
+
388
+ ## Support
389
+
390
+ - Email: cassymyo@gmail.com
391
+ - Issues: https://github.com/cassymyo-spec/zimra/issues
392
+ - Documentation: See README.md, INSTALL.md, QUICKREF.md
393
+
394
+ ## Changelog
395
+
396
+ ### 0.1.0 (2026-02-08)
397
+
398
+ **Initial Release**
399
+
400
+ - Public library API with 6 core functions
401
+ - Receipt creation and submission
402
+ - Fiscal day management
403
+ - Device status and configuration
404
+ - Tax type management
405
+ - 22+ comprehensive unit tests
406
+ - Full error handling and logging
407
+ - Lazy-loaded module caching