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()
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)
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
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)
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, )))