Skip to content

Commit 0565d9a

Browse files
authored
Merge pull request #46 from OpenSPP/feat/simulation-engine
feat(spp_simulation): add simulation engine for program scenario modeling
2 parents 7e29b04 + ec5ffb7 commit 0565d9a

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

+7366
-0
lines changed

spp_simulation/README.rst

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
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%2FOpenSPP2-lightgray.png?logo=github
24+
:target: https://github.com/OpenSPP/OpenSPP2/tree/19.0/spp_simulation
25+
:alt: OpenSPP/OpenSPP2
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 strategies
49+
- **Scenario Comparison**: Side-by-side comparison of multiple targeting
50+
approaches with overlap analysis
51+
- **Custom Metrics**: Define CEL-based aggregate, coverage, and ratio
52+
metrics
53+
54+
Privacy
55+
-------
56+
57+
Only aggregated counts, percentages, and metrics are stored. No
58+
individual beneficiary records are persisted in simulation results.
59+
60+
Models
61+
------
62+
63+
+--------------------------------------+----------------------------------+
64+
| Model | Description |
65+
+======================================+==================================+
66+
| ``spp.simulation.scenario.template`` | Pre-built targeting scenario |
67+
| | templates |
68+
+--------------------------------------+----------------------------------+
69+
| ``spp.simulation.scenario`` | Targeting scenario definitions |
70+
+--------------------------------------+----------------------------------+
71+
| ``spp.simulation.entitlement.rule`` | Amount calculation rules |
72+
+--------------------------------------+----------------------------------+
73+
| ``spp.simulation.run`` | Aggregated simulation results |
74+
| | (non-deletable) |
75+
+--------------------------------------+----------------------------------+
76+
| ``spp.simulation.comparison`` | Side-by-side run comparisons |
77+
+--------------------------------------+----------------------------------+
78+
| ``spp.simulation.metric`` | Custom evaluation metrics |
79+
+--------------------------------------+----------------------------------+
80+
81+
Security Groups
82+
---------------
83+
84+
================== ===============================================
85+
Group Access
86+
================== ===============================================
87+
Simulation Viewer Read-only access to all simulation data
88+
Simulation Officer Create/edit scenarios, run simulations
89+
Simulation Manager Full access including comparisons and archiving
90+
================== ===============================================
91+
92+
Menu Path
93+
---------
94+
95+
Social Protection > Simulation > Scenarios / Results / Comparisons
96+
97+
Configuration: Social Protection > Simulation > Configuration >
98+
Templates / Custom Metrics
99+
100+
.. IMPORTANT::
101+
This is an alpha version, the data model and design can change at any time without warning.
102+
Only for development or testing purpose, do not use in production.
103+
`More details on development status <https://odoo-community.org/page/development-status>`_
104+
105+
**Table of contents**
106+
107+
.. contents::
108+
:local:
109+
110+
Bug Tracker
111+
===========
112+
113+
Bugs are tracked on `GitHub Issues <https://github.com/OpenSPP/OpenSPP2/issues>`_.
114+
In case of trouble, please check there if your issue has already been reported.
115+
If you spotted it first, help us to smash it by providing a detailed and welcomed
116+
`feedback <https://github.com/OpenSPP/OpenSPP2/issues/new?body=module:%20spp_simulation%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
117+
118+
Do not contact contributors directly about support or help with technical issues.
119+
120+
Credits
121+
=======
122+
123+
Authors
124+
-------
125+
126+
* OpenSPP.org
127+
128+
Maintainers
129+
-----------
130+
131+
.. |maintainer-jeremi| image:: https://github.com/jeremi.png?size=40px
132+
:target: https://github.com/jeremi
133+
:alt: jeremi
134+
135+
Current maintainer:
136+
137+
|maintainer-jeremi|
138+
139+
This module is part of the `OpenSPP/OpenSPP2 <https://github.com/OpenSPP/OpenSPP2/tree/19.0/spp_simulation>`_ project on GitHub.
140+
141+
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: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<odoo noupdate="1">
3+
<record id="template_elderly_pension" model="spp.simulation.scenario.template">
4+
<field name="name">Elderly Pension (Age 60+)</field>
5+
<field
6+
name="description"
7+
>Target elderly individuals aged 60 and above for pension benefits.</field>
8+
<field name="category">age</field>
9+
<field name="target_type">individual</field>
10+
<field name="targeting_expression">age_years(r.birthdate) >= 60</field>
11+
<field name="default_amount">1000</field>
12+
<field name="default_amount_mode">fixed</field>
13+
<field name="icon">fa-hourglass-half</field>
14+
<field name="sequence">10</field>
15+
</record>
16+
17+
<record id="template_children_under_5" model="spp.simulation.scenario.template">
18+
<field name="name">Households with Children Under 5</field>
19+
<field
20+
name="description"
21+
>Target households that have at least one child under 5 years of age.</field>
22+
<field name="category">age</field>
23+
<field name="target_type">group</field>
24+
<field
25+
name="targeting_expression"
26+
>members.any(m, age_years(m.birthdate) &lt; 5)</field>
27+
<field name="default_amount">500</field>
28+
<field name="default_amount_mode">fixed</field>
29+
<field name="icon">fa-child</field>
30+
<field name="sequence">20</field>
31+
</record>
32+
33+
<record id="template_female_headed" model="spp.simulation.scenario.template">
34+
<field name="name">Female-Headed Households</field>
35+
<field
36+
name="description"
37+
>Target households where the head of household is female.</field>
38+
<field name="category">vulnerability</field>
39+
<field name="target_type">group</field>
40+
<field name="targeting_expression">is_female(head.gender_id)</field>
41+
<field name="default_amount">750</field>
42+
<field name="default_amount_mode">fixed</field>
43+
<field name="icon">fa-female</field>
44+
<field name="sequence">30</field>
45+
</record>
46+
47+
<record id="template_rural_households" model="spp.simulation.scenario.template">
48+
<field name="name">Rural Households</field>
49+
<field name="description">Target households located in rural areas.</field>
50+
<field name="category">geographic</field>
51+
<field name="target_type">group</field>
52+
<field name="targeting_expression">has_area_tag('RURAL')</field>
53+
<field name="default_amount">600</field>
54+
<field name="default_amount_mode">fixed</field>
55+
<field name="icon">fa-tree</field>
56+
<field name="sequence">40</field>
57+
</record>
58+
59+
<record id="template_disability_targeted" model="spp.simulation.scenario.template">
60+
<field name="name">Disability-Targeted</field>
61+
<field
62+
name="description"
63+
>Target households with at least one member with a disability.</field>
64+
<field name="category">vulnerability</field>
65+
<field name="target_type">group</field>
66+
<field
67+
name="targeting_expression"
68+
>members.any(m, m.disability_id != false)</field>
69+
<field name="default_amount">800</field>
70+
<field name="default_amount_mode">fixed</field>
71+
<field name="icon">fa-wheelchair</field>
72+
<field name="sequence">50</field>
73+
</record>
74+
75+
<record id="template_large_households" model="spp.simulation.scenario.template">
76+
<field name="name">Large Households (5+ Members)</field>
77+
<field
78+
name="description"
79+
>Target households with 5 or more members. Amount scales with household size.</field>
80+
<field name="category">categorical</field>
81+
<field name="target_type">group</field>
82+
<field name="targeting_expression">size(members) >= 5</field>
83+
<field name="default_amount">200</field>
84+
<field name="default_amount_mode">multiplier</field>
85+
<field name="icon">fa-users</field>
86+
<field name="sequence">60</field>
87+
</record>
88+
</odoo>

0 commit comments

Comments
 (0)