Пример #1
0
    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)  # <===
Пример #2
0
    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()})
Пример #3
0
    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'])
Пример #4
0
    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.')
        )
Пример #5
0
    def __init__(self, entity, *args, **kwargs):
        # super(ObjectiveForm, self).__init__(*args, **kwargs)
        super().__init__(*args, **kwargs)
        self.act = entity

        instance = self.instance
        if instance.pk:  # Edition
            fields = self.fields
            efilter = instance.filter

            # TODO: add a method EntityFilter.can_list(self.user) to avoid a query
            # if efilter and not efilter.can_view(self.user)[0]:
            if efilter and not EntityFilter.get_for_user(self.user, content_type=instance.ctype)\
                                           .filter(id=efilter.id).exists():
                fields['ec_label'] = CharField(
                    label=fields['entity_counting'].label,
                    required=False,
                    widget=Label,
                    initial=_(
                        'The filter cannot be changed because it is private.'),
                )
                del fields['entity_counting']
            else:
                fields[
                    'entity_counting'].initial = instance.ctype_id, instance.filter_id
Пример #6
0
    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])
Пример #7
0
    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)
Пример #8
0
    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))
Пример #9
0
    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)
Пример #10
0
    def __init__(self, entity, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.ml = entity

        ct = ContentType.objects.get_for_model(self.person_model)
        self.fields['filters'].queryset = EntityFilter.get_for_user(
            self.user, ct)
Пример #11
0
    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)
Пример #12
0
    def __init__(self, model, field, user, entities, is_bulk=False, **kwargs):
        super().__init__(model,
                         field,
                         user,
                         entities,
                         is_bulk=is_bulk,
                         **kwargs)

        filter_field = self.fields['field_value']
        filter_field.empty_label = _('All')

        first_ct = entities[0].ct if entities else None
        self._has_same_report_ct = all(e.ct == first_ct for e in entities)
        self._uneditable_ids = set()

        if self._has_same_report_ct:
            user = self.user
            filter_field.queryset = EntityFilter.get_for_user(user, first_ct)

            self._uneditable_ids = uneditable_ids = {
                e.id
                for e in entities
                if e.filter and not e.filter.can_view(user)[0]
            }

            if uneditable_ids:
                length = len(uneditable_ids)

                if length == len(entities):
                    self.fields['field_value'] = CharField(
                        label=filter_field.label,
                        required=False,
                        widget=Label,
                        initial=ngettext(
                            'The filter cannot be changed because it is private.',
                            'The filters cannot be changed because they are private.',
                            length),
                    )
                else:
                    self.fields['beware'] = CharField(
                        label=_('Beware !'),
                        required=False,
                        widget=Label,
                        initial=ngettext(
                            'The filter of {count} report cannot be changed because it is private.',
                            'The filters of {count} reports cannot be changed because they are private.',
                            length).format(count=length),
                    )
        else:
            filter_field.help_text = _(
                'Filter field can only be updated when '
                'reports target the same type of entities (e.g: only contacts).'
            )
            filter_field.widget = Label(empty_label='')
            filter_field.value = None
Пример #13
0
    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
Пример #14
0
    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),
        )
Пример #15
0
    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)
        )
Пример #16
0
    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
Пример #17
0
    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())
Пример #18
0
    def get_filter_choices(self, user, *models):
        choices = []
        get_ct = ContentType.objects.get_for_model
        ctypes = [get_ct(model) for model in models]
        efilters_per_ctid = defaultdict(list)

        for efilter in EntityFilter.get_for_user(user, ctypes):
            efilters_per_ctid[efilter.entity_type_id].append(efilter)

        for ct in ctypes:
            efilters = efilters_per_ctid[ct.id]

            if efilters:
                title = str(ct.model_class()._meta.verbose_name_plural)
                choices.append(
                    (title, [(ef.id, u'{} - {}'.format(title, ef.name))
                             for ef in efilters]))

        return choices
Пример #19
0
    def save(self, *args, **kwargs):
        instance = self.instance
        conditions = self.get_cleaned_conditions()
        efilter = instance.efilter

        if conditions:
            role = instance.role
            cdata = self.cleaned_data
            name = cdata['name']
            use_or = cdata['use_or']
            ctype = instance.ctype or ContentType.objects.get_for_model(
                CremeEntity)

            if efilter is None:
                efilter = EntityFilter(
                    name=name,
                    entity_type=ctype,
                    filter_type=self.efilter_type,
                    use_or=use_or,
                )
                generate_string_id_and_save(
                    EntityFilter,
                    [efilter],
                    f'creme_core-credentials_{role.id}-',
                )
                instance.efilter = efilter
            else:
                update_model_instance(
                    efilter,
                    entity_type=ctype,
                    name=name,
                    use_or=use_or,
                )

            efilter.set_conditions(
                conditions,
                check_cycles=
                False,  # There cannot be a cycle without sub-filter.
                check_privacy=False,  # No sense here.
            )
            super().save(*args, **kwargs)
        elif efilter:
            instance.efilter = None
            super().save(*args, **kwargs)
            efilter.delete()
        else:
            super().save(*args, **kwargs)

        return instance
Пример #20
0
    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))
Пример #21
0
    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'])
Пример #22
0
    def populate(self):
        already_populated = RelationType.objects.filter(
            pk=constants.REL_SUB_LINKED_2_ACTIVITY).exists()

        Contact = persons.get_contact_model()
        Organisation = persons.get_organisation_model()

        Activity = get_activity_model()

        # ---------------------------
        create_rtype = RelationType.create
        create_rtype(
            (constants.REL_SUB_LINKED_2_ACTIVITY,
             _('related to the activity')),
            (constants.REL_OBJ_LINKED_2_ACTIVITY, _('(activity) related to'),
             [Activity]),
            minimal_display=(True, False),
        )
        rt_obj_activity_subject = create_rtype(
            (constants.REL_SUB_ACTIVITY_SUBJECT,
             _('is subject of the activity'), [Contact, Organisation]),
            (constants.REL_OBJ_ACTIVITY_SUBJECT,
             _('(activity) has for subject'), [Activity]),
            minimal_display=(True, False),
        )[1]
        rt_obj_part_2_activity = create_rtype(
            (constants.REL_SUB_PART_2_ACTIVITY,
             _('participates to the activity'), [Contact]),
            (constants.REL_OBJ_PART_2_ACTIVITY,
             _('(activity) has as participant'), [Activity]),
            is_internal=True,
            minimal_display=(True, False),
        )[1]

        # ---------------------------
        create_if_needed(Status, {'pk': constants.STATUS_PLANNED},
                         name=pgettext('activities-status', 'Planned'),
                         description=pgettext('activities-status', 'Planned'),
                         is_custom=False)
        create_if_needed(Status, {'pk': constants.STATUS_IN_PROGRESS},
                         name=pgettext('activities-status', 'In progress'),
                         description=pgettext('activities-status',
                                              'In progress'),
                         is_custom=False)
        create_if_needed(Status, {'pk': constants.STATUS_DONE},
                         name=pgettext('activities-status', 'Done'),
                         description=pgettext('activities-status', 'Done'),
                         is_custom=False)
        create_if_needed(Status, {'pk': constants.STATUS_DELAYED},
                         name=pgettext('activities-status', 'Delayed'),
                         description=pgettext('activities-status', 'Delayed'),
                         is_custom=False)
        create_if_needed(Status, {'pk': constants.STATUS_CANCELLED},
                         name=pgettext('activities-status', 'Cancelled'),
                         description=pgettext('activities-status',
                                              'Cancelled'),
                         is_custom=False)

        # ---------------------------
        create_if_needed(ActivityType, {'pk': constants.ACTIVITYTYPE_TASK},
                         name=_('Task'),
                         default_day_duration=0,
                         default_hour_duration="00:15:00",
                         is_custom=False)
        meeting_type = \
        create_if_needed(ActivityType, {'pk': constants.ACTIVITYTYPE_MEETING},   name=_('Meeting'),        default_day_duration=0, default_hour_duration="00:15:00", is_custom=False)
        phone_call_type = \
        create_if_needed(ActivityType, {'pk': constants.ACTIVITYTYPE_PHONECALL}, name=_('Phone call'),     default_day_duration=0, default_hour_duration="00:15:00", is_custom=False)
        create_if_needed(ActivityType,
                         {'pk': constants.ACTIVITYTYPE_GATHERING},
                         name=_('Gathering'),
                         default_day_duration=0,
                         default_hour_duration="00:15:00",
                         is_custom=False)
        create_if_needed(ActivityType, {'pk': constants.ACTIVITYTYPE_SHOW},
                         name=_('Show'),
                         default_day_duration=1,
                         default_hour_duration="00:00:00",
                         is_custom=False)
        create_if_needed(ActivityType, {'pk': constants.ACTIVITYTYPE_DEMO},
                         name=_('Demonstration'),
                         default_day_duration=0,
                         default_hour_duration="01:00:00",
                         is_custom=False)
        create_if_needed(ActivityType, {'pk': constants.ACTIVITYTYPE_INDISPO},
                         name=_('Unavailability'),
                         default_day_duration=1,
                         default_hour_duration="00:00:00",
                         is_custom=False)

        create_if_needed(ActivitySubType,
                         {'pk': constants.ACTIVITYSUBTYPE_MEETING_MEETING},
                         name=_('Meeting'),
                         type=meeting_type,
                         is_custom=False)
        create_if_needed(
            ActivitySubType,
            {'pk': constants.ACTIVITYSUBTYPE_MEETING_QUALIFICATION},
            name=_('Qualification'),
            type=meeting_type,
            is_custom=False)
        create_if_needed(ActivitySubType,
                         {'pk': constants.ACTIVITYSUBTYPE_MEETING_REVIVAL},
                         name=_('Revival'),
                         type=meeting_type,
                         is_custom=False)
        create_if_needed(ActivitySubType,
                         {'pk': constants.ACTIVITYSUBTYPE_MEETING_NETWORK},
                         name=_('Network'),
                         type=meeting_type,
                         is_custom=False)
        create_if_needed(ActivitySubType,
                         {'pk': constants.ACTIVITYSUBTYPE_MEETING_OTHER},
                         name=pgettext('activities-meeting', 'Other'),
                         type=meeting_type,
                         is_custom=False)

        create_if_needed(ActivitySubType,
                         {'pk': constants.ACTIVITYSUBTYPE_PHONECALL_INCOMING},
                         name=_('Incoming'),
                         type=phone_call_type,
                         is_custom=False)
        create_if_needed(ActivitySubType,
                         {'pk': constants.ACTIVITYSUBTYPE_PHONECALL_OUTGOING},
                         name=_('Outgoing'),
                         type=phone_call_type,
                         is_custom=False)
        create_if_needed(
            ActivitySubType,
            {'pk': constants.ACTIVITYSUBTYPE_PHONECALL_CONFERENCE},
            name=_('Conference'),
            type=phone_call_type,
            is_custom=False)
        create_if_needed(ActivitySubType,
                         {'pk': constants.ACTIVITYSUBTYPE_PHONECALL_FAILED},
                         name=_('Outgoing - Failed'),
                         type=phone_call_type,
                         is_custom=False)

        # ---------------------------
        HeaderFilter.create(
            pk=constants.DEFAULT_HFILTER_ACTIVITY,
            name=_('Activity view'),
            model=Activity,
            cells_desc=[
                (EntityCellRegularField, {
                    'name': 'start'
                }),
                (EntityCellRegularField, {
                    'name': 'title'
                }),
                (EntityCellRegularField, {
                    'name': 'type'
                }),
                EntityCellRelation(model=Activity,
                                   rtype=rt_obj_part_2_activity),
                EntityCellRelation(model=Activity,
                                   rtype=rt_obj_activity_subject),
                (EntityCellRegularField, {
                    'name': 'user'
                }),
                (EntityCellRegularField, {
                    'name': 'end'
                }),
            ],
        )

        # ---------------------------
        create_efilter = EntityFilter.create

        for pk, name, atype_id in (
            (constants.EFILTER_MEETINGS, _('Meetings'),
             constants.ACTIVITYTYPE_MEETING),
            (constants.EFILTER_PHONECALLS, _('Phone calls'),
             constants.ACTIVITYTYPE_PHONECALL),
            (constants.EFILTER_TASKS, _('Tasks'), constants.ACTIVITYTYPE_TASK),
        ):
            create_efilter(
                pk,
                name=name,
                model=Activity,
                is_custom=False,
                user='******',
                conditions=[
                    # EntityFilterCondition.build_4_field(
                    #     model=Activity,
                    #     operator=EntityFilterCondition.EQUALS,
                    #     name='type',
                    #     values=[atype_id],
                    # ),
                    condition_handler.RegularFieldConditionHandler.
                    build_condition(
                        model=Activity,
                        operator=operators.EqualsOperator,
                        field_name='type',
                        values=[atype_id],
                    ),
                ],
            )

        create_efilter(
            constants.EFILTER_PARTICIPATE,
            name=_('In which I participate'),
            model=Activity,
            is_custom=False,
            user='******',
            conditions=[
                # EntityFilterCondition.build_4_relation_subfilter(
                #     rtype=rt_obj_part_2_activity,
                #     subfilter=EntityFilter.get_latest_version(FILTER_CONTACT_ME)
                # ),
                condition_handler.RelationSubFilterConditionHandler.
                build_condition(
                    model=Activity,
                    rtype=rt_obj_part_2_activity,
                    subfilter=EntityFilter.get_latest_version(
                        FILTER_CONTACT_ME),
                ),
            ],
        )

        # ---------------------------
        SearchConfigItem.create_if_needed(
            Activity, ['title', 'description', 'type__name'])

        # ---------------------------
        # for user in get_user_model().objects.all():
        #     Calendar.objects.get_default_calendar(user)
        # TODO: remove this code in Creme 2.2 (it avoids install of creme which
        #       are upgraded to 2.1 to force using the command "activities_create_default_calendars")
        cal_is_public = settings.ACTIVITIES_DEFAULT_CALENDAR_IS_PUBLIC

        if cal_is_public is not None:
            if isinstance(cal_is_public, bool):
                users = get_user_model().objects.filter(
                    is_staff=False,
                    is_active=True,
                    calendar__is_default__isnull=True,
                )

                for user in users:
                    Calendar.objects.create_default_calendar(
                        user=user, is_public=cal_is_public)
            else:
                logger.error(
                    'ACTIVITIES_DEFAULT_CALENDAR_IS_PUBLIC is invalid '
                    '(not in {None, True, False}) ')

        # ---------------------------
        create_svalue = SettingValue.objects.get_or_create
        create_svalue(key_id=setting_keys.review_key.id,
                      defaults={'value': True})
        create_svalue(key_id=setting_keys.auto_subjects_key.id,
                      defaults={'value': True})
        create_svalue(key_id=setting_keys.form_user_messages_key.id,
                      defaults={'value': False})

        # ---------------------------
        if not already_populated:
            LEFT = BrickDetailviewLocation.LEFT
            RIGHT = BrickDetailviewLocation.RIGHT

            BrickDetailviewLocation.objects.create_for_model_brick(
                order=5, zone=LEFT, model=Activity)

            create_bdl = BrickDetailviewLocation.objects.create_if_needed
            create_bdl(brick=core_bricks.CustomFieldsBrick,
                       order=40,
                       zone=LEFT,
                       model=Activity)
            create_bdl(brick=bricks.RelatedCalendarBrick,
                       order=90,
                       zone=LEFT,
                       model=Activity)
            create_bdl(brick=bricks.ParticipantsBrick,
                       order=100,
                       zone=LEFT,
                       model=Activity)
            create_bdl(brick=bricks.SubjectsBrick,
                       order=120,
                       zone=LEFT,
                       model=Activity)
            create_bdl(brick=core_bricks.PropertiesBrick,
                       order=450,
                       zone=LEFT,
                       model=Activity)
            create_bdl(brick=core_bricks.RelationsBrick,
                       order=500,
                       zone=LEFT,
                       model=Activity)
            create_bdl(brick=core_bricks.HistoryBrick,
                       order=20,
                       zone=RIGHT,
                       model=Activity)

            if apps.is_installed('creme.assistants'):
                logger.info(
                    'Assistants app is installed => we use the assistants blocks on detail views'
                )

                from creme.assistants import bricks as a_bricks

                create_bdl(brick=a_bricks.TodosBrick,
                           order=100,
                           zone=RIGHT,
                           model=Activity)
                create_bdl(brick=a_bricks.MemosBrick,
                           order=200,
                           zone=RIGHT,
                           model=Activity)
                create_bdl(brick=a_bricks.AlertsBrick,
                           order=300,
                           zone=RIGHT,
                           model=Activity)
                create_bdl(brick=a_bricks.UserMessagesBrick,
                           order=400,
                           zone=RIGHT,
                           model=Activity)

            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=Activity)

            future_id = bricks.FutureActivitiesBrick.id_
            past_id = bricks.PastActivitiesBrick.id_
            create_bdl(brick=future_id, order=20, zone=RIGHT, model=Contact)
            create_bdl(brick=past_id, order=21, zone=RIGHT, model=Contact)
            create_bdl(brick=future_id,
                       order=20,
                       zone=RIGHT,
                       model=Organisation)
            create_bdl(brick=past_id, order=21, zone=RIGHT, model=Organisation)

            BrickHomeLocation.objects.create(brick_id=future_id, order=20)
            BrickHomeLocation.objects.create(brick_id=past_id, order=21)

            # ---------------------------
            create_button = ButtonMenuItem.create_if_needed
            create_button('activities-add_activity_button',
                          model=None,
                          button=buttons.AddRelatedActivityButton,
                          order=10)
            create_button('activities-add_meeting_button',
                          model=None,
                          button=buttons.AddMeetingButton,
                          order=11)
            create_button('activities-add_phonecall_button',
                          model=None,
                          button=buttons.AddPhoneCallButton,
                          order=12)
Пример #23
0
    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)
Пример #24
0
    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)
Пример #25
0
    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)
Пример #26
0
    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
Пример #27
0
    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,
                                   )
Пример #28
0
    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')
Пример #29
0
    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)
Пример #30
0
    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)