Exemple #1
0
class LatexExportEngine(base.BillingExportEngine):
    id = base.BillingExportEngine.generate_id('billing', 'latex')

    FLAVOURS_INFO = {
        l10n.FR: {
            'fr_FR': {
                # Ubuntu packages needed to render correctly this theme
                #  - texlive-latex-recommended
                #  - texlive-fonts-extra
                #  - texlive-lang-french
                #  - texlive-latex-extra
                'clear':
                LatexTheme(
                    verbose_name='.pdf - LateX - Thème clair (France)',
                    templates={
                        billing.get_invoice_model():
                        'billing/export/latex/FR/fr_FR/clear/invoice.tex',
                        billing.get_credit_note_model():
                        'billing/export/latex/FR/fr_FR/clear/credit_note.tex',
                        billing.get_quote_model():
                        'billing/export/latex/FR/fr_FR/clear/quote.tex',
                        billing.get_sales_order_model():
                        'billing/export/latex/FR/fr_FR/clear/sales_order.tex',
                        billing.get_template_base_model():
                        'billing/export/latex/FR/fr_FR/clear/template.tex',
                    },
                    # TODO: by ContentType ?
                    screenshots=['billing/sample_latex.png'],
                ),
            },
        },
    }

    @property
    def flavours(self):
        model = self.model

        for country, languages in self.FLAVOURS_INFO.items():
            for language, themes in languages.items():
                for theme_id, theme_info in themes.items():
                    if model in theme_info.templates:
                        yield base.ExporterFlavour(country, language, theme_id)

    def exporter(self, flavour):
        try:
            theme = self.FLAVOURS_INFO[flavour.country][flavour.language][
                flavour.theme]
            template_path = theme.templates[self.model]
        except KeyError as e:
            logger.warning('LatexExportEngine.exporter(): invalid data [%s].',
                           e)
            return None

        return LatexExporter(
            verbose_name=theme.verbose_name,
            engine=self,
            flavour=flavour,
            template_path=template_path,
            screenshots=theme.screenshots,
        )
Exemple #2
0
class WeasyprintExportEngine(base.BillingExportEngine):
    id = base.BillingExportEngine.generate_id('billing', 'weasyprint')

    FLAVOURS_INFO = {
        l10n.FR: {
            'fr_FR': {
                'mint':
                WeasyprintTheme(
                    verbose_name='.pdf - WeasyPrint - Thème Menthe (France)',
                    # TODO: attribute "directory" ?
                    templates={
                        billing.get_invoice_model():
                        'billing/export/weasyprint/FR/fr_FR/mint/invoice.html',
                        billing.get_credit_note_model():
                        'billing/export/weasyprint/FR/fr_FR/mint/credit_note.html',
                        billing.get_quote_model():
                        'billing/export/weasyprint/FR/fr_FR/mint/quote.html',
                        billing.get_sales_order_model():
                        'billing/export/weasyprint/FR/fr_FR/mint/sales_order.html',
                        billing.get_template_base_model():
                        'billing/export/weasyprint/FR/fr_FR/mint/template.html',
                    },
                    css='billing/export/weasyprint/FR/fr_FR/mint/mint.css',
                    # TODO: by ContentType ?
                    screenshots=['billing/sample_weasyprint.png'],
                ),
            },
        },
    }

    @property
    def flavours(self):
        model = self.model

        for country, languages in self.FLAVOURS_INFO.items():
            for language, themes in languages.items():
                for theme_id, theme_info in themes.items():
                    if model in theme_info.templates:
                        yield base.ExporterFlavour(country, language, theme_id)

    def exporter(self, flavour):
        # TODO: factorise with LateX ?
        try:
            theme = self.FLAVOURS_INFO[flavour.country][flavour.language][
                flavour.theme]
            template_path = theme.templates[self.model]
        except KeyError as e:
            logger.warning(
                'WeasyprintExportEngine.exporter(): invalid data [%s].', e)
            return None

        return WeasyprintExporter(
            verbose_name=theme.verbose_name,
            engine=self,
            flavour=flavour,
            html_template_path=template_path,
            css_template_path=theme.css,
            screenshots=theme.screenshots,
        )
Exemple #3
0
class Xhtml2pdfExportEngine(base.BillingExportEngine):
    id = base.BillingExportEngine.generate_id('billing', 'xhtml2pdf')

    FLAVOURS_INFO = {
        l10n.FR: {
            'fr_FR': {
                'cappuccino':
                Xhtml2pdfTheme(
                    verbose_name='.pdf - Xhtml2pdf - Thème Cappuccino (France)',
                    # description='...',  # TODO ?
                    # TODO: attribute "directory" ?
                    templates={
                        billing.get_invoice_model():
                        'billing/export/xhtml2pdf/FR/fr_FR/cappuccino/invoice.html',
                        billing.get_credit_note_model():
                        'billing/export/xhtml2pdf/FR/fr_FR/cappuccino/credit_note.html',
                        billing.get_quote_model():
                        'billing/export/xhtml2pdf/FR/fr_FR/cappuccino/quote.html',
                        billing.get_sales_order_model():
                        'billing/export/xhtml2pdf/FR/fr_FR/cappuccino/sales_order.html',
                        billing.get_template_base_model():
                        'billing/export/xhtml2pdf/FR/fr_FR/cappuccino/template.html',
                    },
                    # TODO: by ContentType ?
                    screenshots=['billing/sample_xhtml2pdf.png'],
                ),
            },
        },
    }

    @property
    def flavours(self):
        model = self.model

        for country, languages in self.FLAVOURS_INFO.items():
            for language, themes in languages.items():
                for theme_id, theme_info in themes.items():
                    if model in theme_info.templates:
                        yield base.ExporterFlavour(country, language, theme_id)

    def exporter(self, flavour):
        try:
            theme = self.FLAVOURS_INFO[flavour.country][flavour.language][
                flavour.theme]
            template_path = theme.templates[self.model]
        except KeyError as e:
            logger.warning(
                'Xhtml2pdfExportEngine.exporter(): invalid data [%s].', e)
            return None

        return Xhtml2pdfExporter(
            verbose_name=theme.verbose_name,
            engine=self,
            flavour=flavour,
            template_path=template_path,
            screenshots=theme.screenshots,
        )
Exemple #4
0
class Export(base.EntityRelatedMixin, base.CheckedView):
    permissions = 'billing'
    entity_classes = [
        billing.get_invoice_model(),
        billing.get_credit_note_model(),
        billing.get_quote_model(),
        billing.get_sales_order_model(),
        billing.get_template_base_model(),
    ]

    def check_related_entity_permissions(self, entity, user):
        has_perm = user.has_perm_to_view_or_die
        has_perm(entity)
        has_perm(entity.source)
        has_perm(entity.target)

    def get(self, request, *args, **kwargs):
        entity = self.get_related_entity()
        config_item = get_object_or_404(
            ExporterConfigItem,
            content_type=entity.entity_type,
        )

        engine_id = config_item.engine_id
        if not engine_id:
            raise ConflictError(_(
                'The engine is not configured ; '
                'go to the configuration of the app «Billing».'
            ))

        exporter = BillingExportEngineManager().exporter(
            engine_id=engine_id,
            flavour_id=config_item.flavour_id,
            model=type(entity),
        )

        if exporter is None:
            raise ConflictError(_(
                'The configured exporter is invalid ; '
                'go to the configuration of the app «Billing».'
            ))

        export_result = exporter.export(
            entity=entity, user=request.user,
        )

        if isinstance(export_result, HttpResponse):
            return export_result

        assert export_result, FileRef

        return HttpResponseRedirect(export_result.get_download_absolute_url())
Exemple #5
0
    def all_apps_ready(self):
        from creme import billing

        self.CreditNote = billing.get_credit_note_model()
        self.Invoice = billing.get_invoice_model()
        self.Quote = billing.get_quote_model()
        self.SalesOrder = billing.get_sales_order_model()
        self.TemplateBase = billing.get_template_base_model()
        self.ProductLine = billing.get_product_line_model()
        self.ServiceLine = billing.get_service_line_model()
        super().all_apps_ready()

        self.register_billing_algorithm()
        self.register_billing_lines()

        from . import signals
Exemple #6
0
        get_template_base_model,
    )
    from creme.billing.models import (
        CreditNoteStatus,
        InvoiceStatus,
        QuoteStatus,
        SalesOrderStatus,
    )
    from creme.billing.tests.base import (
        skipIfCustomCreditNote,
        skipIfCustomInvoice,
        skipIfCustomQuote,
        skipIfCustomSalesOrder,
    )

    CreditNote = get_credit_note_model()
    Invoice = get_invoice_model()
    Quote = get_quote_model()
    SalesOrder = get_sales_order_model()
    TemplateBase = get_template_base_model()
else:
    from unittest import skip

    def skipIfCustomCreditNote(test_func):
        return skip('App "billing" not installed')(test_func)

    def skipIfCustomInvoice(test_func):
        return skip('App "billing" not installed')(test_func)

    def skipIfCustomQuote(test_func):
        return skip('App "billing" not installed')(test_func)
Exemple #7
0
from .forms.templatebase import BillingTemplateStatusSubCell
from .models import (
    AdditionalInformation,
    CreditNoteStatus,
    ExporterConfigItem,
    InvoiceStatus,
    PaymentTerms,
    QuoteStatus,
    SalesOrderStatus,
    SettlementTerms,
)
from .registry import lines_registry

logger = logging.getLogger(__name__)

CreditNote = billing.get_credit_note_model()
Invoice = billing.get_invoice_model()
Quote = billing.get_quote_model()
SalesOrder = billing.get_sales_order_model()
TemplateBase = billing.get_template_base_model()

ProductLine = billing.get_product_line_model()
ServiceLine = billing.get_service_line_model()


class Populator(BasePopulator):
    dependencies = ['creme_core', 'persons', 'activities']

    def populate(self):
        already_populated = RelationType.objects.filter(
            pk=constants.REL_SUB_BILL_ISSUED, ).exists()
from django.urls import reverse
from django.utils.encoding import smart_str
from django.utils.translation import gettext as _

from creme.creme_core.auth import decorators as auth_dec
from creme.creme_core.core.exceptions import ConflictError
from creme.creme_core.models import CremeEntity, FileRef
from creme.creme_core.utils.file_handling import FileCreator
from creme.creme_core.utils.secure_filename import secure_filename

from creme import billing

logger = logging.getLogger(__name__)
TEMPLATE_PATHS = {
    billing.get_invoice_model(): 'billing/templates/invoice.tex',
    billing.get_credit_note_model(): 'billing/templates/billings.tex',
    billing.get_quote_model(): 'billing/templates/billings.tex',
    billing.get_sales_order_model(): 'billing/templates/billings.tex',
    billing.get_template_base_model(): 'billing/templates/billings.tex',
}


@auth_dec.login_required
@auth_dec.permission_required('billing')
def export_as_pdf(request, base_id):
    entity = get_object_or_404(CremeEntity, pk=base_id).get_real_entity()

    has_perm = request.user.has_perm_to_view_or_die
    has_perm(entity)

    template_path = TEMPLATE_PATHS.get(entity.__class__)
Exemple #9
0
# -*- coding: utf-8 -*-

from creme import billing
from .forms.templatebase import TemplateBaseCreateForm

TemplateBase = billing.get_template_base_model()
to_register = (
    (billing.get_invoice_model(), TemplateBase, TemplateBaseCreateForm),
    (billing.get_quote_model(), TemplateBase, TemplateBaseCreateForm),
    (billing.get_sales_order_model(), TemplateBase, TemplateBaseCreateForm),
    (billing.get_credit_note_model(), TemplateBase, TemplateBaseCreateForm),
)
Exemple #10
0
        model_filter = model.objects.filter
        orga_ids = {
            *model_filter(
                organisation__in=(sender, other_entity), ).values_list(
                    'organisation', flat=True)
        }

        if len(orga_ids) == 2:
            orga_2_clean = orga_2_clean or get_orga_2_clean()
            model_filter(organisation=orga_2_clean).delete()
        else:
            return  # We avoid the queries for the next model (if it's the first iteration)


STATUSES_REPLACEMENTS = {
    billing.get_credit_note_model(): 'status',
    Invoice: 'status',
    billing.get_quote_model(): 'status',
    billing.get_sales_order_model(): 'status',
}


@receiver(core_signals.pre_replace_and_delete)
def handle_replace_statuses(sender, model_field, replacing_instance, **kwargs):
    model = model_field.model

    if STATUSES_REPLACEMENTS.get(model) == model_field.name:
        tpl_mngr = billing.get_template_base_model().objects

        for pk in tpl_mngr.filter(status_id=sender.pk,
                                  ct=ContentType.objects.get_for_model(model),
# -*- coding: utf-8 -*-

from creme import billing

from .custom_forms import BTEMPLATE_CREATION_CFORM

TemplateBase = billing.get_template_base_model()
to_register = (
    (billing.get_invoice_model(), TemplateBase, BTEMPLATE_CREATION_CFORM),
    (billing.get_quote_model(), TemplateBase, BTEMPLATE_CREATION_CFORM),
    (billing.get_sales_order_model(), TemplateBase, BTEMPLATE_CREATION_CFORM),
    (billing.get_credit_note_model(), TemplateBase, BTEMPLATE_CREATION_CFORM),
)
Exemple #12
0
    def populate(self):
        already_populated = RelationType.objects.filter(
            pk=constants.REL_SUB_SOLD).exists()

        Act = commercial.get_act_model()
        ActObjectivePattern = commercial.get_pattern_model()
        Strategy = commercial.get_strategy_model()
        Contact = persons.get_contact_model()
        Organisation = persons.get_organisation_model()
        Product = products.get_product_model()
        Service = products.get_service_model()

        RelationType.create(
            (constants.REL_SUB_SOLD, _('has sold'), [Contact, Organisation]),
            (constants.REL_OBJ_SOLD, _('has been sold by'), [Product, Service
                                                             ]),
        )

        complete_goal_models = {*creme_registry.iter_entity_models()}
        complete_goal_models.discard(Strategy)
        if apps.is_installed('creme.billing'):
            from creme import billing
            from creme.billing.registry import lines_registry

            complete_goal_models.discard(billing.get_credit_note_model())
            complete_goal_models.discard(billing.get_template_base_model())
            complete_goal_models.difference_update(lines_registry)

        RelationType.create(
            (
                constants.REL_SUB_COMPLETE_GOAL,
                _('completes a goal of the commercial action'),
                complete_goal_models,
            ),
            (
                constants.REL_OBJ_COMPLETE_GOAL,
                _('is completed thanks to'),
                [Act],
            ),
        )

        # ---------------------------
        CremePropertyType.create(constants.PROP_IS_A_SALESMAN,
                                 _('is a salesman'), [Contact])

        # ---------------------------
        MarketSegment.objects.get_or_create(
            property_type=None,
            defaults={'name': _('All the organisations')},
        )

        # ---------------------------
        for i, title in enumerate(
            [_('Phone calls'), _('Show'),
             _('Demo')], start=1):
            create_if_needed(ActType, {'pk': i}, title=title, is_custom=False)

        # ---------------------------
        create_hf = HeaderFilter.objects.create_if_needed
        create_hf(
            pk=constants.DEFAULT_HFILTER_ACT,
            model=Act,
            name=_('Com Action view'),
            cells_desc=[
                (EntityCellRegularField, {
                    'name': 'name'
                }),
                (EntityCellRegularField, {
                    'name': 'expected_sales'
                }),
                (EntityCellRegularField, {
                    'name': 'due_date'
                }),
            ],
        )
        create_hf(
            pk=constants.DEFAULT_HFILTER_STRATEGY,
            model=Strategy,
            name=_('Strategy view'),
            cells_desc=[(EntityCellRegularField, {
                'name': 'name'
            })],
        )
        create_hf(
            pk=constants.DEFAULT_HFILTER_PATTERN,
            model=ActObjectivePattern,
            name=_('Objective pattern view'),
            cells_desc=[
                (EntityCellRegularField, {
                    'name': 'name'
                }),
                (EntityCellRegularField, {
                    'name': 'segment'
                }),
            ],
        )

        # ---------------------------
        def build_custom_form_items(creation_descriptor, edition_descriptor,
                                    field_names):
            base_groups_desc = [
                {
                    'name':
                    _('General information'),
                    'layout':
                    LAYOUT_DUAL_FIRST,
                    'cells': [
                        *((EntityCellRegularField, {
                            'name': fname
                        }) for fname in field_names),
                        (
                            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=creation_descriptor,
                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=edition_descriptor,
                groups_desc=base_groups_desc,
            )

        build_custom_form_items(
            creation_descriptor=custom_forms.ACT_CREATION_CFORM,
            edition_descriptor=custom_forms.ACT_EDITION_CFORM,
            field_names=[
                'user',
                'name',
                'expected_sales',
                'cost',
                'goal',
                'start',
                'due_date',
                'act_type',
                'segment',
            ],
        )
        build_custom_form_items(
            creation_descriptor=custom_forms.PATTERN_CREATION_CFORM,
            edition_descriptor=custom_forms.PATTERN_EDITION_CFORM,
            field_names=[
                'user',
                'name',
                'average_sales',
                'segment',
            ],
        )
        build_custom_form_items(
            creation_descriptor=custom_forms.STRATEGY_CREATION_CFORM,
            edition_descriptor=custom_forms.STRATEGY_EDITION_CFORM,
            field_names=[
                'user',
                'name',
            ],
        )

        # ---------------------------
        create_searchconf = SearchConfigItem.objects.create_if_needed
        create_searchconf(Act, ['name', 'expected_sales', 'cost', 'goal'])
        create_searchconf(Strategy, ['name'])
        create_searchconf(ActObjectivePattern, [], disabled=True)

        # ---------------------------
        SettingValue.objects.get_or_create(
            key_id=setting_keys.orga_approaches_key.id,
            defaults={'value': True},
        )

        # ---------------------------
        Job.objects.get_or_create(
            type_id=creme_jobs.com_approaches_emails_send_type.id,
            defaults={
                'language': settings.LANGUAGE_CODE,
                'periodicity': date_period_registry.get_period('days', 1),
                'status': Job.STATUS_OK,
                # The CommercialApproach field for Activities' CustomForms is not
                # in the default configuration, so a enabled job would be annoying.
                'enabled': False,
            },
        )

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

            create_mitem = MenuConfigItem.objects.create
            create_mitem(entry_id=menu.ActsEntry.id,
                         order=50,
                         parent=container)
            create_mitem(entry_id=menu.StrategiesEntry.id,
                         order=55,
                         parent=container)
            create_mitem(entry_id=menu.SegmentsEntry.id,
                         order=60,
                         parent=container)
            create_mitem(entry_id=menu.PatternsEntry.id,
                         order=70,
                         parent=container)

            directory = MenuConfigItem.objects.filter(
                entry_id=ContainerEntry.id,
                entry_data={
                    'label': _('Directory')
                },
            ).first()
            if directory is not None:
                create_mitem(entry_id=menu.SalesmenEntry.id,
                             order=100,
                             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.ActCreationEntry.id,
                             order=40,
                             parent=creations)

        # ---------------------------
        if not already_populated:
            ButtonMenuItem.objects.create_if_needed(
                button=buttons.CompleteGoalButton,
                order=60,
            )

            TOP = BrickDetailviewLocation.TOP
            RIGHT = BrickDetailviewLocation.RIGHT
            LEFT = BrickDetailviewLocation.LEFT

            # BrickDetailviewLocation.objects.multi_create(
            #     defaults={'brick': bricks.ApproachesBrick, 'order': 10, 'zone': RIGHT},
            #     data=[
            #         {},  # default configuration
            #         {'model': Contact},
            #         {'model': Organisation},
            #     ]
            # )

            BrickDetailviewLocation.objects.multi_create(
                defaults={
                    'model': Act,
                    'zone': LEFT
                },
                data=[
                    {
                        'order': 5
                    },  # generic information brick
                    {
                        'brick': bricks.ActObjectivesBrick,
                        'order': 10
                    },
                    {
                        'brick': bricks.RelatedOpportunitiesBrick,
                        'order': 20
                    },
                    {
                        'brick': core_bricks.CustomFieldsBrick,
                        'order': 40
                    },
                    {
                        'brick': core_bricks.PropertiesBrick,
                        'order': 450
                    },
                    {
                        'brick': core_bricks.RelationsBrick,
                        'order': 500
                    },
                    {
                        'brick': core_bricks.HistoryBrick,
                        'order': 20,
                        'zone': RIGHT
                    },
                ],
            )
            BrickDetailviewLocation.objects.multi_create(
                defaults={
                    'model': ActObjectivePattern,
                    'zone': LEFT
                },
                data=[
                    {
                        'brick': bricks.PatternComponentsBrick,
                        'order': 10,
                        'zone': TOP
                    },
                    {
                        'order': 5
                    },
                    {
                        'brick': core_bricks.CustomFieldsBrick,
                        'order': 40
                    },
                    {
                        'brick': core_bricks.PropertiesBrick,
                        'order': 450
                    },
                    {
                        'brick': core_bricks.RelationsBrick,
                        'order': 500
                    },
                    {
                        'brick': core_bricks.HistoryBrick,
                        'order': 20,
                        'zone': RIGHT
                    },
                ],
            )
            BrickDetailviewLocation.objects.multi_create(
                defaults={
                    'model': Strategy,
                    'zone': LEFT
                },
                data=[
                    {
                        'brick': bricks.SegmentDescriptionsBrick,
                        'order': 10,
                        'zone': TOP
                    },
                    {
                        'order': 5
                    },
                    {
                        'brick': core_bricks.CustomFieldsBrick,
                        'order': 40
                    },
                    {
                        'brick': bricks.EvaluatedOrgasBrick,
                        'order': 50
                    },
                    {
                        'brick': bricks.AssetsBrick,
                        'order': 60
                    },
                    {
                        'brick': bricks.CharmsBrick,
                        'order': 70
                    },
                    {
                        '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

                for model in (Act, ActObjectivePattern, Strategy):
                    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': 400
                            },
                        ],
                    )

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

                from creme.documents.bricks import LinkedDocsBrick

                BrickDetailviewLocation.objects.multi_create(
                    defaults={
                        'brick': LinkedDocsBrick,
                        'order': 600,
                        'zone': RIGHT
                    },
                    data=[
                        {
                            'model': Act
                        },
                        {
                            'model': ActObjectivePattern
                        },
                        {
                            'model': Strategy
                        },
                    ],
                )
Exemple #13
0
# -*- coding: utf-8 -*-

################################################################################
#    Creme is a free/open-source Customer Relationship Management software
#    Copyright (C) 2018  Hybird
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
################################################################################

from creme import billing

BILLING_MODELS = [
    billing.get_credit_note_model(),
    billing.get_invoice_model(),
    billing.get_quote_model(),
    billing.get_sales_order_model(),
    billing.get_template_base_model(),
]