@@ -784,19 +784,23 @@ def _create_story_registrant(self, story):
784784 return registrant
785785
786786 def _get_demographic_enricher (self ):
787- """Get or create the demographic enricher for story registrants.
788-
789- Uses a class-level cache since Odoo model instances don't support
790- arbitrary attribute assignment.
787+ """Build a fresh demographic enricher for the current generation run.
788+
789+ No caching: an enricher's internal `_bank_ids` / vocab / country
790+ caches are populated against the current cursor at construction
791+ time. A class-level cache survives TransactionCase savepoint
792+ rollbacks between tests, so by the time a later test re-uses the
793+ cached enricher its `_bank_ids` reference `res.bank` rows that
794+ no longer exist — the next `res.partner.bank` insert then raises
795+ a `res_partner_bank_bank_id_fkey` violation. `_ensure_banks` and
796+ `_cache_vocab_ids` are idempotent (search-then-create), so
797+ re-instantiating costs only a handful of SELECTs.
791798 """
792- cache_key = "_demo_enricher_cache"
793- if not hasattr (type (self ), cache_key ) or getattr (type (self ), cache_key ) is None :
794- from .demographic_enricher import DemographicEnricher
799+ from .demographic_enricher import DemographicEnricher
795800
796- locale = self .env .context .get ("demo_locale" , "fil_PH" )
797- rng = random .Random (99 ) # Separate seed from volume generation
798- setattr (type (self ), cache_key , DemographicEnricher (self .env , locale , rng ))
799- return getattr (type (self ), cache_key )
801+ locale = self .env .context .get ("demo_locale" , "fil_PH" )
802+ rng = random .Random (99 ) # Separate seed from volume generation
803+ return DemographicEnricher (self .env , locale , rng )
800804
801805 def _enrich_all_story_registrants (self , stories ):
802806 """Enrich all story registrants with demographic data if not already set.
@@ -901,21 +905,27 @@ def _create_household_members(self, group, profile, days_back):
901905 registration_date = fields .Date .today () - datetime .timedelta (days = days_back )
902906 members_created = []
903907
908+ VocabCode = self .env ["spp.vocabulary.code" ]
909+ type_ids_by_code = {}
910+ for code in ("head" , "spouse" , "child" , "other" ):
911+ rec = VocabCode .get_code ("urn:openspp:vocab:group-membership-type" , code )
912+ type_ids_by_code [code ] = rec .id if rec else False
913+
914+ def _membership_type_commands (code ):
915+ tid = type_ids_by_code .get (code )
916+ return [Command .link (tid )] if tid else []
917+
904918 # Create head of household
905919 head_data = profile .get ("head" , {})
906920 if head_data :
907921 head = self ._create_individual_member (head_data , registration_date )
908922 if head :
909923 members_created .append (head )
910- # Add as head member
911- head_membership_type = self .env ["spp.vocabulary.code" ].get_code (
912- "urn:openspp:vocab:group-membership-type" , "head"
913- )
914924 self .env ["spp.group.membership" ].create (
915925 {
916926 "group" : group .id ,
917927 "individual" : head .id ,
918- "membership_type_ids" : [ Command . link ( head_membership_type . id )] if head_membership_type else [] ,
928+ "membership_type_ids" : _membership_type_commands ( "head" ) ,
919929 }
920930 )
921931
@@ -929,6 +939,7 @@ def _create_household_members(self, group, profile, days_back):
929939 {
930940 "group" : group .id ,
931941 "individual" : spouse .id ,
942+ "membership_type_ids" : _membership_type_commands ("spouse" ),
932943 }
933944 )
934945
@@ -941,6 +952,7 @@ def _create_household_members(self, group, profile, days_back):
941952 {
942953 "group" : group .id ,
943954 "individual" : adult .id ,
955+ "membership_type_ids" : _membership_type_commands ("other" ),
944956 }
945957 )
946958
@@ -953,6 +965,7 @@ def _create_household_members(self, group, profile, days_back):
953965 {
954966 "group" : group .id ,
955967 "individual" : child .id ,
968+ "membership_type_ids" : _membership_type_commands ("child" ),
956969 }
957970 )
958971
@@ -2681,7 +2694,7 @@ def _get_demo_user(self, role):
26812694 "given_name" : "Baby Morales" ,
26822695 "family_name" : "Morales" ,
26832696 "birthdate" : fields .Date .today (),
2684- "relationship_xmlid" : "spp_registry.group_membership_kind_child " ,
2697+ "relationship_xmlid" : "spp_mis_demo_v2.code_membership_type_child " ,
26852698 },
26862699 },
26872700 # Phase 5.1: Add remove_member CR
0 commit comments