Skip to content

DigitalTouchCode/fisc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

208 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FiscGuy

Tests PyPI version Python Code style: black License

The Modern Python Library for ZIMRA Fiscal Device Integration

FiscGuy gives Django applications a simple, Pythonic interface for every fiscal operation required by the Zimbabwe Revenue Authority — receipt submission, fiscal day management, certificate handling, and more. Built on Django REST Framework, it drops into any Django project in minutes.

Installation · Quick Start · API Reference · REST Endpoints · Full Documentation · Contributing


Features

  • Seven core API functions — open_day, close_day, submit_receipt, get_status, get_configuration, get_taxes, get_buyer
  • Full fiscal day lifecycle — open, manage counters, close with ZIMRA-compliant hash and signature
  • Receipt types — Fiscal Invoice, Credit Note, Debit Note with correct counter tracking
  • Offline resilience — receipts queued locally when FDMS is unreachable, synced automatically on reconnect
  • Certificate management — CSR generation, device registration, certificate renewal via init_device
  • Multi-currency — USD and ZWG support with per-currency counter tracking
  • Multiple payment methods — Cash, Card, Mobile Wallet, Bank Transfer, Coupon, Credit, Other
  • Buyer management — optional buyer TIN and registration data on receipts
  • Cursor pagination — efficient receipt listing for large datasets
  • Typed exceptions — every error condition has its own exception class
  • 90%+ test coverage — mocked ZIMRA and crypto, fast CI

Requirements

  • Python 3.11, 3.12, or 3.13
  • Django 4.2+
  • Django REST Framework 3.14+

Installation

pip install fiscguy

From source

git clone https://github.com/digitaltouchcode/fisc.git
cd fisc
pip install -e ".[dev]"

Quick Start

1. Add to Django settings

# settings.py
INSTALLED_APPS = [
    # ...
    "fiscguy",
    "rest_framework",
]

2. Run migrations

python manage.py migrate

3. Initialise your device

python manage.py init_device

This interactive command collects your device credentials, generates a CSR, registers the device with ZIMRA, and fetches taxes and configuration automatically.

4. Include URLs

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

urlpatterns = [
    path("fiscguy/", include("fiscguy.urls")),
]

5. Submit your first receipt

from fiscguy import open_day, submit_receipt, close_day

open_day()

receipt = submit_receipt({
    "receipt_type": "fiscalinvoice",
    "currency": "USD",
    "total_amount": "115.00",
    "payment_terms": "Cash",
    "lines": [
        {
            "product": "Consulting Service",
            "quantity": "1",
            "unit_price": "115.00",
            "line_total": "115.00",
            "tax_amount": "15.00",
            "tax_name": "standard rated 15%",
        }
    ],
})

close_day()

--

REST Endpoints

When URLs are included, FiscGuy exposes the following endpoints:

Method Endpoint Description
POST /fiscguy/open-day/ Open a new fiscal day
POST /fiscguy/close-day/ Close the current fiscal day
GET /fiscguy/get-status/ Get device and fiscal day status
POST /fiscguy/get-ping/ Ping FDMS to report device is online
GET /fiscguy/receipts/ List receipts (cursor paginated)
POST /fiscguy/receipts/ Submit a new receipt
GET /fiscguy/receipts/{id}/ Retrieve a receipt by ID
GET /fiscguy/configuration/ Get taxpayer configuration
POST /fiscguy/sync-config/ Manually sync configuration from FDMS
GET /fiscguy/taxes/ List all tax types
POST /fiscguy/issue-certificate/ Renew device certificate
* /fiscguy/buyer/ Buyer CRUD (ModelViewSet)

Pagination

Receipt listing supports cursor-based pagination:

GET /fiscguy/receipts/?page_size=20

Default page size: 10. Maximum: 100.


Error Handling

All operations raise typed exceptions. Import them from fiscguy.exceptions:

from fiscguy.exceptions import (
    ReceiptSubmissionError,
    CloseDayError,
    FiscalDayError,
    ConfigurationError,
    CertificateError,
    DevicePingError,
    StatusError,
)

try:
    close_day()
except CloseDayError as e:
    print(f"Close day failed: {e}")
Exception Raised when
ReceiptSubmissionError Receipt processing or FDMS submission fails
CloseDayError FDMS rejects the close day request
FiscalDayError Fiscal day cannot be opened or is already open
ConfigurationError Configuration is missing or sync fails
CertificateError Certificate issuance or renewal fails
DevicePingError Ping to FDMS fails
StatusError Status fetch from FDMS fails
DeviceRegistrationError Device registration with ZIMRA fails
CryptoError RSA signing or hashing fails

Models

FiscGuy adds the following tables to your database:

Model Description
Device Fiscal device registration details
Configuration Taxpayer configuration synced from FDMS
Certs Device certificate and private key
Taxes Tax types synced from FDMS on day open
FiscalDay Daily fiscal period with receipt counter
FiscalCounter Running totals per tax / payment method
Receipt Submitted receipts with hash, signature, QR code
ReceiptLine Individual line items on a receipt
Buyer Optional buyer registration data

Access them directly:

from fiscguy.models import Device, Receipt, FiscalDay, Taxes

device = Device.objects.first()
open_days = FiscalDay.objects.filter(is_open=True)
receipts = Receipt.objects.select_related("buyer").prefetch_related("lines")

Management Commands

init_device

Interactive device setup — run once per device:

python manage.py init_device

The command will:

  1. Prompt for org_name, activation_key, device_id, device_model_name, device_model_version, device_serial_number
  2. Ask whether to use production or testing FDMS
  3. Generate an RSA key pair and CSR
  4. Register the device with ZIMRA to obtain a signed certificate
  5. Fetch and persist configuration and taxes

Testing

# Run all tests
pytest

# With coverage report
pytest --cov=fiscguy --cov-report=html

# Run a specific test file
pytest fiscguy/tests/test_views.py

# Run a specific test
pytest fiscguy/tests/test_closing_day_service.py::TestBuildSaleByTax

All tests mock ZIMRA API calls and crypto operations — no network access required.


Documentation

View Full Documentation

Our comprehensive documentation covers everything you need to know:

Quick Links

GitHub Pages Setup

This documentation is automatically deployed to GitHub Pages when you push to the main branch.

No local scripts needed - GitHub Actions handles everything automatically!

Documentation Contents

Document Description
Installation Detailed installation and setup guide
Receipt Types Fiscal Invoice, Credit Note, Debit Note rules
Fiscal Counters How counters work and how they are calculated
Closing Day Closing day hash string and signature spec
Certificate Management Certificate lifecycle and renewal
Error Reference All exceptions and what causes them
Changelog Version history
Contributing Contributing guidelines

Contributing

Contributions are welcome. Please read CONTRIBUTING.md first.

# Set up dev environment
git clone https://github.com/digitaltouchcode/fisc.git
cd fisc
pip install -e ".[dev]"
pre-commit install

# Before submitting a PR
black fiscguy
isort fiscguy
flake8 fiscguy
pytest

License

MIT — see LICENSE.


Built for Zimbabwe 🇿🇼 by Casper Moyo

Packages

 
 
 

Contributors

Languages