Metadata-Version: 2.4
Name: aa-loa
Version: 0.0.2
Summary: Leave of Absence module for Alliance Auth
Project-URL: Changelog, https://github.com/mbroekman/aa-loa/blob/main/CHANGELOG.md
Project-URL: Homepage, https://github.com/mbroekman/aa-loa
Project-URL: Source, https://github.com/mbroekman/aa-loa
Project-URL: Tracker, https://github.com/mbroekman/aa-loa/issues
Author-email: Maddog Broekman <maddogbroekman@gmail.com>
License: MIT
License-File: LICENSE
Keywords: allianceauth,leave_of_absence,loa
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Requires-Python: <3.14,>=3.10
Requires-Dist: allianceauth>=3.6
Requires-Dist: discord-webhook>=1.3
Description-Content-Type: text/markdown

# Alliance Auth - Leave of Absence (aa-loa)

[![PyPI version](https://img.shields.io/pypi/v/aa-loa)](https://pypi.org/project/aa-loa/)
[![Python versions](https://img.shields.io/pypi/pyversions/aa-loa)](https://pypi.org/project/aa-loa/)
[![Tests](https://github.com/mbroekman/aa-loa/actions/workflows/automated-checks.yml/badge.svg)](https://github.com/mbroekman/aa-loa/actions/workflows/automated-checks.yml)

A complete Leave of Absence (LOA) management module for Alliance Auth. This module allows members to declare periods of absence so that leadership is aware of their inactivity, while seamlessly integrating with other Alliance Auth features (like Discord and Activity Trackers) to prevent accidental purges.

## Features

- **Player Dashboard:** Easy-to-use form for players to submit a start date, end date, and an optional reason. Players can also view their past LOAs, and cancel/revoke an active LOA if they return early.
- **HR Dashboard:** A dedicated view for Directors/HR to see a live table of all active and upcoming LOAs in the alliance.
- **Proxy Submission:** Directors can submit an LOA on behalf of a member who might be unable to access a PC (e.g. emergencies).
- **Discord Role Sync:** Assigns members to a specific Django Group (e.g., `[On Leave]`) when their LOA becomes active. Alliance Auth will automatically sync this to Discord, TS, or Mumble.
- **Purge Protection:** Because the member is in the `[On Leave]` group, audit modules (like `aa-inactives` or `opcalendar`) can simply whitelist this group to exempt the member from activity purges.
- **Webhooks:** Automatically posts a Discord Embed to a webhook URL whenever an LOA is submitted.
- **Welcome Back Notification:** A Celery task automatically removes the member from the LOA group when the end date passes, and sends a "Welcome Back" Alliance Auth notification.

### 🤖 Optional: Discord Bot Integration (`aa-discordbot`)

While `aa-loa` works perfectly fine on its own, it integrates natively with [aa-discordbot](https://github.com/pvyParts/allianceauth-discordbot). 
If your alliance has `aa-discordbot` installed, the internal Alliance Auth notifications generated by this module will automatically be forwarded as **Direct Messages (DMs)** on Discord to the user. This applies to:
- 📩 The "Welcome Back" notification when an LOA automatically expires.
- 🛑 The "Cancellation" notification when HR manually cancels a player's LOA.

---

## Installation

### 1. Install the Python Package
Activate your Alliance Auth virtual environment and install the package:

```bash
pip install -e /path/to/aa-loa/
```

### 2. Update Alliance Auth Settings
Open your `myauth/settings/local.py` file and add `'aa_loa'` to your `INSTALLED_APPS`:

```python
INSTALLED_APPS += [
    # ... other apps
    'aa_loa',
]
```

### 3. Run Database Migrations
Run the migrations to create the database tables:

```bash
python manage.py makemigrations aa_loa
python manage.py migrate
```

### 4. Restart Services
Restart your Alliance Auth web service and Celery workers so they pick up the new code and background tasks:

```bash
sudo systemctl restart supervisor
```
*(Or restart the specific services depending on your hosting environment).*

---

## Configuration

### 1. Setup the LOA Group
1. Go to the **Django Admin Panel** (`/admin/`).
2. Navigate to **Authentication and Authorization** -> **Groups** and create a new group (e.g., `On Leave`).
   - *Optional:* Configure this group in your Discord/TS services to map to a specific `[On Leave]` Discord Role.
3. Navigate to **Leave of Absence Configuration** -> **LOA Config**.
4. Add a new configuration row.
5. Select the `On Leave` group you just created.
6. *(Optional)* Paste a Discord Webhook URL if you want real-time notifications in an HR channel when LOAs are submitted.

### 2. Permissions
Assign the following permissions to the appropriate states or groups in Alliance Auth:

| Permission | Description |
|---|---|
| `aa_loa.basic_access` | Grants access to the LOA module for normal members. Allows them to submit and manage their own LOAs. |
| `aa_loa.manage_loa` | Grants access to the HR Dashboard. Allows users to view all LOAs and submit proxy LOAs for other members. |

### 3. Setup the Celery Periodic Task
To ensure LOA groups are automatically assigned and removed every night, you need to configure the daily Celery task in your `local.py` settings file.

Open your `myauth/settings/local.py` and add the following to your `CELERYBEAT_SCHEDULE` dictionary:

```python
from celery.schedules import crontab

CELERYBEAT_SCHEDULE['aa_loa_sync_groups'] = {
    'task': 'aa_loa.tasks.sync_loa_groups',
    'schedule': crontab(minute='0', hour='0'),
}
```

Restart your celery worker (`sudo systemctl restart supervisor`) and the system will automatically activate/deactivate LOAs every day at midnight!
