Skip to main content

ZIMRA Fiscal Device Integration Library - Simple and Pythonic API for ZIMRA fiscal device operations

Project description

FiscGuy

Tests

PyPI version Downloads Code style: black

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.

Features

  • Secure Device Integration - Certificate-based authentication with ZIMRA FDMS
  • Receipt Management - Create and submit receipts with multiple tax types
  • Fiscal Day Operations - Open and close fiscal days with automatic counter management
  • Device Status - Query device status and configuration
  • Configuration Management - Fetch and manage device configuration
  • Tax Support - Supports standard, zero-rated, exempt, and withholding taxes
  • Fully Tested - Comprehensive unit tests with 90%+ code coverage

Installation

pip install fiscguy

Or from source:

git clone https://github.com/cassymyo-spec/zimra.git
cd zimra
pip install -e .

Quick Start

Important: Register a Device First

Before using Fiscguy, you must register and initialize a fiscal device:

python manage.py init_device

This interactive command will guide you through:

  • Device information entry
  • Certificate generation
  • Device registration with ZIMRA
  • Configuration and tax synchronization

Important: Environment Switching

When running python manage.py init_device:

If switching FROM TEST TO PRODUCTION:

  • Safe to proceed - All test data will be automatically deleted
  • The command will warn you and require confirmation (YES)
  • All the following test data will be permanently deleted:
    • Fiscal Days
    • Fiscal Counters
    • Receipts & Receipt Lines
    • Device Configuration
    • Certificates
    • Device record itself
    • Taxes

If switching FROM PRODUCTION TO TEST:

  • NOT ADVISABLE - This will delete your production records
  • Only do this if you're absolutely sure you want to lose all production data
  • The command will warn you and require confirmation (YES)

How to switch safely:

  1. Run python manage.py init_device
  2. Answer the environment question (yes=production, no=test)
  3. If different from current environment, you'll see a warning
  4. Review the warning carefully
  5. Type YES to confirm deletion and switch

Using Fiscguy with Django REST Framework

Fiscguy is built as a Django REST Framework-first library. After device registration, integrate it into your Django project:

Important: First Sale Automatically Opens Fiscal Day

When you submit your first receipt without an open fiscal day, Fiscguy will automatically open a new fiscal day. This means:

  • You don't need to manually call open_day() before submitting the first receipt
  • The fiscal day will be opened silently and a 5-second delay is applied for ZIMRA processing
  • Subsequent receipts will use the already-open fiscal day
  • You only need to call close_day() when you're done with sales for the day

Example Flow:

1. Submit first receipt → Fiscal day automatically opens
2. Submit more receipts → Use the same open fiscal day
3. Call close_day() → Close the fiscal day when done

1. Add to Django Settings

# settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'rest_framework',
    'fiscguy',  # Add fiscguy here
]

2. Make Migrations

Create migration files for fiscguy models:

python manage.py makemigrations fiscguy

3. Migrate the Database

Apply migrations to your database:

python manage.py migrate fiscguy

4. Include fiscguy URLs in Your Project

Add fiscguy URL endpoints to your Django project:

# urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('fiscguy.urls')),  # Add this line
]

5. Access API Endpoints

Fiscguy provides the following REST API endpoints:

  • POST /api/open_day/ - Open a new fiscal day
  • POST /api/close_day/ - Close the current fiscal day
  • POST /api/receipts/ - Create and submit a receipt
  • GET /api/status/ - Get device and fiscal status
  • GET /api/configuration/ - Get device configuration
  • GET /api/taxes/ - Get available tax types
  • GET /api/receipts/ - List all receipts
  • GET /api/receipts/{id}/ - Get receipt details

Example API Requests

Notes on Credit and Debit Notes

  • A person can also submit a credit note.
  • Debit notes are not mandatory.
  • A credit note can have negative values.

Submit a Receipt:

curl -X POST http://localhost:8000/api/receipts/ \
  -H "Content-Type: application/json" \
  -d '{
    "receipt_type": "fiscalinvoice",
    "currency": "USD",
    "total_amount": "100.00",
    "payment_terms": "cash",
    "lines": [
      {
        "product": "Test Item",
        "quantity": 1,
        "unit_price": "100.00",
        "line_total": "100.00",
        "tax_name": "standard rated 15.5%"
      }
    ]
  }'

Submit a Credit Note:

curl -X POST http://localhost:8000/api/receipts/ \
  -H "Content-Type: application/json" \
  -d '{
    "receipt_type": "creditnote",
    "credit_note_reference": "R-00001" # the receipt you want to raise a credit note on. It must exists both in fiscguy and zimra,
    "credit_note_reason": "discount",
    "currency": "USD",
    "total_amount": "-100.00",
    "payment_terms": "cash",
    "lines": [
      {
        "product": "Test Item",
        "quantity": 1,
        "unit_price": "-100.00",
        "line_total": "-100.00",
        "tax_name": "standard rated 15.5%"
      }
    ]
  }'

Open a Fiscal Day:

curl -X POST http://localhost:8000/api/open_day/ \
  -H "Content-Type: application/json"

Get Device Status:

curl -X GET http://localhost:8000/api/status/ \
  -H "Content-Type: application/json"

Models

Fiscguy provides Django ORM models for:

  • Device - Fiscal device information
  • FiscalDay - Fiscal day records
  • FiscalCounter - Receipt counters for fiscal days
  • Receipt - Receipt records
  • ReceiptLine - Individual receipt line items
  • Taxes - Tax type definitions
  • Configuration - Device configuration
  • Certs - Device certificates and keys
  • Buyer - Buyer/customer information

Error Handling

from fiscguy import submit_receipt
from rest_framework.exceptions import ValidationError

try:
    result = submit_receipt(receipt_data)
except ValidationError as e:
    print(f"Validation error: {e.detail}")
except RuntimeError as e:
    print(f"Runtime error: {e}")

Testing

# All tests
pytest

# With coverage
pytest --cov=fiscguy

# Specific test
pytest fiscguy/tests/test_api.py::SubmitReceiptTest::test_submit_receipt_success

Development

# Clone and setup
git clone https://github.com/cassymyo-spec/zimra.git
cd zimra
python -m venv venv
source venv/bin/activate
pip install -e ".[dev]"

# Run tests
pytest

# Code formatting
black fiscguy
isort fiscguy

# Linting
flake8 fiscguy
pylint fiscguy

# Type checking
mypy fiscguy

Architecture

Public API (api.py)
- open_day, close_day, submit_receipt, etc.
         |
Services Layer
- ReceiptService
- ClosingDayService
         |
Handler Layer
- ZIMRAReceiptHandler
         |
Client Layer
- ZIMRAClient (FDMS API)
- ZIMRACrypto (Signing)

Key Components

  • fiscguy/api.py - Public library interface (6 functions)
  • fiscguy/services/ - Business logic (ReceiptService, ClosingDayService)
  • fiscguy/zimra_base.py - ZIMRA FDMS HTTP client
  • fiscguy/zimra_receipt_handler.py - Receipt formatting and signing
  • fiscguy/zimra_crypto.py - Cryptographic operations
  • fiscguy/models.py - Django ORM models
  • fiscguy/serializers.py - DRF serializers
  • fiscguy/tests/ - Unit tests (22+ tests)

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add/adjust tests
  4. Submit a PR

See CONTRIBUTING.md for detailed guidelines.

License

MIT License

Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fiscguy-0.1.5.tar.gz (37.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fiscguy-0.1.5-py3-none-any.whl (40.6 kB view details)

Uploaded Python 3

File details

Details for the file fiscguy-0.1.5.tar.gz.

File metadata

  • Download URL: fiscguy-0.1.5.tar.gz
  • Upload date:
  • Size: 37.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fiscguy-0.1.5.tar.gz
Algorithm Hash digest
SHA256 1f7a0d7e9f7265d44a1cd30fa9e2e94e8883eb31cfef1f09be1173836e5c40c7
MD5 e40ba27effe2477f0935d5374de677a7
BLAKE2b-256 4391583619ee3c59c4357f579c95103498d41b379e904b78cb8611859c6ddfab

See more details on using hashes here.

Provenance

The following attestation bundles were made for fiscguy-0.1.5.tar.gz:

Publisher: release.yml on DigitalTouchCode/fisc

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fiscguy-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: fiscguy-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 40.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fiscguy-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 894ed0d578f73e9352d96115df4ccd377e683a079dbf900ae7726079459b28e0
MD5 321214dad7bd9796d4b30c0f4fc555a6
BLAKE2b-256 58f73a08a8eee69a0417e11b0cbda49f05eee44f95ac91e8c90fcbf3567b4e7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for fiscguy-0.1.5-py3-none-any.whl:

Publisher: release.yml on DigitalTouchCode/fisc

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page