Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
echo "$changed_files"

if [ "${{ github.event_name }}" = "pull_request" ]; then
modules=$(echo "$changed_files" | python scripts/detect_modules.py --include-critical --max-modules=15)
modules=$(echo "$changed_files" | python scripts/detect_modules.py --include-critical --max-modules=20)
else
modules=$(echo "$changed_files" | python scripts/detect_modules.py --max-modules=10)
fi
Expand Down
7 changes: 4 additions & 3 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ coverage:
status:
project:
default:
# Only check coverage on files changed in this PR, not the entire project.
# CI only tests changed modules, so project-wide coverage would always drop
# on PRs that don't re-test every module.
# Informational only - don't block PRs on project-wide coverage.
# CI only tests changed modules (max 15), so project coverage fluctuates
# depending on which modules are in the test matrix.
informational: true
only_pulls: true
patch:
default:
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ openpyxl
parse-accept-language
pydantic
pyjwt
pyjwt>=2.4.0
Comment on lines 17 to +18

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The pyjwt dependency is specified twice. Please remove the line with just pyjwt and keep pyjwt>=2.4.0 to avoid redundancy and ensure the correct version is used.

pyjwt>=2.4.0

pyproj
python-dateutil
python-magic
Expand Down
3 changes: 2 additions & 1 deletion spp_api_v2_change_request/services/change_request_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import logging
from typing import Any

from odoo import _
from odoo.api import Environment
from odoo.exceptions import UserError, ValidationError

Expand Down Expand Up @@ -392,7 +393,7 @@ def _deserialize_detail(self, detail, data: dict[str, Any]) -> dict[str, Any]:

if unresolved:
raise ValidationError(
"Failed to resolve the following fields:\n" + "\n".join(f"- {msg}" for msg in unresolved)
_("Failed to resolve the following fields:\n") + "\n".join(f"- {msg}" for msg in unresolved)
)

return vals
Expand Down
2 changes: 1 addition & 1 deletion spp_dci_client/services/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ def _sign_request(self, header: dict, message: dict) -> dict:

except Exception as e:
_logger.error("Failed to sign DCI message: %s", str(e))
raise UserError(f"Failed to sign DCI message: {str(e)}") from e
raise UserError(_("Failed to sign DCI message: %s") % str(e)) from e
else:
_logger.debug(
"No signing key configured for data source '%s' - sending unsigned request",
Expand Down
13 changes: 7 additions & 6 deletions spp_dci_client_crvs/services/crvs_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import json
import logging

from odoo import _
from odoo.exceptions import UserError, ValidationError

from odoo.addons.spp_dci.schemas.constants import RegistryType
Expand Down Expand Up @@ -115,7 +116,7 @@ def verify_birth(self, identifier_type: str, identifier_value: str) -> dict | No

except Exception as e:
_logger.error("Failed to verify birth record: %s", str(e), exc_info=True)
raise UserError(f"Failed to verify birth record: {str(e)}") from e
raise UserError(_("Failed to verify birth record: %s") % str(e)) from e

def check_death(self, identifier_type: str, identifier_value: str) -> bool:
"""Check if person is deceased in CRVS system.
Expand Down Expand Up @@ -177,7 +178,7 @@ def check_death(self, identifier_type: str, identifier_value: str) -> bool:

except Exception as e:
_logger.error("Failed to check death status: %s", str(e), exc_info=True)
raise UserError(f"Failed to check death status: {str(e)}") from e
raise UserError(_("Failed to check death status: %s") % str(e)) from e

def subscribe_events(self, event_types: list | None = None) -> list[str]:
"""Subscribe to CRVS vital events.
Expand Down Expand Up @@ -241,15 +242,15 @@ def subscribe_events(self, event_types: list | None = None) -> list[str]:
)

if not subscription_ids:
raise UserError("Failed to subscribe to any CRVS events")
raise UserError(_("Failed to subscribe to any CRVS events"))

return subscription_ids

except UserError:
raise
except Exception as e:
_logger.error("Failed to subscribe to CRVS events: %s", str(e), exc_info=True)
raise UserError(f"Failed to subscribe to CRVS events: {str(e)}") from e
raise UserError(_("Failed to subscribe to CRVS events: %s") % str(e)) from e

def unsubscribe_events(self, subscription_codes: list[str]) -> dict:
"""Unsubscribe from CRVS vital events.
Expand Down Expand Up @@ -280,7 +281,7 @@ def unsubscribe_events(self, subscription_codes: list[str]) -> dict:

except Exception as e:
_logger.error("Failed to unsubscribe from CRVS events: %s", str(e), exc_info=True)
raise UserError(f"Failed to unsubscribe from CRVS events: {str(e)}") from e
raise UserError(_("Failed to unsubscribe from CRVS events: %s") % str(e)) from e

def process_notification(self, notification_data: dict) -> int:
"""Process CRVS notification and create event record.
Expand Down Expand Up @@ -361,7 +362,7 @@ def process_notification(self, notification_data: dict) -> int:

except Exception as e:
_logger.error("Failed to process CRVS notification: %s", str(e), exc_info=True)
raise ValidationError(f"Failed to process CRVS notification: {str(e)}") from e
raise ValidationError(_("Failed to process CRVS notification: %s") % str(e)) from e

def _extract_birth_data(self, record_data: dict) -> dict:
"""Extract birth information from DCI record data.
Expand Down
4 changes: 3 additions & 1 deletion spp_dci_client_crvs/tests/test_crvs_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from odoo.exceptions import UserError, ValidationError
from odoo.tests import tagged

from odoo.addons.spp_dci.schemas.constants import RegistryType

from .common import CRVSClientCommon


Expand All @@ -25,7 +27,7 @@ def setUp(self):
"auth_type": "none",
"our_sender_id": "openspp.example.org",
"our_callback_uri": "https://openspp.example.org/callback",
"registry_type": "CRVS",
"registry_type": RegistryType.CRVS.value,
}
)

Expand Down
8 changes: 4 additions & 4 deletions spp_dci_client_dr/services/dr_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import json
import logging

from odoo import fields
from odoo import _, fields
from odoo.exceptions import UserError, ValidationError

from odoo.addons.spp_dci_client.services import DCIClient
Expand Down Expand Up @@ -145,7 +145,7 @@ def get_disability_status(self, partner) -> dict | None:
str(e),
exc_info=True,
)
raise UserError(f"Failed to get disability status: {str(e)}") from e
raise UserError(_("Failed to get disability status: %s") % str(e)) from e

def get_functional_assessment(self, identifier_type: str, identifier_value: str) -> dict | None:
"""Get functional assessment scores for a person.
Expand Down Expand Up @@ -230,7 +230,7 @@ def get_functional_assessment(self, identifier_type: str, identifier_value: str)
str(e),
exc_info=True,
)
raise UserError(f"Failed to get functional assessment: {str(e)}") from e
raise UserError(_("Failed to get functional assessment: %s") % str(e)) from e

def is_pwd(self, partner) -> bool:
"""Quick check if person is registered as PWD (Person with Disability).
Expand Down Expand Up @@ -354,7 +354,7 @@ def sync_disability_data(self, partner) -> bool:
str(e),
exc_info=True,
)
raise UserError(f"Failed to sync disability data: {str(e)}") from e
raise UserError(_("Failed to sync disability data: %s") % str(e)) from e

def _get_partner_identifier(self, partner):
"""Get suitable identifier for querying DR.
Expand Down
138 changes: 138 additions & 0 deletions spp_hazard_programs/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
===================================
OpenSPP Hazard Programs Integration
===================================

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

.. |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_hazard_programs
:alt: OpenSPP/OpenSPP2

|badge1| |badge2| |badge3|

Links hazard incidents to emergency response programs. Enables programs
to target affected populations using verified impact data, filter
registrants by damage severity, and automatically enable emergency mode
when responding to active incidents.

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

- Link programs to one or more hazard incidents via many-to-many
relation
- Automatically flag programs as emergency when linked to incidents in
alert/active/recovery status
- Filter eligible registrants by damage level threshold (any, moderate+,
severe+, critical only)
- Count affected registrants based on verified impacts matching damage
criteria
- Track which programs are responding to each incident (bidirectional
navigation)

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

+----------------------------------+-----------------------------------+
| Model | Description |
+==================================+===================================+
| ``spp.program`` (extend) | Adds target incidents, emergency |
| | mode, damage filter |
+----------------------------------+-----------------------------------+
| ``spp.hazard.incident`` (extend) | Adds reverse relation to response |
| | programs |
+----------------------------------+-----------------------------------+

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

- **Programs**: Programs > Programs > "Emergency Response" tab
- **Incidents**: Hazard & Emergency > Incidents > All Incidents >
"Response Programs" tab
- **Stat buttons**: Programs show incident count and affected registrant
count; incidents show response program count
- **Filters**: "Emergency Programs" and "Has Target Incidents" filters
in program search view

Security
~~~~~~~~

No new ACL entries. Access inherited from base models:

- ``spp.program``: Controlled by ``spp_programs`` security groups
- ``spp.hazard.incident``: Controlled by ``spp_hazard`` security groups

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

- Override ``get_emergency_eligible_registrants()`` to customize
eligibility logic beyond damage levels
- Override ``_get_damage_level_domain()`` to add custom damage filtering
rules
- Inherit ``spp.program`` to add fields used in emergency calculations
- Use ``is_emergency_program`` and ``is_emergency_mode`` flags in
downstream program logic

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

``spp_hazard``, ``spp_programs``

.. 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:

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_hazard_programs%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-jeremi| image:: https://github.com/jeremi.png?size=40px
:target: https://github.com/jeremi
:alt: jeremi
.. |maintainer-gonzalesedwin1123| image:: https://github.com/gonzalesedwin1123.png?size=40px
:target: https://github.com/gonzalesedwin1123
:alt: gonzalesedwin1123
.. |maintainer-reichie020212| image:: https://github.com/reichie020212.png?size=40px
:target: https://github.com/reichie020212
:alt: reichie020212

Current maintainers:

|maintainer-jeremi| |maintainer-gonzalesedwin1123| |maintainer-reichie020212|

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

You are welcome to contribute.
3 changes: 3 additions & 0 deletions spp_hazard_programs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Part of OpenSPP. See LICENSE file for full copyright and licensing details.

from . import models
31 changes: 31 additions & 0 deletions spp_hazard_programs/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# pylint: disable=pointless-statement
# Part of OpenSPP. See LICENSE file for full copyright and licensing details.


{
"name": "OpenSPP Hazard Programs Integration",
"summary": "Links hazard impacts to program eligibility and entitlements. "
"Enables emergency programs to use hazard data for targeting and benefit calculation.",
"category": "OpenSPP/Targeting",
"version": "19.0.1.0.0",
"sequence": 1,
"author": "OpenSPP.org",
"website": "https://github.com/OpenSPP/OpenSPP2",
"license": "LGPL-3",
"development_status": "Alpha",
"maintainers": ["jeremi", "gonzalesedwin1123", "reichie020212"],
"depends": [
"spp_hazard",
"spp_programs",
],
"data": [
"security/ir.model.access.csv",
"views/program_views.xml",
"views/incident_views.xml",
],
"demo": [],
"assets": {},
"application": False,
"installable": True,
"auto_install": True,
}
4 changes: 4 additions & 0 deletions spp_hazard_programs/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Part of OpenSPP. See LICENSE file for full copyright and licensing details.

from . import program
from . import incident
Loading
Loading