3

\4                 @   s6  d dl mZ d dlmZ d dlmZ eddZeddZeddZ	eddZ
edd	Zedd
ZeddddgZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deeeeZG d d! d!eeeeZG d"d# d#eeeeZd$S )%    )
namedtuple)Decimal)	get_classzpartner.availabilityUnavailable	AvailableStockRequiredzpartner.prices
FixedPriceTaxInclusiveFixedPricePurchaseInfopriceavailabilitystockrecordc               @   s   e Zd ZdZdddZdS )SelectoraB  
    Responsible for returning the appropriate strategy class for a given
    user/session.

    This can be called in three ways:

    #) Passing a request and user.  This is for determining
       prices/availability for a normal user browsing the site.

    #) Passing just the user.  This is for offline processes that don't
       have a request instance but do know which user to determine prices for.

    #) Passing nothing.  This is for offline processes that don't
       correspond to a specific user.  Eg, determining a price to store in
       a search index.

    Nc             K   s   t |S )z;
        Return an instanticated strategy instance
        )Default)selfrequestuserkwargs r   6/var/www/html/oscar2019/oscar/apps/partner/strategy.pystrategy%   s    zSelector.strategy)NN)__name__
__module____qualname____doc__r   r   r   r   r   r      s   r   c               @   s6   e Zd ZdZdddZdddZdd Zdd	d
ZdS )Basea  
    The base strategy class

    Given a product, strategies are responsible for returning a
    ``PurchaseInfo`` instance which contains:

    - The appropriate stockrecord for this customer
    - A pricing policy instance
    - An availability policy instance
    Nc             C   s$   || _ d | _|r |jjr |j| _d S )N)r   r   is_authenticated)r   r   r   r   r   __init__:   s    zBase.__init__c             C   s   t ddS )a  
        Given a product, return a ``PurchaseInfo`` instance.

        The ``PurchaseInfo`` class is a named tuple with attributes:

        - ``price``: a pricing policy object.
        - ``availability``: an availability policy object.
        - ``stockrecord``: the stockrecord that is being used

        If a stockrecord is passed, return the appropriate ``PurchaseInfo``
        instance for that product and stockrecord is returned.
        zoA strategy class must define a fetch_for_product method for returning the availability and pricing information.N)NotImplementedError)r   productr   r   r   r   fetch_for_product@   s    zBase.fetch_for_productc             C   s   t ddS )zH
        Given a parent product, fetch a ``StockInfo`` instance
        znA strategy class must define a fetch_for_parent method for returning the availability and pricing information.N)r   )r   r   r   r   r   fetch_for_parentS   s    zBase.fetch_for_parentc             C   s   | j |jS )a  
        Given a basket line instance, fetch a ``PurchaseInfo`` instance.

        This method is provided to allow purchase info to be determined using a
        basket line's attributes.  For instance, "bundle" products often use
        basket line attributes to store SKUs of contained products.  For such
        products, we need to look at the availability of each contained product
        to determine overall availability.
        )r    r   )r   liner   r   r   r   fetch_for_line]   s    zBase.fetch_for_line)N)N)N)r   r   r   r   r   r    r!   r#   r   r   r   r   r   .   s
   



r   c               @   sR   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdS )
Structuredz
    A strategy class which provides separate, overridable methods for
    determining the 3 things that a ``PurchaseInfo`` instance requires:

    #) A stockrecord
    #) A pricing policy
    #) An availability policy
    Nc             C   s0   |dkr| j |}t| j||| j|||dS )zz
        Return the appropriate ``PurchaseInfo`` instance.

        This method is not intended to be overridden.
        N)r   r   r   )select_stockrecordr
   pricing_policyavailability_policy)r   r   r   r   r   r   r    v   s    


zStructured.fetch_for_productc             C   s(   | j |}t| j||| j||d dS )N)r   r   r   )select_children_stockrecordsr
   parent_pricing_policyparent_availability_policy)r   r   children_stockr   r   r   r!      s    

zStructured.fetch_for_parentc             C   s   t ddS )z4
        Select the appropriate stockrecord
        zEA structured strategy class must define a 'select_stockrecord' methodN)r   )r   r   r   r   r   r%      s    zStructured.select_stockrecordc             C   s8   g }x.|j jddj D ]}|j|| j|f qW |S )zO
        Select appropriate stock record for all children of a product
        T)live)childrenfilterallappendr%   )r   r   recordschildr   r   r   r(      s    z'Structured.select_children_stockrecordsc             C   s   t ddS )z7
        Return the appropriate pricing policy
        zAA structured strategy class must define a 'pricing_policy' methodN)r   )r   r   r   r   r   r   r&      s    zStructured.pricing_policyc             C   s   t dd S )NzHA structured strategy class must define a 'parent_pricing_policy' method)r   )r   r   r+   r   r   r   r)      s    z Structured.parent_pricing_policyc             C   s   t ddS )z<
        Return the appropriate availability policy
        zFA structured strategy class must define a 'availability_policy' methodN)r   )r   r   r   r   r   r   r'      s    zStructured.availability_policyc             C   s   t dd S )NzMA structured strategy class must define a 'parent_availability_policy' method)r   )r   r   r+   r   r   r   r*      s    z%Structured.parent_availability_policy)N)r   r   r   r   r    r!   r%   r(   r&   r)   r'   r*   r   r   r   r   r$   l   s   
	
r$   c               @   s   e Zd ZdZdd ZdS )UseFirstStockRecorda  
    Stockrecord selection mixin for use with the ``Structured`` base strategy.
    This mixin picks the first (normally only) stockrecord to fulfil a product.

    This is backwards compatible with Oscar<0.6 where only one stockrecord per
    product was permitted.
    c             C   s(   y|j j d S  tk
r"   d S X d S )Nr   )stockrecordsr/   
IndexError)r   r   r   r   r   r%      s    z&UseFirstStockRecord.select_stockrecordN)r   r   r   r   r%   r   r   r   r   r3      s   r3   c               @   s    e Zd ZdZdd Zdd ZdS )r   z
    Availability policy mixin for use with the ``Structured`` base strategy.
    This mixin ensures that a product can only be bought if it has stock
    available (if stock is being tracked).
    c             C   s(   |s
t  S |j jst S t|jS d S )N)r   get_product_classtrack_stockr   StockRequiredAvailabilityZnet_stock_level)r   r   r   r   r   r   r'      s    
z!StockRequired.availability_policyc             C   s0   x(|D ] \}}| j ||}|jrt S qW t S )N)r'   is_available_to_buyr   r   )r   r   r+   r2   r   policyr   r   r   r*      s
    
z(StockRequired.parent_availability_policyN)r   r   r   r   r'   r*   r   r   r   r   r      s   	c               @   s    e Zd ZdZdd Zdd ZdS )NoTaxz
    Pricing policy mixin for use with the ``Structured`` base strategy.
    This mixin specifies zero tax and uses the ``price_excl_tax`` from the
    stockrecord.
    c             C   s,   | s|j d krt S t|j|j tddS )Nz0.00)currencyexcl_taxtax)price_excl_taxUnavailablePricer   price_currencyD)r   r   r   r   r   r   r&      s    zNoTax.pricing_policyc             C   s6   dd |D }|st  S |d }t|j|jtddS )Nc             S   s    g | ]}|d  dk	r|d  qS )   Nr   ).0xr   r   r   
<listcomp>   s    z/NoTax.parent_pricing_policy.<locals>.<listcomp>r   z0.00)r<   r=   r>   )r@   r   rA   r?   rB   )r   r   r+   r4   r   r   r   r   r)      s    zNoTax.parent_pricing_policyN)r   r   r   r   r&   r)   r   r   r   r   r;      s   	r;   c               @   s@   e Zd ZdZedZedZdd Zdd Zdd	 Z	d
d Z
dS )FixedRateTaxa  
    Pricing policy mixin for use with the ``Structured`` base strategy.  This
    mixin applies a fixed rate tax to the base price from the product's
    stockrecord.  The price_incl_tax is quantized to two decimal places.
    Rounding behaviour is Decimal's default
    0z0.01c             C   sN   | s|j d krt S | j||}| j|}|j | j|}t|j|j |dS )N)r<   r=   r>   )r?   r@   get_rateget_exponentquantizer	   rA   )r   r   r   rateexponentr>   r   r   r   r&     s    
zFixedRateTax.pricing_policyc             C   sX   dd |D }|st  S |d }| j||}| j|}|j| j|}t|j|j|dS )Nc             S   s    g | ]}|d  dk	r|d  qS )rC   Nr   )rD   rE   r   r   r   rF     s    z6FixedRateTax.parent_pricing_policy.<locals>.<listcomp>r   )r<   r=   r>   )r@   rI   rJ   r?   rK   r   rA   )r   r   r+   r4   r   rL   rM   r>   r   r   r   r)     s    
z"FixedRateTax.parent_pricing_policyc             C   s   | j S )z
        This method serves as hook to be able to plug in support for varying tax rates
        based on the product.

        TODO: Needs tests.
        )rL   )r   r   r   r   r   r   rI   &  s    zFixedRateTax.get_ratec             C   s   | j S )z
        This method serves as hook to be able to plug in support for a varying exponent
        based on the currency.

        TODO: Needs tests.
        )rM   )r   r   r   r   r   rJ   /  s    zFixedRateTax.get_exponentN)r   r   r   r   rB   rL   rM   r&   r)   rI   rJ   r   r   r   r   rG     s   	rG   c               @   s    e Zd ZdZdd Zdd ZdS )DeferredTaxz
    Pricing policy mixin for use with the ``Structured`` base strategy.
    This mixin does not specify the product tax and is suitable to territories
    where tax isn't known until late in the checkout process.
    c             C   s&   | s|j d krt S t|j|j dS )N)r<   r=   )r?   r@   r   rA   )r   r   r   r   r   r   r&   @  s
    zDeferredTax.pricing_policyc             C   s0   dd |D }|st  S |d }t|j|jdS )Nc             S   s    g | ]}|d  dk	r|d  qS )rC   Nr   )rD   rE   r   r   r   rF   H  s    z5DeferredTax.parent_pricing_policy.<locals>.<listcomp>r   )r<   r=   )r@   r   rA   r?   )r   r   r+   r4   r   r   r   r   r)   G  s    z!DeferredTax.parent_pricing_policyN)r   r   r   r   r&   r)   r   r   r   r   rN   9  s   rN   c               @   s   e Zd ZdZdS )r   z
    Default stock/price strategy that uses the first found stockrecord for a
    product, ensures that stock is available (unless the product class
    indicates that we don't need to track stock) and charges zero tax.
    N)r   r   r   r   r   r   r   r   r   Y  s   r   c               @   s   e Zd ZdZedZdS )UKa  
    Sample strategy for the UK that:

    - uses the first stockrecord for each product (effectively assuming
        there is only one).
    - requires that a product has stock available to be bought
    - applies a fixed rate of tax on all products

    This is just a sample strategy used for internal development.  It is not
    recommended to be used in production, especially as the tax rate is
    hard-coded.
    z0.20N)r   r   r   r   rB   rL   r   r   r   r   rO   a  s   rO   c               @   s   e Zd ZdZdS )USa  
    Sample strategy for the US.

    - uses the first stockrecord for each product (effectively assuming
      there is only one).
    - requires that a product has stock available to be bought
    - doesn't apply a tax to product prices (normally this will be done
      after the shipping address is entered).

    This is just a sample one used for internal development.  It is not
    recommended to be used in production.
    N)r   r   r   r   r   r   r   r   rP   r  s   rP   N)collectionsr   decimalr   rB   oscar.core.loadingr   r   r   r8   r@   r   r	   r
   objectr   r   r$   r3   r   r;   rG   rN   r   rO   rP   r   r   r   r   <module>   s*   





>P8 