def test_disable02(self): "Relationship creation & deletion" user = self.user hayao = FakeContact.objects.create(user=user, first_name='Hayao', last_name='Miyazaki') ghibli = FakeOrganisation.objects.create(user=user, name='Ghibli') rtype = RelationType.create(('test-subject_employed', 'is employed'), ('test-object_employed', 'employs'))[0] old_count = HistoryLine.objects.count() rel = Relation(user=user, subject_entity=hayao, object_entity=ghibli, type=rtype) HistoryLine.disable(rel) rel.save() self.assertEqual(old_count, HistoryLine.objects.count()) # ----------------------- rel = self.refresh(rel) HistoryLine.disable(rel) rel.delete() self.assertEqual(old_count, HistoryLine.objects.count())
def _set_orga_as_subject(sender, instance, **kwargs): if instance.type_id != REL_SUB_PART_2_ACTIVITY: return # NB: when a Relation is created, it is saved twice in order to set the link # with its symmetric instance if instance.symmetric_relation_id is None: return activity = instance.object_entity.get_real_entity() if not is_auto_orga_subject_enabled(): return user = instance.user Relation.objects.safe_multi_save( Relation( subject_entity=orga, type_id=REL_SUB_ACTIVITY_SUBJECT, object_entity=activity, user=user, ) for orga in Organisation.objects.filter( relations__type__in=( persons_constants.REL_OBJ_EMPLOYED_BY, persons_constants.REL_OBJ_MANAGES, ), relations__object_entity=instance.subject_entity_id, ).exclude(is_deleted=False, is_managed=True))
def post_save_relation_opp_subject_activity(sender, instance, **kwargs): if instance.type_id == REL_OBJ_ACTIVITY_SUBJECT: object_entity = instance.object_entity get_ct = ContentType.objects.get_for_model if object_entity.entity_type == get_ct(get_opportunity_model()): # relations = Relation.objects.filter(subject_entity=object_entity, # type=REL_SUB_COMPLETE_GOAL, # object_entity__entity_type=get_ct(get_act_model()), # ) # # create_relation = partial(Relation.objects.create, # subject_entity=instance.subject_entity, # type_id=REL_SUB_COMPLETE_GOAL, # user=instance.user, # ) # # for relation in relations: # create_relation(object_entity=relation.object_entity) activity = instance.subject_entity user = instance.user Relation.objects.safe_multi_save( Relation( subject_entity=activity, type_id=REL_SUB_COMPLETE_GOAL, object_entity=relation.object_entity, user=user, ) for relation in Relation.objects.filter( subject_entity_id=object_entity.id, type=REL_SUB_COMPLETE_GOAL, object_entity__entity_type=get_ct(get_act_model()), ))
def _get_relations_to_create(self): instance = self.instance return super()._get_relations_to_create().append( Relation( user=instance.user, subject_entity=instance, type_id=constants.REL_SUB_GEN_BY_EVENT, object_entity=self.event, ))
def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['forced_relations'] = [ Relation( type_id=constants.REL_SUB_COMPLETE_GOAL, object_entity=self.related_entity, ), ] return kwargs
def get_form_kwargs(self): kwargs = super().get_form_kwargs() rtype = self.get_rtype() if rtype: kwargs['forced_relations'] = [ Relation(object_entity=self.linked_orga, type=rtype), ] return kwargs
def _get_relations_to_create(this): instance = this.instance return super()._get_relations_to_create().append( Relation( subject_entity=this.related_entity.get_real_entity(), type_id=constants.REL_SUB_RELATED_2_DOC, object_entity=instance, user=instance.user, ), )
def _get_relations_to_create(self): instance = self.instance return super()._get_relations_to_create().append( Relation(subject_entity=instance, type_id=REL_SUB_LINKED_2_PTASK, object_entity=self._task, user=instance.user, ) )
def test_relations_credentials06(self): "Link credentials on the created entity + forced relationships." user = self.login(is_superuser=False, creatable_models=[FakeContact]) create_creds = partial(SetCredentials.objects.create, role=self.role) create_creds( value=EntityCredentials.VIEW | EntityCredentials.LINK, set_type=SetCredentials.ESET_OWN, ) create_creds(value=EntityCredentials.VIEW, set_type=SetCredentials.ESET_ALL) orga = FakeOrganisation.objects.create(user=user, name='Oshino corp.') rtype = RelationType.create( ('test-subject_heals', 'heals'), ('test-object_heals', 'is healed by'), )[1] data = { 'first_name': 'Kanbaru', 'last_name': 'Suruga', } forced_relations = [Relation(type=rtype, object_entity=orga)] # KO --- form1 = FakeContactForm( user=user, data={ **data, 'user': self.other_user.id }, forced_relations=forced_relations, ) self.assertFormInstanceErrors( form1, ( 'user', _('You are not allowed to link with the «{models}» of this user.' ).format(models='Test Contacts', ), ), ) # OK --- form2 = FakeContactForm( user=user, data={ **data, 'user': user.id }, forced_relations=forced_relations, ) self.assertFalse(form2.errors) subject = form2.save() self.assertRelationCount(1, subject, rtype, orga)
def _get_relations_to_create(this): instance = this.instance cdata = this.cleaned_data return super()._get_relations_to_create().extend( Relation( user=instance.user, subject_entity=instance, type_id=rtype_id, object_entity=cdata['customers_managed_orga'], ) for rtype_id in cdata['customers_rtypes'])
def test_manager_safe_multi_save01(self): "Create several relation" rtype1, srtype1 = RelationType.create( ('test-subject_challenge', 'challenges'), ('test-object_challenge', 'is challenged by')) rtype2, srtype2 = RelationType.create( ('test-subject_foobar', 'loves'), ('test-object_foobar', 'is loved by')) user = self.user create_contact = partial(FakeContact.objects.create, user=user) ryuko = create_contact(first_name='Ryuko', last_name='Matoi') satsuki = create_contact(first_name='Satsuki', last_name='Kiryuin') count = Relation.objects.safe_multi_save([ Relation(user=user, subject_entity=ryuko, type=rtype1, object_entity=satsuki), Relation(user=user, subject_entity=ryuko, type=rtype2, object_entity=satsuki), ]) self.assertEqual(2, count) rel1 = self.get_object_or_fail(Relation, type=rtype1) self.assertEqual(ryuko.id, rel1.subject_entity_id) self.assertEqual(satsuki.id, rel1.object_entity_id) self.assertEqual(user.id, rel1.user_id) self.assertEqual(srtype1, rel1.symmetric_relation.type) rel2 = self.get_object_or_fail(Relation, type=rtype2) self.assertEqual(ryuko.id, rel2.subject_entity_id) self.assertEqual(satsuki.id, rel2.object_entity_id) self.assertEqual(user.id, rel2.user_id) self.assertEqual(srtype2, rel2.symmetric_relation.type)
def _get_relations_to_create(this): relations = super()._get_relations_to_create() rtype = this.cleaned_data.get('rtype_for_organisation') instance = this.instance if rtype: relations.append(Relation( subject_entity=instance, type=rtype, object_entity=self.linked_orga, user=instance.user, )) return relations
def test_relations05(self): "Forced Relations (no <relations> block)." user = self.login() orga = FakeOrganisation.objects.create(user=user, name='Oshino corp.') rtype = RelationType.create(('test-subject_heals', 'has healed'), ('test-object_heals', 'healed by'), )[1] form = FakeContactForm( user=user, forced_relations=[Relation(type=rtype, object_entity=orga)], ) self.assertNotIn('rtypes_info', form.fields)
def _set_orga_as_subject(sender, instance, **kwargs): if instance.type_id != REL_SUB_PART_2_ACTIVITY: return # NB: when a Relation is created, it is saved twice in order to set the link # with its symmetric instance if instance.symmetric_relation_id is None: return activity = instance.object_entity.get_real_entity() if not activity.is_auto_orga_subject_enabled(): return # create_rel = partial(Relation.objects.get_or_create, # type_id=REL_SUB_ACTIVITY_SUBJECT, # object_entity=activity, # defaults={'user': instance.user}, # ) # # for orga in Organisation.objects.filter(relations__type__in=(persons_constants.REL_OBJ_EMPLOYED_BY, # persons_constants.REL_OBJ_MANAGES, # ), # relations__object_entity=instance.subject_entity_id, # ) \ # .exclude(is_deleted=False, is_managed=True): # try: # create_rel(subject_entity=orga) # except Relation.MultipleObjectsReturned: # logger.warning('_set_orga_as_subject(): duplicated ' # 'Relation <subject=%s type=%s object=%s>', # orga.id, REL_SUB_ACTIVITY_SUBJECT, activity.id, # ) user = instance.user Relation.objects.safe_multi_save( Relation( subject_entity=orga, type_id=REL_SUB_ACTIVITY_SUBJECT, object_entity=activity, user=user, ) for orga in Organisation.objects .filter(relations__type__in=( persons_constants.REL_OBJ_EMPLOYED_BY, persons_constants.REL_OBJ_MANAGES, ), relations__object_entity=instance.subject_entity_id, ) .exclude(is_deleted=False, is_managed=True) )
def test_manager_safe_multi_save03(self): "Avoid creating existing relations" rtype1 = RelationType.create( ('test-subject_challenge', 'challenges'), ('test-object_challenge', 'is challenged by'))[0] rtype2 = RelationType.create(('test-subject_foobar', 'loves'), ('test-object_foobar', 'is loved by'))[0] user = self.user create_contact = partial(FakeContact.objects.create, user=user) ryuko = create_contact(first_name='Ryuko', last_name='Matoi') satsuki = create_contact(first_name='Satsuki', last_name='Kiryuin') def build_rel1(): return Relation(user=user, subject_entity=ryuko, type=rtype1, object_entity=satsuki) rel1 = build_rel1() rel1.save() with self.assertNoException(): Relation.objects.safe_multi_save([ build_rel1(), Relation(user=user, subject_entity=ryuko, type=rtype2, object_entity=satsuki), build_rel1(), ]) self.assertStillExists(rel1) rel2 = self.get_object_or_fail(Relation, type=rtype2) self.assertEqual(ryuko.id, rel2.subject_entity_id) self.assertEqual(satsuki.id, rel2.object_entity_id) self.assertEqual(user.id, rel2.user_id)
def save(self, *args, **kwargs): instance = self.instance instance.floating_type = self.floating_type instance.type, instance.sub_type = self._get_activity_type_n_subtype() # super(_ActivityForm, self).save(*args, **kwargs) super().save(*args, **kwargs) # create_relation = partial(Relation.objects.create, object_entity=instance, # type_id=constants.REL_SUB_PART_2_ACTIVITY, user=instance.user, # ) # # for participant in self.participants: # create_relation(subject_entity=participant) Relation.objects.safe_multi_save( Relation( subject_entity=participant, type_id=constants.REL_SUB_PART_2_ACTIVITY, object_entity=instance, user=instance.user, ) for participant in self.participants) return instance
def __init__(self, linked_orga, rtype=None, *args, **kwargs): if rtype: kwargs['forced_relations'] = [ Relation(type=rtype, object_entity=linked_orga), ] super().__init__(*args, **kwargs) # if not linked_orga: # linked_orga = self.initial.get('linked_orga') # if linked_orga: # warnings.warn('RelatedContactForm: the use of initial for "linked_orga" is deprecated ; ' # 'use constructor argument "linked_orga" instead.', # DeprecationWarning # ) self.linked_orga = linked_orga # if not self.linked_orga: # warnings.warn('RelatedContactForm: empty "linked_orga" argument is deprecated ;.', # DeprecationWarning # ) # return # fields = self.fields # fields['orga_overview'].initial = self.linked_orga # if not rtype: # rtype = self.initial.get('relation_type') # if rtype: # warnings.warn('RelatedContactForm: the use of initial for "rtype" is deprecated ; ', # 'use constructor argument "rtype" instead.', # DeprecationWarning # ) self.relation_type = rtype # if rtype: # relation_field = CharField(label=gettext('Relation type'), # widget=TextInput(attrs={'readonly': 'readonly'}), # initial=self.relation_type, # todo: required=False ?? # ) # else: # get_ct = ContentType.objects.get_for_model # relation_field = ModelChoiceField(label=gettext('Status in the organisation'), # queryset=RelationType.objects.filter( # subject_ctypes=get_ct(Contact), # object_ctypes=get_ct(Organisation), # is_internal=False, # ), # ) # # fields['relation'] = relation_field if rtype: del self.fields['rtype_for_organisation'] else: rtype_f = self.fields['rtype_for_organisation'] rtype_f.label = gettext('Status in «{organisation}»').format( organisation=linked_orga, ) # TODO: factorise (see User form hooking) get_ct = ContentType.objects.get_for_model rtype_f.queryset = RelationType.objects.filter( subject_ctypes=get_ct(Contact), object_ctypes=get_ct(Organisation), is_internal=False, )
def _post_instance_creation(self, instance, line, updated): # super(ActivityMassImportForm, self)._post_instance_creation(instance, line, updated) super()._post_instance_creation(instance, line, updated) cdata = self.cleaned_data user = instance.user participant_ids = set() if updated: # TODO: improve get_participant_relations() (not retrieve real entities) participant_ids.update( Relation.objects.filter( type=constants.REL_SUB_PART_2_ACTIVITY, object_entity=instance.id, ).values_list('subject_entity', flat=True)) # create_sub_rel = partial(Relation.objects.get_or_create, object_entity=instance, # type_id=constants.REL_SUB_ACTIVITY_SUBJECT, # defaults={'user': user}, # ) # else: # create_sub_rel = partial(Relation.objects.create, object_entity=instance, # type_id=constants.REL_SUB_ACTIVITY_SUBJECT, user=user, # ) def add_participant(participant): if participant.id not in participant_ids: # Relation.objects.create( Relation.objects.safe_create( subject_entity=participant, type_id=constants.REL_SUB_PART_2_ACTIVITY, object_entity=instance, user=user, ) participant_ids.add(participant.id) # We could create a cache in self (or even put a cache-per-request in Calendar.get_user_default_calendar() # but the import can take a long time, & the default Calendar could change => TODO: use a time based cache ? default_calendars_cache = {} def add_to_default_calendar(part_user): calendar = default_calendars_cache.get(part_user.id) if calendar is None: default_calendars_cache[part_user.id] = calendar = \ Calendar.get_user_default_calendar(part_user) instance.calendars.add(calendar) i_participate, my_calendar = cdata['my_participation'] if i_participate: add_participant(user.linked_contact) instance.calendars.add(my_calendar) for participant in self.user_participants: add_participant(participant) add_to_default_calendar(participant.is_user) dyn_participants, err_messages = cdata[ 'participants'].extract_value(line, self.user) for err_msg in err_messages: self.append_error(err_msg) for participant in dyn_participants: add_participant(participant) part_user = participant.is_user if part_user is not None: instance.calendars.add( Calendar.get_user_default_calendar(part_user)) # Subjects ---- subjects, err_messages = cdata['subjects'].extract_value( line, self.user) for err_msg in err_messages: self.append_error(err_msg) # create_sub_rel = partial(Relation.objects.get_or_create, object_entity=instance, # type_id=constants.REL_SUB_ACTIVITY_SUBJECT, # defaults={'user': user}, # ) # # for subject in subjects: # try: # create_sub_rel(subject_entity=subject) # except Relation.MultipleObjectsReturned: # pass Relation.objects.safe_multi_save( Relation( subject_entity=subject, type_id=constants.REL_SUB_ACTIVITY_SUBJECT, object_entity=instance, user=user, ) for subject in subjects)
def test_relations04(self): "Forced Relations." user = self.login() create_contact = partial(FakeContact.objects.create, user=user) contact1 = create_contact(first_name='Hitagi', last_name='Senjyogahara') contact2 = create_contact(first_name='Koyomi', last_name='Araragi') orga = FakeOrganisation.objects.create(user=user, name='Oshino corp.') create_rtype = RelationType.create rtype1 = create_rtype( ('test-subject_loves', 'loves'), ('test-object_loves', 'is loved'), )[0] rtype2 = create_rtype( ('test-subject_heals', 'has healed', [FakeOrganisation]), ('test-object_heals', 'healed by', [FakeContact]), )[1] fields1 = FakeContactForm( user=user, forced_relations=[Relation(type=rtype2, object_entity=orga)], ).fields with self.assertNoException(): info_field = fields1['rtypes_info'] self.assertIn('relation_types', fields1) self.assertHTMLEqual( _('This relationship will be added: {predicate} «{entity}»'). format( predicate=rtype2.predicate, entity=orga, ), info_field.initial) # --- forced_relations = [ Relation(type=rtype2, object_entity=orga), Relation(type=rtype1, object_entity=contact1), ] fields2 = FakeContactForm(user=user, forced_relations=forced_relations).fields self.assertIn('relation_types', fields2) self.assertHTMLEqual( _('These relationships will be added: {}').format( '<ul><li>{} «{}»</li><li>{} «{}»</li></ul>'.format( rtype2.predicate, orga, rtype1.predicate, contact1, )), fields2['rtypes_info'].initial) # --- form = FakeContactForm( user=user, forced_relations=forced_relations, data={ 'user': user.id, 'first_name': 'Kanbaru', 'last_name': 'Suruga', 'relation_types': self.formfield_value_multi_relation_entity( (rtype1.id, contact2), ), }, ) self.assertFalse(form.errors) subject = form.save() self.assertRelationCount(1, subject, rtype1, contact1) self.assertRelationCount(1, subject, rtype1, contact2) self.assertRelationCount(1, subject, rtype2, orga)
def build_rel1(): return Relation(user=user, subject_entity=ryuko, type=rtype1, object_entity=satsuki)