source: remit/finance_core/reporting.py @ dd2c3d9

client
Last change on this file since dd2c3d9 was dd2c3d9, checked in by Alex Dehnert <adehnert@…>, 15 years ago

Allow filtering by term

  • Property mode set to 100644
File size: 3.6 KB
Line 
1from decimal import Decimal
2from django.db.models import Q, Sum
3import finance_core.models
4
5def build_table_annotate(line_items, main_lineitem_limit_primary, primary_axis, primary_axis_objs, secondary_axis, ):
6    # Setup
7    arcprimary = {}
8    table = []
9    zero = Decimal('0.00')
10    for num, (pk, label, qobj, objrel_qobj) in enumerate(primary_axis):
11        arcprimary[pk] = num
12        table.append([zero]*len(secondary_axis))
13
14    def lineitem_total(obj):
15        if obj.lineitem__amount__sum is None: return zero
16        else: return obj.lineitem__amount__sum
17
18    # Do the real work
19    for num, (pk, label, qobj_lineitem, qobj_primary) in enumerate(secondary_axis):
20        secondary_results = (primary_axis_objs.filter(main_lineitem_limit_primary, qobj_primary, ).annotate(Sum('lineitem__amount')))
21        for cell in secondary_results:
22            #print cell, cell.pk, arcprimary[cell.pk], num, table[arcprimary[cell.pk]]
23            table[arcprimary[cell.pk]][num] = lineitem_total(cell)
24
25    return table
26
27def build_table_aggregate(line_items, main_lineitem_limit_primary, primary_axis, primary_axis_objs, secondary_axis):
28    # This uses a simpler but probably slower method
29    # In theory, if we grow unit tests, comparing this method with
30    # the one above using annotate would be a good idea
31    zero = Decimal('0.00')
32    def total_amount(queryset):
33        amount = queryset.aggregate(Sum('amount'))['amount__sum']
34        if amount is None: return zero
35        else: return amount
36    table = [ # Primary axis
37            [ # Secondary axis
38                total_amount(line_items.filter(primary[2], secondary[2]))
39            for secondary in secondary_axis]
40        for primary in primary_axis]
41
42    return table
43
44build_table = build_table_annotate
45
46
47def get_primary_axis(slug, base_area, term, ):
48    if slug in axes and axes[slug][1]:
49        return axes[slug][0](base_area, term, )
50    else:
51        raise NotImplementedError
52
53def get_secondary_axis(slug, base_area, term, ):
54    if slug in axes and axes[slug][2]:
55        return axes[slug][0](base_area, term, )
56    else:
57        raise NotImplementedError
58
59def get_budget_areas(base_area, term, ):
60    name = 'Budget Areas'
61    base_area_depth = base_area.depth
62    areas = base_area.get_descendants()
63    if term:
64        areas = areas.filter(Q(always=True) or Q(budget_term=term))
65    axis = [
66        (
67            area.pk,
68            area.indented_name(base_area_depth),
69            Q(budget_area=area),
70            Q(lineitem__budget_area=area),
71        )
72        for area in areas
73    ]
74    axis_objs = areas
75    return name, axis, axis_objs,
76
77def get_budget_terms(base_area, term, ):
78    name = 'Budget Terms'
79    if term:
80        terms = finance_core.models.BudgetTerm.objects.filter(pk=term.pk)
81    else:
82        terms = finance_core.models.BudgetTerm.objects.all()
83    axis = [
84        (
85            term.pk,
86            term.name,
87            Q(budget_term=term),
88            Q(lineitem__budget_term=term),
89        )
90        for term in terms
91    ]
92    return name, axis, terms
93
94def get_layers(base_area, term, ):
95    name = 'Layers'
96    axis = [
97        (
98            finance_core.models.layer_num(layer),
99            finance_core.models.layer_name(layer),
100            Q(layer=finance_core.models.layer_num(layer)),
101            Q(lineitem__layer=finance_core.models.layer_num(layer)),
102        )
103        for layer in finance_core.models.layers
104    ]
105    return name, axis, None,
106
107axes = {
108    'budget-areas': (get_budget_areas, True,  True,  ),
109    'budget-terms': (get_budget_terms, True,  True,  ),
110    'layers':       (get_layers,       False, True,  ),
111}
112
Note: See TracBrowser for help on using the repository browser.