Exemplo n.º 1
0
def post_save_relation_opp_subject_activity(sender, instance, **kwargs):
    if instance.type_id == REL_OBJ_ACTIVITY_SUBJECT:
        object_entity = instance.object_entity
        get_ct = ContentType.objects.get_for_model

        if object_entity.entity_type == get_ct(get_opportunity_model()):
            # relations = Relation.objects.filter(subject_entity=object_entity,
            #                                     type=REL_SUB_COMPLETE_GOAL,
            #                                     object_entity__entity_type=get_ct(get_act_model()),
            #                                    )
            #
            # create_relation = partial(Relation.objects.create,
            #                           subject_entity=instance.subject_entity,
            #                           type_id=REL_SUB_COMPLETE_GOAL,
            #                           user=instance.user,
            #                          )
            #
            # for relation in relations:
            #     create_relation(object_entity=relation.object_entity)
            activity = instance.subject_entity
            user = instance.user

            Relation.objects.safe_multi_save(
                Relation(
                    subject_entity=activity,
                    type_id=REL_SUB_COMPLETE_GOAL,
                    object_entity=relation.object_entity,
                    user=user,
                ) for relation in Relation.objects.filter(
                    subject_entity_id=object_entity.id,
                    type=REL_SUB_COMPLETE_GOAL,
                    object_entity__entity_type=get_ct(get_act_model()),
                ))
Exemplo n.º 2
0
    def get_related_opportunities(self):
        relopps = self._related_opportunities

        if relopps is None:
            relopps = list(get_opportunity_model().objects.filter(
                is_deleted=False,
                relations__type=REL_SUB_COMPLETE_GOAL,
                relations__object_entity=self.id,
            ))
            self._related_opportunities = relopps

        return relopps
Exemplo n.º 3
0
    def _execute(self, job):
        from creme import persons
        from creme.opportunities import get_opportunity_model
        from creme.opportunities.constants import REL_SUB_TARGETS

        from .models import CommercialApproach

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

        emails = []

        get_ct = ContentType.objects.get_for_model
        ct_orga = get_ct(Organisation)
        ct_contact = get_ct(Contact)
        ct_opp = get_ct(Opportunity)

        now_value = now()
        managed_orga_ids = [
            *Organisation.objects.filter(is_managed=True).values_list(
                'id', flat=True),
        ]
        opp_filter = Opportunity.objects.filter

        EMAIL_SENDER = settings.EMAIL_SENDER

        for rtype, delay in self.list_target_orga:
            com_apps_filter = CommercialApproach.objects.filter(
                creation_date__gt=now_value - timedelta(days=delay), ).filter

            # TODO: are 'values_list' real optimizations here ??
            #       ==> remove them when CommercialApproach use real ForeignKey
            for orga in Organisation.objects.filter(
                    is_managed=False,
                    relations__type=rtype,
                    relations__object_entity__in=managed_orga_ids,
            ):
                if com_apps_filter(entity_content_type=ct_orga,
                                   entity_id=orga.id).exists():
                    continue

                if com_apps_filter(
                        entity_content_type=ct_contact,
                        entity_id__in=orga.get_managers().values_list(
                            'id', flat=True),
                ).exists():
                    continue

                if com_apps_filter(
                        entity_content_type=ct_contact,
                        entity_id__in=orga.get_employees().values_list(
                            'id', flat=True),
                ).exists():
                    continue

                if com_apps_filter(
                        entity_content_type=ct_opp,
                        entity_id__in=opp_filter(
                            relations__type=REL_SUB_TARGETS,
                            relations__object_entity=orga,
                        ).values_list('id', flat=True),
                ).exists():
                    continue

                emails.append(
                    EmailMessage(
                        gettext(
                            '[CremeCRM] The organisation «{}» seems neglected'
                        ).format(orga),
                        gettext(
                            "It seems you haven't created a commercial approach for "
                            "the organisation «{orga}» since {delay} days.").
                        format(
                            orga=orga,
                            delay=delay,
                        ),
                        EMAIL_SENDER,
                        [orga.user.email],
                    ))

        # TODO: factorise jobs which send emails
        if emails:
            try:
                with get_connection() as connection:
                    connection.send_messages(emails)
            except Exception as e:
                JobResult.objects.create(
                    job=job,
                    messages=[
                        gettext('An error has occurred while sending emails'),
                        gettext('Original error: {}').format(e),
                    ],
                )
Exemplo n.º 4
0
from creme import commercial
from .constants import REL_OBJ_COMPLETE_GOAL
from .models import (
    CommercialApproach,
    MarketSegment,
    MarketSegmentDescription,
    CommercialAsset,
    MarketSegmentCharm,
    ActObjective,
    ActObjectivePatternComponent,
)
from .setting_keys import orga_approaches_key

get_ct = ContentType.objects.get_for_model
Opportunity = get_opportunity_model()
Act = commercial.get_act_model()
ActObjectivePattern = commercial.get_pattern_model()
Strategy = commercial.get_strategy_model()


class ApproachesBrick(QuerysetBrick):
    id_ = QuerysetBrick.generate_id('commercial', 'approaches')
    dependencies = (CommercialApproach, )
    # order_by = 'title'
    order_by = '-creation_date'
    verbose_name = _('Commercial approaches')
    template_name = 'commercial/bricks/approaches.html'

    # TODO: factorise with assistants blocks (CremeEntity method ??)
    @staticmethod
Exemplo n.º 5
0
    def populate(self):
        already_populated = RelationType.objects.filter(
            pk=constants.REL_SUB_IS_INVITED_TO, ).exists()

        Event = get_event_model()
        Contact = get_contact_model()
        Opportunity = get_opportunity_model()

        create_rtype = RelationType.create
        create_rtype(
            (constants.REL_SUB_IS_INVITED_TO, _('is invited to the event'),
             [Contact]),
            (constants.REL_OBJ_IS_INVITED_TO, _('has invited'), [Event]),
            is_internal=True,
        )
        create_rtype(
            (
                constants.REL_SUB_ACCEPTED_INVITATION,
                _('accepted the invitation to the event'),
                [Contact],
            ),
            (
                constants.REL_OBJ_ACCEPTED_INVITATION,
                _('prepares to receive'),
                [Event],
            ),
            is_internal=True,
        )
        create_rtype(
            (
                constants.REL_SUB_REFUSED_INVITATION,
                _('refused the invitation to the event'),
                [Contact],
            ),
            (
                constants.REL_OBJ_REFUSED_INVITATION,
                _('do not prepare to receive any more'),
                [Event],
            ),
            is_internal=True,
        )
        create_rtype(
            (constants.REL_SUB_CAME_EVENT, _('came to the event'), [Contact]),
            (constants.REL_OBJ_CAME_EVENT, _('received'), [Event]),
            is_internal=True,
        )
        create_rtype(
            (constants.REL_SUB_NOT_CAME_EVENT, _('did not come to the event'),
             [Contact]),
            (constants.REL_OBJ_NOT_CAME_EVENT, _('did not receive'), [Event]),
            is_internal=True,
        )
        create_rtype(
            (
                constants.REL_SUB_GEN_BY_EVENT,
                _('generated by the event'),
                [Opportunity],
            ),
            (
                constants.REL_OBJ_GEN_BY_EVENT,
                _('(event) has generated the opportunity'),
                [Event],
            ),
            is_internal=True,
        )

        # ---------------------------
        HeaderFilter.objects.create_if_needed(
            pk=constants.DEFAULT_HFILTER_EVENT,
            name=_('Event view'),
            model=Event,
            cells_desc=[
                (EntityCellRegularField, {
                    'name': 'name'
                }),
                (EntityCellRegularField, {
                    'name': 'type'
                }),
                (EntityCellRegularField, {
                    'name': 'start_date'
                }),
                (EntityCellRegularField, {
                    'name': 'end_date'
                }),
            ],
        )

        # ---------------------------
        base_groups_desc = [
            {
                'name':
                _('General information'),
                'layout':
                LAYOUT_DUAL_FIRST,
                'cells': [
                    (EntityCellRegularField, {
                        'name': 'user'
                    }),
                    (EntityCellRegularField, {
                        'name': 'name'
                    }),
                    (EntityCellRegularField, {
                        'name': 'type'
                    }),
                    (EntityCellRegularField, {
                        'name': 'place'
                    }),
                    (EntityCellRegularField, {
                        'name': 'start_date'
                    }),
                    (EntityCellRegularField, {
                        'name': 'end_date'
                    }),
                    (EntityCellRegularField, {
                        'name': 'budget'
                    }),
                    (EntityCellRegularField, {
                        'name': 'final_cost'
                    }),
                    (
                        EntityCellCustomFormSpecial,
                        {
                            'name':
                            EntityCellCustomFormSpecial.REMAINING_REGULARFIELDS
                        },
                    ),
                ],
            },
            {
                'name': _('Description'),
                'layout': LAYOUT_DUAL_SECOND,
                'cells': [
                    (EntityCellRegularField, {
                        'name': 'description'
                    }),
                ],
            },
            {
                'name':
                _('Custom fields'),
                'layout':
                LAYOUT_DUAL_SECOND,
                'cells': [
                    (
                        EntityCellCustomFormSpecial,
                        {
                            'name':
                            EntityCellCustomFormSpecial.REMAINING_CUSTOMFIELDS
                        },
                    ),
                ],
            },
        ]

        CustomFormConfigItem.objects.create_if_needed(
            descriptor=custom_forms.EVENT_CREATION_CFORM,
            groups_desc=[
                *base_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.EVENT_EDITION_CFORM,
            groups_desc=base_groups_desc,
        )

        # ---------------------------
        SearchConfigItem.objects.create_if_needed(
            Event,
            ['name', 'description', 'type__name'],
        )

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

            MenuConfigItem.objects.create(
                entry_id=EventsEntry.id,
                parent=container,
                order=200,
            )

        # ---------------------------
        if not already_populated:
            for i, name in enumerate(
                [_('Show'),
                 _('Conference'),
                 _('Breakfast'),
                 _('Brunch')],
                    start=1,
            ):
                create_if_needed(EventType, {'pk': i}, name=name)

            RIGHT = BrickDetailviewLocation.RIGHT

            BrickDetailviewLocation.objects.multi_create(
                defaults={
                    'model': Event,
                    'zone': BrickDetailviewLocation.LEFT
                },
                data=[
                    {
                        'order': 5
                    },  # generic info block
                    {
                        'brick': core_bricks.CustomFieldsBrick,
                        'order': 40
                    },
                    {
                        'brick': core_bricks.PropertiesBrick,
                        'order': 450
                    },
                    {
                        'brick': core_bricks.RelationsBrick,
                        'order': 500
                    },
                    {
                        'brick': bricks.ResultsBrick,
                        'order': 2,
                        'zone': RIGHT
                    },
                    {
                        '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 view')

                from creme.assistants import bricks as a_bricks

                BrickDetailviewLocation.objects.multi_create(
                    defaults={
                        'model': Event,
                        '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 blocks on detail view')

                from creme.documents.bricks import LinkedDocsBrick

                BrickDetailviewLocation.objects.create_if_needed(
                    brick=LinkedDocsBrick,
                    order=600,
                    zone=RIGHT,
                    model=Event,
                )
Exemplo n.º 6
0
# -*- coding: utf-8 -*-

from django.utils.translation import gettext_lazy as _

from creme import opportunities
from creme.creme_core.gui.custom_form import CustomFormDescriptor
from creme.opportunities.forms import opportunity as opp_forms

Opportunity = opportunities.get_opportunity_model()

OPPORTUNITY_CREATION_CFORM = CustomFormDescriptor(
    id='opportunities-opportunity_creation',
    model=Opportunity,
    verbose_name=_('Creation form for opportunity'),
    base_form_class=opp_forms.BaseCustomForm,
    extra_sub_cells=[
        opp_forms.OppEmitterSubCell(),
        opp_forms.OppTargetSubCell(),
    ],
)
OPPORTUNITY_EDITION_CFORM = CustomFormDescriptor(
    id='opportunities-opportunity_edition',
    model=Opportunity,
    verbose_name=_('Edition form for opportunity'),
    base_form_class=opp_forms.BaseCustomForm,
    extra_sub_cells=[opp_forms.OppTargetSubCell()],
)

del Opportunity
Exemplo n.º 7
0
    def populate(self):
        already_populated = RelationType.objects.filter(pk=constants.REL_SUB_IS_INVITED_TO).exists()

        Event = get_event_model()
        Contact = get_contact_model()
        Opportunity = get_opportunity_model()

        create_rtype = RelationType.create
        create_rtype((constants.REL_SUB_IS_INVITED_TO,       _(u'is invited to the event'),               [Contact]),
                     (constants.REL_OBJ_IS_INVITED_TO,       _(u'has invited'),                           [Event]),
                     is_internal=True,
                    )
        create_rtype((constants.REL_SUB_ACCEPTED_INVITATION, _(u'accepted the invitation to the event'),  [Contact]),
                     (constants.REL_OBJ_ACCEPTED_INVITATION, _(u'prepares to receive'),                   [Event]),
                     is_internal=True,
                     )
        create_rtype((constants.REL_SUB_REFUSED_INVITATION,  _(u'refused the invitation to the event'),   [Contact]),
                     (constants.REL_OBJ_REFUSED_INVITATION,  _(u'do not prepare to receive any more'),    [Event]),
                     is_internal=True,
                    )
        create_rtype((constants.REL_SUB_CAME_EVENT,          _(u'came to the event'),                     [Contact]),
                     (constants.REL_OBJ_CAME_EVENT,          _(u'received'),                              [Event]),
                     is_internal=True,
                    )
        create_rtype((constants.REL_SUB_NOT_CAME_EVENT,      _(u'did not come to the event'),             [Contact]),
                     (constants.REL_OBJ_NOT_CAME_EVENT,      _(u'did not receive'),                       [Event]),
                     is_internal=True,
                    )
        create_rtype((constants.REL_SUB_GEN_BY_EVENT,        _(u'generated by the event'),                [Opportunity]),
                     (constants.REL_OBJ_GEN_BY_EVENT,        _(u'(event) has generated the opportunity'), [Event]),
                     is_internal=True,
                    )

        # ---------------------------
        HeaderFilter.create(pk=constants.DEFAULT_HFILTER_EVENT, name=_(u'Event view'), model=Event,
                            cells_desc=[(EntityCellRegularField, {'name': 'name'}),
                                        (EntityCellRegularField, {'name': 'type'}),
                                        (EntityCellRegularField, {'name': 'start_date'}),
                                        (EntityCellRegularField, {'name': 'end_date'}),
                                       ],
                           )

        # ---------------------------
        SearchConfigItem.create_if_needed(Event, ['name', 'description', 'type__name'])

        # ---------------------------
        if not already_populated:
            for i, name in enumerate([_(u'Show'), _(u'Conference'), _(u'Breakfast'), _(u'Brunch')], start=1):
                create_if_needed(EventType, {'pk': i}, name=name)

            create_bdl = BrickDetailviewLocation.create_if_needed
            LEFT  = BrickDetailviewLocation.LEFT
            RIGHT = BrickDetailviewLocation.RIGHT

            BrickDetailviewLocation.create_4_model_brick(          order=5,   zone=LEFT,  model=Event)
            create_bdl(brick_id=core_bricks.CustomFieldsBrick.id_, order=40,  zone=LEFT,  model=Event)
            create_bdl(brick_id=core_bricks.PropertiesBrick.id_,   order=450, zone=LEFT,  model=Event)
            create_bdl(brick_id=core_bricks.RelationsBrick.id_,    order=500, zone=LEFT,  model=Event)
            create_bdl(brick_id=bricks.ResutsBrick.id_,            order=2,   zone=RIGHT, model=Event)
            create_bdl(brick_id=core_bricks.HistoryBrick.id_,      order=20,  zone=RIGHT, model=Event)

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

                from creme.assistants import bricks as a_bricks

                create_bdl(brick_id=a_bricks.TodosBrick.id_,        order=100, zone=RIGHT, model=Event)
                create_bdl(brick_id=a_bricks.MemosBrick.id_,        order=200, zone=RIGHT, model=Event)
                create_bdl(brick_id=a_bricks.AlertsBrick.id_,       order=300, zone=RIGHT, model=Event)
                create_bdl(brick_id=a_bricks.UserMessagesBrick.id_, order=400, zone=RIGHT, model=Event)

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

                from creme.documents.bricks import LinkedDocsBrick

                create_bdl(brick_id=LinkedDocsBrick.id_, order=600, zone=RIGHT, model=Event)