def test_edit_objective02(self): "Private filter" self.login() priv_efilter = EntityFilter.create( 'test-filter_priv01', 'Acme (private)', Organisation, is_custom=True, is_private=True, user=self.other_user, ) act = self.create_act() objective = ActObjective.objects.create( act=act, name='OBJ#1', counter_goal=3, ctype=priv_efilter.entity_type, filter=priv_efilter, ) url = objective.get_edit_absolute_url() response = self.assertGET200(url) with self.assertNoException(): fields = response.context['form'].fields label_f = fields['ec_label'] self.assertNotIn('entity_counting', fields) self.assertIsInstance(label_f.widget, Label) self.assertEqual( _('The filter cannot be changed because it is private.'), label_f.initial) name = 'New name' pub_efilter = EntityFilter.create('test-filter01', 'Acme', Organisation, is_custom=True) counter_goal = 4 response = self.client.post( url, data={ 'name': name, # Should not be used 'entity_counting': self.formfield_value_filtered_entity_type( pub_efilter.entity_type, pub_efilter, ), 'counter_goal': counter_goal, }) self.assertNoFormError(response) objective = self.refresh(objective) self.assertEqual(name, objective.name) self.assertEqual(counter_goal, objective.counter_goal) self.assertEqual(priv_efilter, objective.filter) # <===
def test_ml_contacts_filter02(self): "With a real EntityFilter." user = self.login() create_contact = partial(Contact.objects.create, user=user) recipients = [ create_contact(first_name='Ranma', last_name='Saotome'), create_contact(first_name='Genma', last_name='Saotome'), create_contact(first_name='Akane', last_name='Tendô'), ] expected_ids = {recipients[0].id, recipients[1].id} efilter = EntityFilter.create( 'test-filter01', 'Saotome', Contact, is_custom=True, conditions=[ condition_handler.RegularFieldConditionHandler.build_condition( model=Contact, operator=operators.IEQUALS, field_name='last_name', values=['Saotome'], ), ], ) self.assertSetEqual( expected_ids, {c.id for c in efilter.filter(Contact.objects.all())}) EntityFilter.create( 'test-filter02', 'Useless', FakeOrganisation, is_custom=True, ) # Should not be a valid choice mlist = MessagingList.objects.create(user=self.user, name='ml01') url = self._build_addcontactfilter_url(mlist) context = self.client.get(url).context with self.assertNoException(): choices = [*context['form'].fields['filters'].choices] self.assertListEqual([ ('', _('All')), *((ef.id, ef.name) for ef in EntityFilter.objects.filter( entity_type=ContentType.objects.get_for_model(Contact), )), ], choices) self.assertNoFormError( self.client.post(url, data={'filters': efilter.id})) self.assertSetEqual(expected_ids, {c.id for c in mlist.contacts.all()})
def test_select_efilter(self): self.login() efilter = EntityFilter.create( 'test-filter01', 'Contains "club"', FakeOrganisation, is_custom=True, conditions=[ EntityFilterCondition.build_4_field( model=FakeOrganisation, operator=EntityFilterCondition.CONTAINS, name='name', values=['club'], ), ], ) # # We set the current list view state # # Now needs a POST request for session changes. # self.assertPOST200(FakeOrganisation.get_lv_absolute_url(), data={'filter': efilter.id}) response = self.assertGET200( self._build_add_url(FakeOrganisation, efilter_id=efilter.id)) with self.assertNoException(): form = response.context['form'] self.assertEqual(efilter.id, form.initial['filter'])
def test_with_filter02(self): "Private filters (which belong to other users) are forbidden." self.login() efilter = EntityFilter.create( 'test-filter01', 'Contains "club"', FakeOrganisation, is_custom=True, is_private=True, user=self.other_user, conditions=[ # EntityFilterCondition.build_4_field( # model=FakeOrganisation, # operator=EntityFilterCondition.CONTAINS, # name='name', values=['club'], # ), RegularFieldConditionHandler.build_condition( model=FakeOrganisation, field_name='name', operator=operators.CONTAINS, values=['club'], ), ], ) response = self.assertPOST200( self._build_add_url(FakeOrganisation), follow=True, data={'filter': efilter.id, 'actions': self.build_formfield_value( name='name', operator='lower', value='', ), }, ) self.assertFormError( response, 'form', 'filter', _('Select a valid choice. That choice is not one of the available choices.') )
def test_clone(self): self.login() act = self.create_act() efilter = EntityFilter.create('test-filter01', 'Acme', Organisation, is_custom=True) create_obj = partial(ActObjective.objects.create, act=act) obj1 = create_obj(name='Hello counter') obj2 = create_obj(name='Orga counter', counter_goal=2, filter=efilter, ctype=Organisation) cloned = act.clone() self.assertEqual(act.name, cloned.name) self.assertEqual(act.due_date, cloned.due_date) self.assertEqual(act.segment, cloned.segment) cloned_objs = ActObjective.objects.filter(act=cloned).order_by('name') self.assertEqual(2, len(cloned_objs)) self.assertObjectivesEqual(obj1, cloned_objs[0]) self.assertObjectivesEqual(obj2, cloned_objs[1])
def test_add_root_pattern_component03(self): "Counted relation with filter (no parent component)" pattern = self._create_pattern() name = 'Called contacts' ct = ContentType.objects.get_for_model(FakeContact) efilter = EntityFilter.create('test-filter01', 'Ninja', FakeContact, is_custom=True) response = self.client.post( self._build_addcomp_url(pattern), data={ 'name': name, 'entity_counting': self.formfield_value_filtered_entity_type(ct, efilter), 'success_rate': 15, }, ) self.assertNoFormError(response) with self.assertNoException(): component = pattern.components.get(name=name) self.assertEqual(ct, component.ctype) self.assertEqual(efilter, component.filter)
def test_objective_create_entity04(self): "The objective has a filter -> error" self.login() act = self.create_act() efilter = EntityFilter.create( 'test-filter01', 'Acme', Organisation, is_custom=True, conditions=[ # EntityFilterCondition.build_4_field( # model=Organisation, # operator=EntityFilterCondition.ICONTAINS, # name='name', values=['Ferraille'], # ), condition_handler.RegularFieldConditionHandler.build_condition( model=Organisation, operator=operators.ICONTAINS, field_name='name', values=['Ferraille'], ), ], ) objective = ActObjective.objects.create( act=act, name='Orga counter', counter_goal=2, ctype=Organisation, filter=efilter, ) self.assertGET409(self._build_create_related_entity_url(objective))
def test_edit_objective01(self): self.login() act = self.create_act() objective = ActObjective.objects.create(act=act, name='OBJ#1') self.assertEqual(1, objective.counter_goal) url = objective.get_edit_absolute_url() response = self.assertGET200(url) # self.assertTemplateUsed(response, 'creme_core/generics/blockform/edit_popup.html') self.assertTemplateUsed(response, 'creme_core/generics/blockform/edit-popup.html') # self.assertEqual(_('Objective for «%s»') % act, response.context.get('title')) self.assertEqual(_('Objective for «{entity}»').format(entity=act), response.context.get('title') ) name = 'OBJ_NAME' efilter = EntityFilter.create('test-filter01', 'Acme', Organisation, is_custom=True) ct = efilter.entity_type counter_goal = 3 response = self.client.post(url, data={'name': name, 'entity_counting': self.formfield_value_filtered_entity_type(ct, efilter), 'counter_goal': counter_goal, } ) self.assertNoFormError(response) objective = self.refresh(objective) self.assertEqual(name, objective.name) self.assertEqual(counter_goal, objective.counter_goal) self.assertEqual(ct, objective.ctype) self.assertEqual(efilter, objective.filter)
def test_fatalerror(self): self.login() efilter = EntityFilter.create( 'test-filter01', 'Contains "club"', FakeOrganisation, is_custom=True, ) response = self.client.post(self._build_add_url(FakeOrganisation), follow=True, data={ 'filter': efilter.id, 'actions': self.build_formfield_value( name='name', operator='rm_end', value='5', ), }) efilter.delete() self.assertDoesNotExist(efilter) job = self._get_job(response) with self.assertNoException(): batch_process_type.execute(job) self.assertEqual(Job.STATUS_ERROR, job.status) self.assertEqual(_(u'The filter does not exist anymore'), job.error) self.assertTrue(job.is_finished)
def test_resume_job(self): user = self.login() create_orga = partial(FakeOrganisation.objects.create, user=user, description='club') orga01 = create_orga(name='Coding club') orga02 = create_orga(name='Manga club') orga03 = create_orga(name='Anime club') efilter = EntityFilter.create( 'test-filter01', 'Contains "club"', FakeOrganisation, is_custom=True, ) efilter.set_conditions([ EntityFilterCondition.build_4_field( model=FakeOrganisation, operator=EntityFilterCondition.CONTAINS, name='description', values=['club']) ]) self.assertEqual({orga01, orga02, orga03}, set(efilter.filter(FakeOrganisation.objects.all()))) response = self.client.post(self._build_add_url(FakeOrganisation), follow=True, data={ 'filter': efilter.id, 'actions': self.build_formfield_value( name='name', operator='rm_end', value='5', ), }) self.assertNoFormError(response) job = self._get_job(response) # We simulate a job which has been interrupted orga01.name = 'Coding' orga01.save() EntityJobResult.objects.create(job=job, entity=orga01) batch_process_type.execute(job) self.assertEqual('Manga', self.refresh(orga02).name) self.assertEqual('Anime', self.refresh(orga03).name) self.assertEqual( 'Coding', self.refresh(orga01).name) # <== Should not be modified again
def test_list_view_export_with_filter01(self): user = self.login() hf = self._build_hf_n_contacts() efilter = EntityFilter.create( 'test-filter01', 'Red', FakeContact, user=user, is_custom=False, conditions=[ EntityFilterCondition.build_4_field( model=FakeContact, operator=EntityFilterCondition.ISTARTSWITH, name='last_name', values=['Wong'], ), ], ) existing_hline_ids = list( HistoryLine.objects.values_list('id', flat=True)) url = FakeContact.get_lv_absolute_url() # TODO: remove when filter ID is sent to export view as GET arg self.assertPOST200(url, data={'filter': efilter.id}) response = self.assertGET200(self._build_contact_dl_url(list_url=url)) result = [force_text(line) for line in response.content.splitlines()] self.assertEqual(2, len(result)) self.assertEqual('"","Wong","Edward","","is a girl"', result[1]) # History hlines = HistoryLine.objects.exclude(id__in=existing_hline_ids) self.assertEqual(1, len(hlines)) hline = hlines[0] self.assertEqual([1, hf.name, efilter.name], hline.modifications) self.assertEqual( [ _('Export of {count} «{model}» (view «{view}» & filter «{filter}»)' ).format( count=1, model='Test Contact', view=hf.name, filter=efilter.name, ), ], hline.get_verbose_modifications(user), )
def test_fk_printer03(self): "EntityFilter." user = self.login() name = 'Nerv' desc1 = 'important' desc2 = 'beware' efilter = EntityFilter.create( pk='test-ef_orga', name='My filter', model=FakeOrganisation, is_custom=True, conditions=[ RegularFieldConditionHandler.build_condition( model=FakeOrganisation, operator=operators.STARTSWITH, field_name='name', values=[name], ), RegularFieldConditionHandler.build_condition( model=FakeOrganisation, operator=operators.CONTAINS, field_name='description', values=[desc1, desc2], ), ], ) r = FakeReport() field = r._meta.get_field('efilter') fmt_value = _('«{enum_value}»').format self.assertHTMLEqual( '<div class="entity_filter-summary">{name}' '<ul>' '<li>{cond1}</li>' '<li>{cond2}</li>' '</ul>' '</div>'.format( name=efilter.name, cond1=_('«{field}» starts with {values}').format( field=_('Name'), values=fmt_value(enum_value=name), ), cond2=_('«{field}» contains {values}').format( field=_('Description'), values=_('{first} or {last}').format( first=fmt_value(enum_value=desc1), last=fmt_value(enum_value=desc2), ), ), ), field_printers.print_foreignkey_html(r, efilter, user, field) )
def test_with_filter03(self): "__currentuser__ condition (need global_info)." user = self.login() create_orga = partial(FakeOrganisation.objects.create, user=user) orga01 = create_orga(name='Genshiken') orga02 = create_orga(name='Manga club') orga03 = create_orga(name='Anime club', user=self.other_user) efilter = EntityFilter.create( 'test-filter01', 'Assigned to me', FakeOrganisation, is_custom=True, conditions=[ # EntityFilterCondition.build_4_field( # model=FakeOrganisation, # operator=EntityFilterCondition.EQUALS, # name='user', # values=['__currentuser__'], # ), RegularFieldConditionHandler.build_condition( model=FakeOrganisation, field_name='user', operator=operators.EQUALS, values=[operands.CurrentUserOperand.type_id], ), ], ) response = self.client.post( self._build_add_url(FakeOrganisation), follow=True, data={ 'filter': efilter.id, 'actions': self.build_formfield_value( name='name', operator='upper', value='', ), }, ) self.assertNoFormError(response) job = self._get_job(response) job_type_registry(job.id) self.assertEqual('GENSHIKEN', self.refresh(orga01).name) self.assertEqual('MANGA CLUB', self.refresh(orga02).name) self.assertEqual('Anime club', self.refresh(orga03).name) # <== not changed
def test_count_relations02(self): "With filter" user = self.login() efilter = EntityFilter.create('test-filter01', 'Acme', Organisation, is_custom=True, conditions=[EntityFilterCondition.build_4_field( model=Organisation, operator=EntityFilterCondition.ICONTAINS, name='name', values=['Ferraille'], ), ], ) act = self.create_act() objective = ActObjective.objects.create(act=act, name='Orga counter', counter_goal=2, ctype=ContentType.objects.get_for_model(Organisation), filter=efilter, ) self.assertEqual(0, objective.get_count()) create_orga = partial(Organisation.objects.create, user=user) orga01 = create_orga(name='Ferraille corp') orga02 = create_orga(name='World company') orga03 = create_orga(name='Ferraille inc') all_orgas = set(efilter.filter(Organisation.objects.all())) self.assertIn(orga01, all_orgas) self.assertNotIn(orga02, all_orgas) completes_goal = partial(Relation.objects.create, type_id=REL_SUB_COMPLETE_GOAL, object_entity=act, user=user ) completes_goal(subject_entity=orga01) self.assertEqual(1, self.refresh(objective).get_count()) completes_goal(subject_entity=orga02) self.assertEqual(1, self.refresh(objective).get_count()) completes_goal(subject_entity=orga03) self.assertEqual(2, self.refresh(objective).get_count()) contact = Contact.objects.create(user=user, first_name='Monsieur', last_name='Ferraille') completes_goal(subject_entity=contact) self.assertEqual(2, self.refresh(objective).get_count())
def test_objective_create_entity04(self): "The objective has a filter -> error" self.login() act = self.create_act() efilter = EntityFilter.create('test-filter01', 'Acme', Organisation, is_custom=True, conditions=[EntityFilterCondition.build_4_field( model=Organisation, operator=EntityFilterCondition.ICONTAINS, name='name', values=['Ferraille'], ) ], ) objective = ActObjective.objects.create(act=act, name='Orga counter', counter_goal=2, ctype=ContentType.objects.get_for_model(Organisation), filter=efilter, ) self.assertGET409(self._build_create_related_entity_url(objective))
def test_select_efilter(self): self.login() efilter = EntityFilter.create( 'test-filter01', 'Contains "club"', FakeOrganisation, is_custom=True, conditions=[ # EntityFilterCondition.build_4_field( # model=FakeOrganisation, # operator=EntityFilterCondition.CONTAINS, # name='name', values=['club'], # ), RegularFieldConditionHandler.build_condition( model=FakeOrganisation, field_name='name', operator=operators.CONTAINS, values=['club'], ), ], ) response = self.assertGET200(self._build_add_url(FakeOrganisation, efilter_id=efilter.id)) with self.assertNoException(): form = response.context['form'] self.assertEqual(efilter.id, form.initial['filter'])
def test_with_filter01(self): user = self.login() create_orga = partial(FakeOrganisation.objects.create, user=user) orga01 = create_orga(name='Genshiken') orga02 = create_orga(name='Manga club') orga03 = create_orga(name='Anime club') efilter = EntityFilter.create( 'test-filter01', 'Contains "club"', FakeOrganisation, is_custom=True, conditions=[ EntityFilterCondition.build_4_field( model=FakeOrganisation, operator=EntityFilterCondition.CONTAINS, name='name', values=['club'], ), ], ) self.assertEqual( {orga02, orga03}, set(efilter.filter( FakeOrganisation.objects.all()))) # <== not 'orga01' response = self.client.post(self._build_add_url(FakeOrganisation), follow=True, data={ 'filter': efilter.id, 'actions': self.build_formfield_value( name='name', operator='lower', value='', ), }) self.assertNoFormError(response) job = self._get_job(response) batch_process_type.execute(job) self.assertEqual('manga club', self.refresh(orga02).name) self.assertEqual('anime club', self.refresh(orga03).name) self.assertEqual('Genshiken', self.refresh(orga01).name) # <== not changed self.get_object_or_fail(EntityJobResult, job=job, entity=orga02) self.assertFalse(EntityJobResult.objects.filter(job=job, entity=orga01)) self.assertEqual([ ungettext(u'{count} entity has been successfully modified.', u'{count} entities have been successfully modified.', 2).format(count=2), ], job.stats) progress = job.progress self.assertIsNone(progress.percentage) self.assertEqual( ungettext(u'{count} entity has been processed.', u'{count} entities have been processed.', 2).format(count=2), progress.label)
def populate(self): already_populated = RelationType.objects.filter( pk=constants.REL_SUB_RELATED_2_DOC).exists() Document = get_document_model() Folder = get_folder_model() RelationType.create( (constants.REL_SUB_RELATED_2_DOC, _(u'related to the document')), (constants.REL_OBJ_RELATED_2_DOC, _(u'document related to'), [Document])) # --------------------------- # TODO: pk string (or UUID) (+ move DOCUMENTS_FROM_EMAILS in 'emails' app) ?? entities_cat = create_if_needed( FolderCategory, {'pk': constants.DOCUMENTS_FROM_ENTITIES}, name=str(constants.DOCUMENTS_FROM_ENTITIES_NAME), is_custom=False) create_if_needed(FolderCategory, {'pk': constants.DOCUMENTS_FROM_EMAILS}, name=str(constants.DOCUMENTS_FROM_EMAILS_NAME), is_custom=False) # TODO: created by 'products' & 'persons' app ? create_doc_cat = DocumentCategory.objects.get_or_create create_doc_cat(uuid=constants.UUID_DOC_CAT_IMG_PRODUCT, defaults={ 'name': _(u'Product image'), 'is_custom': False, }) create_doc_cat(uuid=constants.UUID_DOC_CAT_IMG_ORGA, defaults={ 'name': _(u'Organisation logo'), 'is_custom': False, }) create_doc_cat(uuid=constants.UUID_DOC_CAT_IMG_CONTACT, defaults={ 'name': _(u'Contact photograph'), 'is_custom': False, }) # --------------------------- user_qs = get_user_model().objects.order_by('id') user = user_qs.filter(is_superuser=True, is_staff=False).first() or \ user_qs.filter(is_superuser=True).first() or \ user_qs[0] if not folder_model_is_custom(): get_create_folder = Folder.objects.get_or_create get_create_folder( uuid=constants.UUID_FOLDER_RELATED2ENTITIES, defaults={ 'user': user, 'title': 'Creme', 'category': entities_cat, 'description': _(u'Folder containing all the documents related to entities' ), }) get_create_folder(uuid=constants.UUID_FOLDER_IMAGES, defaults={ 'user': user, 'title': _(u'Images'), }) # --------------------------- HeaderFilter.create( pk=constants.DEFAULT_HFILTER_DOCUMENT, model=Document, name=_(u'Document view'), cells_desc=[ (EntityCellRegularField, { 'name': 'title' }), # (EntityCellRegularField, {'name': 'folder__title'}), (EntityCellRegularField, { 'name': 'linked_folder__title' }), (EntityCellRegularField, { 'name': 'mime_type' }), ]) HeaderFilter.create(pk=constants.DEFAULT_HFILTER_FOLDER, model=Folder, name=_(u'Folder view'), cells_desc=[ (EntityCellRegularField, { 'name': 'title' }), (EntityCellRegularField, { 'name': 'description' }), (EntityCellRegularField, { 'name': 'category' }), ]) # --------------------------- EntityFilter.create( constants.EFILTER_IMAGES, name=_(u'Images'), model=Document, is_custom=False, user='******', conditions=[ EntityFilterCondition.build_4_field( model=Document, operator=EntityFilterCondition.STARTSWITH, name='mime_type__name', values=[constants.MIMETYPE_PREFIX_IMG], ), ], ) # --------------------------- create_sci = SearchConfigItem.create_if_needed # create_sci(Document, ['title', 'description', 'folder__title', 'categories__name']) create_sci(Document, [ 'title', 'description', 'linked_folder__title', 'categories__name' ]) create_sci(Folder, ['title', 'description', 'category__name']) # --------------------------- if not already_populated: LEFT = BrickDetailviewLocation.LEFT RIGHT = BrickDetailviewLocation.RIGHT create_bdl = BrickDetailviewLocation.create_if_needed BrickDetailviewLocation.create_4_model_brick(order=5, zone=LEFT, model=Folder) create_bdl(brick_id=core_bricks.CustomFieldsBrick.id_, order=40, zone=LEFT, model=Folder) create_bdl(brick_id=bricks.ChildFoldersBrick.id_, order=50, zone=LEFT, model=Folder) create_bdl(brick_id=bricks.FolderDocsBrick.id_, order=60, zone=LEFT, model=Folder) create_bdl(brick_id=core_bricks.PropertiesBrick.id_, order=450, zone=LEFT, model=Folder) create_bdl(brick_id=core_bricks.RelationsBrick.id_, order=500, zone=LEFT, model=Folder) create_bdl(brick_id=core_bricks.HistoryBrick.id_, order=20, zone=RIGHT, model=Folder) if apps.is_installed('creme.assistants'): logger.info( 'Assistants app is installed => we use the assistants blocks on detail view' ) from creme.assistants import bricks as a_bricks create_bdl(brick_id=a_bricks.TodosBrick.id_, order=100, zone=RIGHT, model=Folder) create_bdl(brick_id=a_bricks.MemosBrick.id_, order=200, zone=RIGHT, model=Folder) create_bdl(brick_id=a_bricks.AlertsBrick.id_, order=300, zone=RIGHT, model=Folder) create_bdl(brick_id=a_bricks.UserMessagesBrick.id_, order=400, zone=RIGHT, model=Folder)
def test_add_objectives_from_pattern02(self): "With components" user = self.login() act = self.create_act(expected_sales=20000) pattern = ActObjectivePattern.objects.create(user=user, name='Mr Pattern', average_sales=5000, # NB: 20000 / 5000 => Ratio = 4 segment=act.segment, ) get_ct = ContentType.objects.get_for_model ct_contact = get_ct(Contact) ct_orga = get_ct(Organisation) efilter = EntityFilter.create('test-filter01', 'Ninja', Contact, is_custom=True) create_comp = partial(ActObjectivePatternComponent.objects.create, pattern=pattern) root01 = create_comp(name='Root01', success_rate=20, ctype=ct_contact, filter=efilter) create_comp(name='Root02', success_rate=50) create_comp(name='Child 01', success_rate=33, parent=root01) create_comp(name='Child 02', success_rate=10, parent=root01, ctype=ct_orga) self.assertNoFormError(self.client.post(self._build_addobjectivefrompattern_url(act), data={'pattern': pattern.id}, ) ) self.assertEqual(5, ActObjective.objects.filter(act=act).count()) with self.assertNoException(): objectives = act.objectives objective01 = objectives.get(name='Root01') objective02 = objectives.get(name='Root02') objective11 = objectives.get(name='Child 01') objective12 = objectives.get(name='Child 02') objective00 = objectives.exclude(pk__in=[objective01.id, objective02.id, objective11.id, objective12.id, ] )[0] self.assertTrue(all(o.counter == 0 for o in [objective00, objective01, objective02, objective11, objective12, ] ) ) # Content types self.assertIsNone(objective00.ctype_id) self.assertEqual(ct_contact, objective01.ctype) self.assertEqual(ct_orga, objective12.ctype) self.assertIsNone(objective02.ctype_id) self.assertIsNone(objective11.ctype_id) # Entity Filters self.assertIsNone(objective00.filter_id) self.assertEqual(efilter, objective01.filter) self.assertIsNone(objective12.filter_id) self.assertIsNone(objective02.filter_id) self.assertIsNone(objective11.filter_id) self.assertEqual(4, objective00.counter_goal) # ratio = 4 self.assertEqual(20, objective01.counter_goal) # 20% -> 4 * 5 self.assertEqual(8, objective02.counter_goal) # 50% -> 4 * 2 self.assertEqual(61, objective11.counter_goal) # 33% -> 20 * 3,3 self.assertEqual(200, objective12.counter_goal) # 10% -> 20 * 10
def populate(self): already_populated = RelationType.objects.filter(pk=constants.REL_SUB_BILL_ISSUED).exists() Contact = persons.get_contact_model() Organisation = persons.get_organisation_model() Product = products.get_product_model() Service = products.get_service_model() # --------------------------- # line_entities = [ProductLine, ServiceLine] line_entities = list(lines_registry) RelationType.create((constants.REL_SUB_BILL_ISSUED, _('issued by'), BILLING_MODELS), (constants.REL_OBJ_BILL_ISSUED, _('has issued'), [Organisation]), is_internal=True, minimal_display=(False, True), ) rt_sub_bill_received = \ RelationType.create((constants.REL_SUB_BILL_RECEIVED, _('received by'), BILLING_MODELS), (constants.REL_OBJ_BILL_RECEIVED, _('has received'), [Organisation, Contact]), is_internal=True, minimal_display=(False, True), )[0] RelationType.create((constants.REL_SUB_HAS_LINE, _('had the line'), BILLING_MODELS), (constants.REL_OBJ_HAS_LINE, _('is the line of'), line_entities), is_internal=True, minimal_display=(True, True), ) RelationType.create((constants.REL_SUB_LINE_RELATED_ITEM, _('has the related item'), line_entities), (constants.REL_OBJ_LINE_RELATED_ITEM, _('is the related item of'), [Product, Service]), is_internal=True, ) RelationType.create((constants.REL_SUB_CREDIT_NOTE_APPLIED, _('is used in the billing document'), [CreditNote]), (constants.REL_OBJ_CREDIT_NOTE_APPLIED, _('used the credit note'), [Quote, SalesOrder, Invoice]), is_internal=True, minimal_display=(True, True), ) if apps.is_installed('creme.activities'): logger.info('Activities app is installed => an Invoice/Quote/SalesOrder can be the subject of an Activity') from creme.activities.constants import REL_SUB_ACTIVITY_SUBJECT RelationType.objects.get(pk=REL_SUB_ACTIVITY_SUBJECT) \ .add_subject_ctypes(Invoice, Quote, SalesOrder) # --------------------------- create_if_needed(PaymentTerms, {'pk': 1}, name=_('Deposit'), description=_(r'20% deposit will be required'), is_custom=False, ) # --------------------------- # NB: pk=1 + is_custom=False --> default status (used when a quote is converted in invoice for example) create_if_needed(SalesOrderStatus, {'pk': 1}, name=pgettext('billing-salesorder', 'Issued'), order=1, is_custom=False) # Default status if not already_populated: create_if_needed(SalesOrderStatus, {'pk': 2}, name=pgettext('billing-salesorder', 'Accepted'), order=3) create_if_needed(SalesOrderStatus, {'pk': 3}, name=pgettext('billing-salesorder', 'Rejected'), order=4) create_if_needed(SalesOrderStatus, {'pk': 4}, name=pgettext('billing-salesorder', 'Created'), order=2) # --------------------------- def create_invoice_status(pk, name, **kwargs): create_if_needed(InvoiceStatus, {'pk': pk}, name=name, **kwargs) create_invoice_status(1, pgettext('billing-invoice', 'Draft'), order=1, is_custom=False) # Default status create_invoice_status(2, pgettext('billing-invoice', 'To be sent'), order=2, is_custom=False) if not already_populated: create_invoice_status(3, pgettext('billing-invoice', 'Sent'), order=3, pending_payment=True) create_invoice_status(4, pgettext('billing-invoice', 'Resulted'), order=5) create_invoice_status(5, pgettext('billing-invoice', 'Partly resulted'), order=4, pending_payment=True) create_invoice_status(6, _('Collection'), order=7) create_invoice_status(7, _('Resulted collection'), order=6) create_invoice_status(8, pgettext('billing-invoice', 'Canceled'), order=8) # --------------------------- create_if_needed(CreditNoteStatus, {'pk': 1}, name=pgettext('billing-creditnote', 'Draft'), order=1, is_custom=False) if not already_populated: create_if_needed(CreditNoteStatus, {'pk': 2}, name=pgettext('billing-creditnote', 'Issued'), order=2) create_if_needed(CreditNoteStatus, {'pk': 3}, name=pgettext('billing-creditnote', 'Consumed'), order=3) create_if_needed(CreditNoteStatus, {'pk': 4}, name=pgettext('billing-creditnote', 'Out of date'), order=4) # --------------------------- EntityFilter.create( 'billing-invoices_unpaid', name=_('Invoices unpaid'), model=Invoice, user='******', conditions=[EntityFilterCondition.build_4_field( model=Invoice, operator=EntityFilterCondition.EQUALS, name='status__pending_payment', values=[True], ), ], ) EntityFilter.create( 'billing-invoices_unpaid_late', name=_('Invoices unpaid and late'), model=Invoice, user='******', conditions=[EntityFilterCondition.build_4_field( model=Invoice, operator=EntityFilterCondition.EQUALS, name='status__pending_payment', values=[True], ), EntityFilterCondition.build_4_date( model=Invoice, name='expiration_date', date_range='in_past', ), ], ) current_year_invoice_filter = EntityFilter.create( 'billing-current_year_invoices', name=_('Current year invoices'), model=Invoice, user='******', conditions=[EntityFilterCondition.build_4_date( model=Invoice, name='issuing_date', date_range='current_year', ), ], ) current_year_unpaid_invoice_filter = EntityFilter.create( 'billing-current_year_unpaid_invoices', name=_('Current year and unpaid invoices'), model=Invoice, user='******', conditions=[EntityFilterCondition.build_4_date( model=Invoice, name='issuing_date', date_range='current_year', ), EntityFilterCondition.build_4_field( model=Invoice, operator=EntityFilterCondition.EQUALS, name='status__pending_payment', values=[True], ), ], ) # --------------------------- def create_hf(hf_pk, name, model, status=True): HeaderFilter.create(pk=hf_pk, name=name, model=model, cells_desc=[(EntityCellRegularField, {'name': 'name'}), EntityCellRelation(model=model, rtype=rt_sub_bill_received), (EntityCellRegularField, {'name': 'number'}), (EntityCellRegularField, {'name': 'status'}) if status else None, (EntityCellRegularField, {'name': 'total_no_vat'}), (EntityCellRegularField, {'name': 'issuing_date'}), (EntityCellRegularField, {'name': 'expiration_date'}), ], ) create_hf(constants.DEFAULT_HFILTER_INVOICE, _('Invoice view'), Invoice) create_hf(constants.DEFAULT_HFILTER_QUOTE, _('Quote view'), Quote) create_hf(constants.DEFAULT_HFILTER_ORDER, _('Sales order view'), SalesOrder) create_hf(constants.DEFAULT_HFILTER_CNOTE, _('Credit note view'), CreditNote) create_hf(constants.DEFAULT_HFILTER_TEMPLATE, _('Template view'), TemplateBase, status=False) def create_hf_lines(hf_pk, name, model): build_cell = EntityCellRegularField.build HeaderFilter.create(pk=hf_pk, name=name, model=model, cells_desc=[build_cell(model=model, name='on_the_fly_item'), build_cell(model=model, name='quantity'), build_cell(model=model, name='unit_price'), ] ) create_hf_lines('billing-hg_product_lines', _('Product lines view'), ProductLine) create_hf_lines('billing-hg_service_lines', _('Service lines view'), ServiceLine) # --------------------------- for model in (Invoice, CreditNote, Quote, SalesOrder): SearchConfigItem.create_if_needed(model, ['name', 'number', 'status__name']) for model in (ProductLine, ServiceLine): SearchConfigItem.create_if_needed(model, [], disabled=True) # --------------------------- SettingValue.objects.get_or_create(key_id=setting_keys.payment_info_key.id, defaults={'value': True}) # --------------------------- if not already_populated: create_if_needed(QuoteStatus, {'pk': 1}, name=pgettext('billing-quote', 'Pending'), order=2) # Default status create_if_needed(QuoteStatus, {'pk': 2}, name=pgettext('billing-quote', 'Accepted'), order=3, won=True) create_if_needed(QuoteStatus, {'pk': 3}, name=pgettext('billing-quote', 'Rejected'), order=4) create_if_needed(QuoteStatus, {'pk': 4}, name=pgettext('billing-quote', 'Created'), order=1) # --------------------------- create_if_needed(SettlementTerms, {'pk': 1}, name=_('30 days')) create_if_needed(SettlementTerms, {'pk': 2}, name=_('Cash')) create_if_needed(SettlementTerms, {'pk': 3}, name=_('45 days')) create_if_needed(SettlementTerms, {'pk': 4}, name=_('60 days')) create_if_needed(SettlementTerms, {'pk': 5}, name=_('30 days, end month the 10')) # --------------------------- create_if_needed(AdditionalInformation, {'pk': 1}, name=_('Trainer accreditation'), description=_('being certified trainer courses could be supported by your OPCA') ) # --------------------------- create_bmi = ButtonMenuItem.create_if_needed create_bmi(pk='billing-generate_invoice_number', model=Invoice, button=buttons.GenerateInvoiceNumberButton, order=0) create_bmi(pk='billing-quote_orga_button', model=Organisation, button=buttons.AddQuoteButton, order=100) create_bmi(pk='billing-salesorder_orga_button', model=Organisation, button=buttons.AddSalesOrderButton, order=101) create_bmi(pk='billing-invoice_orga_button', model=Organisation, button=buttons.AddInvoiceButton, order=102) create_bmi(pk='billing-quote_contact_button', model=Contact, button=buttons.AddQuoteButton, order=100) create_bmi(pk='billing-salesorder_contact_button', model=Contact, button=buttons.AddSalesOrderButton, order=101) create_bmi(pk='billing-invoice_contact_button', model=Contact, button=buttons.AddInvoiceButton, order=102) # --------------------------- get_ct = ContentType.objects.get_for_model create_cbci = CustomBrickConfigItem.objects.create build_cell = EntityCellRegularField.build def build_cells(model, *extra_cells): return [ build_cell(model, 'name'), build_cell(model, 'number'), build_cell(model, 'issuing_date'), build_cell(model, 'expiration_date'), build_cell(model, 'discount'), build_cell(model, 'additional_info'), build_cell(model, 'payment_terms'), build_cell(model, 'currency'), ] + list(extra_cells) + [ build_cell(model, 'comment'), # -- build_cell(model, 'created'), build_cell(model, 'modified'), build_cell(model, 'user'), ] cbci_invoice = create_cbci(id='billing-invoice_info', name=_('Invoice information'), content_type=get_ct(Invoice), cells=build_cells(Invoice, build_cell(Invoice, 'status'), build_cell(Invoice, 'payment_type'), ), ) cbci_c_note = create_cbci(id='billing-creditnote_info', name=_('Credit note information'), content_type=get_ct(CreditNote), cells=build_cells(CreditNote, build_cell(CreditNote, 'status')), ) cbci_quote = create_cbci(id='billing-quote_info', name=_('Quote information'), content_type=get_ct(Quote), cells=build_cells(Quote, build_cell(Quote, 'status'), build_cell(Quote, 'acceptation_date'), ), ) cbci_s_order = create_cbci(id='billing-salesorder_info', name=_('Salesorder information'), content_type=get_ct(SalesOrder), cells=build_cells(SalesOrder, build_cell(SalesOrder, 'status')), ) cbci_tbase = create_cbci(id='billing-templatebase_info', name=pgettext('billing', 'Template information'), content_type=get_ct(TemplateBase), cells=build_cells(TemplateBase, EntityCellFunctionField.build(TemplateBase, 'get_verbose_status'), ), ) models_4_blocks = [(Invoice, cbci_invoice, True), # Boolean -> insert CreditNote block (CreditNote, cbci_c_note, False), (Quote, cbci_quote, True), (SalesOrder, cbci_s_order, True), (TemplateBase, cbci_tbase, False), ] create_bdl = BrickDetailviewLocation.create_if_needed TOP = BrickDetailviewLocation.TOP LEFT = BrickDetailviewLocation.LEFT RIGHT = BrickDetailviewLocation.RIGHT for model, cbci, has_credit_notes in models_4_blocks: create_bdl(brick_id=bricks.ProductLinesBrick.id_, order=10, zone=TOP, model=model) create_bdl(brick_id=bricks.ServiceLinesBrick.id_, order=20, zone=TOP, model=model) if has_credit_notes: create_bdl(brick_id=bricks.CreditNotesBrick.id_, order=30, zone=TOP, model=model) create_bdl(brick_id=cbci.generate_id(), order=5, zone=LEFT, model=model) create_bdl(brick_id=core_bricks.CustomFieldsBrick.id_, order=40, zone=LEFT, model=model) create_bdl(brick_id=bricks.BillingPaymentInformationBrick.id_, order=60, zone=LEFT, model=model) create_bdl(brick_id=bricks.BillingPrettyAddressBrick.id_, order=70, zone=LEFT, model=model) create_bdl(brick_id=core_bricks.PropertiesBrick.id_, order=450, zone=LEFT, model=model) create_bdl(brick_id=core_bricks.RelationsBrick.id_, order=500, zone=LEFT, model=model) create_bdl(brick_id=bricks.TargetBrick.id_, order=2, zone=RIGHT, model=model) create_bdl(brick_id=bricks.TotalBrick.id_, order=3, zone=RIGHT, model=model) create_bdl(brick_id=core_bricks.HistoryBrick.id_, order=20, zone=RIGHT, model=model) if apps.is_installed('creme.assistants'): logger.info('Assistants app is installed => we use the assistants blocks on detail views') from creme.assistants.bricks import AlertsBrick, MemosBrick, TodosBrick, UserMessagesBrick for t in models_4_blocks: model = t[0] create_bdl(brick_id=TodosBrick.id_, order=100, zone=RIGHT, model=model) create_bdl(brick_id=MemosBrick.id_, order=200, zone=RIGHT, model=model) create_bdl(brick_id=AlertsBrick.id_, order=300, zone=RIGHT, model=model) create_bdl(brick_id=UserMessagesBrick.id_, order=400, zone=RIGHT, model=model) if apps.is_installed('creme.documents'): # logger.info('Documents app is installed => we use the documents block on detail views') from creme.documents.bricks import LinkedDocsBrick for t in models_4_blocks: create_bdl(brick_id=LinkedDocsBrick.id_, order=600, zone=RIGHT, model=t[0]) create_bdl(brick_id=bricks.PaymentInformationBrick.id_, order=300, zone=LEFT, model=Organisation) create_bdl(brick_id=bricks.ReceivedInvoicesBrick.id_, order=14, zone=RIGHT, model=Organisation) create_bdl(brick_id=bricks.ReceivedQuotesBrick.id_, order=18, zone=RIGHT, model=Organisation) # --------------------------- if apps.is_installed('creme.reports'): logger.info('Reports app is installed => we create 2 billing reports, with 3 graphs, and related blocks in home') self.create_reports(rt_sub_bill_received, current_year_invoice_filter, current_year_unpaid_invoice_filter, )
def test_actobjectivepattern_clone01(self): pattern = self._create_pattern() ct_contact = ContentType.objects.get_for_model(FakeContact) ct_orga = ContentType.objects.get_for_model(FakeOrganisation) efilter = EntityFilter.create('test-filter01', 'Ninja', FakeContact, is_custom=True) create_comp = partial( ActObjectivePatternComponent.objects.create, pattern=pattern, success_rate=1, ) comp1 = create_comp(name='1', ctype=ct_orga) comp11 = create_comp(name='1.1', parent=comp1, success_rate=20, ctype=ct_contact) __ = create_comp(name='1.1.1', parent=comp11) __ = create_comp(name='1.1.2', parent=comp11) comp12 = create_comp(name='1.2', parent=comp1, ctype=ct_contact, filter=efilter) __ = create_comp(name='1.2.1', parent=comp12) __ = create_comp(name='1.2.2', parent=comp12) comp2 = create_comp(name='2', success_rate=50) comp21 = create_comp(name='2.1', parent=comp2) __ = create_comp(name='2.1.1', parent=comp21) __ = create_comp(name='2.1.2', parent=comp21) comp22 = create_comp(name='2.2', parent=comp2) __ = create_comp(name='2.2.1', parent=comp22) __ = create_comp(name='2.2.2', parent=comp22) cloned_pattern = pattern.clone() filter_comp = partial(ActObjectivePatternComponent.objects.filter, pattern=cloned_pattern) self.assertEqual(14, filter_comp().count()) cloned_comp1 = self.get_object_or_fail( ActObjectivePatternComponent, pattern=cloned_pattern, name=comp1.name, ) self.assertIsNone(cloned_comp1.parent) self.assertEqual(1, cloned_comp1.success_rate) self.assertEqual(ct_orga, cloned_comp1.ctype) self.assertIsNone(cloned_comp1.filter) with self.assertNoException(): cloned_comp11, cloned_comp12 = cloned_comp1.children.all() self.assertEqual(ct_contact, cloned_comp11.ctype) self.assertEqual(efilter, cloned_comp12.filter) self.assertCompNamesEqual(filter_comp(parent__name__in=['1.1', '1.2']), '1.1.1', '1.1.2', '1.2.1', '1.2.2') cloned_comp2 = self.get_object_or_fail( ActObjectivePatternComponent, pattern=cloned_pattern, name=comp2.name, ) self.assertIsNone(cloned_comp2.parent) self.assertEqual(50, cloned_comp2.success_rate) self.assertIsNone(cloned_comp2.ctype) self.assertIsNone(cloned_comp1.filter) self.assertCompNamesEqual(cloned_comp2.children, '2.1', '2.2') self.assertCompNamesEqual(filter_comp(parent__name__in=['2.1', '2.2']), '2.1.1', '2.1.2', '2.2.1', '2.2.2')
def populate(self): already_populated = core_models.RelationType.objects.filter( pk=constants.REL_SUB_EMPLOYED_BY).exists() Contact = persons.get_contact_model() Organisation = persons.get_organisation_model() rt_map = {} for rt_info in [ ( (constants.REL_SUB_EMPLOYED_BY, _('is an employee of'), [Contact]), (constants.REL_OBJ_EMPLOYED_BY, _('employs'), [Organisation]), ), ( (constants.REL_SUB_CUSTOMER_SUPPLIER, _('is a customer of'), [Contact, Organisation]), (constants.REL_OBJ_CUSTOMER_SUPPLIER, _('is a supplier of'), [Contact, Organisation]), ), ( (constants.REL_SUB_MANAGES, _('manages'), [Contact]), (constants.REL_OBJ_MANAGES, _('managed by'), [Organisation]), ), ( (constants.REL_SUB_PROSPECT, _('is a prospect of'), [Contact, Organisation]), (constants.REL_OBJ_PROSPECT, _('has as prospect'), [Contact, Organisation]), ), ( (constants.REL_SUB_SUSPECT, _('is a suspect of'), [Contact, Organisation]), (constants.REL_OBJ_SUSPECT, _('has as suspect'), [Contact, Organisation]), ), ( (constants.REL_SUB_PARTNER, _('is a partner of'), [Contact, Organisation]), (constants.REL_OBJ_PARTNER, _('has as partner'), [Contact, Organisation]), ), ( (constants.REL_SUB_INACTIVE, _('is an inactive customer of'), [Contact, Organisation]), (constants.REL_OBJ_INACTIVE, _('has as inactive customer'), [Contact, Organisation]), ), ( (constants.REL_SUB_SUBSIDIARY, _('has as subsidiary'), [Organisation]), (constants.REL_OBJ_SUBSIDIARY, _('is a subsidiary of'), [Organisation]), ), ( (constants.REL_SUB_COMPETITOR, _('is a competitor of'), [Contact, Organisation]), (constants.REL_OBJ_COMPETITOR, _('has as competitor'), [Contact, Organisation]), ), ]: rt, sym_rt = core_models.RelationType.create(*rt_info) rt_map[rt.id] = rt rt_map[sym_rt.id] = sym_rt # --------------------------- EntityFilter.create( constants.FILTER_MANAGED_ORGA, name=_('Managed by creme'), model=Organisation, user='******', conditions=[ # EntityFilterCondition.build_4_field( # model=Organisation, # operator=EntityFilterCondition.EQUALS, # name='is_managed', # values=[True], # ), condition_handler.RegularFieldConditionHandler.build_condition( model=Organisation, operator=operators.EqualsOperator, field_name='is_managed', values=[True], ), ], ) EntityFilter.create( constants.FILTER_CONTACT_ME, name=_('Me'), model=Contact, user='******', conditions=[ # EntityFilterCondition.build_4_field( # model=Contact, # operator=EntityFilterCondition.EQUALS, # name='is_user', # values=[EntityFilterVariable.CURRENT_USER], # ), condition_handler.RegularFieldConditionHandler.build_condition( model=Contact, operator=operators.EqualsOperator, field_name='is_user', values=[operands.CurrentUserOperand.type_id], ), ], ) # --------------------------- create_hf = core_models.HeaderFilter.create create_hf( pk=constants.DEFAULT_HFILTER_CONTACT, model=Contact, name=_('Contact view'), cells_desc=[ (EntityCellRegularField, { 'name': 'last_name' }), (EntityCellRegularField, { 'name': 'first_name' }), (EntityCellRegularField, { 'name': 'phone' }), (EntityCellRegularField, { 'name': 'email' }), (EntityCellRegularField, { 'name': 'user' }), EntityCellRelation( model=Contact, rtype=rt_map[constants.REL_SUB_EMPLOYED_BY]), ], ) create_hf( pk=constants.DEFAULT_HFILTER_ORGA, model=Organisation, name=_('Organisation view'), cells_desc=[ (EntityCellRegularField, { 'name': 'name' }), (EntityCellRegularField, { 'name': 'phone' }), (EntityCellRegularField, { 'name': 'user' }), EntityCellRelation(model=Organisation, rtype=rt_map[constants.REL_OBJ_MANAGES]), ], ) create_hf( pk=constants.DEFAULT_HFILTER_ORGA_CUSTOMERS, model=Organisation, name=_('Prospect/Suspect view'), cells_desc=[ (EntityCellRegularField, { 'name': 'name' }), (EntityCellRegularField, { 'name': 'sector' }), (EntityCellRegularField, { 'name': 'phone' }), (EntityCellRegularField, { 'name': 'email' }), (EntityCellRegularField, { 'name': 'user' }), EntityCellRelation( model=Organisation, rtype=rt_map[constants.REL_SUB_CUSTOMER_SUPPLIER]), EntityCellRelation(model=Organisation, rtype=rt_map[constants.REL_SUB_PROSPECT]), EntityCellRelation(model=Organisation, rtype=rt_map[constants.REL_SUB_SUSPECT]), ], ) # --------------------------- create_sci = core_models.SearchConfigItem.create_if_needed create_sci(Contact, ['last_name', 'first_name', 'phone', 'mobile', 'email']) create_sci( Organisation, ['name', 'phone', 'email', 'sector__title', 'legal_form__title']) # --------------------------- if not already_populated: create_if_needed(Civility, {'pk': 1}, title=_('Madam'), shortcut=_('Mrs.')) create_if_needed(Civility, {'pk': 2}, title=_('Miss'), shortcut=_('Ms.')) create_if_needed(Civility, {'pk': 3}, title=_('Mister'), shortcut=_('Mr.')) create_if_needed(Civility, {'pk': 4}, title=_('N/A'), shortcut='') # --------------------------- # TODO: add relation to admin ???? if not Organisation.objects.exists(): Organisation.objects.create( user=get_user_model().objects.get_admin(), name=_('ReplaceByYourSociety'), is_managed=True, uuid=constants.UUID_FIRST_ORGA, ) # --------------------------- create_if_needed(Position, {'pk': 1}, title=_('CEO')) create_if_needed(Position, {'pk': 2}, title=_('Secretary')) create_if_needed(Position, {'pk': 3}, title=_('Technician')) # --------------------------- create_if_needed(Sector, {'pk': 1}, title=_('Food Industry')) create_if_needed(Sector, {'pk': 2}, title=_('Industry')) create_if_needed(Sector, {'pk': 3}, title=_('Software')) create_if_needed(Sector, {'pk': 4}, title=_('Telecom')) create_if_needed(Sector, {'pk': 5}, title=_('Restoration')) # --------------------------- # TODO: depend on the country no ?? create_if_needed(LegalForm, {'pk': 1}, title='SARL') create_if_needed(LegalForm, {'pk': 2}, title='Association loi 1901') create_if_needed(LegalForm, {'pk': 3}, title='SA') create_if_needed(LegalForm, {'pk': 4}, title='SAS') # --------------------------- create_if_needed(StaffSize, {'pk': 1}, size='1 - 5', order=1) create_if_needed(StaffSize, {'pk': 2}, size='6 - 10', order=2) create_if_needed(StaffSize, {'pk': 3}, size='11 - 50', order=3) create_if_needed(StaffSize, {'pk': 4}, size='51 - 100', order=4) create_if_needed(StaffSize, {'pk': 5}, size='100 - 500', order=5) create_if_needed(StaffSize, {'pk': 6}, size='> 500', order=6) # --------------------------- create_bmi = core_models.ButtonMenuItem.create_if_needed create_bmi(pk='persons-customer_contact_button', model=Contact, button=buttons.BecomeCustomerButton, order=20) create_bmi(pk='persons-prospect_contact_button', model=Contact, button=buttons.BecomeProspectButton, order=21) create_bmi(pk='persons-suspect_contact_button', model=Contact, button=buttons.BecomeSuspectButton, order=22) create_bmi(pk='persons-inactive_contact_button', model=Contact, button=buttons.BecomeInactiveButton, order=24) create_bmi(pk='persons-customer_orga_button', model=Organisation, button=buttons.BecomeCustomerButton, order=20) create_bmi(pk='persons-prospect_orga_button', model=Organisation, button=buttons.BecomeProspectButton, order=21) create_bmi(pk='persons-suspect_orga_button', model=Organisation, button=buttons.BecomeSuspectButton, order=22) create_bmi(pk='persons-inactive_orga_button', model=Organisation, button=buttons.BecomeInactiveButton, order=23) create_bmi(pk='persons-supplier_button', model=Organisation, button=buttons.BecomeSupplierButton, order=24) create_bmi(pk='persons-linked_contact_button', model=Organisation, button=buttons.AddLinkedContactButton, order=25) # Populate bricks ------------------ create_rbi = core_models.RelationBrickItem.objects.create_if_needed rbi_1 = create_rbi(constants.REL_SUB_CUSTOMER_SUPPLIER) rbi_2 = create_rbi(constants.REL_OBJ_CUSTOMER_SUPPLIER) create_cbci = core_models.CustomBrickConfigItem.objects.create build_cell = EntityCellRegularField.build # cbci_orga_1 = create_cbci( id='persons-organisation_main_info', name=_('Organisation information'), content_type=Organisation, cells=[ build_cell(Organisation, 'name'), build_cell(Organisation, 'is_managed'), build_cell(Organisation, 'staff_size'), build_cell(Organisation, 'legal_form'), build_cell(Organisation, 'sector'), build_cell(Organisation, 'capital'), build_cell(Organisation, 'siren'), build_cell(Organisation, 'naf'), build_cell(Organisation, 'siret'), build_cell(Organisation, 'rcs'), build_cell(Organisation, 'tvaintra'), build_cell(Organisation, 'subject_to_vat'), build_cell(Organisation, 'annual_revenue'), build_cell(Organisation, 'creation_date'), build_cell(Organisation, 'image'), # -- build_cell(Organisation, 'description'), # -- build_cell(Organisation, 'created'), build_cell(Organisation, 'modified'), build_cell(Organisation, 'user'), ], ) # cbci_orga_2 = create_cbci( id='persons-organisation_details', name=_('Organisation details'), content_type=Organisation, cells=[ build_cell(Organisation, 'phone'), build_cell(Organisation, 'fax'), build_cell(Organisation, 'email'), build_cell(Organisation, 'url_site'), ], ) cbci_orga_extra = create_cbci( id='persons-organisation_complementary', name=_('Organisation complementary information'), content_type=Organisation, cells=[ build_cell(Organisation, 'staff_size'), build_cell(Organisation, 'sector'), build_cell(Organisation, 'capital'), build_cell(Organisation, 'siren'), build_cell(Organisation, 'naf'), build_cell(Organisation, 'siret'), build_cell(Organisation, 'rcs'), build_cell(Organisation, 'tvaintra'), build_cell(Organisation, 'subject_to_vat'), build_cell(Organisation, 'annual_revenue'), build_cell(Organisation, 'creation_date'), build_cell(Organisation, 'image'), # -- build_cell(Organisation, 'description'), # -- build_cell(Organisation, 'fax'), build_cell(Organisation, 'email'), build_cell(Organisation, 'url_site'), ], ) HAT = core_models.BrickDetailviewLocation.HAT LEFT = core_models.BrickDetailviewLocation.LEFT RIGHT = core_models.BrickDetailviewLocation.RIGHT create_bdl = core_models.BrickDetailviewLocation.objects.create_if_needed create_bdl(brick=bricks.OrganisationCardHatBrick, order=1, zone=HAT, model=Organisation) create_bdl(brick=cbci_orga_extra.generate_id(), order=5, zone=LEFT, model=Organisation) create_bdl(brick=core_bricks.CustomFieldsBrick, order=40, zone=LEFT, model=Organisation) create_bdl(brick=bricks.PrettyAddressesBrick, order=50, zone=LEFT, model=Organisation) create_bdl(brick=bricks.PrettyOtherAddressesBrick, order=60, zone=LEFT, model=Organisation) create_bdl(brick=bricks.ManagersBrick, order=100, zone=LEFT, model=Organisation) create_bdl(brick=bricks.EmployeesBrick, order=120, zone=LEFT, model=Organisation) create_bdl(brick=core_bricks.PropertiesBrick, order=450, zone=LEFT, model=Organisation) create_bdl(brick=core_bricks.RelationsBrick, order=500, zone=LEFT, model=Organisation) create_bdl(brick=rbi_1.brick_id, order=5, zone=RIGHT, model=Organisation) create_bdl(brick=rbi_2.brick_id, order=10, zone=RIGHT, model=Organisation) create_bdl(brick=core_bricks.HistoryBrick, order=30, zone=RIGHT, model=Organisation) create_cbci( id='persons-contact_main_info', name=_('Contact information'), content_type=Contact, cells=[ build_cell(Contact, 'civility'), build_cell(Contact, 'first_name'), build_cell(Contact, 'last_name'), build_cell(Contact, 'sector'), build_cell(Contact, 'position'), build_cell(Contact, 'full_position'), build_cell(Contact, 'is_user'), build_cell(Contact, 'birthday'), build_cell(Contact, 'image'), # -- build_cell(Contact, 'description'), # -- build_cell(Contact, 'created'), build_cell(Contact, 'modified'), build_cell(Contact, 'user'), ], ) create_cbci( id='persons-contact_details', name=_('Contact details'), content_type=Contact, cells=[ build_cell(Contact, 'phone'), build_cell(Contact, 'mobile'), build_cell(Contact, 'fax'), build_cell(Contact, 'email'), build_cell(Contact, 'url_site'), build_cell(Contact, 'skype'), ], ) cbci_contact_extra = create_cbci( id='persons-contact_complementary', name=_('Contact complementary information'), content_type=Contact, cells=[ build_cell(Contact, 'sector'), build_cell(Contact, 'full_position'), build_cell(Contact, 'birthday'), build_cell(Contact, 'image'), # -- build_cell(Contact, 'description'), # -- build_cell(Contact, 'fax'), build_cell(Contact, 'url_site'), build_cell(Contact, 'skype'), ], ) create_bdl(brick=bricks.ContactCardHatBrick, order=1, zone=HAT, model=Contact) create_bdl(brick=cbci_contact_extra.generate_id(), order=30, zone=LEFT, model=Contact) create_bdl(brick=core_bricks.CustomFieldsBrick, order=40, zone=LEFT, model=Contact) create_bdl(brick=bricks.PrettyAddressesBrick, order=50, zone=LEFT, model=Contact) create_bdl(brick=bricks.PrettyOtherAddressesBrick, order=60, zone=LEFT, model=Contact) create_bdl(brick=core_bricks.PropertiesBrick, order=450, zone=LEFT, model=Contact) create_bdl(brick=core_bricks.RelationsBrick, order=500, zone=LEFT, model=Contact) create_bdl(brick=core_bricks.HistoryBrick, order=20, zone=RIGHT, model=Contact) if apps.is_installed('creme.assistants'): logger.info( 'Assistants app is installed => we use the assistants blocks on detail views and portal' ) from creme.assistants import bricks as a_bricks create_bdl(brick=a_bricks.TodosBrick, order=100, zone=RIGHT, model=Contact) create_bdl(brick=a_bricks.MemosBrick, order=200, zone=RIGHT, model=Contact) create_bdl(brick=a_bricks.AlertsBrick, order=300, zone=RIGHT, model=Contact) create_bdl(brick=a_bricks.UserMessagesBrick, order=500, zone=RIGHT, model=Contact) create_bdl(brick=a_bricks.TodosBrick, order=100, zone=RIGHT, model=Organisation) create_bdl(brick=a_bricks.MemosBrick, order=200, zone=RIGHT, model=Organisation) create_bdl(brick=a_bricks.AlertsBrick, order=300, zone=RIGHT, model=Organisation) create_bdl(brick=a_bricks.UserMessagesBrick, order=500, zone=RIGHT, model=Organisation) if apps.is_installed('creme.documents'): # logger.info('Documents app is installed => we use the documents block on detail views') from creme.documents.bricks import LinkedDocsBrick create_bdl(brick=LinkedDocsBrick, order=600, zone=RIGHT, model=Contact) create_bdl(brick=LinkedDocsBrick, order=600, zone=RIGHT, model=Organisation) if apps.is_installed('creme.activities'): core_models.BrickHomeLocation.objects.create( brick_id=bricks.NeglectedOrganisationsBrick.id_, order=15)
def test_create02(self): user = self.login() lv_url = FakeContact.get_lv_absolute_url() # Create a view to post the entity filter HeaderFilter.create( pk='creme_core-tests_views_header_filter_test_create02', name='A FakeContact view', # Starts with "A" => first model=FakeContact, cells_desc=[ (EntityCellRegularField, { 'name': 'last_name' }), (EntityCellRegularField, { 'name': 'first_name' }), (EntityCellRegularField, { 'name': 'email' }), ], ) # Set a filter in the session (should be kept) efilter = EntityFilter.create( 'creme_core-tests_views_header_filter_test_create02', name='Misato', model=FakeContact, is_custom=True, conditions=[ # EntityFilterCondition.build_4_field( # model=FakeContact, # operator=EntityFilterCondition.EQUALS, # name='first_name', values=['Misato'], # ), RegularFieldConditionHandler.build_condition( model=FakeContact, field_name='first_name', operator=EQUALS, values=['Misato'], ), ], ) response = self.assertPOST200(lv_url, data={'filter': efilter.id}) self.assertEqual(efilter.id, response.context['list_view_state'].entity_filter_id) # -- ct = self.contact_ct loves = RelationType.create(('test-subject_love', 'Is loving'), ('test-object_love', 'Is loved by'))[0] customfield = CustomField.objects.create( name='Size (cm)', field_type=CustomField.INT, content_type=ct, ) # funcfield = FakeContact.function_fields.get('get_pretty_properties') funcfield = function_field_registry.get(FakeContact, 'get_pretty_properties') url = self._build_add_url(ct) response = self.assertGET200(url) with self.assertNoException(): cells_f = response.context['form'].fields['cells'] build_4_field = partial(EntityCellRegularField.build, model=FakeContact) self.assertCellsEqual([ build_4_field(name='first_name'), build_4_field(name='last_name'), EntityCellRelation( model=FakeContact, rtype=RelationType.objects.get(pk=FAKE_REL_SUB_EMPLOYED_BY), ), ], cells_f.initial) field_name = 'first_name' name = 'DefaultHeaderFilter' response = self.client.post(url, follow=True, data={ 'name': name, 'user': user.id, 'is_private': 'on', 'cells': 'relation-{rtype},' 'regular_field-{rfield},' 'function_field-{ffield},' 'custom_field-{cfield}'.format( rfield=field_name, cfield=customfield.id, rtype=loves.id, ffield=funcfield.name, ) }) self.assertNoFormError(response) hfilter = self.get_object_or_fail(HeaderFilter, name=name) self.assertEqual(user, hfilter.user) self.assertTrue(hfilter.is_private) cells = hfilter.cells self.assertEqual(4, len(cells)) cell = cells[0] self.assertIsInstance(cell, EntityCellRelation) self.assertEqual(loves.id, cell.value) cell = cells[1] self.assertIsInstance(cell, EntityCellRegularField) self.assertEqual(field_name, cell.value) cell = cells[2] self.assertIsInstance(cell, EntityCellFunctionField) self.assertEqual(funcfield.name, cell.value) cell = cells[3] self.assertIsInstance(cell, EntityCellCustomField) self.assertEqual(str(customfield.id), cell.value) self.assertRedirects(response, lv_url) # -- context = self.assertGET200(lv_url).context selected_hfilter = context['header_filters'].selected self.assertIsInstance(selected_hfilter, HeaderFilter) self.assertEqual(hfilter.id, selected_hfilter.id) lvs = context['list_view_state'] self.assertEqual(hfilter.id, lvs.header_filter_id) self.assertEqual(efilter.id, lvs.entity_filter_id)
def test_model_error(self): user = self.login() description = 'Genshiken member' efilter = EntityFilter.create( 'test-filter01', 'Belongs to Genshiken', FakeContact, is_custom=True, conditions=[ EntityFilterCondition.build_4_field( model=FakeContact, operator=EntityFilterCondition.EQUALS, name='description', values=[description], ) ], ) first_name = 'Kanako' last_name = 'Ouno' create_contact = partial(FakeContact.objects.create, user=user, description=description) contact01 = create_contact(first_name=first_name, last_name=last_name) create_contact(first_name='Mitsunori', last_name='Kugayama') with self.assertRaises(ValidationError): contact01.last_name = '' contact01.full_clean() response = self.client.post( self._build_add_url(FakeContact), follow=True, data={ 'filter': efilter.id, 'actions': json_dump([ self.build_formfield_entry(name='last_name', operator='rm_start', value=6), self.build_formfield_entry(name='first_name', operator='upper', value=''), ]), }) self.assertNoFormError(response) job = self._get_job(response) batch_process_type.execute(job) contact01 = self.refresh(contact01) self.assertEqual(last_name, contact01.last_name) # No change !! self.assertEqual( first_name, contact01.first_name ) # TODO: make the changes that are possible (u'KANAKO') ?? jresult = self.get_object_or_fail(EntityJobResult, job=job, entity=contact01) self.assertEqual([ u'{} => {}'.format(_('Last name'), _(u'This field cannot be blank.')) ], jresult.messages) self.assertEqual([ ungettext(u'{count} entity has been successfully modified.', u'{count} entities have been successfully modified.', 1).format(count=1), ], job.stats)