Contracts¶
This document describes the minimum contract the shop models are supposed to fulfill.
The simple example at examples/simple/
is supposed to demonstrate the
most simple use of Plata.
Product model¶
The (base) product model has to be specified as PLATA_SHOP_PRODUCT
using Django’s app_label.model_name
notation. The model referenced
will be the model pointed to by the OrderItem
order line items.
Since it’s your responsibility to write all views and URLs for your product catalogue, there aren’t many things Plata’s products have to fulfill.
Plata provides an abstract model at plata.product.models.ProductBase
.
You do not have to use it - it just provides the standard interface to
the price determination routines already.
get_price(currency=None, orderitem=None)
:The
get_price
method has to accept at least the current currency and optionally more arguments too, such as the current line item for the implementation of price tiers.This method must return a
Price
instance. It has to raise aPrice.DoesNotExist
exception if no price could be found for the passed arguments.handle_order_item(self, orderitem)
:This method is called when modifying order items. This method is responsible for filling in the
name
andsku
(Stock Keeping Unit) field on the order item.
Different product models¶
If you need different product models, consider using Django’s model inheritance and something like django-polymorphic.
Price model¶
Plata has a bundled abstract price model which does almost everything required. You have to provide the concrete price model yourself though.
The only thing it lacks for a basic price is a foreign key to product.
ProductBase.get_price
assumes that the foreign key is defined with
related_name='prices'
.
When modifying a cart or an order, Plata will call the price object’s
handle_order_item
method, passing the order item instance as the only
argument. This method is responsible for filling the following attributes
on the order item:
_unit_price
: Unit price excl. tax._unit_tax
: The tax on a single unit.tax_rate
: The applied tax rate as a percentage. This is slightly redundant as it could be calculated from_unit_price
and_unit_tax
.tax_class
: (Optional) a foreign key toplata.shop.models.TaxClass
. This is purely informative. This field is not mandatory.is_sale
: Boolean flag denoting whether the price is a sale price or not. This flag is unconditionally set toFalse
by the price base class.
The price model offers the following attributes:
unit_price_excl_tax
A
decimal.Decimal
describing the unit price with tax excluded.unit_price_incl_tax
andunit_price
are offered by the default implementation too, but they aren’t mandatory.unit_tax
A
decimal.Decimal
too. This is the tax amount per unit, not the tax rate.tax_class.rate
The tax rate as a percentage, meaning
19.6
for a tax rate of 19.6%.tax_class
A
plata.shop.models.TaxClass
object for the given price.
Contact model¶
The example at examples/custom
shows how the contact model might be
replaced with a different model. The following fields and methods are
mandatory:
Contact.user
:ForeignKey
orOneToOneField
toauth.User
.Contact.update_from_order(self, order, request=None)
: Updates the contact instance with data from the passed order (and from the optional request).Contact.ADDRESS_FIELDS
: A list of fields which are available as billing and/or shipping address fields.
The last point isn’t strictly necessary and can be circumvented by
overriding plata.shop.views.Shop.checkout_form()
.
plata.contact.models.Contact
offers all that, and more.