Skip to content

Commit 8e77302

Browse files
committed
fix(spp_mis_demo_v2): ensure HH debug GIS layer for MIS demo
1 parent 27368e9 commit 8e77302

4 files changed

Lines changed: 165 additions & 1 deletion

File tree

spp_mis_demo_v2/models/indicator_providers.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@
3434

3535
_logger = logging.getLogger(__name__)
3636

37+
DEBUG_HH_POINTS_LAYER_NAME = "HH Points (Debug)"
38+
DEBUG_HH_POINTS_LAYER_DOMAIN = (
39+
"[('is_registrant', '=', True), "
40+
"('is_group', '=', True), "
41+
"('coordinates', '!=', False), "
42+
"('active', '=', True)]"
43+
)
44+
3745
# Standard variables from spp_studio to activate (module.xml_id format)
3846
STANDARD_VARIABLES = [
3947
# Demographics (computed)
@@ -128,6 +136,93 @@ def _activate_variables(env, xml_ids, source_name):
128136
return activated, skipped, errors
129137

130138

139+
def _find_debug_layer_view(env):
140+
"""Find the most useful GIS view for debug household points."""
141+
view_model = env["ir.ui.view"]
142+
143+
# Prefer geofence map when available (best fit for geofence query debugging)
144+
geofence_view = view_model.search(
145+
[
146+
("model", "=", "spp.gis.geofence"),
147+
("type", "=", "gis"),
148+
],
149+
limit=1,
150+
)
151+
if geofence_view:
152+
return geofence_view
153+
154+
# Fallback to the standard area map
155+
return view_model.search(
156+
[
157+
("model", "=", "spp.area"),
158+
("type", "=", "gis"),
159+
],
160+
limit=1,
161+
)
162+
163+
164+
def _ensure_household_points_debug_layer(env):
165+
"""Create/update the HH points debug GIS layer (hidden on startup)."""
166+
coordinates_field = env["ir.model.fields"].search(
167+
[
168+
("model", "=", "res.partner"),
169+
("name", "=", "coordinates"),
170+
],
171+
limit=1,
172+
)
173+
if not coordinates_field:
174+
_logger.info(
175+
"[spp.mis.demo] Skipping HH debug layer: res.partner.coordinates not available"
176+
)
177+
return False
178+
179+
view = _find_debug_layer_view(env)
180+
if not view:
181+
_logger.info(
182+
"[spp.mis.demo] Skipping HH debug layer: no GIS view found for geofence/area"
183+
)
184+
return False
185+
186+
layer_model = env["spp.gis.data.layer"]
187+
layer = layer_model.search(
188+
[
189+
("name", "=", DEBUG_HH_POINTS_LAYER_NAME),
190+
("geo_field_id", "=", coordinates_field.id),
191+
("view_id", "=", view.id),
192+
],
193+
limit=1,
194+
)
195+
196+
vals = {
197+
"name": DEBUG_HH_POINTS_LAYER_NAME,
198+
"geo_field_id": coordinates_field.id,
199+
"view_id": view.id,
200+
"geo_repr": "basic",
201+
"active_on_startup": False,
202+
"layer_opacity": 0.9,
203+
"begin_color": "#0057B8",
204+
"sequence": 25,
205+
"domain": DEBUG_HH_POINTS_LAYER_DOMAIN,
206+
}
207+
208+
if layer:
209+
layer.write(vals)
210+
_logger.info(
211+
"[spp.mis.demo] Updated HH debug layer '%s' on view %s",
212+
layer.name,
213+
view.display_name,
214+
)
215+
return layer
216+
217+
layer = layer_model.create(vals)
218+
_logger.info(
219+
"[spp.mis.demo] Created HH debug layer '%s' on view %s",
220+
layer.name,
221+
view.display_name,
222+
)
223+
return layer
224+
225+
131226
def post_init_hook(env_or_cr, registry=None):
132227
"""Post-initialization hook for demo module.
133228
@@ -162,3 +257,5 @@ def post_init_hook(env_or_cr, registry=None):
162257
total_skipped,
163258
total_errors,
164259
)
260+
261+
_ensure_household_points_debug_layer(env)

spp_mis_demo_v2/models/mis_demo_generator.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,10 @@ def action_generate(self):
561561
_logger.info("Generating GPS coordinates for registrants...")
562562
self._generate_coordinates(stats)
563563

564-
# Step 12: Refresh GIS reports so map data is available immediately
564+
# Step 12: Ensure debug GIS layers are present (idempotent)
565+
self._ensure_debug_gis_layers(stats)
566+
567+
# Step 13: Refresh GIS reports so map data is available immediately
565568
self._refresh_gis_reports(stats)
566569

567570
# Step 13: Create PRISM API client with known credentials
@@ -577,6 +580,18 @@ def action_generate(self):
577580
self.state = "draft"
578581
raise UserError(_("Error generating demo data: %s") % e) from e
579582

583+
def _ensure_debug_gis_layers(self, stats):
584+
"""Ensure optional debug GIS layers exist after demo generation."""
585+
try:
586+
from .indicator_providers import _ensure_household_points_debug_layer
587+
588+
layer = _ensure_household_points_debug_layer(self.env)
589+
stats["debug_hh_points_layer_ready"] = bool(layer)
590+
except Exception as e:
591+
# Debug layer should never block demo generation.
592+
_logger.warning("Could not ensure debug GIS layers: %s", e)
593+
stats["debug_hh_points_layer_ready"] = False
594+
580595
def _ensure_demo_stories_exist(self, stats):
581596
"""Check if demo story registrants exist and create them if not."""
582597
try:

spp_mis_demo_v2/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from . import test_claim169_demo
77
from . import test_demo_programs
88
from . import test_formula_configuration
9+
from . import test_gis_debug_layer
910
from . import test_mis_demo_generator
1011
from . import test_registry_variables
1112
from . import test_demo_statistics
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Part of OpenSPP. See LICENSE file for full copyright and licensing details.
2+
"""Tests for MIS demo household-points debug GIS layer."""
3+
4+
from odoo.tests import TransactionCase, tagged
5+
6+
from odoo.addons.spp_mis_demo_v2.models.indicator_providers import (
7+
DEBUG_HH_POINTS_LAYER_DOMAIN,
8+
DEBUG_HH_POINTS_LAYER_NAME,
9+
_ensure_household_points_debug_layer,
10+
)
11+
12+
13+
@tagged("post_install", "-at_install")
14+
class TestGISDebugLayer(TransactionCase):
15+
"""Validate HH points debug layer creation and defaults."""
16+
17+
def test_household_points_debug_layer_exists_and_disabled_on_startup(self):
18+
"""Post-init should provide HH points debug layer in a safe default state."""
19+
layer = self.env["spp.gis.data.layer"].search(
20+
[("name", "=", DEBUG_HH_POINTS_LAYER_NAME)],
21+
limit=1,
22+
)
23+
self.assertTrue(layer, "Expected HH points debug layer to be created")
24+
self.assertEqual(layer.geo_field_id.model, "res.partner")
25+
self.assertEqual(layer.geo_field_id.name, "coordinates")
26+
self.assertFalse(layer.active_on_startup, "Debug layer must be disabled by default")
27+
self.assertEqual(layer.domain, DEBUG_HH_POINTS_LAYER_DOMAIN)
28+
29+
def test_household_points_debug_layer_setup_is_idempotent(self):
30+
"""Running helper repeatedly should update existing layer, not duplicate it."""
31+
layer_model = self.env["spp.gis.data.layer"]
32+
before_count = layer_model.search_count([("name", "=", DEBUG_HH_POINTS_LAYER_NAME)])
33+
34+
_ensure_household_points_debug_layer(self.env)
35+
36+
after_count = layer_model.search_count([("name", "=", DEBUG_HH_POINTS_LAYER_NAME)])
37+
self.assertEqual(before_count, after_count)
38+
39+
def test_generator_reensures_household_points_debug_layer(self):
40+
"""Generator flow should re-ensure debug layer for --generate workflows."""
41+
layer_model = self.env["spp.gis.data.layer"]
42+
layer_model.search([("name", "=", DEBUG_HH_POINTS_LAYER_NAME)]).unlink()
43+
44+
generator = self.env["spp.mis.demo.generator"].create({"name": "GIS Debug Layer Ensure"})
45+
stats = {}
46+
generator._ensure_debug_gis_layers(stats)
47+
48+
layer = layer_model.search([("name", "=", DEBUG_HH_POINTS_LAYER_NAME)], limit=1)
49+
self.assertTrue(layer)
50+
self.assertFalse(layer.active_on_startup)
51+
self.assertTrue(stats.get("debug_hh_points_layer_ready"))

0 commit comments

Comments
 (0)