==============
standard rules
==============

This module implent the standard rules for building cart. See the doc
doc/rules.txt for more info about the structure of the rules.

For this documentation we'll create a FakeCart object::

    >>> class FakeCart(object):
    ...     products = {}
    ...     cart = {}
    >>> products = {u'coca light': {u'price' : { u'included_tax' : 1.5,
    ...                                          u'vat' : 5.5},
    ...                             u'quantity' : 3.0,
    ...                             u'weight' : 0.05},
    ...             u'shoes': {u'price' : {u'included_tax' : 15.0,
    ...                                    u'vat' : 19.6},
    ...                        u'reductions' : [{u'value' : 3,
    ...                                          u'percentage' : False,
    ...                                         },
    ...                                        ],
    ...                        u'quantity' : 1.0,
    ...                        u'weight' : 0.5},
    ...             u'television': {u'price' : { u'included_tax' : 350.0,
    ...                                          u'vat' : 19.6},
    ...                             u'reductions' : [{u'value' : 10,
    ...                                               u'percentage' : True,
    ...                                              },
    ...                                              {u'value' : 100,
    ...                                               u'percentage' : False,
    ...                                              },
    ...                                             ],
    ...                             u'quantity' : 1.0,
    ...                             u'weight' : 50}
    ...            }
    >>> fake_cart = FakeCart()
    >>> fake_cart.products = products

ObjectAmount
------------

This is the first rule. It calculates the total of each product in a cart::

    >>> from rules.standard_rules import ObjectAmount

So try to aplly the rule on the cart::

    >>> process = ObjectAmount()
    >>> fake_cart = process(fake_cart)
    >>> res_amount = {u'coca light': {u'price': {u'included_tax': 1.5,
    ...                                          u'vat': 5.5},
    ...                               u'quantity': 3.0,
    ...                               u'weight' : 0.050000000000000003,
    ...                               'total_weight' : 0.15000000000000002,
    ...                               'total': {'amount_vat':
    ...                                         0.23459715639810419,
    ...                                         'included_tax': 4.5,
    ...                                         'vat': 5.5,
    ...                                         'without_tax':
    ...                                         4.2654028436018958}},
    ...               u'shoes': {u'price': {u'included_tax': 15.0,
    ...                                     u'vat': 19.600000000000001},
    ...                          u'quantity': 1.0,
    ...                          u'weight' : 0.5,
    ...                          u'reductions': [{u'percentage': False,
    ...                                           u'value': 3}],
    ...                          'total_weight' : 0.5,
    ...                          'total': {'amount_vat': 2.4581939799331103,
    ...                                    'included_tax': 15.0,
    ...                                    'vat': 19.600000000000001,
    ...                                    'without_tax':
    ...                                     12.54180602006689}},
    ...               u'television': {u'price': {u'included_tax': 350.0,
    ...                                          u'vat': 19.600000000000001},
    ...                               u'quantity': 1.0,
    ...                               u'weight' : 50,
    ...                               u'reductions': [{u'percentage': True,
    ...                                                u'value': 10},
    ...                                               {u'percentage': False,
    ...                                                u'value': 100}],
    ...                               'total_weight' : 50.0,
    ...                               'total': {'amount_vat':
    ...                                         57.35785953177259,
    ...                                         'included_tax': 350.0,
    ...                                         'vat': 19.600000000000001,
    ...                                         'without_tax':
    ...                                         292.64214046822741}}}
    >>> fake_cart.products == res_amount
    True

ObjectReduction
---------------

This rule calculate all reductions for each cart products::

    >>> from rules.standard_rules import ObjectReduction
    >>> process = ObjectReduction()
    >>> fake_cart = process(fake_cart)
    >>> res_reduct = {u'coca light': {u'price': {u'included_tax': 1.5,
    ...                                          u'vat': 5.5},
    ...                               u'quantity': 3.0,
    ...                               u'weight' : 0.050000000000000003,
    ...                               'total_weight' : 0.15000000000000002,
    ...                               'total': {'amount_vat':
    ...                                         0.23459715639810419,
    ...                                         'included_tax': 4.5,
    ...                                         'vat': 5.5,
    ...                                         'without_tax':
    ...                                         4.2654028436018958}},
    ...               u'shoes': {u'price': {u'included_tax': 15.0,
    ...                                     u'vat': 19.600000000000001},
    ...                          u'quantity': 1.0,
    ...                          u'weight' : 0.5,
    ...                          u'reductions': [{u'percentage': False,
    ...                                           u'value': 3}],
    ...                          'total_weight' : 0.5,
    ...                          'total': {'amount_vat': 1.9665551839464879,
    ...                                    'included_tax': 12.0,
    ...                                    'vat': 19.600000000000001,
    ...                                    'without_tax': 10.033444816053512}},
    ...               u'television': {u'price': {u'included_tax': 350.0,
    ...                                          u'vat': 19.600000000000001},
    ...                               u'quantity': 1.0,
    ...                               u'weight' : 50,
    ...                               u'reductions': [{u'percentage': True,
    ...                                                u'value': 10},
    ...                                               {u'percentage': False,
    ...                                                u'value': 100}],
    ...                               'total_weight' : 50.0,
    ...                               'total': {'amount_vat':
    ...                                         35.23411371237458,
    ...                                         'included_tax': 215.0,
    ...                                         'vat': 19.600000000000001,
    ...                                         'without_tax':
    ...                                         179.76588628762542}}}
    >>> res_reduct == fake_cart.products
    True

CartAmount
----------

This rule calculate the amount of the Cart and create a sub_total by vat::

    >>> from rules.standard_rules import CartAmount
    >>> process = CartAmount()
    >>> fake_cart = process(fake_cart)
    >>> res_cart = {'price_by_vat': {5.5: {'without_tax': 4.2654028436018958,
    ...                               	   'included_tax':4.5,
    ...                                	   'amount_vat': 0.23459715639810419,
    ...                                	   'vat': 5.5
    ...                              	  },
    ...                              19.600000000000001: {'without_tax':
    ... 						                          189.79933110367892,
    ...                                              	  'included_tax': 227.0,
    ...                                              	  'amount_vat':
    ... 						                          37.200668896321076,
    ...                                              	  'vat':
    ... 						                          19.600000000000001
    ...                                             	 }
    ...                        	    },
    ...             'amount': 231.5,
    ...             'quantity_total': 5,
    ...             'weight': 50.649999999999999,
    ...            }
    >>> fake_cart.cart == res_cart
    True

CartReduction
-------------

This rule add a reduction on the cart amount::

    >>> reductions = [{u'percentage': True,
    ...                u'value': 10},
    ...               {u'percentage': False,
    ...                u'value': 100}]
    >>> fake_cart.cart['reductions'] = reductions
    >>> from rules.standard_rules import CartReduction
    >>> process = CartReduction()
    >>> fake_cart = process(fake_cart)
    >>> reduct_cart = {'amount': 108.34999999999998,
    ...                'quantity_total': 5,
    ...                'weight': 50.649999999999999,
    ...                'price_by_vat': {5.5: {'amount_vat': 0.19908077401623903,
    ...                                       'included_tax':
    ...                                       3.8187312106751303,
    ...                                       'vat': 5.5,
    ...                                       'without_tax':
    ...                                       3.6196504366588913},
    ...                                 19.600000000000001: {'amount_vat':
    ...                                                      17.130542376845881,
    ...                                                      'included_tax':
    ...                                                      104.53126878932486,
    ...                                                      'vat':
    ...                                                      19.600000000000001,
    ...                                                      'without_tax':
    ...                                                      87.400726412478974}
    ...                                },
    ...      'reductions': [{u'percentage': True, u'value': 10},
    ...                     {u'percentage': False, u'value': 100}]}
    >>> fake_cart.products == res_reduct
    True
    >>> fake_cart.cart == reduct_cart
    True


Chain mode
----------

Like you could see in the doc about rules you could chain all this rules.
Now let's try to link this 4 rules::

    >>> fake_cart = FakeCart()
    >>> fake_cart.products = products
    >>> process = CartReduction()
    >>> process = CartAmount(process)
    >>> process = ObjectReduction(process)
    >>> process = ObjectAmount(process)
    >>> fake_cart = process(fake_cart)
    >>> fake_cart.products == res_reduct
    True
    >>> fake_cart.cart == reduct_cart
    True

