示例#1
0
    def _update_linked_docs(self):
        # TODO: factorise (Relation.get_real_objects() ??)
        relations = Relation.objects.filter(subject_entity=self.id,
                                            type=REL_SUB_CREDIT_NOTE_APPLIED,
                                           ) \
                                    .select_related('object_entity')
        Relation.populate_real_object_entities(relations)

        for rel in relations:
            rel.object_entity.get_real_entity().save()
示例#2
0
    def detailview_display(self, context):
        activity = context['object']
        btc = self.get_template_context(
            context,
            activity.relations.filter(type=constants.REL_OBJ_ACTIVITY_SUBJECT)
                    .select_related('type', 'object_entity'),
        )

        Relation.populate_real_object_entities(btc['page'].object_list)

        return self._render(btc)
示例#3
0
    def get_credit_notes(self):
        credit_notes = self._creditnotes_cache

        if credit_notes is None:
            self._creditnotes_cache = credit_notes = []

            if self.id:
                relations = Relation.objects.filter(subject_entity=self.id,
                                                    type=REL_OBJ_CREDIT_NOTE_APPLIED,
                                                   ) \
                                            .select_related('object_entity')
                Relation.populate_real_object_entities(relations)
                credit_notes.extend(rel.object_entity.get_real_entity()
                                    for rel in relations
                                    if not rel.object_entity.is_deleted)

        return credit_notes
示例#4
0
    def post(self, request, *args, **kwargs):
        klass = self.get_ctype().model_class()

        try:
            rtype_id, set_as_current, workflow_action = self.behaviours[klass]
        except KeyError as e:
            raise Http404('Bad billing document type') from e

        user = request.user
        user.has_perm_to_create_or_die(klass)
        # TODO: check in template too (must upgrade 'has_perm' to use owner!=None)
        user.has_perm_to_link_or_die(klass, owner=user)

        opp = self.get_related_entity()

        b_document = klass.objects.create(
            user=user,
            issuing_date=now(),
            status_id=1,
            currency=opp.currency,
            source=opp.emitter,
            target=opp.target,
        )

        create_relation = partial(
            Relation.objects.create,
            subject_entity=b_document,
            user=user,
        )
        create_relation(type_id=rtype_id, object_entity=opp)

        b_document.generate_number(
        )  # Need the relationship with emitter organisation
        b_document.name = self.generated_name.format(document=b_document,
                                                     opportunity=opp)
        b_document.save()

        relations = Relation.objects.filter(
            subject_entity=opp.id,
            type__in=[
                constants.REL_OBJ_LINKED_PRODUCT,
                constants.REL_OBJ_LINKED_SERVICE,
            ],
        ).select_related('object_entity')

        # TODO: Missing test case
        if relations:
            Relation.populate_real_object_entities(relations)
            vat_value = Vat.get_default_vat()
            Product = get_product_model()

            for relation in relations:
                item = relation.object_entity.get_real_entity()
                line_klass = ProductLine if isinstance(
                    item, Product) else ServiceLine
                line_klass.objects.create(
                    related_item=item,
                    related_document=b_document,
                    unit_price=item.unit_price,
                    unit=item.unit,
                    vat_value=vat_value,
                )

        if set_as_current:
            create_relation(type_id=constants.REL_SUB_CURRENT_DOC,
                            object_entity=opp)

        if workflow_action:
            workflow_action(opp.emitter, opp.target, user)

        # if request.is_ajax():
        if is_ajax(request):
            return HttpResponse()

        return redirect(opp)
示例#5
0
    def generate_png(self, user):
        from os.path import join

        import pygraphviz as pgv

        # NB: to work with utf8 label in node: all node must be added explicitly with
        #     unicode label, and when edges are a created, nodes identified by their
        #     labels encoded as string

        graph = pgv.AGraph(directed=True)

        # NB: "self.roots.all()" causes a strange additional query (retrieving of the base CremeEntity !)....
        has_perm_to_view = user.has_perm_to_view
        roots = [
            root for root in RootNode.objects.filter(
                graph=self.id).select_related('entity')
            if not root.entity.is_deleted and has_perm_to_view(root.entity)
        ]

        add_node = graph.add_node
        add_edge = graph.add_edge

        # TODO: entity cache ? regroups relations by type ? ...

        CremeEntity.populate_real_entities([root.entity for root in roots
                                            ])  #small optimisation

        for root in roots:
            add_node(str(root.entity), shape='box')
            # add_node('filled box',    shape='box', style='filled', color='#FF00FF')
            # add_node('filled box v2', shape='box', style='filled', fillcolor='#FF0000', color='#0000FF', penwidth='2.0') #default pensize="1.0"

        orbital_nodes = {}  #cache

        for root in roots:
            subject = root.entity
            str_subject = str(subject)
            relations   = subject.relations.filter(type__in=root.relation_types.all())\
                                           .select_related('object_entity', 'type')

            Relation.populate_real_object_entities(
                relations)  # Small optimisation

            for relation in relations:
                object_ = relation.object_entity
                if not user.has_perm_to_view(object_):
                    continue

                uni_object = str(object_)
                str_object = uni_object

                orbital_node = orbital_nodes.get(object_.id)
                if not orbital_node:
                    add_node(uni_object)
                    orbital_nodes[object_.id] = str_object

                add_edge(str_subject,
                         str_object,
                         label=str(relation.type.predicate))
                # add_edge('b', 'd', color='#FF0000', fontcolor='#00FF00', label='foobar', style='dashed')

        orbital_rtypes = self.orbital_relation_types.all()

        if orbital_rtypes:
            orbital_ids = orbital_nodes.keys()

            for relation in Relation.objects.filter(
                    subject_entity__in=orbital_ids,
                    object_entity__in=orbital_ids,
                    type__in=orbital_rtypes).select_related('type'):
                add_edge(orbital_nodes[relation.subject_entity_id],
                         orbital_nodes[relation.object_entity_id],
                         label=str(relation.type.predicate),
                         style='dashed')

        # print graph.string()

        graph.layout(prog='dot')  # Algo: neato dot twopi circo fdp nop

        img_format = 'png'  # Format: pdf svg
        img_basename = 'graph_{}.{}'.format(self.id, img_format)

        try:
            path = FileCreator(join(settings.MEDIA_ROOT, 'upload', 'graphs'),
                               img_basename).create()
        except FileCreator.Error as e:
            raise self.GraphException(e) from e

        try:
            # graph.draw(join(dir_path, filename), format='png')  # Format: pdf svg
            graph.draw(path, format=img_format)  # Format: pdf svg
        except IOError as e:
            delete_file(path)

            raise self.GraphException(str(e)) from e

        fileref = FileRef.objects.create(  # user=request.user, TODO
            filedata='upload/graphs/' + basename(path),
            basename=img_basename,
        )

        return HttpResponseRedirect(
            reverse('creme_core__dl_file', args=(fileref.filedata, )))