3

\'                 @   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ZejedZej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 ))AbstractVoucherSeta)  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.

    - start_datetime, end_datetime: defines the validity datetime 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_addzStart datetimezEnd datetimezoffer.ConditionalOffervoucher_setOffer
offer_typeVoucher)related_namer   limit_choices_to	on_deletenullblankc               @   s(   e Zd ZdZdZdZedZedZdS )zAbstractVoucherSet.MetaTvoucherdate_created
VoucherSetZVoucherSetsN)	__name__
__module____qualname__abstract	app_labelget_latest_by_r   verbose_name_plural r)   r)   =/var/www/html/oscar2019/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 j }xt|| jD ]}| j  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| j	 |S )zAdd a new voucher to this setr   r   )length)r,   coder   usagestart_datetimeend_datetime)r   r	   code_length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 }| 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j | _tj 0 t j|| | j  | jj| j	| j
d W d Q R X d S )N)r8   r9   )maxr0   r/   r   atomicsupersaver4   updater8   r9   )r-   argskwargs)	__class__r)   r*   rG   T   s    
zAbstractVoucherSet.savec             C   s   | j jtdd}|d S )Nnum_basket_additions)resultrM   )r/   	aggregater   )r-   valuer)   r)   r*   rL   ^   s    z'AbstractVoucherSet.num_basket_additionsc             C   s   | j jtdd}|d S )N
num_orders)rM   rM   )r/   rN   r   )r-   rO   r)   r)   r*   rP   c   s    zAbstractVoucherSet.num_ordersc             C   s   | j jtdd}|d S )Ntotal_discount)rM   rM   )r/   rN   r   )r-   rO   r)   r)   r*   rQ   h   s    z!AbstractVoucherSet.total_discount)N) r!   r"   r#   __doc__r   	CharFieldr'   r,   PositiveIntegerFieldr0   IntegerFieldr:   	TextFielddescriptionDateTimeFieldr   r8   r9   OneToOneFieldCASCADEr>   r+   r.   r4   r2   rC   rG   propertyrL   rP   rQ   __classcell__r)   r)   )rK   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Zeje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%ZG d&d' d'Zd(d) Zd*d+ Z fd,d-Z d<d/d0Z!d1d2 Z"d=d3d4Z#d5d6 Z$de$_%d7d8 Z&de&_%e'd9d: 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_textCodeTz$Case insensitive / No spaces allowed)r   db_indexuniquer_   zoffer.ConditionalOfferr/   Offersr   r   )r   r   r   
Single use	Multi-useOnce per customerz Can be used once by one customerz0Can be used multiple times by multiple customersz"Can only be used once per customerZUsage)r   choicesr   zStart datetimezEnd datetimezTimes added to basketr   )r   zTimes on orderszTotal discount   r   z0.00)decimal_places
max_digitsr   zvoucher.VoucherSet)r   r   r   r   )r   c               @   s(   e Zd ZdZdZdZedZedZdS )zAbstractVoucher.MetaTr   r   r   VouchersN)	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jtdd S )Nz(End date should be later than start date)allr8   r9   r   ValidationErrorr'   )r-   r)   r)   r*   clean   s    
zAbstractVoucher.cleanc                s   | j j | _ t j|| d S )N)r6   upperrF   rG   )r-   rI   rJ   )rK   r)   r*   rG      s    zAbstractVoucher.saveNc             C   s(   |p
t j }| j|  ko"| jkS   S )z@
        Test whether this voucher is currently active.
        )r   rA   r8   r9   )r-   rB   r)   r)   r*   rC      s    zAbstractVoucher.is_activec             C   s   t j }| j|k S )zJ
        Test whether this voucher has passed its expiration date
        )r   rA   r9   )r-   rA   r)   r)   r*   
is_expired   s    zAbstractVoucher.is_expiredc             C   s   d\}}| j | jkr.| jj  }|std}nT| j | jkr@d}nB| j | jkr|js`d}td}n"| jj| |dj  }|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 usedTz1This voucher is only available to signed in users)r   userz6You have already used this voucher in a previous order)Frq   )	r7   r=   applicationsexistsr'   	MULTI_USEONCE_PER_CUSTOMERis_authenticatedfilter)r-   rr   is_availablemessager)   r)   r*   is_available_to_user   s"    
z$AbstractVoucher.is_available_to_userc             C   sD   |j r| jj| ||d n| jj| |d |  jd7  _| j  dS )z>
        Records a usage of this voucher in an order.
        )r   orderrr   )r   r|      N)rw   rs   r<   rP   rG   )r-   r|   rr   r)   r)   r*   record_usage   s
    zAbstractVoucher.record_usagec             C   s   |  j |d 7  _ | j  dS )z=
        Record a discount that this offer has given
        discountN)rQ   rG   )r-   r   r)   r)   r*   record_discount   s    zAbstractVoucher.record_discountc             C   s   | j j d 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   )r?   rl   benefit)r-   r)   r)   r*   r      s    zAbstractVoucher.benefit)rd   re   rf   )N)N)*r!   r"   r#   rR   r   rS   r'   r,   r6   ManyToManyFieldr?   r=   ru   rv   ZUSAGE_CHOICESr7   rX   r8   r9   rT   rL   rP   DecimalFieldr   rQ   
ForeignKeyrZ   r   r   r+   r.   rn   rG   rC   rp   r{   r~   alters_datar   r[   r   r\   r)   r)   )rK   r*   r]   n   sL   








r]   c               @   sz   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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.Voucherrs   r   )r   r   r   TUser)r   r   r   r   zorder.OrderOrder)r   r   )r   c               @   s$   e Zd ZdZdZedZedZdS )zAbstractVoucherApplication.MetaTr   zVoucher ApplicationzVoucher ApplicationsN)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   rr   )r'   r   rr   )r-   r)   r)   r*   r.     s    z"AbstractVoucherApplication.__str__N)r!   r"   r#   rR   r   r   rZ   r'   r   r
   rr   r|   rX   r   r+   r.   r)   r)   r)   r*   r      s&   r   N)decimalr   django.corer   	django.dbr   r   django.db.modelsr   django.utilsr   django.utils.translationr   r'   Zoscar.apps.voucher.utilsr	   oscar.core.compatr
   oscar.core.loadingr   Modelr   r]   r   r)   r)   r)   r*   <module>   s   ` 