3

\*                 @   s   d dl mZ d dl mZ d dlmZ d dlmZ d dlm	Z	m
Z
 d dlmZ e
ddZe	d	d
dg\ZZdddgZG dd deZG dd deZG dd deZdS )    )Decimal)ROUND_UP)gettext_lazy)	ungettext)get_classes	get_model)currencyoffer	Conditionzoffer.utilsrange_anchor
unit_priceCountConditionCoverageConditionValueConditionc               @   sf   e Zd ZdZedZedd Zedd ZG dd dZ	d	d
 Z
dd Zdd Zdd Zdd ZdS )r   z[
    An offer condition dependent on the NUMBER of matching items from the
    basket.
    z0Basket includes %(count)d item(s) from %(range)sc             C   s   | j | jt| jj d S )N)countrange)_descriptionvaluestrr   lower)self r   6/var/www/html/oscar2019/oscar/apps/offer/conditions.pyname   s    zCountCondition.namec             C   s   | j | jt| jd S )N)r   r   )r   r   r   r   )r   r   r   r   description   s    zCountCondition.descriptionc               @   s$   e Zd ZdZdZedZedZdS )zCountCondition.Metar	   TzCount conditionzCount conditionsN)__name__
__module____qualname__	app_labelproxy_verbose_nameverbose_name_pluralr   r   r   r   Meta%   s   r#   c             C   sN   d}xD|j  D ]8}| j|r8|j|dkr8||j|7 }|| jkrdS qW dS )zH
        Determines whether a given basket meets this condition
        r   TF)	all_linescan_apply_conditionquantity_without_offer_discountr   )r   r	   basketnum_matchesliner   r   r   is_satisfied+   s    

zCountCondition.is_satisfiedc             C   sZ   t | drt| dS d}x6|j D ]*}| j|r"|j|dkr"||j|7 }q"W || _|S )N_num_matchesr   )hasattrgetattrr$   r%   r&   r+   )r   r'   r	   r(   r)   r   r   r   _get_num_matches8   s    


zCountCondition._get_num_matchesc             C   s&   | j ||}d|  k o | jk S   S )Nr   )r.   r   )r   r	   r'   r(   r   r   r   is_partially_satisfiedC   s    z%CountCondition.is_partially_satisfiedc             C   s.   | j ||}| j| }tdd||| jd S )Nz)Buy %(delta)d more product from %(range)sz*Buy %(delta)d more products from %(range)s)deltar   )r.   r   r   r   )r   r	   r'   r(   r0   r   r   r   get_upsell_messageG   s
    
z!CountCondition.get_upsell_messagec       
      C   s   d}x|D ]\}}}||7 }q
W t d| j| }|dkr<dS xL| j||ddD ]8\}}t|j||}	|j|	|d ||	8 }|dkrNP qNW dS )a(  
        Marks items within the basket lines as consumed so they
        can't be reused in other offers.

        :basket: The basket
        :affected_lines: The lines that have been affected by the discount.
                         This should be list of tuples (line, discount, qty)
        r   NT)most_expensive_first)r	   )maxr   get_applicable_linesminr&   consume)
r   r	   r'   affected_linesZnum_consumedr)   __quantity
to_consumequantity_to_consumer   r   r   consume_itemsN   s    
zCountCondition.consume_itemsN)r   r   r   __doc__r    r   propertyr   r   r#   r*   r.   r/   r1   r<   r   r   r   r   r      s   c               @   sn   e Zd ZdZedZedd Zedd ZG dd dZ	d	d
 Z
dd Zdd Zdd Zdd Zdd ZdS )r   zd
    An offer condition dependent on the number of DISTINCT matching items from
    the basket.
    z9Basket includes %(count)d distinct item(s) from %(range)sc             C   s   | j | jt| jj d S )N)r   r   )r   r   r   r   r   )r   r   r   r   r   s   s    zCoverageCondition.namec             C   s   | j | jt| jd S )N)r   r   )r   r   r   r   )r   r   r   r   r   y   s    zCoverageCondition.descriptionc               @   s$   e Zd ZdZdZedZedZdS )zCoverageCondition.Metar	   TzCoverage ConditionzCoverage ConditionsN)r   r   r   r   r   r    r!   r"   r   r   r   r   r#      s   r#   c             C   s^   g }xT|j  D ]H}|j|sq|j}| j|rD|j|krD|j|j t|| jkrdS qW dS )zH
        Determines whether a given basket meets this condition
        TF)r$   is_available_for_offer_discountproductr%   idappendlenr   )r   r	   r'   covered_idsr)   r@   r   r   r   r*      s    
zCoverageCondition.is_satisfiedc             C   sP   g }xB|j  D ]6}|j|sq|j}| j|r|j|kr|j|j qW t|S )N)r$   r?   r@   r%   rA   rB   rC   )r   r'   r	   rD   r)   r@   r   r   r   _get_num_covered_products   s    
z+CoverageCondition._get_num_covered_productsc             C   s*   | j | j|| }tdd||| jd S )Nz)Buy %(delta)d more product from %(range)sz*Buy %(delta)d more products from %(range)s)r0   r   )r   rE   r   r   )r   r	   r'   r0   r   r   r   r1      s    z$CoverageCondition.get_upsell_messagec             C   s"   d| j ||  k o| jk S   S )Nr   )rE   r   )r   r	   r'   r   r   r   r/      s    z(CoverageCondition.is_partially_satisfiedc       
      C   s   g }x|D ]\}}}|j |j q
W td| jt| }|dkrDdS xb|j D ]V}|j}	| j|sdqN|	|krnqN|j|szqN|jd|d |j |	 |d8 }|dkrNP qNW dS )zr
        Marks items within the basket lines as consumed so they
        can't be reused in other offers.
        r   N   )r	   )	rB   r@   r3   r   rC   r$   r%   r?   r6   )
r   r	   r'   r7   Zconsumed_productsr)   r8   r9   r:   r@   r   r   r   r<      s&    


zCoverageCondition.consume_itemsc             C   sf   g }t d}xT|j D ]H}| j|rL|jj|krL|j|jj |t||7 }t|| jkr|S qW |S )Nz0.00)	Dr$   r%   r@   rA   rB   r   rC   r   )r   r	   r'   rD   r   r)   r   r   r   get_value_of_satisfying_items   s    z/CoverageCondition.get_value_of_satisfying_itemsN)r   r   r   r=   r    r   r>   r   r   r#   r*   rE   r1   r/   r<   rH   r   r   r   r   r   k   s   c               @   sf   e Zd ZdZedZedd Zedd ZG dd dZ	d	d
 Z
dd Zdd Zdd Zdd ZdS )r   zZ
    An offer condition dependent on the VALUE of matching items from the
    basket.
    z)Basket includes %(amount)s from %(range)sc             C   s    | j t| jt| jj d S )N)amountr   )r   r   r   r   r   r   )r   r   r   r   r      s    zValueCondition.namec             C   s   | j t| jt| jd S )N)rI   r   )r   r   r   r   r   )r   r   r   r   r      s    zValueCondition.descriptionc               @   s$   e Zd ZdZdZedZedZdS )zValueCondition.Metar	   TzValue conditionzValue conditionsN)r   r   r   r   r   r    r!   r"   r   r   r   r   r#      s   r#   c             C   sd   t d}xV|j D ]J}| j|rN|j|dkrNt||}||t|j| 7 }|| jkrdS qW dS )zG
        Determine whether a given basket meets this condition
        z0.00r   TF)rG   r$   r%   r&   r   intr   )r   r	   r'   value_of_matchesr)   pricer   r   r   r*      s    


zValueCondition.is_satisfiedc             C   sp   t | drt| dS td}xH|j D ]<}| j|r&|j|dkr&t||}||t|j| 7 }q&W || _|S )N_value_of_matchesz0.00r   )	r,   r-   rG   r$   r%   r&   r   rJ   rM   )r   r	   r'   rK   r)   rL   r   r   r   _get_value_of_matches   s    



z$ValueCondition._get_value_of_matchesc             C   s*   | j ||}td|  k o$| jk S   S )Nz0.00)rN   rG   r   )r   r	   r'   rK   r   r   r   r/     s    z%ValueCondition.is_partially_satisfiedc             C   s*   | j ||}tdt| j| | jd S )Nz#Spend %(value)s more from %(range)s)r   r   )rN   r    r   r   r   )r   r	   r'   rK   r   r   r   r1     s    z!ValueCondition.get_upsell_messagec             C   s   t d}x(|D ] \}}}t||}||| 7 }qW td| j| }	|	dkrNdS x`| j||ddD ]L\}}t|j||	| jt dt}
|j	|
|d |	||
 8 }	|	dkr`P q`W dS )z
        Marks items within the basket lines as consumed so they
        can't be reused in other offers.

        We allow lines to be passed in as sometimes we want them sorted
        in a specific order.
        z0.00r   NT)r2   rF   )r	   )
rG   r   r3   r   r4   r5   r&   quantizer   r6   )r   r	   r'   r7   Zvalue_consumedr)   r8   qtyrL   r:   r;   r   r   r   r<     s     	
zValueCondition.consume_itemsN)r   r   r   r=   r    r   r>   r   r   r#   r*   rN   r/   r1   r<   r   r   r   r   r      s   N)decimalr   rG   r   django.utils.translationr   r    r   oscar.core.loadingr   r   #oscar.templatetags.currency_filtersr   r
   r   r   __all__r   r   r   r   r   r   r   <module>   s   

Yi