# Path: magnate/utils/attrs.py
# def enum_converter(EnumType, value):
#     """
#     Convert a string into an :class:`enum.Enum`
# 
#     :arg EnumType: An Enum type to convert to
#     :arg value: The value to convert to an Enum
# 
#     Typically, this function will be used with the :meth:`attr.ib` convert
#     parameter and :func:`functools.partial`.  Example::
# 
#         @attr.s
#         class CommodityData:
#             type = attr.ib(convert=partial(enum_converter, CommodityType))
#     """
#     if not isinstance(value, EnumType):
#         try:
#             return EnumType[value]
#         except Exception:
#             # Let the validator catch this
#             pass
#     return value
# 
# def enum_validator(EnumType, instance, attribute, value):
#     """
#     Validate that a value is a member of an :class:`enum.Enum`
# 
#     :arg EnumType: An Enum type to convert to
#     :arg instance: The instance of the attr.s class that is being created
#     :arg attribute: The attribute of the attr.s class that is being set
#     :arg value: The value the attribute is being set to
# 
#     This function will be used with the :meth:`attr.ib` validate parameter and
#     :func:`functools.partial`.  Example::
# 
#         @attr.s
#         class CommodityData:
#             type = attr.ib(validator=partial(enum_validator, CommodityType))
#     """
#     if not isinstance(value, EnumType):
#         raise ValueError('{} is not a {}'.format(value, EnumType))


import enum
import attr
from functools import partial
from .utils.attrs import enum_converter, enum_validator
# Enums are class-like but here we are using the function interface for
# creating them so that we don't have to manually specify ids for each
# category
#pylint: disable=invalid-name
OrderStatusType = enum.Enum('OrderStatusType', ('presale', 'submitted', 'rejected', 'finalized'))
#pylint: enable=invalid-name


@attr.s
class Order:
    """Information needed to complete a transaction.

    * :py:attr:`location` The location at which the sale is occuring
    * :py:attr:`commodity`: the name of the commodity being bought or sold
    * :py:attr:`price`: the price at which the user is agreeing to buy or sell
    * :py:attr:`hold_quantity`: The amount of the commodity to place in or
        take from the ship's hold
    * :py:attr:`warehouse_quantity`: The amount of the commodity to place in
        or take from the player's warehouse space at the location
    * :py:attr:`buy`: if True, the user is asking to buy the commodity.
        Otherwise, the user is selling the commodity
    * :py:attr:`status`: Status of the transaction.  May be any one of the EnumTypes
    """
    location = attr.ib(validator=attr.validators.instance_of(str))
    commodity = attr.ib(validator=attr.validators.instance_of(str))
    price = attr.ib(validator=attr.validators.instance_of(int))
    hold_quantity = attr.ib(validator=attr.validators.instance_of(int), default=0)
    warehouse_quantity = attr.ib(validator=attr.validators.instance_of(int), default=0)
    buy = attr.ib(validator=attr.validators.instance_of(bool), default=True)
    status = attr.ib(default=OrderStatusType.presale,

# Path: magnate/utils/attrs.py
# def enum_converter(EnumType, value):
#     """
#     Convert a string into an :class:`enum.Enum`
# 
#     :arg EnumType: An Enum type to convert to
#     :arg value: The value to convert to an Enum
# 
#     Typically, this function will be used with the :meth:`attr.ib` convert
#     parameter and :func:`functools.partial`.  Example::
# 
#         @attr.s
#         class CommodityData:
#             type = attr.ib(convert=partial(enum_converter, CommodityType))
#     """
#     if not isinstance(value, EnumType):
#         try:
#             return EnumType[value]
#         except Exception:
#             # Let the validator catch this
#             pass
#     return value
# 
# def enum_validator(EnumType, instance, attribute, value):
#     """
#     Validate that a value is a member of an :class:`enum.Enum`
# 
#     :arg EnumType: An Enum type to convert to
#     :arg instance: The instance of the attr.s class that is being created
#     :arg attribute: The attribute of the attr.s class that is being set
#     :arg value: The value the attribute is being set to
# 
#     This function will be used with the :meth:`attr.ib` validate parameter and
#     :func:`functools.partial`.  Example::
# 
#         @attr.s
#         class CommodityData:
#             type = attr.ib(validator=partial(enum_validator, CommodityType))
#     """
#     if not isinstance(value, EnumType):
#         raise ValueError('{} is not a {}'.format(value, EnumType))


# Path: magnate/order.py
import enum
import attr
from functools import partial
from .utils.attrs import enum_converter, enum_validator

# Enums are class-like but here we are using the function interface for
# creating them so that we don't have to manually specify ids for each
# category
#pylint: disable=invalid-name
OrderStatusType = enum.Enum('OrderStatusType', ('presale', 'submitted', 'rejected', 'finalized'))
#pylint: enable=invalid-name


@attr.s
class Order:
    """Information needed to complete a transaction.

    * :py:attr:`location` The location at which the sale is occuring
    * :py:attr:`commodity`: the name of the commodity being bought or sold
    * :py:attr:`price`: the price at which the user is agreeing to buy or sell
    * :py:attr:`hold_quantity`: The amount of the commodity to place in or
        take from the ship's hold
    * :py:attr:`warehouse_quantity`: The amount of the commodity to place in
        or take from the player's warehouse space at the location
    * :py:attr:`buy`: if True, the user is asking to buy the commodity.
        Otherwise, the user is selling the commodity
    * :py:attr:`status`: Status of the transaction.  May be any one of the EnumTypes
    """
    location = attr.ib(validator=attr.validators.instance_of(str))
    commodity = attr.ib(validator=attr.validators.instance_of(str))
    price = attr.ib(validator=attr.validators.instance_of(int))
    hold_quantity = attr.ib(validator=attr.validators.instance_of(int), default=0)
    warehouse_quantity = attr.ib(validator=attr.validators.instance_of(int), default=0)
    buy = attr.ib(validator=attr.validators.instance_of(bool), default=True)
    status = attr.ib(default=OrderStatusType.presale,

                     validator=partial(enum_validator, OrderStatusType),