Skip to content

Commit 6fa3059

Browse files
committed
feat(spp_simulation): add simulation engine for program scenario modeling
New module providing: - Scenario templates and configurable simulation scenarios - Simulation run execution with metric tracking - Scenario-to-program conversion for promoting simulations to real programs - Comparison wizard for side-by-side scenario analysis - Targeting efficiency and coverage metrics
1 parent 5ac7496 commit 6fa3059

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+6892
-0
lines changed

spp_simulation/README.rst

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
.. image:: https://odoo-community.org/readme-banner-image
2+
:target: https://odoo-community.org/get-involved?utm_source=readme
3+
:alt: Odoo Community Association
4+
5+
============================
6+
OpenSPP Targeting Simulation
7+
============================
8+
9+
..
10+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
11+
!! This file is generated by oca-gen-addon-readme !!
12+
!! changes will be overwritten. !!
13+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
14+
!! source digest: sha256:fd3e34b59c516e27a1d09522eca711429d907a328efb7a60b408f4edb71d552f
15+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16+
17+
.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
18+
:target: https://odoo-community.org/page/development-status
19+
:alt: Alpha
20+
.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png
21+
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
22+
:alt: License: LGPL-3
23+
.. |badge3| image:: https://img.shields.io/badge/github-OpenSPP%2Fopenspp--modules-lightgray.png?logo=github
24+
:target: https://github.com/OpenSPP/openspp-modules/tree/19.0/spp_simulation
25+
:alt: OpenSPP/openspp-modules
26+
27+
|badge1| |badge2| |badge3|
28+
29+
Targeting Simulation & Fairness Analysis
30+
========================================
31+
32+
Simulate targeting scenarios, analyze fairness and distribution, and
33+
compare different targeting strategies before committing to criteria.
34+
35+
Key Features
36+
------------
37+
38+
- **Scenario Builder**: Define targeting criteria using CEL expressions
39+
with live preview counts
40+
- **Template Library**: Pre-built templates for common targeting
41+
patterns (elderly pension, female-headed households, etc.)
42+
- **Distribution Analysis**: Gini coefficient, Lorenz curve, percentile
43+
breakdown
44+
- **Fairness Analysis**: Disparity ratios across gender, disability,
45+
location with traffic-light status indicators
46+
- **Targeting Efficiency**: Confusion matrix, leakage rate,
47+
undercoverage against ideal populations
48+
- **Budget Simulation**: Fixed cap and proportional reduction
49+
strategies
50+
- **Scenario Comparison**: Side-by-side comparison of multiple
51+
targeting approaches with overlap analysis
52+
- **Custom Metrics**: Define CEL-based aggregate, coverage, and ratio
53+
metrics
54+
55+
Privacy
56+
-------
57+
58+
Only aggregated counts, percentages, and metrics are stored. No
59+
individual beneficiary records are persisted in simulation results.
60+
61+
Models
62+
------
63+
64+
+----------------------------------+----------------------------------+
65+
| Model | Description |
66+
+==================================+==================================+
67+
| ``sp | Pre-built targeting scenario |
68+
| p.simulation.scenario.template`` | templates |
69+
+----------------------------------+----------------------------------+
70+
| ``spp.simulation.scenario`` | Targeting scenario definitions |
71+
+----------------------------------+----------------------------------+
72+
| ``s | Amount calculation rules |
73+
| pp.simulation.entitlement.rule`` | |
74+
+----------------------------------+----------------------------------+
75+
| ``spp.simulation.run`` | Aggregated simulation results |
76+
| | (non-deletable) |
77+
+----------------------------------+----------------------------------+
78+
| ``spp.simulation.comparison`` | Side-by-side run comparisons |
79+
+----------------------------------+----------------------------------+
80+
| ``spp.simulation.metric`` | Custom evaluation metrics |
81+
+----------------------------------+----------------------------------+
82+
83+
Security Groups
84+
---------------
85+
86+
================== ===============================================
87+
Group Access
88+
================== ===============================================
89+
Simulation Viewer Read-only access to all simulation data
90+
Simulation Officer Create/edit scenarios, run simulations
91+
Simulation Manager Full access including comparisons and archiving
92+
================== ===============================================
93+
94+
Menu Path
95+
---------
96+
97+
Social Protection > Simulation > Scenarios / Results / Comparisons
98+
99+
Configuration: Social Protection > Simulation > Configuration >
100+
Templates / Custom Metrics
101+
102+
.. IMPORTANT::
103+
This is an alpha version, the data model and design can change at any time without warning.
104+
Only for development or testing purpose, do not use in production.
105+
`More details on development status <https://odoo-community.org/page/development-status>`_
106+
107+
**Table of contents**
108+
109+
.. contents::
110+
:local:
111+
112+
Bug Tracker
113+
===========
114+
115+
Bugs are tracked on `GitHub Issues <https://github.com/OpenSPP/openspp-modules/issues>`_.
116+
In case of trouble, please check there if your issue has already been reported.
117+
If you spotted it first, help us to smash it by providing a detailed and welcomed
118+
`feedback <https://github.com/OpenSPP/openspp-modules/issues/new?body=module:%20spp_simulation%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
119+
120+
Do not contact contributors directly about support or help with technical issues.
121+
122+
Credits
123+
=======
124+
125+
Authors
126+
-------
127+
128+
* OpenSPP.org
129+
130+
Maintainers
131+
-----------
132+
133+
.. |maintainer-jeremi| image:: https://github.com/jeremi.png?size=40px
134+
:target: https://github.com/jeremi
135+
:alt: jeremi
136+
137+
Current maintainer:
138+
139+
|maintainer-jeremi|
140+
141+
This module is part of the `OpenSPP/openspp-modules <https://github.com/OpenSPP/openspp-modules/tree/19.0/spp_simulation>`_ project on GitHub.
142+
143+
You are welcome to contribute.

spp_simulation/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Part of OpenSPP. See LICENSE file for full copyright and licensing details.
2+
3+
from . import models
4+
from . import services
5+
from . import wizard

spp_simulation/__manifest__.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# pylint: disable=pointless-statement
2+
# Part of OpenSPP. See LICENSE file for full copyright and licensing details.
3+
{
4+
"name": "OpenSPP Targeting Simulation",
5+
"summary": "Simulate targeting scenarios, analyze fairness and distribution, "
6+
"and compare different targeting strategies before committing to criteria.",
7+
"category": "OpenSPP/Targeting",
8+
"version": "19.0.2.0.0",
9+
"author": "OpenSPP.org",
10+
"website": "https://github.com/OpenSPP/OpenSPP2",
11+
"license": "LGPL-3",
12+
"development_status": "Alpha",
13+
"maintainers": ["jeremi"],
14+
"depends": [
15+
"base",
16+
"mail",
17+
"spp_programs",
18+
"spp_cel_domain",
19+
"spp_cel_widget",
20+
"spp_security",
21+
"spp_aggregation",
22+
"spp_metrics_core",
23+
],
24+
"data": [
25+
# Security
26+
"security/simulation_security.xml",
27+
"security/ir.model.access.csv",
28+
# Data
29+
"data/scenario_templates.xml",
30+
# Views
31+
"views/simulation_scenario_template_views.xml",
32+
"views/simulation_scenario_views.xml",
33+
"views/simulation_run_views.xml",
34+
"views/simulation_comparison_views.xml",
35+
"views/simulation_metric_views.xml",
36+
"views/menu.xml",
37+
# Wizard
38+
"wizard/compare_wizard_views.xml",
39+
# Report
40+
"report/simulation_report_views.xml",
41+
"report/simulation_report.xml",
42+
],
43+
"assets": {
44+
"web.assets_backend": [
45+
"spp_simulation/static/src/results_summary/*",
46+
"spp_simulation/static/src/fairness_table/*",
47+
"spp_simulation/static/src/comparison_table/*",
48+
"spp_simulation/static/src/overlap_table/*",
49+
],
50+
},
51+
"demo": [],
52+
"images": [],
53+
"application": True,
54+
"installable": True,
55+
"auto_install": False,
56+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
<data noupdate="1">
4+
<record id="template_elderly_pension" model="spp.simulation.scenario.template">
5+
<field name="name">Elderly Pension (Age 60+)</field>
6+
<field name="description">Target elderly individuals aged 60 and above for pension benefits.</field>
7+
<field name="category">age</field>
8+
<field name="target_type">individual</field>
9+
<field name="targeting_expression">age_years(r.birthdate) >= 60</field>
10+
<field name="default_amount">1000</field>
11+
<field name="default_amount_mode">fixed</field>
12+
<field name="icon">fa-hourglass-half</field>
13+
<field name="sequence">10</field>
14+
</record>
15+
16+
<record id="template_children_under_5" model="spp.simulation.scenario.template">
17+
<field name="name">Households with Children Under 5</field>
18+
<field name="description">Target households that have at least one child under 5 years of age.</field>
19+
<field name="category">age</field>
20+
<field name="target_type">group</field>
21+
<field name="targeting_expression">members.any(m, age_years(m.birthdate) &lt; 5)</field>
22+
<field name="default_amount">500</field>
23+
<field name="default_amount_mode">fixed</field>
24+
<field name="icon">fa-child</field>
25+
<field name="sequence">20</field>
26+
</record>
27+
28+
<record id="template_female_headed" model="spp.simulation.scenario.template">
29+
<field name="name">Female-Headed Households</field>
30+
<field name="description">Target households where the head of household is female.</field>
31+
<field name="category">vulnerability</field>
32+
<field name="target_type">group</field>
33+
<field name="targeting_expression">is_female(head.gender_id)</field>
34+
<field name="default_amount">750</field>
35+
<field name="default_amount_mode">fixed</field>
36+
<field name="icon">fa-female</field>
37+
<field name="sequence">30</field>
38+
</record>
39+
40+
<record id="template_rural_households" model="spp.simulation.scenario.template">
41+
<field name="name">Rural Households</field>
42+
<field name="description">Target households located in rural areas.</field>
43+
<field name="category">geographic</field>
44+
<field name="target_type">group</field>
45+
<field name="targeting_expression">has_area_tag('RURAL')</field>
46+
<field name="default_amount">600</field>
47+
<field name="default_amount_mode">fixed</field>
48+
<field name="icon">fa-tree</field>
49+
<field name="sequence">40</field>
50+
</record>
51+
52+
<record id="template_disability_targeted" model="spp.simulation.scenario.template">
53+
<field name="name">Disability-Targeted</field>
54+
<field name="description">Target households with at least one member with a disability.</field>
55+
<field name="category">vulnerability</field>
56+
<field name="target_type">group</field>
57+
<field name="targeting_expression">members.any(m, m.disability_id != false)</field>
58+
<field name="default_amount">800</field>
59+
<field name="default_amount_mode">fixed</field>
60+
<field name="icon">fa-wheelchair</field>
61+
<field name="sequence">50</field>
62+
</record>
63+
64+
<record id="template_large_households" model="spp.simulation.scenario.template">
65+
<field name="name">Large Households (5+ Members)</field>
66+
<field name="description">Target households with 5 or more members. Amount scales with household size.</field>
67+
<field name="category">categorical</field>
68+
<field name="target_type">group</field>
69+
<field name="targeting_expression">size(members) >= 5</field>
70+
<field name="default_amount">200</field>
71+
<field name="default_amount_mode">multiplier</field>
72+
<field name="icon">fa-users</field>
73+
<field name="sequence">60</field>
74+
</record>
75+
</data>
76+
</odoo>

0 commit comments

Comments
 (0)