B
    `B+                 @   s   d dl mZ d dlmZ d dlmZmZ 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 d d	lmZ G d
d dejZG dd dejZG dd dejZdS )    )Decimal)
exceptions)modelstransaction)Sum)timezone)gettext_lazy)get_unused_code)AUTH_USER_MODEL)	get_modelc            	       s  e Zd ZdZejedddZejeddZ	ej
eddd	Zejed
dZejdddZeedZeedZejddedddiejdddZG dd dZdd Zdd Zdd Zd(ddZ fd d!Zed"d# Zed$d% Zed&d' Z  ZS ))AbstractVoucherSetaC  A collection of vouchers (potentially auto-generated)

    a VoucherSet is a group of voucher that are generated
    automatically.

    - count: the minimum number of vouchers in the set. If this is kept at
    zero, vouchers are created when and as needed.

    - code_length: the length of the voucher code. Codes are by default created
    with groups of 4 characters: XXXX-XXXX-XXXX. The dashes (-) do not count for
    the code_length.

    - :py:attr:`.start_datetime` and :py:attr:`.end_datetime` together define the validity
      range for all vouchers in the set.
    Named   )verbose_name
max_lengthzNumber of vouchers)r   zLength of Code   )r   defaultDescriptionT)auto_now_adddb_indexzStart datetimezEnd datetimezoffer.ConditionalOffervoucher_setZOffer
offer_typeVoucher)related_namer   limit_choices_to	on_deletenullblankc               @   s.   e Zd ZdZdZdZdgZedZedZ	dS )zAbstractVoucherSet.MetaTvoucherdate_createdz-date_createdZ
VoucherSetZVoucherSetsN)
__name__
__module____qualname__abstract	app_labelget_latest_byordering_r   verbose_name_plural r)   r)   Q/home/dcms/DCMS/lib/python3.7/site-packages/oscar/apps/voucher/abstract_models.pyMeta-   s   r+   c             C   s   | j S )N)name)selfr)   r)   r*   __str__5   s    zAbstractVoucherSet.__str__c             C   s,   | j  }xt|| jD ]}|   qW dS )zGenerate vouchers for this setN)voucherscountrangeadd_new)r-   Zcurrent_countir)   r)   r*   generate_vouchers8   s    
z$AbstractVoucherSet.generate_vouchersc             C   sN   t dd}t| jd}|jj| j|| |j| j| jd}| j	rJ|j
| j	 |S )zAdd a new voucher to this setr   r   )length)r,   coder   usagestart_datetimeend_datetime)r   r	   code_lengthZobjectscreater,   
SINGLE_USEr8   r9   offeroffersadd)r-   r   r6   r   r)   r)   r*   r2   >   s    

zAbstractVoucherSet.add_newNc             C   s(   |p
t  }| j|  ko"| jkS   S )z3Test whether this voucher set is currently active. )r   nowr8   r9   )r-   test_datetimer)   r)   r*   	is_activeO   s    zAbstractVoucherSet.is_activec          	      sV   t | j| j | _t 0 t j|| |   | jj| j	| j
d W d Q R X d S )N)r8   r9   )maxr0   r/   r   Zatomicsupersaver4   updater8   r9   )r-   argskwargs)	__class__r)   r*   rE   T   s    
zAbstractVoucherSet.savec             C   s   | j jtdd}|d S )Nnum_basket_additions)resultrK   )r/   	aggregater   )r-   valuer)   r)   r*   rJ   ^   s    z'AbstractVoucherSet.num_basket_additionsc             C   s   | j jtdd}|d S )N
num_orders)rK   rK   )r/   rL   r   )r-   rM   r)   r)   r*   rN   c   s    zAbstractVoucherSet.num_ordersc             C   s   | j jtdd}|d S )Ntotal_discount)rK   rK   )r/   rL   r   )r-   rM   r)   r)   r*   rO   h   s    z!AbstractVoucherSet.total_discount)N) r    r!   r"   __doc__r   	CharFieldr'   r,   PositiveIntegerFieldr0   ZIntegerFieldr:   Z	TextFielddescriptionDateTimeFieldr   r8   r9   ZOneToOneFieldCASCADEr=   r+   r.   r4   r2   rB   rE   propertyrJ   rN   rO   __classcell__r)   r)   )rI   r*   r      s,   

r   c                   s  e Zd ZdZejeddeddZejeddddedd	Zej	d
dedddidZ
d\ZZZeedfeedfeedffZejeddeedZejedddZejedddZejedddZejedddZejeddded d!Zejd"dddejd#Zejddd$ZG d%d& d&Zd'd( Zd)d* Z fd+d,Z d<d.d/Z!d0d1 Z"d=d2d3Z#d4d5 Z$d6d7 Z%de%_&d8d9 Z'de'_&e(d:d; Z)  Z*S )>AbstractVouchera.  
    A voucher.  This is simply a link to a collection of offers.

    Note that there are three possible "usage" modes:
    (a) Single use
    (b) Multi-use
    (c) Once per customer

    Oscar enforces those modes by creating VoucherApplication
    instances when a voucher is used for an order.
    r      zIThis will be shown in the checkout and basket once the voucher is entered)r   	help_textZCodeTz$Case insensitive / No spaces allowed)r   r   uniquerZ   zoffer.ConditionalOfferr/   ZOffersr   r   )r   r   r   )z
Single usez	Multi-usezOnce per customerz Can be used once by one customerz0Can be used multiple times by multiple customersz"Can only be used once per customerUsage)r   choicesr   zStart datetime)r   zEnd datetimezTimes added to basketr   )r   zTimes on orderszTotal discount   r   z0.00)Zdecimal_placesZ
max_digitsr   zvoucher.VoucherSet)r   r   r   r   )r   r   c               @   s.   e Zd ZdZdZdgZdZedZedZ	dS )zAbstractVoucher.MetaTr   z-date_createdr   r   ZVouchersN)
r    r!   r"   r#   r$   r&   r%   r'   r   r(   r)   r)   r)   r*   r+      s   r+   c             C   s   | j S )N)r,   )r-   r)   r)   r*   r.      s    zAbstractVoucher.__str__c             C   s,   t | j| j| j| jkgr(ttdd S )Nz(End date should be later than start date)allr8   r9   r   ZValidationErrorr'   )r-   r)   r)   r*   clean   s    
zAbstractVoucher.cleanc                s   | j  | _ t j|| d S )N)r6   upperrD   rE   )r-   rG   rH   )rI   r)   r*   rE      s    zAbstractVoucher.saveNc             C   s(   |p
t  }| j|  ko"| jkS   S )z@
        Test whether this voucher is currently active.
        )r   r@   r8   r9   )r-   rA   r)   r)   r*   rB      s    zAbstractVoucher.is_activec             C   s   t  }| j|k S )zJ
        Test whether this voucher has passed its expiration date
        )r   r@   r9   )r-   r@   r)   r)   r*   
is_expired   s    zAbstractVoucher.is_expiredc             C   s   d\}}| j | jkr.| j  }|std}nT| j | jkr@d}nB| j | jkr|js`d}td}n"| jj| |d  }|std}||fS )z
        Test whether this voucher is available to the passed user.

        Returns a tuple of a boolean for whether it is successful, and a
        availability message.
        )F z"This voucher has already been usedTFz1This voucher is only available to signed in users)r   userz6You have already used this voucher in a previous order)	r7   r<   applicationsexistsr'   	MULTI_USEONCE_PER_CUSTOMERis_authenticatedfilter)r-   rd   is_availablemessager)   r)   r*   is_available_to_user   s"    
z$AbstractVoucher.is_available_to_userc             C   s^   | j |jd\}}|sd|fS dtd }}x(| j D ]}|j|dr8d}d}P q8W ||fS )z
        Tests whether this voucher is available to the passed basket.

        Returns a tuple of a boolean for whether it is successful, and a
        availability message.
        )rd   Fz-This voucher is not available for this basket)basketTrc   )rm   ownerr'   r>   r_   Zis_condition_satisfied)r-   rn   rk   rl   r=   r)   r)   r*   is_available_for_basket   s    z'AbstractVoucher.is_available_for_basketc             C   sD   |j r| jj| ||d n| jj| |d |  jd7  _|   dS )z>
        Records a usage of this voucher in an order.
        )r   orderrd   )r   rq      N)ri   re   r;   rN   rE   )r-   rq   rd   r)   r)   r*   record_usage   s
    zAbstractVoucher.record_usagec             C   s   |  j |d 7  _ |   dS )z=
        Record a discount that this offer has given
        discountN)rO   rE   )r-   rt   r)   r)   r*   record_discount   s    zAbstractVoucher.record_discountc             C   s   | j  jS )z
        Returns the first offer's benefit instance.

        A voucher is commonly only linked to one offer. In that case,
        this helper can be used for convenience.
        )r>   firstbenefit)r-   r)   r)   r*   rw     s    zAbstractVoucher.benefit)N)N)+r    r!   r"   rP   r   rQ   r'   r,   r6   ZManyToManyFieldr>   r<   rg   rh   ZUSAGE_CHOICESr7   rT   r8   r9   rR   rJ   rN   ZDecimalFieldr   rO   
ForeignKeyrU   r   r   r+   r.   r`   rE   rB   rb   rm   rp   rs   Zalters_dataru   rV   rw   rW   r)   r)   )rI   r*   rX   n   sN   








rX   c               @   s|   e Zd ZdZejdejdeddZeje	ddejeddZ
ejd	ejed
dZejdddZG dd dZdd ZdS )AbstractVoucherApplicationz
    For tracking how often a voucher has been used in an order.

    This is used to enforce the voucher usage mode in
    Voucher.is_available_to_user, and created in Voucher.record_usage.
    zvoucher.Voucherre   r   )r   r   r   TZUser)r   r   r   r   zorder.OrderZOrder)r   r   )r   r   c               @   s*   e Zd ZdZdZdgZedZedZdS )zAbstractVoucherApplication.MetaTr   z-date_createdzVoucher ApplicationzVoucher ApplicationsN)	r    r!   r"   r#   r$   r&   r'   r   r(   r)   r)   r)   r*   r+   ,  s
   r+   c             C   s   t d| j| jd S )Nz '%(voucher)s' used by '%(user)s')r   rd   )r'   r   rd   )r-   r)   r)   r*   r.   3  s    z"AbstractVoucherApplication.__str__N)r    r!   r"   rP   r   rx   rU   r'   r   r
   rd   rq   rT   r   r+   r.   r)   r)   r)   r*   ry     s&   ry   N)decimalr   Zdjango.corer   Z	django.dbr   r   Zdjango.db.modelsr   Zdjango.utilsr   Zdjango.utils.translationr   r'   Zoscar.apps.voucher.utilsr	   Zoscar.core.compatr
   Zoscar.core.loadingr   ZModelr   rX   ry   r)   r)   r)   r*   <module>   s   ` $