コード例 #1
0
    def get_cached_context_data(self):
        sum_dict = lambda *ds: {
            k: sum(d.get(k, 0) or 0 for d in ds)
            for k in ds[0]
        }

        context = self.get_aggregate_data()

        context['top_progetti'] = context.pop('top_progetti_per_costo')

        context[
            'territori_piu_finanziati_pro_capite'] = self.top_comuni_pro_capite(
                filters={'progetto__soggetto_set__pk': self.object.pk})

        # == COLLABORATORI CON CUI SI SPARTISCONO PIÙ SOLDI =======================================

        top_collaboratori = Soggetto.objects.filter(
            progetto__ruolo__soggetto=self.object).exclude(
                pk=self.object.pk).values('pk').annotate(
                    totale=Count('pk')).order_by('-totale')[:5]

        soggetto_by_pk = Soggetto.objects.in_bulk(x['pk']
                                                  for x in top_collaboratori)

        context['top_collaboratori'] = []
        for c in top_collaboratori:
            soggetto = soggetto_by_pk[c['pk']]
            soggetto.totale = c['totale']
            context['top_collaboratori'].append(soggetto)

        # == TOTALI PER REGIONI (E NAZIONI) =======================================================

        progetti = self.get_progetti_queryset()

        # i progetti del soggetto localizzati in più territori (vengono considerati a parte per evitare di contarli più volte nelle aggregazioni)
        progetti_multilocalizzati_pks = [
            x['pk'] for x in progetti.values('pk').annotate(
                cnt=Count('territorio_set__cod_reg', distinct=True)).filter(
                    cnt__gt=1)
        ]

        totali_non_multilocalizzati = {
            x.pop('id'): x
            for x in progetti.exclude(pk__in=progetti_multilocalizzati_pks).
            totali_group_by('territorio_set__cod_reg')
        }

        totali_multilocalizzati_nazionali = {}
        totali_multilocalizzati_non_nazionali = {}
        for progetto in Progetto.objects.filter(
                pk__in=progetti_multilocalizzati_pks).prefetch_related(
                    'territorio_set'):
            totali_progetto = {
                'totale_costi': float(progetto.fin_totale_pubblico or 0),
                'totale_pagamenti': float(progetto.pagamento or 0),
                'totale_progetti': 1
            }

            if any(t.is_nazionale for t in progetto.territori) and not any(
                    t.is_estero for t in progetto.territori
            ):  # con almeno una localizzazione nazionale e nessuna estera
                totali_multilocalizzati_nazionali = sum_dict(
                    totali_progetto, totali_multilocalizzati_nazionali)
            else:
                totali_multilocalizzati_non_nazionali = sum_dict(
                    totali_progetto, totali_multilocalizzati_non_nazionali)

        if any(totali_multilocalizzati_nazionali.viewvalues()):
            totali_non_multilocalizzati[0] = sum_dict(
                totali_multilocalizzati_nazionali,
                totali_non_multilocalizzati.get(0, {}))

        # totali_non_multilocalizzati = {key: tots for key, tots in totali_non_multilocalizzati.items() if any(tots.viewvalues())}

        context['territori'] = []

        for territorio in Territorio.objects.regioni(with_nation=True).filter(
                cod_reg__in=totali_non_multilocalizzati.keys()).order_by(
                    '-territorio', 'denominazione').defer('geom'):
            territorio.totali = totali_non_multilocalizzati[territorio.cod_reg]
            context['territori'].append(territorio)

        # assegno a un territorio fittizio i progetti multilocalizzati senza localizzazione nazionale
        if any(totali_multilocalizzati_non_nazionali.viewvalues()):
            territorio = Territorio(denominazione=u'In più territori',
                                    territorio='X')
            territorio.totali = totali_multilocalizzati_non_nazionali
            context['territori'].append(territorio)

        # == TOTALI PER RUOLO =====================================================================

        totali_by_ruolo_by_progetto = defaultdict(dict)

        for ruolo in dict(Ruolo.RUOLO).keys():
            for totali in Ruolo.objects.filter(
                    soggetto=self.object,
                    ruolo=ruolo,
                    progetto__active_flag=True,
                    progetto__visualizzazione_flag='0').values(
                        'progetto_id').annotate(
                            totale_costi=Sum('progetto__fin_totale_pubblico'),
                            totale_pagamenti=Sum('progetto__pagamento'),
                            totale_progetti=Count('progetto')):
                totali_by_ruolo_by_progetto[totali.pop(
                    'progetto_id')][ruolo] = totali

        totali_by_ruolo = defaultdict(dict)

        for totaliprogetto_by_ruolo in totali_by_ruolo_by_progetto.values():
            codice = ''.join(
                totaliprogetto_by_ruolo.keys()
            )  # in caso di più ruoli per uno stesso progetto si crea un nuovo codice
            totali = totaliprogetto_by_ruolo.values(
            )[0]  # prendo il primo dei totali per ruolo, tanto DEVONO essere tutti uguali

            totali_by_ruolo[codice] = sum_dict(totali, totali_by_ruolo[codice])

        context['ruoli'] = [{
            'nome':
            '/'.join(sorted([dict(Ruolo.RUOLO)[r] for r in codice])),
            'codice':
            codice,
            'totali':
            totali
        } for codice, totali in totali_by_ruolo.items()]

        return context