Metadata-Version: 2.4
Name: jmbg-labs
Version: 1.0.0
Summary: A Python library for validating and parsing Serbian unique master citizen numbers (JMBG)
Author-email: JMBG Labs <contact@jmbg-labs.com>
License: MIT
Project-URL: Homepage, https://github.com/jmbg-labs/python
Project-URL: Repository, https://github.com/jmbg-labs/python
Project-URL: Issues, https://github.com/jmbg-labs/python/issues
Keywords: jmbg,serbia,validation,identity,citizen-number
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# JMBG Python Library

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Python Version](https://img.shields.io/badge/Python-3.8%2B-blue)](https://www.python.org/)

A Python library for validating and parsing Serbian unique master citizen numbers (JMBG - Jedinstveni Matični Broj Građana).

## Features

- ✅ Validate JMBG numbers with comprehensive checks
- ✅ Extract birth date, region, and gender information
- ✅ Support for all Serbian regions
- ✅ Calculate age from JMBG
- ✅ Type-safe with Python type hints
- ✅ Fully tested with unittest
- ✅ No external dependencies

## Installation

Install via pip:

```bash
pip install jmbg-labs
```

Or clone the repository:

```bash
git clone https://github.com/jmbg-labs/python.git
cd python
```

## Usage

### Basic Validation

```python
from jmbg import Jmbg, valid

# Quick validation
if valid('0101000710009'):
    print("Valid JMBG")

# Parse and validate
try:
    jmbg = Jmbg.parse('0101000710009')
    print(f"Valid JMBG: {jmbg.format()}")
except JmbgError as e:
    print(f"Invalid JMBG: {e}")
```

### Extract Information

```python
from jmbg import Jmbg

jmbg = Jmbg('0101000710009')

# Get birth date
date = jmbg.get_date()  # datetime.date object
print(date.strftime('%Y-%m-%d'))  # 2000-01-01

# Get age
print(jmbg.get_age())  # e.g., 26

# Check gender
if jmbg.is_male():
    print("Male")

if jmbg.is_female():
    print("Female")

# Access individual parts
print(jmbg.day)           # 1
print(jmbg.month)         # 1
print(jmbg.year)          # 2000
print(jmbg.region)        # 71
print(jmbg.region_text)   # "Belgrade"
print(jmbg.country)       # "Serbia"
print(jmbg.unique)        # 0
print(jmbg.checksum)      # 9
```

### Using Built-in Methods

```python
jmbg = Jmbg('1505995800002')

# String conversion
print(str(jmbg))  # "1505995800002"
print(jmbg.format())  # "1505995800002"

# Property access
print(jmbg.original)        # "1505995800002"
print(jmbg.day_original)    # "15"
print(jmbg.month_original)  # "05"
print(jmbg.year_original)   # "995"
print(jmbg.region_original) # "80"
print(jmbg.unique_original) # "000"

# Check adult status
if jmbg.is_adult():
    print("Adult (18+)")
```

## JMBG Format

JMBG consists of 13 digits: `DDMMYYYRRBBBC`

- **DD** - Day of birth (01-31)
- **MM** - Month of birth (01-12)
- **YYY** - Year of birth (last 3 digits)
- **RR** - Region code
- **BBB** - Unique number (000-499 for males, 500-999 for females)
- **C** - Checksum digit

### Supported Regions

The library supports all Serbian and ex-Yugoslav regions including (beware: ex-Yugoslav regions codes may have changed since the breakup):

- **Serbia** (71-79): Belgrade, Kragujevac, Niš, etc.
- **Serbia/Vojvodina** (80-89): Novi Sad, Subotica, Pančevo, etc.
- **Serbia/Kosovo** (91-96): Priština, Peć, Prizren, etc.
- **Bosnia and Herzegovina** (10-19)
- **Montenegro** (21-29)
- **Croatia** (30-39)
- **Macedonia** (41-49)
- **Slovenia** (50)

## Validation Rules

The library performs comprehensive validation:

1. **Length check** - Must be exactly 13 digits
2. **Format check** - Must contain only numeric characters
3. **Date validation** - Birth date must be valid (including leap year support)
4. **Region validation** - Region code must exist in the registry
5. **Checksum validation** - Modulo 11 algorithm verification

## Development

### Running Tests

```bash
# Run all tests
python -m unittest discover

# Run specific test file
python -m unittest test_jmbg

# Run tests with verbose output
python -m unittest test_jmbg -v
```

### Code Style

```bash
# Format code with black
black .

# Check types with mypy
mypy jmbg.py
```

## Requirements

- Python ^3.8
- No external dependencies (for production use)

## Contributing

Contributions are welcome! Please ensure:

1. All tests pass (`python -m unittest discover`)
2. Code follows PEP 8 standards
3. Add tests for new features
4. Update documentation as needed

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Credits

Developed by [JMBG Labs](https://github.com/jmbg-labs)

## Support

- 🐛 [Report Issues](https://github.com/jmbg-labs/python/issues)
- 📖 [Source Code](https://github.com/jmbg-labs/python)

## Examples

### Validate Multiple JMBGs

```python
from jmbg import Jmbg, valid

jmbgs = ['0710003730015', '1705978730032', 'invalid']

for jmbg_string in jmbgs:
    if valid(jmbg_string):
        jmbg = Jmbg.parse(jmbg_string)
        print(f"{jmbg.format()} - Born: {jmbg.get_date()}, "
              f"Region: {jmbg.region_text}, "
              f"Gender: {'Male' if jmbg.is_male() else 'Female'}")
    else:
        print(f"{jmbg_string} - Invalid")
```

### Age Calculation

```python
from jmbg import Jmbg

jmbg = Jmbg('0710003730015')
age = jmbg.get_age()

if age >= 18:
    print("Adult")
else:
    print("Minor")
```

### Error Handling

```python
from jmbg import Jmbg
from jmbg_error import JmbgError

try:
    jmbg = Jmbg('1234567890123')
except JmbgError as e:
    # Handle specific validation errors
    print(f"Validation failed: {e}")
    # Possible messages:
    # - "JMBG string must have exactly 13 digits, got X"
    # - "JMBG must contain only numeric characters"
    # - "Date 'DD/MM/YYYY' is not valid"
    # - "Region 'XX' is not valid for JMBG"
    # - "Checksum is not valid"
```

### Working with Gender

```python
from jmbg import Jmbg
from gender import Gender

jmbg = Jmbg('0710003730015')

# Get gender enum
gender = jmbg.gender()
if gender == Gender.MALE:
    print("Male")
elif gender == Gender.FEMALE:
    print("Female")

# Or use convenience methods
print(jmbg.is_male())    # True
print(jmbg.is_female())  # False
```

### Date Operations

```python
from jmbg import Jmbg
import datetime

jmbg = Jmbg('2902992710005')  # Leap year date
birth_date = jmbg.get_date()

# Calculate days until next birthday
today = datetime.date.today()
next_birthday = datetime.date(today.year, birth_date.month, birth_date.day)
if next_birthday < today:
    next_birthday = datetime.date(today.year + 1, birth_date.month, birth_date.day)

days_until = (next_birthday - today).days
print(f"Days until birthday: {days_until}")
```
