.. -*- Mode: doctest -*-

Doctest for domain/sellable.txt

Imports that will be used in this doctest:

    >>> from stoqlib.database.runtime import new_store
    >>> from stoqlib.domain.product import Product
    >>> from stoqlib.domain.sellable import Sellable
    >>> from stoqlib.domain.sellable import SellableCategory
    >>> from decimal import Decimal

Create a new store

    >>> store = new_store()

SellableCategory
================

.. TODO:
..     def get_commission(self):
..     def get_description(self):
..     def get_commission(self):
..     def get_markup(self):


Sellable
========

    >>> sellable = Sellable(description=u"Sellable",
    ...                     store=store)

    >>> sellable
    <Sellable ...>

Commission is initially set to 0:

    >>> sellable.get_commission() == Decimal('0.00')
    True

    >>> sellable.get_description()
    u'Sellable'


    >>> product = Product(sellable=sellable, store=store)

Properties: Markup, Price and Commission
========================================

Markup is initially set to 0, since we haven't defined price or cost:

    >>> sellable.markup == Decimal('0')
    True

Let's say that the initial price is 20 and the cost to 10

    >>> sellable.price = 20
    >>> sellable.cost = 10

Then we will have a markup of 100%:

    >>> sellable.markup == Decimal('100')
    True

If we modify markup directly, the price will be updated:

    >>> sellable.markup = 200
    >>> sellable.price
    <currency ...30...>

But the cost will stay the same:

    >>> sellable.cost
    <currency ...10...>

The default commission is 0

    >>> sellable.commission == Decimal('0.00')
    True

It can be modified:

    >>> sellable.commission = Decimal('10.00')

    >>> sellable.commission
    Decimal('10.00')

Querying sellable status
========================

.. TODO:
..     def is_unavailable(self):
..     def set_unavailable(self):
..     def cancel(self):

A newly created sellable is in the status unavailable, because there are no available
items to sell:

    >>> sellable.status == Sellable.STATUS_UNAVAILABLE
    True

Since there's no stock, then it cannot be sold:

    >>> sellable.can_be_sold()
    False

At some point we get stocks, then we make it possible to sell it:

    >>> sellable.can_sell()

And the it's possible to sell it:

    >>> sellable.can_be_sold()
    True

Accessors
=========

.. TODO
..     def get_code_str(self):
..     def get_short_description(self):
..     def get_suggested_markup(self):
..     def get_unit_description(self):
..     def get_description(self):

Class methods:
=============

.. TODO:
..     def check_barcode_exists(cls, barcode):

This will return a list of available sellables:

    >>> sellable.status == Sellable.STATUS_AVAILABLE
    True

    >>> sellable in Sellable.get_available_sellables(store)
    True

Selling the sellable, removes it from the list of available sellables:

    >>> sellable.set_unavailable()
    >>> sellable in Sellable.get_available_sellables(store)
    False

Also, we can get a list of available sellable by a list of categories:

    >>> category = SellableCategory(description=u'Battery', store=store)
    >>> sellable.category = category
    >>> sellable.can_sell()
    >>> sellable in Sellable.get_unblocked_by_categories(store, [category])
    True

Unblocked means available or sold:

    >>> sellable in Sellable.get_unblocked_sellables(store)
    True

    >> sellable.set_unavailable()
    >>> sellable in Sellable.get_unblocked_sellables(store)
    True

Blocking the sellable removes from the return value:

    >>> sellable.status = Sellable.STATUS_BLOCKED
    >>> sellable in Sellable.get_unblocked_sellables(store)
    False

Unavailable means that it cannot be sold (no stock):

    >>> Sellable.get_unavailable_sellables(store).count() == 5
    True

    >>> sellable.barcode = u'1138'

We can query using a specific barcode:

    >>> sellable.barcode == u'1138'
    True

    >>> Sellable.get_availables_by_barcode(store, u'1138')
    Traceback (most recent call last):
        ...
    BarcodeDoesNotExists: The sellable with barcode '1138' doesn't exists or is not available to be sold

    >>> sellable.cancel()

    >>> sellable == Sellable.get_availables_by_barcode(store, u'1138')
    True

And for sold sellables using a specific barcode:

    >>> sellable == Sellable.get_availables_and_unavailable_by_barcode(store, u'1138')
    True

    >>> sellable.status = Sellable.STATUS_BLOCKED

    >>> Sellable.get_availables_and_unavailable_by_barcode(store, u'1138')
    Traceback (most recent call last):
        ...
    BarcodeDoesNotExists: The sellable with barcode '1138' doesn't exists or is not available to be sold


SaleItem
============

.. TODO:
..   def set_unavailable(self):
..   def cancel(self):
..   def get_total(self):
..   def get_quantity_unit_string(self):


    >>> store.close()
