| [13e7c01] | 1 | from decimal import Decimal |
|---|
| [162f527] | 2 | from django.db.models import Q, Sum |
|---|
| 3 | import finance_core.models |
|---|
| [13e7c01] | 4 | |
|---|
| 5 | def 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') |
|---|
| [162f527] | 10 | for num, (pk, label, qobj, objrel_qobj) in enumerate(primary_axis): |
|---|
| [13e7c01] | 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 | print secondary_axis |
|---|
| [162f527] | 20 | for num, (pk, label, qobj_lineitem, qobj_primary) in enumerate(secondary_axis): |
|---|
| [13e7c01] | 21 | print num |
|---|
| 22 | secondary_results = (primary_axis_objs.filter(main_lineitem_limit_primary, qobj_primary, ).annotate(Sum('lineitem__amount'))) |
|---|
| 23 | for cell in secondary_results: |
|---|
| 24 | #print cell, cell.pk, arcprimary[cell.pk], num, table[arcprimary[cell.pk]] |
|---|
| 25 | table[arcprimary[cell.pk]][num] = lineitem_total(cell) |
|---|
| 26 | |
|---|
| 27 | return table |
|---|
| 28 | |
|---|
| 29 | def build_table_aggregate(line_items, main_lineitem_limit_primary, primary_axis, primary_axis_objs, secondary_axis): |
|---|
| 30 | # This uses a simpler but probably slower method |
|---|
| 31 | # In theory, if we grow unit tests, comparing this method with |
|---|
| 32 | # the one above using annotate would be a good idea |
|---|
| 33 | zero = Decimal('0.00') |
|---|
| 34 | def total_amount(queryset): |
|---|
| 35 | amount = queryset.aggregate(Sum('amount'))['amount__sum'] |
|---|
| 36 | if amount is None: return zero |
|---|
| 37 | else: return amount |
|---|
| 38 | table = [ # Primary axis |
|---|
| 39 | [ # Secondary axis |
|---|
| [162f527] | 40 | total_amount(line_items.filter(primary[2], secondary[2])) |
|---|
| [13e7c01] | 41 | for secondary in secondary_axis] |
|---|
| 42 | for primary in primary_axis] |
|---|
| 43 | |
|---|
| 44 | return table |
|---|
| 45 | |
|---|
| 46 | build_table = build_table_annotate |
|---|
| [162f527] | 47 | |
|---|
| 48 | |
|---|
| 49 | def get_primary_axis(slug, base_area): |
|---|
| 50 | if slug == 'budget-areas': |
|---|
| 51 | return get_budget_areas(base_area) |
|---|
| 52 | else: |
|---|
| 53 | raise UnsupportedOperationException() |
|---|
| 54 | |
|---|
| 55 | def get_secondary_axis(slug, base_area): |
|---|
| 56 | if slug == 'budget-areas': |
|---|
| 57 | return get_budget_areas(base_area) |
|---|
| 58 | elif slug == 'layers': |
|---|
| 59 | return get_layers(base_area) |
|---|
| 60 | else: |
|---|
| 61 | raise NotImplementedError |
|---|
| 62 | |
|---|
| 63 | def get_budget_areas(base_area): |
|---|
| 64 | name = 'Budget Areas' |
|---|
| 65 | base_area_depth = base_area.depth |
|---|
| 66 | axis = [ |
|---|
| 67 | ( |
|---|
| 68 | area.pk, |
|---|
| 69 | area.indented_name(base_area_depth), |
|---|
| 70 | Q(budget_area=area), |
|---|
| 71 | Q(lineitem__budget_area=area), |
|---|
| 72 | ) |
|---|
| 73 | for area in base_area.get_descendants() |
|---|
| 74 | ] |
|---|
| 75 | axis_objs = base_area.get_descendants() |
|---|
| 76 | return name, axis, axis_objs, |
|---|
| 77 | |
|---|
| 78 | def get_layers(base_area): |
|---|
| 79 | name = 'Layers' |
|---|
| 80 | axis = [ |
|---|
| 81 | ( |
|---|
| 82 | finance_core.models.layer_num(layer), |
|---|
| 83 | finance_core.models.layer_name(layer), |
|---|
| 84 | Q(layer=finance_core.models.layer_num(layer)), |
|---|
| 85 | Q(lineitem__layer=finance_core.models.layer_num(layer)), |
|---|
| 86 | ) |
|---|
| 87 | for layer in finance_core.models.layers |
|---|
| 88 | ] |
|---|
| 89 | return name, axis, None, |
|---|
| 90 | |
|---|