示例#1
0
    def test_filtered_cells(self):
        hidden = 'first_name'
        FieldsConfig.objects.create(
            content_type=FakeContact,
            descriptions=[
                (hidden, {
                    FieldsConfig.HIDDEN: True
                }),
            ],
        )

        rtype = self.get_object_or_fail(RelationType, id=REL_SUB_HAS)

        hf = HeaderFilter.objects.create_if_needed(
            pk='tests-hf_contact',
            name='Contact view',
            model=FakeContact,
            cells_desc=[
                (EntityCellRegularField, {
                    'name': 'last_name'
                }),
                (EntityCellRegularField, {
                    'name': hidden
                }),
                EntityCellRelation(model=FakeContact, rtype=rtype),
            ],
        )
        self.assertListEqual(
            [
                EntityCellRegularField.build(FakeContact, 'last_name'),
                EntityCellRelation(model=FakeContact, rtype=rtype),
            ],
            hf.filtered_cells,
        )
示例#2
0
    def test_relationtype_registry01(self):
        "Default data + register() method."
        registry = lv_search.RelationSearchRegistry()

        cell1 = EntityCellRelation.build(model=FakeContact,
                                         rtype_id=REL_SUB_HAS)

        field = registry.get_field(cell=cell1, user=self.user)
        self.assertIsInstance(field, lv_form.RelationField)
        self.assertIsNone(registry.builder(REL_SUB_HAS))
        self.assertEqual(lv_form.RelationField, registry.default_builder)

        # ---
        class MyRelationField(lv_form.ListViewSearchField):
            pass

        rtype2 = RelationType.create(
            ('test-subject_loves', 'loves'),
            ('test-object_loved', 'is loved by'),
        )[0]
        cell2 = EntityCellRelation(model=FakeContact, rtype=rtype2)

        registry.register(rtype_id=rtype2.id, sfield_builder=MyRelationField)
        self.assertIsInstance(registry.get_field(cell=cell2, user=self.user),
                              MyRelationField)
        self.assertIsInstance(registry.get_field(cell=cell1, user=self.user),
                              lv_form.RelationField)

        self.assertIsNone(registry.builder(REL_SUB_HAS))
        self.assertEqual(MyRelationField, registry.builder(rtype2.id))
示例#3
0
    def test_populate_entities_relations01(self):
        user = self.login()

        create_rt = RelationType.create
        loved = create_rt(('test-subject_love', u'Is loving'),
                          ('test-object_love', u'Is loved by'))[1]
        hated = create_rt(('test-subject_hate', u'Is hating'),
                          ('test-object_hate', u'Is hated by'))[1]

        hf = HeaderFilter.create(
            pk='test-hf',
            name=u'Contact view',
            model=FakeContact,
            cells_desc=[
                EntityCellRegularField.build(model=FakeContact,
                                             name='last_name'),
                EntityCellRelation(model=FakeContact, rtype=loved),
                EntityCellRelation(model=FakeContact, rtype=hated),
            ],
        )

        create_contact = partial(FakeContact.objects.create, user=user)
        nagate = create_contact(first_name='Nagate', last_name='Tanikaze')
        shizuka = create_contact(first_name='Shizuka', last_name='Hoshijiro')
        izana = create_contact(first_name='Izana', last_name='Shinatose')
        norio = create_contact(first_name='Norio', last_name='Kunato')

        create_rel = partial(Relation.objects.create, user=user)
        create_rel(subject_entity=nagate, type=loved, object_entity=izana)
        create_rel(subject_entity=nagate, type=hated, object_entity=norio)
        create_rel(subject_entity=shizuka, type=loved, object_entity=norio)

        # NB: sometimes a query to get this CT is performed when the Relations
        # are retrieved. So we force the cache to be filled has he should be
        ContentType.objects.get_for_model(CremeEntity)

        with self.assertNumQueries(2):
            hf.populate_entities([nagate, shizuka], user)

        with self.assertNumQueries(0):
            r1 = nagate.get_relations(loved.id, real_obj_entities=True)
            r2 = nagate.get_relations(hated.id, real_obj_entities=True)
            r3 = shizuka.get_relations(loved.id, real_obj_entities=True)
            r4 = shizuka.get_relations(hated.id, real_obj_entities=True)

        with self.assertNumQueries(0):
            objs1 = [r.object_entity.get_real_entity() for r in r1]
            objs2 = [r.object_entity.get_real_entity() for r in r2]
            objs3 = [r.object_entity.get_real_entity() for r in r3]
            objs4 = [r.object_entity.get_real_entity() for r in r4]

        self.assertEqual([izana], objs1)
        self.assertEqual([norio], objs2)
        self.assertEqual([norio], objs3)
        self.assertEqual([], objs4)
示例#4
0
    def test_relationship(self):
        constraint = GHCCRelation(model=FakeContact)

        rtype1 = RelationType.create(
            ('test-subject_likes', 'likes'),
            ('test-object_likes', 'is liked by'),
        )[0]
        self.assertTrue(
            constraint.check_cell(EntityCellRelation(FakeContact, rtype1)))

        rtype2 = RelationType.create(
            ('test-subject_loves', 'is loving', [FakeContact]),
            ('test-object_loves', 'is loved by', [FakeContact]),
        )[0]
        self.assertTrue(
            constraint.check_cell(EntityCellRelation(FakeContact, rtype2)))

        rtype3 = RelationType.create(
            ('test-subject_branch', 'has branch', [FakeOrganisation]),
            ('test-object_branch', 'is a branch of', [FakeOrganisation]),
        )[0]
        self.assertFalse(
            constraint.check_cell(EntityCellRelation(FakeContact, rtype3)))

        # ---
        cell1 = constraint.get_cell(cell_key=f'relation-{rtype2.id}')
        self.assertIsInstance(cell1, EntityCellRelation)
        self.assertEqual(rtype2, cell1.relation_type)

        self.assertIsNone(
            constraint.get_cell(cell_key=f'relation-{rtype3.id}'))

        # ---
        cells = [*constraint.cells()]
        self.assertGreaterEqual(len(cells), 2)
        self.assertIsInstance(cells[0], EntityCellRelation)

        def find_cell(rtype):
            for cell in cells:
                if cell.relation_type == rtype:
                    return

            self.fail(f'{rtype} not found in cells.')

        find_cell(rtype1)
        find_cell(rtype2)

        for cell in cells:
            if cell.relation_type == rtype3:
                self.fail(f'{rtype3} should not be found in cells.')
示例#5
0
    def test_relationtype_registry06(self):
        "Register a default sub-registry."
        user1 = self.user
        user2 = CremeUser(
            username='******',
            email='*****@*****.**',
            first_name='Chie',
            last_name='Uru',
        )

        class MyRelationField1(lv_form.ListViewSearchField):
            pass

        class MyRelationField2(lv_form.ListViewSearchField):
            pass

        class MyRelRegistry(lv_search.AbstractListViewSearchFieldRegistry):
            def get_field(self, *, cell, user, **kwarg):
                cls = MyRelationField1 if user.username == user1.username else MyRelationField2

                return cls(cell=cell, user=user)

        registry = lv_search.RelationSearchRegistry().register_default(
            MyRelRegistry)

        cell = EntityCellRelation.build(model=FakeContact,
                                        rtype_id=REL_SUB_HAS)
        get_field = registry.get_field
        self.assertIsInstance(get_field(cell=cell, user=user1),
                              MyRelationField1)
        self.assertIsInstance(get_field(cell=cell, user=user2),
                              MyRelationField2)
示例#6
0
 def create_hf(hf_pk, name, model, status=True):
     HeaderFilter.objects.create_if_needed(
         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'
             }),
         ],
     )
示例#7
0
    def _get_cells(self, model):
        cells = []

        for cell_cls, data in self._cells:
            cell = None

            if cell_cls is EntityCellRegularField:
                cell = EntityCellRegularField.build(model=model, name=data)
            elif cell_cls is EntityCellFunctionField:
                cell = EntityCellFunctionField.build(model,
                                                     func_field_name=data)
            else:  # EntityCellRelation
                rtype = self._get_relationtype(data)

                if rtype is False:
                    logger.warning(
                        'SmartColumnsRegistry: relation type "%s" does not exist',
                        data)
                else:
                    cell = EntityCellRelation(model=model, rtype=rtype)

            # Has no sense here:
            #  EntityCellActions : not configurable in HeaderFilter form
            #  EntityCellCustomField : dynamically created by user
            # TODO: other types

            if cell is not None:
                cells.append(cell)

        return cells
示例#8
0
    def test_cell_registry_relation02(self):
        "Default data."
        registry = lv_search.ListViewSearchFieldRegistry()
        cell = EntityCellRelation.build(model=FakeContact,
                                        rtype_id=REL_SUB_HAS)

        field = registry.get_field(cell=cell, user=self.user)
        self.assertIsInstance(field, lv_form.RelationField)
示例#9
0
    def _build_hf_n_contacts(self):
        user = self.user

        create_orga = partial(FakeOrganisation.objects.create, user=user)
        self.organisations = organisations = {
                name: create_orga(name=name)
                    for name in ('Bebop', 'Swordfish')
            }

        rtype_pilots = RelationType.create(('test-subject_pilots', 'pilots'),
                                           ('test-object_pilots',  'is piloted by')
                                          )[0]

        create_ptype = CremePropertyType.create
        ptype_beautiful = create_ptype(str_pk='test-prop_beautiful', text='is beautiful')
        ptype_girl      = create_ptype(str_pk='test-prop_girl',      text='is a girl')

        create_contact = partial(FakeContact.objects.create, user=user)
        self.contacts = contacts = {
            first_name: create_contact(first_name=first_name, last_name=last_name)
                for first_name, last_name in [('Spike', 'Spiegel'),
                                              ('Jet', 'Black'),
                                              ('Faye', 'Valentine'),
                                              ('Edward', 'Wong'),
                                             ]
        }

        create_rel = partial(Relation.objects.create, user=user, type=rtype_pilots,
                             object_entity=organisations['Bebop'],
                            )
        create_rel(subject_entity=contacts['Jet'])
        create_rel(subject_entity=contacts['Spike'])
        create_rel(subject_entity=contacts['Spike'], object_entity=organisations['Swordfish'])

        create_prop = CremeProperty.objects.create
        create_prop(type=ptype_girl,      creme_entity=contacts['Faye'])
        create_prop(type=ptype_girl,      creme_entity=contacts['Edward'])
        create_prop(type=ptype_beautiful, creme_entity=contacts['Faye'])

        cells = [
            EntityCellRegularField.build(model=FakeContact, name='civility'),
            EntityCellRegularField.build(model=FakeContact, name='last_name'),
            EntityCellRegularField.build(model=FakeContact, name='first_name'),
            EntityCellRelation(model=FakeContact, rtype=rtype_pilots),
            # TODO: EntityCellCustomField
            EntityCellFunctionField.build(model=FakeContact, func_field_name='get_pretty_properties'),
        ]
        hf = HeaderFilter.create(pk='test-hf_contact', name='Contact view',
                                 model=FakeContact, cells_desc=cells,
                                )

        # return cells
        return hf
示例#10
0
    def test_relationtype_registry03(self):
        "Set default."

        class MyRelationField(lv_form.ListViewSearchField):
            pass

        registry = lv_search.RelationSearchRegistry(default=MyRelationField)
        self.assertEqual(MyRelationField, registry.default_builder)

        cell = EntityCellRelation.build(model=FakeContact,
                                        rtype_id=REL_SUB_HAS)
        self.assertIsInstance(registry.get_field(cell=cell, user=self.user),
                              MyRelationField)
示例#11
0
    def test_relationtype_registry02(self):
        "Register in constructor."

        class MyRelationField(lv_form.ListViewSearchField):
            pass

        registry = lv_search.RelationSearchRegistry(to_register=[
            (REL_SUB_HAS, MyRelationField),
        ])

        cell = EntityCellRelation.build(model=FakeContact,
                                        rtype_id=REL_SUB_HAS)
        self.assertIsInstance(registry.get_field(cell=cell, user=self.user),
                              MyRelationField)
示例#12
0
    def get_cells(self, hfilter):
        cells = super().get_cells(hfilter=hfilter)

        rtypes = RelationType.objects.filter(pk__in=self.RTYPE_IDS)

        # NB: add relations items to use the pre-cache system of HeaderFilter
        #     (TODO: problem: retrieve other related events too)
        cells.extend(
            EntityCellRelation(model=Contact, rtype=rtype, is_hidden=True)
            for rtype in rtypes)

        event = self.get_related_entity()
        cells.append(gui.EntityCellVolatileInvitation(event=event))
        cells.append(gui.EntityCellVolatilePresence(event=event))

        return cells
示例#13
0
    def test_create02(self):
        "With cells"
        user = self.login()

        create_rtype = RelationType.create
        loves = create_rtype(('test-subject_love', u'Is loving'),
                             ('test-object_love', u'Is loved by'))[0]
        likes = create_rtype(('test-subject_like', u'Is liking'),
                             ('test-object_like', u'Is liked by'))[0]

        hf = HeaderFilter.create(
            pk='tests-hf_contact',
            name='Contact view',
            model=FakeContact,
            is_custom=True,
            is_private=True,
            user=user,
            cells_desc=[
                (EntityCellRegularField, {
                    'name': 'last_name'
                }),
                EntityCellRelation(model=FakeContact, rtype=loves),
                (EntityCellRelation, {
                    'rtype_id': likes.id
                }),
                None,
            ],
        )

        hf = self.refresh(hf)
        self.assertEqual(user, hf.user)
        self.assertTrue(hf.is_private)

        cells = hf.cells
        self.assertEqual(3, len(cells))

        cell = cells[0]
        self.assertIsInstance(cell, EntityCellRegularField)
        self.assertEqual('last_name', cell.value)

        cell = cells[1]
        self.assertIsInstance(cell, EntityCellRelation)
        self.assertEqual(loves.id, cell.value)

        cell = cells[2]
        self.assertIsInstance(cell, EntityCellRelation)
        self.assertEqual(likes.id, cell.value)
示例#14
0
    def test_mixed_populate_entities04(self):
        "Mixed types."
        user = self.create_user()

        pos = FakePosition.objects.all()[0]
        create_contact = partial(FakeContact.objects.create, user=user)
        contacts = [
            create_contact(first_name='Nagate',
                           last_name='Tanikaze',
                           position=pos),
            create_contact(first_name='Shizuka', last_name='Hoshijiro'),
            create_contact(first_name='Izana', last_name='Shinatose'),
        ]

        loved = RelationType.create(
            ('test-subject_love', 'Is loving'),
            ('test-object_love', 'Is loved by'),
        )[1]
        Relation.objects.create(
            user=user,
            subject_entity=contacts[0],
            type=loved,
            object_entity=contacts[2],
        )

        build_rfield = partial(EntityCellRegularField.build, model=FakeContact)
        cells = [
            build_rfield(name='last_name'),
            build_rfield(name='position'),
            EntityCellRelation(model=FakeContact, rtype=loved),
        ]

        # NB: sometimes a query to get this CT is performed when the Relations
        # are retrieved. So we force the cache to be filled has he should be
        ContentType.objects.get_for_model(CremeEntity)

        # Drop caches
        contacts = [self.refresh(c) for c in contacts]

        with self.assertNumQueries(3):
            EntityCell.mixed_populate_entities(cells, contacts, user)

        with self.assertNumQueries(0):
            contacts[0].position  # NOQA

        with self.assertNumQueries(0):
            contacts[0].get_relations(loved.id, real_obj_entities=True)
示例#15
0
    def test_relation(self):
        self.assertEqual(_('Relationships'), EntityCellRelation.verbose_name)

        loves = RelationType.create(('test-subject_love', 'Is loving'),
                                    ('test-object_love', 'Is loved by'))[0]
        cell = EntityCellRelation(model=FakeContact, rtype=loves)
        self.assertIsInstance(cell, EntityCellRelation)
        self.assertEqual(FakeContact, cell.model)
        self.assertEqual(str(loves.id), cell.value)
        self.assertEqual(loves.predicate, cell.title)
        self.assertEqual(f'relation-{loves.id}', cell.key)
        self.assertIs(cell.is_multiline, True)
        self.assertEqual(loves, cell.relation_type)
        self.assertEqual(settings.CSS_DEFAULT_LISTVIEW,
                         cell.listview_css_class)
        self.assertEqual(settings.CSS_DEFAULT_HEADER_LISTVIEW,
                         cell.header_listview_css_class)
示例#16
0
 def test_build_4_relation(self):
     loves = RelationType.create(('test-subject_love', 'Is loving'),
                                 ('test-object_love', 'Is loved by'))[0]
     cell = EntityCellRelation(model=FakeContact, rtype=loves)
     self.assertIsInstance(cell, EntityCellRelation)
     self.assertEqual(FakeContact, cell.model)
     self.assertEqual(str(loves.id), cell.value)
     self.assertEqual(loves.predicate, cell.title)
     self.assertEqual('relation-{}'.format(loves.id), cell.key)
     # self.assertIs(cell.has_a_filter, True)
     # self.assertIs(cell.editable,     False)
     # self.assertIs(cell.sortable,     False)
     self.assertIs(cell.is_multiline, True)
     # self.assertEqual('',    cell.filter_string)
     self.assertEqual(loves, cell.relation_type)
     self.assertEqual(settings.CSS_DEFAULT_LISTVIEW,
                      cell.listview_css_class)
     self.assertEqual(settings.CSS_DEFAULT_HEADER_LISTVIEW,
                      cell.header_listview_css_class)
示例#17
0
    def test_cell_registry_relation01(self):
        cell = EntityCellRelation.build(model=FakeContact,
                                        rtype_id=REL_SUB_HAS)
        registry = lv_search.ListViewSearchFieldRegistry(to_register=())

        field = registry.get_field(cell=cell, user=self.user)
        self.assertIsInstance(field, lv_form.ListViewSearchField)

        class MyField(lv_form.RelationField):
            pass

        class Registry:
            def get_field(this, *, cell, user):
                return MyField(cell=cell, user=user)

        registry.register(cell_id=EntityCellRelation.type_id,
                          registry_class=Registry)
        field = registry.get_field(cell=cell, user=self.user)
        self.assertIsInstance(field, MyField)
示例#18
0
    def test_relations(self):
        rtype1 = self.get_object_or_fail(
            RelationType,
            id=fake_constants.FAKE_REL_SUB_EMPLOYED_BY,
        )
        rtype2 = self.get_object_or_fail(
            RelationType,
            id=fake_constants.FAKE_REL_OBJ_EMPLOYED_BY,
        )
        rtype3 = self.get_object_or_fail(
            RelationType,
            id=fake_constants.FAKE_REL_SUB_BILL_ISSUED,
        )

        field1 = EntityCellsField(model=FakeContact)

        choices1 = self._find_sub_widget(field1, 'relation').choices
        self.assertCellInChoices(f'relation-{rtype1.id}', choices=choices1)
        self.assertCellNotInChoices(f'relation-{rtype2.id}', choices=choices1)
        self.assertCellNotInChoices(f'relation-{rtype3.id}', choices=choices1)

        # ---
        field2 = EntityCellsField()
        field2.model = FakeContact

        choices2 = self._find_sub_widget(field2, 'relation').choices
        self.assertCellInChoices(f'relation-{rtype1.id}', choices=choices2)
        self.assertCellNotInChoices(f'relation-{rtype2.id}', choices=choices2)

        self.assertListEqual(
            [EntityCellRelation(model=FakeContact, rtype=rtype1)],
            field2.clean(f'relation-{rtype1.id}'))
        self.assertFieldValidationError(
            EntityCellRelationsField,
            'incompatible',
            field2.clean,
            f'relation-{rtype2.id}',
            message_args={'model': 'Test Contact'},
        )
示例#19
0
    def test_relation(self):
        "EntityCellRelation are not sortable."
        sorter = QuerySorter()

        field_name = 'name'
        cells = [
            EntityCellRegularField.build(model=FakeOrganisation,
                                         name=field_name),
            EntityCellRelation.build(model=FakeOrganisation,
                                     rtype_id=REL_SUB_HAS),
        ]

        sortinfo = sorter.get(
            model=FakeInvoice,
            cells=cells,
            cell_key=cells[1].key,
            order=Order(),
        )
        self.assertEqual((field_name, 'cremeentity_ptr_id'),
                         sortinfo.field_names)
        self.assertEqual(cells[0].key, sortinfo.main_cell_key)
        self.assertTrue(sortinfo.main_order.asc)
示例#20
0
    def _create_report(self, name='Report #1', efilter=None, extra_cells=()):
        cells = [
            EntityCellRegularField.build(model=FakeContact, name='last_name'),
            EntityCellRegularField.build(model=FakeContact, name='user'),
            EntityCellRelation(model=FakeContact, rtype=RelationType.objects.get(pk=REL_SUB_HAS)),
            EntityCellFunctionField.build(model=FakeContact, func_field_name='get_pretty_properties'),
            *extra_cells,
        ]

        hf = HeaderFilter.create(pk='test_hf', name='name', model=FakeContact, cells_desc=cells)

        response = self.client.post(self.ADD_URL, follow=True,
                                    data={'user':   self.user.pk,
                                          'name':   name,
                                          'ct':     self.ct_contact.id,
                                          'hf':     hf.id,
                                          'filter': efilter.id if efilter else '',
                                         },
                                   )
        self.assertNoFormError(response)

        return self.get_object_or_fail(Report, name=name)
示例#21
0
    def __call__(self, context, request):
        self.user = request.user
        cells = context['header_filters'].selected.cells
        rtypes = RelationType.objects.filter(pk__in=self._RTYPE_IDS)

        # NB: add relations items to use the pre-cache system of HeaderFilter
        #     (TODO: problem: retrieve other related events too)
        cells.extend(
            EntityCellRelation(model=Contact, rtype=rtype, is_hidden=True)
            for rtype in rtypes)

        cells.append(
            EntityCellVolatile(model=Contact,
                               value='invitation_management',
                               title=_('Invitation'),
                               render_func=self.invitation_render))
        cells.append(
            EntityCellVolatile(model=Contact,
                               value='presence_management',
                               title=_('Presence'),
                               render_func=self.presence_render))

        # TODO: in the future listview CBV a method that returns the instance of class registry
        #       (None would have the same meaning than context['show_actions']==False)
        if context['show_actions']:
            actions_cell = cells[0]
            view_action_class = next(
                (c for c in actions_cell.registry.instance_action_classes(
                    model=Contact) if (issubclass(c, ViewAction))), None)

            actions_cell.registry = action_registry = RelatedContactsActionsRegistry(
                event=self.event)
            action_registry.register_instance_actions(
                AddRelatedOpportunityAction)

            if view_action_class is not None:
                action_registry.register_instance_actions(view_action_class)
示例#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]

        # ---------------------------
        def create_status(pk, name):
            create_if_needed(
                Status,
                {'pk': pk},
                name=name,
                description=name,
                is_custom=False,
            )

        create_status(constants.STATUS_PLANNED,
                      pgettext('activities-status', 'Planned')),
        create_status(constants.STATUS_IN_PROGRESS,
                      pgettext('activities-status', 'In progress')),
        create_status(constants.STATUS_DONE,
                      pgettext('activities-status', 'Done')),
        create_status(constants.STATUS_DELAYED,
                      pgettext('activities-status', 'Delayed')),
        create_status(constants.STATUS_CANCELLED,
                      pgettext('activities-status', 'Cancelled')),

        # ---------------------------
        act_types_info = {
            constants.ACTIVITYTYPE_TASK: {
                'name': _('Task'),
                'day': 0,
                'hour': '00:15:00',
            },
            constants.ACTIVITYTYPE_MEETING: {
                'name': _('Meeting'),
                'day': 0,
                'hour': '00:15:00',
            },
            constants.ACTIVITYTYPE_PHONECALL: {
                'name': _('Phone call'),
                'day': 0,
                'hour': '00:15:00',
            },
            constants.ACTIVITYTYPE_GATHERING: {
                'name': _('Gathering'),
                'day': 0,
                'hour': '00:15:00',
            },
            constants.ACTIVITYTYPE_SHOW: {
                'name': _('Show'),
                'day': 1,
                'hour': '00:00:00',
            },
            constants.ACTIVITYTYPE_DEMO: {
                'name': _('Demonstration'),
                'day': 0,
                'hour': '01:00:00',
            },
            constants.ACTIVITYTYPE_INDISPO: {
                'name': _('Unavailability'),
                'day': 1,
                'hour': '00:00:00',
            },
        }
        act_types = {
            pk: create_if_needed(
                ActivityType,
                {'pk': pk},
                name=info['name'],
                default_day_duration=info['day'],
                default_hour_duration=info['hour'],
                is_custom=False,
            )
            for pk, info in act_types_info.items()
        }

        def create_subtype(atype, pk, name):
            create_if_needed(
                ActivitySubType,
                {'pk': pk},
                name=name,
                type=atype,
                is_custom=False,
            )

        meeting_t = act_types[constants.ACTIVITYTYPE_MEETING]
        for pk, name in [
            (constants.ACTIVITYSUBTYPE_MEETING_MEETING, _('Meeting')),
            (constants.ACTIVITYSUBTYPE_MEETING_QUALIFICATION,
             _('Qualification')),
            (constants.ACTIVITYSUBTYPE_MEETING_REVIVAL, _('Revival')),
            (constants.ACTIVITYSUBTYPE_MEETING_NETWORK, _('Network')),
            (constants.ACTIVITYSUBTYPE_MEETING_OTHER,
             pgettext('activities-meeting', 'Other')),
        ]:
            create_subtype(meeting_t, pk, name)

        pcall_t = act_types[constants.ACTIVITYTYPE_PHONECALL]
        for pk, name in [
            (constants.ACTIVITYSUBTYPE_PHONECALL_INCOMING, _('Incoming')),
            (constants.ACTIVITYSUBTYPE_PHONECALL_OUTGOING, _('Outgoing')),
            (constants.ACTIVITYSUBTYPE_PHONECALL_CONFERENCE, _('Conference')),
            (constants.ACTIVITYSUBTYPE_PHONECALL_FAILED,
             _('Outgoing - Failed')),
        ]:
            create_subtype(pcall_t, pk, name)

        # ---------------------------
        HeaderFilter.objects.create_if_needed(
            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.objects.smart_update_or_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=[
                    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=[
                condition_handler.RelationSubFilterConditionHandler.
                build_condition(
                    model=Activity,
                    rtype=rt_obj_part_2_activity,
                    subfilter=EntityFilter.objects.get_latest_version(
                        FILTER_CONTACT_ME),
                ),
            ],
        )

        # ---------------------------
        when_group = {
            'name':
            _('When'),
            'layout':
            LAYOUT_DUAL_SECOND,
            'cells': [
                act_forms.StartSubCell(model=Activity).into_cell(),
                act_forms.EndSubCell(model=Activity).into_cell(),
                (EntityCellRegularField, {
                    'name': 'is_all_day'
                }),
            ],
        }
        alerts_groups = [
            {
                'name':
                _('Generate an alert on a specific date'),
                'layout':
                LAYOUT_DUAL_SECOND,
                'cells': [
                    act_forms.DatetimeAlertSubCell(model=Activity).into_cell(),
                ],
            },
            {
                'name':
                _('Generate an alert in a while'),
                'layout':
                LAYOUT_DUAL_SECOND,
                'cells': [
                    act_forms.PeriodAlertSubCell(model=Activity).into_cell(),
                ],
            },
        ]
        participants_group = {
            'name':
            _('Participants & subjects'),
            'cells': [
                act_forms.MyParticipationSubCell(model=Activity).into_cell(),
                act_forms.ParticipatingUsersSubCell(
                    model=Activity).into_cell(),
                act_forms.OtherParticipantsSubCell(model=Activity).into_cell(),
                act_forms.ActivitySubjectsSubCell(model=Activity).into_cell(),
                act_forms.LinkedEntitiesSubCell(model=Activity).into_cell(),
            ],
        }
        common_groups_desc = [
            {
                'name': _('Description'),
                'cells': [
                    (EntityCellRegularField, {
                        'name': 'description'
                    }),
                ],
            },
            {
                'name':
                _('Custom fields'),
                'cells': [
                    (
                        EntityCellCustomFormSpecial,
                        {
                            'name':
                            EntityCellCustomFormSpecial.REMAINING_CUSTOMFIELDS
                        },
                    ),
                ],
            },
        ]
        relations_n_properties_groups = [
            {
                'name':
                _('Properties'),
                'cells': [
                    (
                        EntityCellCustomFormSpecial,
                        {
                            'name':
                            EntityCellCustomFormSpecial.CREME_PROPERTIES
                        },
                    ),
                ],
            },
            {
                'name':
                _('Relationships'),
                'cells': [
                    (
                        EntityCellCustomFormSpecial,
                        {
                            'name': EntityCellCustomFormSpecial.RELATIONS
                        },
                    ),
                ],
            },
        ]

        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.ACTIVITY_CREATION_CFORM,
            groups_desc=[
                {
                    'name':
                    _('General information'),
                    'layout':
                    LAYOUT_DUAL_FIRST,
                    'cells': [
                        (EntityCellRegularField, {
                            'name': 'user'
                        }),
                        (EntityCellRegularField, {
                            'name': 'title'
                        }),
                        (EntityCellRegularField, {
                            'name': 'minutes'
                        }),
                        (EntityCellRegularField, {
                            'name': 'place'
                        }),
                        (EntityCellRegularField, {
                            'name': 'duration'
                        }),
                        (EntityCellRegularField, {
                            'name': 'status'
                        }),
                        (EntityCellRegularField, {
                            'name': 'busy'
                        }),
                        act_forms.ActivitySubTypeSubCell(
                            model=Activity).into_cell(),
                        # act_forms.CommercialApproachSubCell(model=Activity).into_cell(),
                        (
                            EntityCellCustomFormSpecial,
                            {
                                'name':
                                EntityCellCustomFormSpecial.
                                REMAINING_REGULARFIELDS
                            },
                        ),
                    ],
                },
                when_group,
                *alerts_groups,
                participants_group,
                *common_groups_desc,
                *relations_n_properties_groups,
                # {
                #     'name': _('Users to keep informed'),
                #     'cells': [
                #         (
                #             act_forms.UserMessagesSubCell(model=Activity).into_cell(),
                #         ),
                #     ],
                # },
            ],
        )
        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.ACTIVITY_CREATION_FROM_CALENDAR_CFORM,
            groups_desc=[
                {
                    'name':
                    _('General information'),
                    'layout':
                    LAYOUT_DUAL_FIRST,
                    'cells': [
                        (EntityCellRegularField, {
                            'name': 'user'
                        }),
                        (EntityCellRegularField, {
                            'name': 'title'
                        }),
                        # (EntityCellRegularField, {'name': 'minutes'}),
                        (EntityCellRegularField, {
                            'name': 'place'
                        }),
                        (EntityCellRegularField, {
                            'name': 'duration'
                        }),
                        (EntityCellRegularField, {
                            'name': 'status'
                        }),
                        (EntityCellRegularField, {
                            'name': 'busy'
                        }),
                        act_forms.ActivitySubTypeSubCell(
                            model=Activity).into_cell(),
                        # act_forms.CommercialApproachSubCell(model=Activity).into_cell(),
                        # NB: we do not want 'minutes' in the default form
                        # (
                        #     EntityCellCustomFormSpecial,
                        #     {'name': EntityCellCustomFormSpecial.REMAINING_REGULARFIELDS},
                        # ),
                    ],
                },
                when_group,
                *alerts_groups,
                participants_group,
                *common_groups_desc,
                *relations_n_properties_groups,
            ],
        )
        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.UNAVAILABILITY_CREATION_FROM,
            groups_desc=[
                {
                    'name':
                    _('General information'),
                    'layout':
                    LAYOUT_DUAL_FIRST,
                    'cells': [
                        (EntityCellRegularField, {
                            'name': 'user'
                        }),
                        (EntityCellRegularField, {
                            'name': 'title'
                        }),
                        act_forms.UnavailabilityTypeSubCell(
                            model=Activity).into_cell(),
                    ],
                },
                when_group,
                {
                    'name':
                    _('Unavailable users'),
                    'cells': [
                        act_forms.ParticipatingUsersSubCell(
                            model=Activity).into_cell(),
                    ],
                },
                *common_groups_desc,
                *relations_n_properties_groups,
            ],
        )
        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.ACTIVITY_EDITION_CFORM,
            groups_desc=[
                {
                    'name':
                    _('General information'),
                    'layout':
                    LAYOUT_DUAL_FIRST,
                    'cells': [
                        (EntityCellRegularField, {
                            'name': 'user'
                        }),
                        (EntityCellRegularField, {
                            'name': 'title'
                        }),
                        (EntityCellRegularField, {
                            'name': 'minutes'
                        }),
                        (EntityCellRegularField, {
                            'name': 'place'
                        }),
                        (EntityCellRegularField, {
                            'name': 'duration'
                        }),
                        (EntityCellRegularField, {
                            'name': 'status'
                        }),
                        (EntityCellRegularField, {
                            'name': 'busy'
                        }),
                        act_forms.ActivitySubTypeSubCell(
                            model=Activity).into_cell(),
                        (
                            EntityCellCustomFormSpecial,
                            {
                                'name':
                                EntityCellCustomFormSpecial.
                                REMAINING_REGULARFIELDS
                            },
                        ),
                    ],
                },
                when_group,
                *common_groups_desc,
            ],
        )

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

        # ---------------------------
        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})

        # ---------------------------
        # TODO: move to "not already_populated" section in creme2.4
        if not MenuConfigItem.objects.filter(
                entry_id__startswith='activities-').exists():
            create_mitem = MenuConfigItem.objects.create
            container = create_mitem(
                entry_id=ContainerEntry.id,
                entry_data={'label': _('Activities')},
                order=10,
            )
            create_mitem(entry_id=menu.CalendarEntry.id,
                         order=10,
                         parent=container)
            create_mitem(entry_id=menu.ActivitiesEntry.id,
                         order=20,
                         parent=container)
            create_mitem(entry_id=menu.PhoneCallsEntry.id,
                         order=30,
                         parent=container)
            create_mitem(entry_id=menu.MeetingsEntry.id,
                         order=40,
                         parent=container)

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

            BrickDetailviewLocation.objects.multi_create(
                defaults={
                    'model': Activity,
                    'zone': LEFT
                },
                data=[
                    {
                        'order': 5
                    },
                    {
                        'brick': core_bricks.CustomFieldsBrick,
                        'order': 40
                    },
                    {
                        'brick': bricks.RelatedCalendarBrick,
                        'order': 90
                    },
                    {
                        'brick': bricks.ParticipantsBrick,
                        'order': 100
                    },
                    {
                        'brick': bricks.SubjectsBrick,
                        'order': 120
                    },
                    {
                        'brick': core_bricks.PropertiesBrick,
                        'order': 450
                    },
                    {
                        'brick': core_bricks.RelationsBrick,
                        'order': 500
                    },
                    {
                        'brick': core_bricks.HistoryBrick,
                        'order': 20,
                        'zone': RIGHT
                    },
                ],
            )

            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

                BrickDetailviewLocation.objects.multi_create(
                    defaults={
                        'model': Activity,
                        'zone': RIGHT
                    },
                    data=[
                        {
                            'brick': a_bricks.TodosBrick,
                            'order': 100
                        },
                        {
                            'brick': a_bricks.MemosBrick,
                            'order': 200
                        },
                        {
                            'brick': a_bricks.AlertsBrick,
                            'order': 300
                        },
                        {
                            'brick': a_bricks.UserMessagesBrick,
                            'order': 400
                        },
                    ],
                )

            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

                BrickDetailviewLocation.objects.create_if_needed(
                    brick=LinkedDocsBrick,
                    order=600,
                    zone=RIGHT,
                    model=Activity,
                )

            future_id = bricks.FutureActivitiesBrick.id_
            past_id = bricks.PastActivitiesBrick.id_

            BrickDetailviewLocation.objects.multi_create(
                defaults={'zone': RIGHT},
                data=[
                    {
                        'brick': future_id,
                        'order': 20,
                        'model': Contact
                    },
                    {
                        'brick': past_id,
                        'order': 21,
                        'model': Contact
                    },
                    {
                        'brick': future_id,
                        'order': 20,
                        'model': Organisation
                    },
                    {
                        'brick': past_id,
                        'order': 21,
                        'model': Organisation
                    },
                ],
            )

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

            # ---------------------------
            create_button = ButtonMenuItem.objects.create_if_needed
            create_button(button=buttons.AddRelatedActivityButton, order=10)
            create_button(button=buttons.AddMeetingButton, order=11)
            create_button(button=buttons.AddPhoneCallButton, order=12)
示例#23
0
    def populate(self):
        already_populated = RelationType.objects.filter(
            pk=constants.REL_SUB_TARGETS).exists()

        Contact = persons.get_contact_model()
        Organisation = persons.get_organisation_model()
        Product = products.get_product_model()
        Service = products.get_service_model()

        # ---------------------------
        create_rtype = RelationType.create
        rt_sub_targets = create_rtype(
            (
                constants.REL_SUB_TARGETS,
                _('targets the organisation/contact'),
                [Opportunity],
            ),
            (
                constants.REL_OBJ_TARGETS,
                _('targeted by the opportunity'),
                [Organisation, Contact],
            ),
            is_internal=True,
            minimal_display=(True, True),
        )[0]
        rt_obj_emit_orga = create_rtype(
            (
                constants.REL_SUB_EMIT_ORGA,
                _('has generated the opportunity'),
                [Organisation],
            ),
            (
                constants.REL_OBJ_EMIT_ORGA,
                _('has been generated by'),
                [Opportunity],
            ),
            is_internal=True,
            minimal_display=(True, True),
        )[1]
        create_rtype((constants.REL_SUB_LINKED_PRODUCT,
                      _('is linked to the opportunity'), [Product]),
                     (constants.REL_OBJ_LINKED_PRODUCT,
                      _('concerns the product'), [Opportunity]))
        create_rtype(
            (constants.REL_SUB_LINKED_SERVICE,
             _('is linked to the opportunity'), [Service]),
            (constants.REL_OBJ_LINKED_SERVICE, _('concerns the service'),
             [Opportunity]),
        )
        create_rtype(
            (constants.REL_SUB_LINKED_CONTACT,
             _('involves in the opportunity'), [Contact]),
            (constants.REL_OBJ_LINKED_CONTACT, _('stages'), [Opportunity])),
        create_rtype(
            (constants.REL_SUB_RESPONSIBLE, _('is responsible for'), [Contact
                                                                      ]),
            (constants.REL_OBJ_RESPONSIBLE, _('has as responsible contact'),
             [Opportunity]),
        )

        if apps.is_installed('creme.activities'):
            logger.info('Activities app is installed'
                        ' => an Opportunity 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(Opportunity)

        if apps.is_installed('creme.billing'):
            logger.info(
                'Billing app is installed'
                ' => we create relationships between Opportunities & billing models'
            )

            from creme import billing

            Invoice = billing.get_invoice_model()
            Quote = billing.get_quote_model()
            SalesOrder = billing.get_sales_order_model()

            create_rtype(
                (
                    constants.REL_SUB_LINKED_SALESORDER,
                    _('is associate with the opportunity'),
                    [SalesOrder],
                ),
                (constants.REL_OBJ_LINKED_SALESORDER,
                 _('has generated the salesorder'), [Opportunity]),
            )
            create_rtype(
                (
                    constants.REL_SUB_LINKED_INVOICE,
                    pgettext('opportunities-invoice',
                             'generated for the opportunity'),
                    [Invoice],
                ),
                (
                    constants.REL_OBJ_LINKED_INVOICE,
                    _('has resulted in the invoice'),
                    [Opportunity],
                ),
            )
            create_rtype(
                (
                    constants.REL_SUB_LINKED_QUOTE,
                    pgettext('opportunities-quote',
                             'generated for the opportunity'),
                    [Quote],
                ),
                (
                    constants.REL_OBJ_LINKED_QUOTE,
                    _('has resulted in the quote'),
                    [Opportunity],
                ),
            )
            create_rtype(
                (
                    constants.REL_SUB_CURRENT_DOC,
                    _('is the current accounting document of'),
                    [SalesOrder, Invoice, Quote],
                ),
                (
                    constants.REL_OBJ_CURRENT_DOC,
                    _('has as current accounting document'),
                    [Opportunity],
                ),
            )

        # ---------------------------
        create_sv = SettingValue.objects.get_or_create
        create_sv(key_id=setting_keys.quote_key.id, defaults={'value': False})
        create_sv(key_id=setting_keys.target_constraint_key.id,
                  defaults={'value': True})
        create_sv(key_id=setting_keys.emitter_constraint_key.id,
                  defaults={'value': True})

        # ---------------------------
        create_efilter = partial(
            EntityFilter.objects.smart_update_or_create,
            model=Opportunity,
            user='******',
        )
        build_cond = partial(
            condition_handler.RegularFieldConditionHandler.build_condition,
            model=Opportunity,
        )
        create_efilter(
            'opportunities-opportunities_won',
            name=_('Opportunities won'),
            conditions=[
                build_cond(
                    operator=operators.EqualsOperator,
                    field_name='sales_phase__won',
                    values=[True],
                ),
            ],
        )
        create_efilter(
            'opportunities-opportunities_lost',
            name=_('Opportunities lost'),
            conditions=[
                build_cond(
                    operator=operators.EqualsOperator,
                    field_name='sales_phase__lost',
                    values=[True],
                ),
            ],
        )
        create_efilter(
            'opportunities-neither_won_nor_lost_opportunities',
            name=_('Neither won nor lost opportunities'),
            conditions=[
                build_cond(
                    operator=operators.EqualsNotOperator,
                    field_name='sales_phase__won',
                    values=[True],
                ),
                build_cond(
                    operator=operators.EqualsNotOperator,
                    field_name='sales_phase__lost',
                    values=[True],
                ),
            ],
        )

        # ---------------------------
        HeaderFilter.objects.create_if_needed(
            pk=constants.DEFAULT_HFILTER_OPPORTUNITY,
            model=Opportunity,
            name=_('Opportunity view'),
            cells_desc=[
                (EntityCellRegularField, {
                    'name': 'name'
                }),
                EntityCellRelation(model=Opportunity, rtype=rt_sub_targets),
                (EntityCellRegularField, {
                    'name': 'sales_phase'
                }),
                (EntityCellRegularField, {
                    'name': 'estimated_sales'
                }),
                (EntityCellRegularField, {
                    'name': 'made_sales'
                }),
                (EntityCellRegularField, {
                    'name': 'closing_date'
                }),
            ],
        )

        # ---------------------------
        common_groups_desc = [
            {
                'name': _('Description'),
                'layout': LAYOUT_DUAL_SECOND,
                'cells': [
                    (EntityCellRegularField, {
                        'name': 'description'
                    }),
                ],
            },
            {
                'name':
                _('Custom fields'),
                'layout':
                LAYOUT_DUAL_SECOND,
                'cells': [
                    (
                        EntityCellCustomFormSpecial,
                        {
                            'name':
                            EntityCellCustomFormSpecial.REMAINING_CUSTOMFIELDS
                        },
                    ),
                ],
            },
        ]
        common_field_names = [
            'reference',
            'estimated_sales',
            'made_sales',
            'currency',
            'sales_phase',
            'chance_to_win',
            'expected_closing_date',
            'closing_date',
            'origin',
            'first_action_date',
        ]

        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.OPPORTUNITY_CREATION_CFORM,
            groups_desc=[
                {
                    'name':
                    _('General information'),
                    'layout':
                    LAYOUT_DUAL_FIRST,
                    'cells': [
                        (EntityCellRegularField, {
                            'name': 'user'
                        }),
                        (EntityCellRegularField, {
                            'name': 'name'
                        }),
                        OppEmitterSubCell().into_cell(),
                        OppTargetSubCell().into_cell(),
                        *((EntityCellRegularField, {
                            'name': fname
                        }) for fname in common_field_names),
                        (
                            EntityCellCustomFormSpecial,
                            {
                                'name':
                                EntityCellCustomFormSpecial.
                                REMAINING_REGULARFIELDS
                            },
                        ),
                    ],
                },
                *common_groups_desc,
                {
                    'name':
                    _('Properties'),
                    'cells': [
                        (
                            EntityCellCustomFormSpecial,
                            {
                                'name':
                                EntityCellCustomFormSpecial.CREME_PROPERTIES
                            },
                        ),
                    ],
                },
                {
                    'name':
                    _('Relationships'),
                    'cells': [
                        (
                            EntityCellCustomFormSpecial,
                            {
                                'name': EntityCellCustomFormSpecial.RELATIONS
                            },
                        ),
                    ],
                },
            ],
        )
        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.OPPORTUNITY_EDITION_CFORM,
            groups_desc=[
                {
                    'name':
                    _('General information'),
                    'cells': [
                        (EntityCellRegularField, {
                            'name': 'user'
                        }),
                        (EntityCellRegularField, {
                            'name': 'name'
                        }),
                        OppTargetSubCell().into_cell(),
                        *((EntityCellRegularField, {
                            'name': fname
                        }) for fname in common_field_names),
                        (
                            EntityCellCustomFormSpecial,
                            {
                                'name':
                                EntityCellCustomFormSpecial.
                                REMAINING_REGULARFIELDS
                            },
                        ),
                    ],
                },
                *common_groups_desc,
            ],
        )

        # ---------------------------
        SearchConfigItem.objects.create_if_needed(
            Opportunity,
            ['name', 'made_sales', 'sales_phase__name', 'origin__name'],
        )

        # ---------------------------
        # TODO: move to "not already_populated" section in creme2.4
        if not MenuConfigItem.objects.filter(
                entry_id__startswith='opportunities-').exists():
            container = MenuConfigItem.objects.get_or_create(
                entry_id=ContainerEntry.id,
                entry_data={'label': _('Commercial')},
                defaults={'order': 30},
            )[0]

            MenuConfigItem.objects.create(
                entry_id=menu.OpportunitiesEntry.id,
                order=10,
                parent=container,
            )

            creations = MenuConfigItem.objects.filter(
                entry_id=ContainerEntry.id,
                entry_data={
                    'label': _('+ Creation')
                },
            ).first()
            if creations is not None:
                MenuConfigItem.objects.create(
                    entry_id=menu.OpportunityCreationEntry.id,
                    order=30,
                    parent=creations,
                )

        # ---------------------------
        if not already_populated:
            create_sphase = SalesPhase.objects.create
            create_sphase(order=1, name=_('Forthcoming'))
            create_sphase(order=4,
                          name=pgettext('opportunities-sales_phase',
                                        'Abandoned'))
            create_sphase(order=5,
                          name=pgettext('opportunities-sales_phase', 'Won'),
                          won=True)
            create_sphase(order=6,
                          name=pgettext('opportunities-sales_phase', 'Lost'),
                          lost=True)
            create_sphase(order=3, name=_('Under negotiation'))
            create_sphase(order=2, name=_('In progress'))

            # ---------------------------
            create_origin = Origin.objects.create
            create_origin(name=pgettext('opportunities-origin', 'None'))
            create_origin(name=_('Web site'))
            create_origin(name=_('Mouth'))
            create_origin(name=_('Show'))
            create_origin(name=_('Direct email'))
            create_origin(name=_('Direct phone call'))
            create_origin(name=_('Employee'))
            create_origin(name=_('Partner'))
            create_origin(name=pgettext('opportunities-origin', 'Other'))

            # ---------------------------
            create_button = ButtonMenuItem.objects.create_if_needed
            create_button(
                model=Organisation,
                button=LinkedOpportunityButton,
                order=30,
            )
            create_button(
                model=Contact,
                button=LinkedOpportunityButton,
                order=30,
            )

            # ---------------------------
            LEFT = BrickDetailviewLocation.LEFT
            RIGHT = BrickDetailviewLocation.RIGHT

            build_cell = EntityCellRegularField.build
            cbci = CustomBrickConfigItem.objects.create(
                id='opportunities-complementary',
                name=_('Opportunity complementary information'),
                content_type=Opportunity,
                cells=[
                    build_cell(Opportunity, 'reference'),
                    build_cell(Opportunity, 'currency'),
                    build_cell(Opportunity, 'chance_to_win'),
                    build_cell(Opportunity, 'expected_closing_date'),
                    build_cell(Opportunity, 'closing_date'),
                    build_cell(Opportunity, 'origin'),
                    build_cell(Opportunity, 'first_action_date'),
                    build_cell(Opportunity, 'description'),
                ],
            )

            BrickDetailviewLocation.objects.multi_create(
                defaults={
                    'model': Opportunity,
                    'zone': LEFT
                },
                data=[
                    {
                        'brick': bricks.OpportunityCardHatBrick,
                        'order': 1,
                        'zone': BrickDetailviewLocation.HAT,
                    },
                    {
                        'brick': cbci.brick_id,
                        'order': 5
                    },
                    {
                        'brick': core_bricks.CustomFieldsBrick,
                        'order': 40
                    },
                    {
                        'brick': bricks.BusinessManagersBrick,
                        'order': 60
                    },
                    {
                        'brick': bricks.LinkedContactsBrick,
                        'order': 62
                    },
                    {
                        'brick': bricks.LinkedProductsBrick,
                        'order': 64
                    },
                    {
                        'brick': bricks.LinkedServicesBrick,
                        'order': 66
                    },
                    {
                        'brick': core_bricks.PropertiesBrick,
                        'order': 450
                    },
                    {
                        'brick': core_bricks.RelationsBrick,
                        'order': 500
                    },
                    {
                        'brick': bricks.OppTargetBrick,
                        'order': 1,
                        'zone': RIGHT
                    },
                    {
                        'brick': bricks.OppTotalBrick,
                        'order': 2,
                        'zone': RIGHT
                    },
                    {
                        'brick': core_bricks.HistoryBrick,
                        'order': 20,
                        'zone': RIGHT
                    },
                ],
            )

            if apps.is_installed('creme.activities'):
                logger.info(
                    'Activities app is installed'
                    ' => we use the "Future activities" & "Past activities" blocks'
                )

                from creme.activities import bricks as act_bricks

                BrickDetailviewLocation.objects.multi_create(
                    defaults={
                        'model': Opportunity,
                        'zone': RIGHT
                    },
                    data=[
                        {
                            'brick': act_bricks.FutureActivitiesBrick,
                            'order': 20
                        },
                        {
                            'brick': act_bricks.PastActivitiesBrick,
                            'order': 21
                        },
                    ],
                )

            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

                BrickDetailviewLocation.objects.multi_create(
                    defaults={
                        'model': Opportunity,
                        'zone': RIGHT
                    },
                    data=[
                        {
                            'brick': a_bricks.TodosBrick,
                            'order': 100
                        },
                        {
                            'brick': a_bricks.MemosBrick,
                            'order': 200
                        },
                        {
                            'brick': a_bricks.AlertsBrick,
                            'order': 300
                        },
                        {
                            'brick': a_bricks.UserMessagesBrick,
                            'order': 500
                        },
                    ],
                )

            if apps.is_installed('creme.documents'):
                # logger.info('Documents app is installed
                # => we use the documents block on detail view')

                from creme.documents.bricks import LinkedDocsBrick

                BrickDetailviewLocation.objects.create_if_needed(
                    brick=LinkedDocsBrick,
                    order=600,
                    zone=RIGHT,
                    model=Opportunity,
                )

            if apps.is_installed('creme.billing'):
                logger.info('Billing app is installed'
                            ' => we use the billing blocks on detail view')

                BrickDetailviewLocation.objects.multi_create(
                    defaults={
                        'model': Opportunity,
                        'zone': LEFT
                    },
                    data=[
                        {
                            'brick': bricks.QuotesBrick,
                            'order': 70
                        },
                        {
                            'brick': bricks.SalesOrdersBrick,
                            'order': 72
                        },
                        {
                            'brick': bricks.InvoicesBrick,
                            'order': 74
                        },
                    ],
                )

            if apps.is_installed('creme.emails'):
                logger.info('Emails app is installed'
                            ' => we use the emails blocks on detail view')

                from creme.emails.bricks import MailsHistoryBrick

                BrickDetailviewLocation.objects.create_if_needed(
                    brick=MailsHistoryBrick,
                    order=600,
                    zone=RIGHT,
                    model=Opportunity,
                )

            BrickDetailviewLocation.objects.create_if_needed(
                brick=bricks.TargettingOpportunitiesBrick,
                order=16,
                zone=RIGHT,
                model=Organisation,
            )

            # ---------------------------
            if apps.is_installed('creme.reports'):
                logger.info(
                    'Reports app is installed'
                    ' => we create an Opportunity report, with 2 graphs, and related blocks'
                )
                self.create_report_n_graphes(rt_obj_emit_orga)
示例#24
0
    def cells(self, not_hiddable_cell_keys=()):
        model = self.model

        for rtype in RelationType.objects.compatible(model,
                                                     include_internals=True):
            yield EntityCellRelation(model=model, rtype=rtype)
示例#25
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)
示例#26
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)
示例#27
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)
示例#28
0
    def populate(self):
        already_populated = 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 = RelationType.create(*rt_info)
            rt_map[rt.id] = rt
            rt_map[sym_rt.id] = sym_rt

        get_rtype = RelationType.objects.get
        get_rtype(pk=core_constants.REL_SUB_HAS).add_subject_ctypes(
            Contact, Organisation)
        get_rtype(
            pk=core_constants.REL_OBJ_HAS).add_subject_ctypes(Organisation)

        # ---------------------------
        EntityFilter.objects.smart_update_or_create(
            constants.FILTER_MANAGED_ORGA,
            name=_('Managed by creme'),
            model=Organisation,
            user='******',
            conditions=[
                condition_handler.RegularFieldConditionHandler.build_condition(
                    model=Organisation,
                    operator=operators.EqualsOperator,
                    field_name='is_managed',
                    values=[True],
                ),
            ],
        )
        EntityFilter.objects.smart_update_or_create(
            constants.FILTER_CONTACT_ME,
            name=_('Me'),
            model=Contact,
            user='******',
            conditions=[
                condition_handler.RegularFieldConditionHandler.build_condition(
                    model=Contact,
                    operator=operators.EqualsOperator,
                    field_name='is_user',
                    values=[operands.CurrentUserOperand.type_id],
                ),
            ],
        )

        # ---------------------------
        create_hf = HeaderFilter.objects.create_if_needed
        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],
                ),
            ],
        )

        # ---------------------------
        creation_only_groups_desc = [
            {
                'name':
                _('Properties'),
                'cells': [
                    (
                        EntityCellCustomFormSpecial,
                        {
                            'name':
                            EntityCellCustomFormSpecial.CREME_PROPERTIES
                        },
                    ),
                ],
            },
            {
                'name':
                _('Relationships'),
                'cells': [
                    (
                        EntityCellCustomFormSpecial,
                        {
                            'name': EntityCellCustomFormSpecial.RELATIONS
                        },
                    ),
                ],
            },
        ]
        description_group_desc = {
            'name': _('Description'),
            'layout': LAYOUT_DUAL_SECOND,
            'cells': [
                (EntityCellRegularField, {
                    'name': 'description'
                }),
            ],
        }
        cfields_group_desc = {
            'name':
            _('Custom fields'),
            'layout':
            LAYOUT_DUAL_SECOND,
            'cells': [
                (
                    EntityCellCustomFormSpecial,
                    {
                        'name':
                        EntityCellCustomFormSpecial.REMAINING_CUSTOMFIELDS
                    },
                ),
            ],
        }
        contact_groups_desc = [
            {
                'name':
                _('General information'),
                'layout':
                LAYOUT_DUAL_FIRST,
                'cells': [
                    (EntityCellRegularField, {
                        'name': 'user'
                    }),
                    (EntityCellRegularField, {
                        'name': 'civility'
                    }),
                    (EntityCellRegularField, {
                        'name': 'last_name'
                    }),
                    (EntityCellRegularField, {
                        'name': 'first_name'
                    }),
                    (EntityCellRegularField, {
                        'name': 'position'
                    }),
                    (EntityCellRegularField, {
                        'name': 'full_position'
                    }),
                    (EntityCellRegularField, {
                        'name': 'sector'
                    }),
                    (EntityCellRegularField, {
                        'name': 'birthday'
                    }),
                    (EntityCellRegularField, {
                        'name': 'image'
                    }),
                    (
                        EntityCellCustomFormSpecial,
                        {
                            'name':
                            EntityCellCustomFormSpecial.REMAINING_REGULARFIELDS
                        },
                    ),
                ],
            },
            description_group_desc,
            {
                'name':
                _('Contact details'),
                'layout':
                LAYOUT_DUAL_SECOND,
                'cells': [
                    (EntityCellRegularField, {
                        'name': 'skype'
                    }),
                    (EntityCellRegularField, {
                        'name': 'phone'
                    }),
                    (EntityCellRegularField, {
                        'name': 'mobile'
                    }),
                    (EntityCellRegularField, {
                        'name': 'fax'
                    }),
                    (EntityCellRegularField, {
                        'name': 'email'
                    }),
                    (EntityCellRegularField, {
                        'name': 'url_site'
                    }),
                ],
            },
            cfields_group_desc,
            AddressesGroup(model=Contact),
        ]
        orga_groups_desc = [
            {
                'name':
                _('General information'),
                'layout':
                LAYOUT_DUAL_FIRST,
                'cells': [
                    (EntityCellRegularField, {
                        'name': 'user'
                    }),
                    (EntityCellRegularField, {
                        'name': 'name'
                    }),
                    (EntityCellRegularField, {
                        'name': 'phone'
                    }),
                    (EntityCellRegularField, {
                        'name': 'fax'
                    }),
                    (EntityCellRegularField, {
                        'name': 'email'
                    }),
                    (EntityCellRegularField, {
                        'name': 'url_site'
                    }),
                    (EntityCellRegularField, {
                        'name': 'sector'
                    }),
                    (EntityCellRegularField, {
                        'name': 'legal_form'
                    }),
                    (EntityCellRegularField, {
                        'name': 'staff_size'
                    }),
                    (EntityCellRegularField, {
                        'name': 'capital'
                    }),
                    (EntityCellRegularField, {
                        'name': 'annual_revenue'
                    }),
                    (EntityCellRegularField, {
                        'name': 'siren'
                    }),
                    (EntityCellRegularField, {
                        'name': 'naf'
                    }),
                    (EntityCellRegularField, {
                        'name': 'siret'
                    }),
                    (EntityCellRegularField, {
                        'name': 'rcs'
                    }),
                    (EntityCellRegularField, {
                        'name': 'tvaintra'
                    }),
                    (EntityCellRegularField, {
                        'name': 'subject_to_vat'
                    }),
                    (EntityCellRegularField, {
                        'name': 'creation_date'
                    }),
                    (EntityCellRegularField, {
                        'name': 'image'
                    }),
                    (
                        EntityCellCustomFormSpecial,
                        {
                            'name':
                            EntityCellCustomFormSpecial.REMAINING_REGULARFIELDS
                        },
                    ),
                ],
            },
            description_group_desc,
            cfields_group_desc,
            AddressesGroup(model=Organisation),
        ]

        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.CONTACT_CREATION_CFORM,
            groups_desc=[
                *contact_groups_desc,
                *creation_only_groups_desc,
            ],
        )
        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.CONTACT_EDITION_CFORM,
            groups_desc=contact_groups_desc,
        )
        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.ORGANISATION_CREATION_CFORM,
            groups_desc=[
                *orga_groups_desc,
                *creation_only_groups_desc,
            ],
        )
        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.ORGANISATION_EDITION_CFORM,
            groups_desc=orga_groups_desc,
        )

        # ---------------------------
        create_sci = SearchConfigItem.objects.create_if_needed
        create_sci(Contact,
                   ['last_name', 'first_name', 'phone', 'mobile', 'email'])
        create_sci(
            Organisation,
            ['name', 'phone', 'email', 'sector__title', 'legal_form__title'])

        # ---------------------------
        # TODO: move to "not already_populated" section in creme2.4
        if not MenuConfigItem.objects.filter(
                entry_id__startswith='persons-').exists():
            directory = MenuConfigItem.objects.get_or_create(
                entry_id=ContainerEntry.id,
                entry_data={'label': _('Directory')},
                defaults={'order': 20},
            )[0]

            create_mitem = MenuConfigItem.objects.create
            create_mitem(entry_id=menu.OrganisationsEntry.id,
                         order=10,
                         parent=directory)
            create_mitem(entry_id=menu.ContactsEntry.id,
                         order=20,
                         parent=directory)
            create_mitem(entry_id=menu.CustomersEntry.id,
                         order=30,
                         parent=directory)

            creations = MenuConfigItem.objects.filter(
                entry_id=ContainerEntry.id,
                entry_data={
                    'label': _('+ Creation')
                },
            ).first()
            if creations is not None:
                create_mitem(
                    entry_id=menu.OrganisationCreationEntry.id,
                    order=10,
                    parent=creations,
                )
                create_mitem(
                    entry_id=menu.ContactCreationEntry.id,
                    order=20,
                    parent=creations,
                )

        # ---------------------------
        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 = ButtonMenuItem.objects.create_if_needed
            create_bmi(model=Contact,
                       button=buttons.BecomeCustomerButton,
                       order=20)
            create_bmi(model=Contact,
                       button=buttons.BecomeProspectButton,
                       order=21)
            create_bmi(model=Contact,
                       button=buttons.BecomeSuspectButton,
                       order=22)
            create_bmi(model=Contact,
                       button=buttons.BecomeInactiveButton,
                       order=24)

            create_bmi(model=Organisation,
                       button=buttons.BecomeCustomerButton,
                       order=20)
            create_bmi(model=Organisation,
                       button=buttons.BecomeProspectButton,
                       order=21)
            create_bmi(model=Organisation,
                       button=buttons.BecomeSuspectButton,
                       order=22)
            create_bmi(model=Organisation,
                       button=buttons.BecomeInactiveButton,
                       order=23)
            create_bmi(model=Organisation,
                       button=buttons.BecomeSupplierButton,
                       order=24)
            create_bmi(model=Organisation,
                       button=buttons.AddLinkedContactButton,
                       order=25)

            # Populate bricks ------------------
            create_rbi = 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 = 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 = BrickDetailviewLocation.HAT
            LEFT = BrickDetailviewLocation.LEFT
            RIGHT = BrickDetailviewLocation.RIGHT

            BrickDetailviewLocation.objects.multi_create(
                defaults={
                    'model': Organisation,
                    'zone': LEFT
                },
                data=[
                    {
                        'brick': bricks.OrganisationCardHatBrick,
                        'order': 1,
                        'zone': HAT
                    },
                    {
                        'brick': cbci_orga_extra.brick_id,
                        'order': 5
                    },
                    {
                        'brick': core_bricks.CustomFieldsBrick,
                        'order': 40
                    },
                    {
                        'brick': bricks.PrettyAddressesBrick,
                        'order': 50
                    },
                    {
                        'brick': bricks.PrettyOtherAddressesBrick,
                        'order': 60
                    },
                    {
                        'brick': bricks.ManagersBrick,
                        'order': 100
                    },
                    {
                        'brick': bricks.EmployeesBrick,
                        'order': 120
                    },
                    {
                        'brick': core_bricks.PropertiesBrick,
                        'order': 450
                    },
                    {
                        'brick': core_bricks.RelationsBrick,
                        'order': 500
                    },
                    {
                        'brick': rbi_1.brick_id,
                        'order': 5,
                        'zone': RIGHT
                    },
                    {
                        'brick': rbi_2.brick_id,
                        'order': 10,
                        'zone': RIGHT
                    },
                    {
                        'brick': core_bricks.HistoryBrick,
                        'order': 30,
                        'zone': RIGHT
                    },
                ],
            )

            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'),
                ],
            )

            BrickDetailviewLocation.objects.multi_create(
                defaults={
                    'model': Contact,
                    'zone': LEFT
                },
                data=[
                    {
                        'brick': bricks.ContactCardHatBrick,
                        'order': 1,
                        'zone': HAT
                    },
                    {
                        'brick': cbci_contact_extra.brick_id,
                        'order': 30
                    },
                    {
                        'brick': core_bricks.CustomFieldsBrick,
                        'order': 40
                    },
                    {
                        'brick': bricks.PrettyAddressesBrick,
                        'order': 50
                    },
                    {
                        'brick': bricks.PrettyOtherAddressesBrick,
                        'order': 60
                    },
                    {
                        'brick': core_bricks.PropertiesBrick,
                        'order': 450
                    },
                    {
                        'brick': core_bricks.RelationsBrick,
                        'order': 500
                    },
                    {
                        'brick': core_bricks.HistoryBrick,
                        'order': 20,
                        'zone': RIGHT
                    },
                ],
            )

            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

                for model in (Contact, Organisation):
                    BrickDetailviewLocation.objects.multi_create(
                        defaults={
                            'model': model,
                            'zone': RIGHT
                        },
                        data=[
                            {
                                'brick': a_bricks.TodosBrick,
                                'order': 100
                            },
                            {
                                'brick': a_bricks.MemosBrick,
                                'order': 200
                            },
                            {
                                'brick': a_bricks.AlertsBrick,
                                'order': 300
                            },
                            {
                                'brick': a_bricks.UserMessagesBrick,
                                'order': 500
                            },
                        ],
                    )

            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

                BrickDetailviewLocation.objects.multi_create(
                    defaults={
                        'brick': LinkedDocsBrick,
                        'order': 600,
                        'zone': RIGHT
                    },
                    data=[
                        {
                            'model': Contact
                        },
                        {
                            'model': Organisation
                        },
                    ],
                )

            if apps.is_installed('creme.activities'):
                BrickHomeLocation.objects.create(
                    brick_id=bricks.NeglectedOrganisationsBrick.id_,
                    order=15,
                )
示例#29
0
    def populate(self):
        already_populated = RelationType.objects.filter(
            pk=constants.REL_SUB_TARGETS).exists()

        Contact = persons.get_contact_model()
        Organisation = persons.get_organisation_model()
        Product = products.get_product_model()
        Service = products.get_service_model()

        # ---------------------------
        create_rtype = RelationType.create
        rt_sub_targets = create_rtype(
            (constants.REL_SUB_TARGETS, _('targets the organisation/contact'),
             [Opportunity]),
            (constants.REL_OBJ_TARGETS, _('targeted by the opportunity'),
             [Organisation, Contact]),
            is_internal=True,
            minimal_display=(True, True),
        )[0]
        rt_obj_emit_orga = create_rtype(
            (constants.REL_SUB_EMIT_ORGA, _('has generated the opportunity'),
             [Organisation]),
            (constants.REL_OBJ_EMIT_ORGA, _('has been generated by'),
             [Opportunity]),
            is_internal=True,
            minimal_display=(True, True),
        )[1]
        create_rtype((constants.REL_SUB_LINKED_PRODUCT,
                      _('is linked to the opportunity'), [Product]),
                     (constants.REL_OBJ_LINKED_PRODUCT,
                      _('concerns the product'), [Opportunity]))
        create_rtype((constants.REL_SUB_LINKED_SERVICE,
                      _('is linked to the opportunity'), [Service]),
                     (constants.REL_OBJ_LINKED_SERVICE,
                      _('concerns the service'), [Opportunity]))
        create_rtype(
            (constants.REL_SUB_LINKED_CONTACT,
             _('involves in the opportunity'), [Contact]),
            (constants.REL_OBJ_LINKED_CONTACT, _('stages'), [Opportunity]))
        create_rtype((constants.REL_SUB_RESPONSIBLE, _('is responsible for'),
                      [Contact]),
                     (constants.REL_OBJ_RESPONSIBLE,
                      _('has as responsible contact'), [Opportunity]))

        if apps.is_installed('creme.activities'):
            logger.info(
                'Activities app is installed => an Opportunity 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(Opportunity)

        if apps.is_installed('creme.billing'):
            logger.info(
                'Billing app is installed => we create relationships between Opportunities & billing models'
            )

            from creme.billing import get_invoice_model, get_quote_model, get_sales_order_model

            Invoice = get_invoice_model()
            Quote = get_quote_model()
            SalesOrder = get_sales_order_model()

            create_rtype(
                (constants.REL_SUB_LINKED_SALESORDER,
                 _('is associate with the opportunity'), [SalesOrder]),
                (constants.REL_OBJ_LINKED_SALESORDER,
                 _('has generated the salesorder'), [Opportunity]))
            create_rtype((constants.REL_SUB_LINKED_INVOICE,
                          _('generated for the opportunity'), [Invoice]),
                         (constants.REL_OBJ_LINKED_INVOICE,
                          _('has resulted in the invoice'), [Opportunity]))
            create_rtype((constants.REL_SUB_LINKED_QUOTE,
                          _('generated for the opportunity'), [Quote]),
                         (constants.REL_OBJ_LINKED_QUOTE,
                          _('has resulted in the quote'), [Opportunity]))
            create_rtype(
                (constants.REL_SUB_CURRENT_DOC,
                 _('is the current accounting document of'),
                 [SalesOrder, Invoice, Quote]),
                (constants.REL_OBJ_CURRENT_DOC,
                 _('has as current accounting document'), [Opportunity]))

        # ---------------------------
        create_sv = SettingValue.objects.get_or_create
        create_sv(key_id=setting_keys.quote_key.id, defaults={'value': False})
        create_sv(key_id=setting_keys.target_constraint_key.id,
                  defaults={'value': True})
        create_sv(key_id=setting_keys.emitter_constraint_key.id,
                  defaults={'value': True})

        # ---------------------------
        create_efilter = partial(EntityFilter.create,
                                 model=Opportunity,
                                 user='******')
        # create_cond    = partial(EntityFilterCondition.build_4_field, model=Opportunity)
        build_cond = partial(
            condition_handler.RegularFieldConditionHandler.build_condition,
            model=Opportunity,
        )
        create_efilter(
            'opportunities-opportunities_won',
            name=_('Opportunities won'),
            conditions=[
                # create_cond(operator=EntityFilterCondition.EQUALS,
                #             name='sales_phase__won',
                #             values=[True],
                #            ),
                build_cond(
                    operator=operators.EqualsOperator,
                    field_name='sales_phase__won',
                    values=[True],
                ),
            ],
        )
        create_efilter(
            'opportunities-opportunities_lost',
            name=_('Opportunities lost'),
            conditions=[
                # create_cond(operator=EntityFilterCondition.EQUALS,
                #             name='sales_phase__lost',
                #             values=[True],
                #            ),
                build_cond(
                    operator=operators.EqualsOperator,
                    field_name='sales_phase__lost',
                    values=[True],
                ),
            ],
        )
        create_efilter(
            'opportunities-neither_won_nor_lost_opportunities',
            name=_('Neither won nor lost opportunities'),
            conditions=[
                # create_cond(operator=EntityFilterCondition.EQUALS_NOT,
                #             name='sales_phase__won',
                #             values=[True],
                #           ),
                build_cond(
                    operator=operators.EqualsNotOperator,
                    field_name='sales_phase__won',
                    values=[True],
                ),
                # create_cond(operator=EntityFilterCondition.EQUALS_NOT,
                #             name='sales_phase__lost',
                #             values=[True],
                #            ),
                build_cond(
                    operator=operators.EqualsNotOperator,
                    field_name='sales_phase__lost',
                    values=[True],
                ),
            ],
        )

        # ---------------------------
        HeaderFilter.create(
            pk=constants.DEFAULT_HFILTER_OPPORTUNITY,
            model=Opportunity,
            name=_('Opportunity view'),
            cells_desc=[
                (EntityCellRegularField, {
                    'name': 'name'
                }),
                EntityCellRelation(model=Opportunity, rtype=rt_sub_targets),
                (EntityCellRegularField, {
                    'name': 'sales_phase'
                }),
                (EntityCellRegularField, {
                    'name': 'estimated_sales'
                }),
                (EntityCellRegularField, {
                    'name': 'made_sales'
                }),
                (EntityCellRegularField, {
                    'name': 'closing_date'
                }),
            ],
        )

        # ---------------------------
        SearchConfigItem.create_if_needed(
            Opportunity,
            ['name', 'made_sales', 'sales_phase__name', 'origin__name'])

        # ---------------------------
        if not already_populated:
            create_sphase = SalesPhase.objects.create
            create_sphase(name=_('Forthcoming'), order=1)
            create_sphase(name=pgettext('opportunities-sales_phase',
                                        'Abandoned'),
                          order=4)
            create_sphase(name=pgettext('opportunities-sales_phase', 'Won'),
                          order=5,
                          won=True)
            create_sphase(name=pgettext('opportunities-sales_phase', 'Lost'),
                          order=6,
                          lost=True)
            create_sphase(name=_('Under negotiation'), order=3)
            create_sphase(name=_('In progress'), order=2)

            # ---------------------------
            create_origin = Origin.objects.create
            create_origin(name=pgettext('opportunities-origin', 'None'))
            create_origin(name=_('Web site'))
            create_origin(name=_('Mouth'))
            create_origin(name=_('Show'))
            create_origin(name=_('Direct email'))
            create_origin(name=_('Direct phone call'))
            create_origin(name=_('Employee'))
            create_origin(name=_('Partner'))
            create_origin(name=pgettext('opportunities-origin', 'Other'))

            # ---------------------------
            create_button = ButtonMenuItem.create_if_needed
            create_button(pk='opportunities-linked_opp_button',
                          model=Organisation,
                          button=LinkedOpportunityButton,
                          order=30)  # TODO: This pk is kept for compatibility
            create_button(pk='opportunities-linked_opp_button_contact',
                          model=Contact,
                          button=LinkedOpportunityButton,
                          order=30)

            # ---------------------------
            create_bdl = partial(
                BrickDetailviewLocation.objects.create_if_needed,
                model=Opportunity)
            LEFT = BrickDetailviewLocation.LEFT
            RIGHT = BrickDetailviewLocation.RIGHT

            build_cell = EntityCellRegularField.build
            cbci = CustomBrickConfigItem.objects.create(
                id='opportunities-complementary',
                name=_('Opportunity complementary information'),
                content_type=Opportunity,
                cells=[
                    build_cell(Opportunity, 'reference'),
                    build_cell(Opportunity, 'currency'),
                    build_cell(Opportunity, 'chance_to_win'),
                    build_cell(Opportunity, 'expected_closing_date'),
                    build_cell(Opportunity, 'closing_date'),
                    build_cell(Opportunity, 'origin'),
                    build_cell(Opportunity, 'first_action_date'),
                    build_cell(Opportunity, 'description'),
                ],
            )

            create_bdl(brick=bricks.OpportunityCardHatBrick,
                       order=1,
                       zone=BrickDetailviewLocation.HAT)
            create_bdl(brick=cbci.generate_id(), order=5, zone=LEFT)
            create_bdl(brick=core_bricks.CustomFieldsBrick,
                       order=40,
                       zone=LEFT)
            create_bdl(brick=bricks.BusinessManagersBrick, order=60, zone=LEFT)
            create_bdl(brick=bricks.LinkedContactsBrick, order=62, zone=LEFT)
            create_bdl(brick=bricks.LinkedProductsBrick, order=64, zone=LEFT)
            create_bdl(brick=bricks.LinkedServicesBrick, order=66, zone=LEFT)
            create_bdl(brick=core_bricks.PropertiesBrick, order=450, zone=LEFT)
            create_bdl(brick=core_bricks.RelationsBrick, order=500, zone=LEFT)
            create_bdl(brick=bricks.OppTargetBrick, order=1, zone=RIGHT)
            create_bdl(brick=bricks.OppTotalBrick, order=2, zone=RIGHT)
            create_bdl(brick=core_bricks.HistoryBrick, order=20, zone=RIGHT)

            if apps.is_installed('creme.activities'):
                logger.info(
                    'Activities app is installed => we use the "Future activities" & "Past activities" blocks'
                )

                from creme.activities import bricks as act_bricks

                create_bdl(brick=act_bricks.FutureActivitiesBrick,
                           order=20,
                           zone=RIGHT)
                create_bdl(brick=act_bricks.PastActivitiesBrick,
                           order=21,
                           zone=RIGHT)

            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 assistants_bricks

                create_bdl(brick=assistants_bricks.TodosBrick,
                           order=100,
                           zone=RIGHT)
                create_bdl(brick=assistants_bricks.MemosBrick,
                           order=200,
                           zone=RIGHT)
                create_bdl(brick=assistants_bricks.AlertsBrick,
                           order=300,
                           zone=RIGHT)
                create_bdl(brick=assistants_bricks.UserMessagesBrick,
                           order=500,
                           zone=RIGHT)

            if apps.is_installed('creme.documents'):
                # logger.info('Documents app is installed => we use the documents block on detail view')

                from creme.documents.bricks import LinkedDocsBrick

                create_bdl(brick=LinkedDocsBrick, order=600, zone=RIGHT)

            if apps.is_installed('creme.billing'):
                logger.info(
                    'Billing app is installed => we use the billing blocks on detail view'
                )

                create_bdl(brick=bricks.QuotesBrick, order=70, zone=LEFT)
                create_bdl(brick=bricks.SalesOrdersBrick, order=72, zone=LEFT)
                create_bdl(brick=bricks.InvoicesBrick, order=74, zone=LEFT)

            if apps.is_installed('creme.emails'):
                logger.info(
                    'Emails app is installed => we use the emails blocks on detail view'
                )

                from creme.emails.bricks import MailsHistoryBrick

                create_bdl(brick=MailsHistoryBrick, order=600, zone=RIGHT)

            create_bdl(brick=bricks.TargettingOpportunitiesBrick,
                       order=16,
                       zone=RIGHT,
                       model=Organisation)

            # ---------------------------
            if apps.is_installed('creme.reports'):
                logger.info(
                    'Reports app is installed => we create an Opportunity report, with 2 graphs, and related blocks'
                )
                self.create_report_n_graphes(rt_obj_emit_orga)