Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pyproj
python-dateutil
python-magic
python-multipart
pytz
qrcode
requests
schwifty
Expand Down
245 changes: 245 additions & 0 deletions spp_attendance/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
==================
OpenSPP Attendance
==================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f14cdc55cd485da151349989e21bdafb68dcad327eef90ac39756a284a0d3779
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OpenSPP%2FOpenSPP2-lightgray.png?logo=github
:target: https://github.com/OpenSPP/OpenSPP2/tree/19.0/spp_attendance
:alt: OpenSPP/OpenSPP2

|badge1| |badge2| |badge3|

Tracks participant attendance for social protection program activities.
Records presence/absence with date, time, location, and activity type.
Provides OAuth-secured API endpoints for external systems to submit
attendance data and import participants from external registries.

**Positioning vs ``spp_session_tracking``:** this module is a
standalone, API-first attendance service — it keeps its own participant
registry (synced from an external registry) and receives attendance
events from external systems over REST, so it can run on a bare instance
without the program stack. ``spp_session_tracking`` covers the
complementary case: attendance at sessions and trainings managed
*inside* a program instance. The two do not share models and can
coexist.

Key Capabilities
~~~~~~~~~~~~~~~~

- Record attendance with date, time, type, location, and category
(present/absent)
- Query attendance history via ``get_attendance_list()`` with filtering
by date range, type, and location
- Import participants from external registries via configurable field
mapping
- Generate OAuth client credentials for external API access
- Enforce configurable uniqueness constraints (date/time/type/location)
to prevent duplicate records

Key Models
~~~~~~~~~~

+------------------------------------------+----------------------------------+
| Model | Description |
+==========================================+==================================+
| ``spp.attendance.subscriber`` | Participant registry, inherits |
| | res.partner |
+------------------------------------------+----------------------------------+
| ``spp.attendance.list`` | Attendance record with date, |
| | time, type, location |
+------------------------------------------+----------------------------------+
| ``spp.attendance.type`` | Configurable attendance event |
| | types |
+------------------------------------------+----------------------------------+
| ``spp.attendance.location`` | Configurable attendance |
| | locations |
+------------------------------------------+----------------------------------+
| ``spp.attendance.api.client.credential`` | OAuth credentials for external |
| | API clients |
+------------------------------------------+----------------------------------+
| ``spp.import.attendance.wizard`` | Wizard for importing from |
| | external registries |
+------------------------------------------+----------------------------------+

Configuration
~~~~~~~~~~~~~

After installing:

1. Navigate to **Settings > SPP Attendance Settings** to configure:

- Uniqueness constraints (date/time/type/location)
- Server URL and API endpoints
- Field mappings for import (personal information, identifiers,
contact details)

2. Create attendance types: **Attendance > Configuration > Attendance
Type**
3. Create locations: **Attendance > Configuration > Attendance
Location**
4. Generate OAuth credentials: **Settings > Attendance API Client
Credentials**

UI Location
~~~~~~~~~~~

- **Main Menu**: Attendance > Subscriber
- **Configuration**: Attendance > Configuration (Attendance Type,
Attendance Location)
- **API Credentials**: Settings > Attendance API Client Credentials
- **Settings**: Settings > SPP Attendance Settings
- **Subscriber Form**: Contains "Attendance" and "Person Information"
tabs

Security
~~~~~~~~

=========================================== =========
Group Access
=========================================== =========
``spp_attendance.group_attendance_viewer`` Read
``spp_attendance.group_attendance_manager`` Full CRUD
=========================================== =========

Extension Points
~~~~~~~~~~~~~~~~

- Override ``get_attendance_list()`` on ``spp.attendance.subscriber`` to
customize attendance queries
- Inherit ``spp.attendance.list`` to add domain-specific attendance
metadata
- Extend ``_import_attendance()`` in wizard to customize import logic

Dependencies
~~~~~~~~~~~~

``base``, ``spp_oauth``, ``spp_security``

.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.

**Table of contents**

.. contents::
:local:

Usage
=====

Syncing participants from a registry
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The participant import (Settings > SPP Attendance Settings, used by the
*Import Attendance* wizard) is fully configuration-driven: an auth
endpoint, a search endpoint, and JSON-path mappings into the response.
The shipped defaults target the SPDCI-style interface of a legacy
openspp-modules registry (``/oauth2/client/token`` +
``/registry/sync/search``).

To sync from an **OpenSPP2** registry instead, point the settings at the
DCI server modules (``spp_dci_server`` + ``spp_dci_server_social`` must
be installed on the registry instance):

+-----------------+----------------------------------------------------+
| Setting | Value for an OpenSPP2 registry |
+=================+====================================================+
| Server URL | ``https://<registry-host>`` |
+-----------------+----------------------------------------------------+
| Auth Endpoint | ``/api/v2/spp/oauth/token`` (spp_api_v2 |
| | client-credentials endpoint) |
+-----------------+----------------------------------------------------+
| Import Endpoint | ``/dci_api/v1/registry/sync/search`` |
+-----------------+----------------------------------------------------+

The JSON-path mappings (personal information, identifier, names, contact
fields) must match the DCI search response envelope of the target
registry; adjust them from the defaults as needed.

API access for external systems
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1. Create client credentials under **Attendance > Configuration > API
Clients**. The client secret is displayed **once** at creation (and
on regeneration) — store it securely; only a hash is kept.
2. Obtain a token: ``POST /auth/token`` with
``client_id``/``client_secret``.
3. Call the attendance endpoints with the token in the ``Authorization``
header (``Bearer`` scheme).

Signing keys come from ``spp_oauth`` (Settings > General Settings >
OpenSPP OAuth); the RSA keypair must be configured before tokens can be
issued.

Changelog
=========

19.0.2.0.0
~~~~~~~~~~

- Initial migration from openspp-modules
- fix(security): store API client secrets as scrypt hashes instead of
plaintext. Secrets are shown once at creation/regeneration and can no
longer be read back afterwards — including secrets that existed before
the upgrade, which a migration hashes in place. Clients keep
authenticating with their unchanged secrets. The Attendance Viewer
group's read access to the credential model is removed.
- fix: the REST API works on Odoo 19 again — every response with a body
crashed with ``AttributeError`` because ``date_utils.json_default``
was removed from Odoo
- fix: gender is never fabricated as "Male" — the res.partner field
default, the subscriber related-field default, the registry-import
fallback and the subscriber-create fallback all stamped it when gender
was unknown; the value now comes only from source data
- fix(wizard): a missing sync-configuration parameter raises the
intended error message instead of crashing with ``KeyError``; access
tokens already carrying a ``Basic`` scheme are no longer
double-prefixed
- fix(wizard): registry sync requests carry a 30s timeout so a hung
remote registry cannot freeze the worker

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OpenSPP/OpenSPP2/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OpenSPP/OpenSPP2/issues/new?body=module:%20spp_attendance%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* OpenSPP.org

Maintainers
-----------

.. |maintainer-reichie020212| image:: https://github.com/reichie020212.png?size=40px
:target: https://github.com/reichie020212
:alt: reichie020212

Current maintainer:

|maintainer-reichie020212|

This module is part of the `OpenSPP/OpenSPP2 <https://github.com/OpenSPP/OpenSPP2/tree/19.0/spp_attendance>`_ project on GitHub.

You are welcome to contribute.
3 changes: 3 additions & 0 deletions spp_attendance/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import controllers
from . import models
from . import wizard
34 changes: 34 additions & 0 deletions spp_attendance/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# pylint: disable=pointless-statement
{
"name": "OpenSPP Attendance",
"category": "OpenSPP",
"version": "19.0.2.0.0",
"summary": "This module accurately tracks participant attendance for social protection program activities, capturing essential details like date, time, location, and activity type. It integrates attendance records to inform conditional benefit eligibility and leverages spp_oauth to secure API endpoints for external data submission.",
"sequence": 1,
"author": "OpenSPP.org",
"website": "https://github.com/OpenSPP/OpenSPP2",
"license": "LGPL-3",
"development_status": "Alpha",
"maintainers": ["reichie020212"],
"depends": ["base", "spp_oauth", "spp_security"],
"external_dependencies": {"python": ["pytz"]},
"data": [
"data/ir_config_parameter_data.xml",
"security/privileges.xml",
"security/security.xml",
"security/ir.model.access.csv",
"views/main_views.xml",
"views/attendance_views.xml",
"views/attendance_api_client_views.xml",
"views/res_config_view.xml",
"views/attendance_type_views.xml",
"views/attendance_location_views.xml",
"wizard/import_attendance_view.xml",
],
"assets": {},
"demo": [],
"images": [],
"application": True,
"installable": True,
"auto_install": False,
}
1 change: 1 addition & 0 deletions spp_attendance/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import controllers
Loading
Loading