Summary instance methods

Having defined our Summary class, we can now put it to use in querying and formatting our financial information. Given the following summary definition:

class MySummary(commerce.Summary):
    products = commerce.Items()
    delivery = commerce.Delivery()
    total    = commerce.Total()

    class Meta:
        currency = "USD"
        locale = "de-DE"

The simplest use is of course getting the relevant amounts:

>>> my_summary = MySummary(my_model_instance)
>>> my_summary.total
1234.56
>>> my_summary.delivery
129.90
>>> my_summary.products
[<Product: First Product>, <Product: Second Product>]
>>> my_summary.products[0].AMOUNT
933.12

Warning

Any changes to your data after the summary has been created may not be reflected in the summary. This is a deliberate assumption to make optimisation simpler, and is not difficult to abide by. If the summary must be updated, you can recreate it using the updated model instance.

Note

The instance you give to your summary class need not actually be a Django model instance. It can be any python object that has the attributes required by the summary class. Instead of a Many-To-Many relationship, your python object can simply have an attribute with a list of item objects (which can simply be another python object).

Numbers can be formatted to the relevant locale (in this case German):

>>> print my_summary.total
$1.234,56
>>> print my_summary
First Product   $   933,12
Second Product  $   171,54

Delivery        $   129,90
         Total  $ 1.234,56
>>> print my_summary.total.html
<span class="money"><span class="currency">$</span>1.234<span class="cents">,56</span></span>

Accessing elements

Each type of element (Items, Extra, Total) has a slightly different form.

When you access an Items attribute (eg. my_summary.products) you get a Django QuerySet in return. The queryset is identical to a QuerySet returned when using Django’s model API, except that the relevant amount for each item (see item_amount_from) is included as an additional attribute. The name of the attribute is by default AMOUNT, but can be defined by setting the cache_amount_as parameter when defining the Summary class. The queryset is retrieved only once, and the amount is calculated only once.

Extra elements are returned as a special object with four attributes:

Attribute Type
.extra.verbose_name unicode
.extra.amount FormattedDecimal
.extra.included bool
.extra.description unicode

Total elements are simply FormattedDecimal objects.

Each of the elements can be programmatically accessed using the _meta attribute of the summary. The _meta attribute may change in the future, but will contain at least the following attributes:

Attribute Type
._meta.locale unicode
._meta.currency unicode
._meta.decimal_html unicode
._meta.extras OrderedDict of all Extra elements
._meta.items OrderedDict of all Items elements
._meta.totals OrderedDict of all Total elements

Formatting

A FormattedDecimal works exactly like a decimal, except it has a few extra formatting abilities attached:

>>> my_summary.total
Decimal("1234.56")
>>> my_summary.total + 7
Decimal("1241.56")
>>> print my_summary.total
$1.234,56
>>> my_summary.total.html
u'<span class="money"><span class="currency">$</span>1.234<span class="cents">,56</span></span>'

Summary Formsets

Editable statements using forms can be easily generated, once you have defined your fields as being editable (see Summary Syntax):

>>> my_summary.formset
<Formset: >
>>> print my_summary.formset
<tr><td> ... etc
>>> print my_summary.forms.as_ul
<li> ... etc

Note that non-editable fields are included for convenience. The remaining functionality should be familiar to Django developers:

>>> my_summary.forms.is_valid()
True
>>> my_summary.forms.save()