B
    `)H                 @   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
 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ZeddZeddZeddZeddZeddZG dd deZdS )    )Decimal)http)messages)ImproperlyConfigured)reverse)gettext_lazy)prices)	get_class	get_model   )
exceptionszshipping.repository
Repositoryzcheckout.applicatorSurchargeApplicatorzcheckout.calculatorsOrderTotalCalculatorzcheckout.utilsCheckoutSessionDataorderShippingAddressBillingAddressaddressUserAddressc                   s   e Zd ZdZdZdZ f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d Zdd Zdd Zdd Zdd Zdd Z fdd Zd!d" Zd#d$ Zd+d%d&Zd'd( Zd,d)d*Z  ZS )-CheckoutSessionMixinz
    Mixin to provide common functionality shared between checkout views.

    All checkout views subclass this mixin. It ensures that all relevant
    checkout information is available in the template context.
    Nc          
      s   t || _y| | W nH tjk
r` } z(x|jD ]}t|| q4W t|j	S d }~X Y nX y| 
| W n, tjk
r } zt|j	S d }~X Y nX t j|f||S )N)r   checkout_sessioncheck_pre_conditionsr   FailedPreConditionr   warningr   ZHttpResponseRedirecturlcheck_skip_conditionsPassedSkipConditionsuperdispatch)selfrequestargskwargsemessage)	__class__ J/home/dcms/DCMS/lib/python3.7/site-packages/oscar/apps/checkout/session.pyr   3   s    
zCheckoutSessionMixin.dispatchc             C   s@   |  |}x0|D ](}t| |s*td| t| || qW d S )Nz2There is no method '%s' to call as a pre-condition)get_pre_conditionshasattrr   getattr)r    r!   pre_conditionsmethod_namer'   r'   r(   r   I   s    


z)CheckoutSessionMixin.check_pre_conditionsc             C   s   | j dkrg S | j S )zL
        Return the pre-condition method names to run for this view
        N)r,   )r    r!   r'   r'   r(   r)   R   s    
z'CheckoutSessionMixin.get_pre_conditionsc             C   s@   |  |}x0|D ](}t| |s*td| t| || qW d S )Nz3There is no method '%s' to call as a skip-condition)get_skip_conditionsr*   r   r+   )r    r!   skip_conditionsr-   r'   r'   r(   r   Z   s    


z*CheckoutSessionMixin.check_skip_conditionsc             C   s   | j dkrg S | j S )zM
        Return the skip-condition method names to run for this view
        N)r/   )r    r!   r'   r'   r(   r.   c   s    
z(CheckoutSessionMixin.get_skip_conditionsc             C   s"   |j jrtjtdtddd S )Nzbasket:summaryz5You need to add some items to your basket to checkout)r   r%   )basketZis_emptyr   r   r   _)r    r!   r'   r'   r(   check_basket_is_not_emptym   s
    z.CheckoutSessionMixin.check_basket_is_not_emptyc       	      C   sz   g }|j }xT|j D ]F}||}|j|j\}}|std|j	 |d }|
| qW |rvtjtd|ddS )z
        Check that the basket is permitted to be submitted as an order. That
        is, all the basket lines are available to buy - nothing has gone out of
        stock since it was added to the basket.
        z]'%(title)s' is no longer available to buy (%(reason)s). Please adjust your basket to continue)titlereasonzbasket:summary)r   r   N)strategyr0   Z	all_linesZfetch_for_lineZavailabilityZis_purchase_permittedZquantityr1   productZ	get_titleappendr   r   r   )	r    r!   r   r5   lineresultZis_permittedr4   msgr'   r'   r(   check_basket_is_validu   s     

z*CheckoutSessionMixin.check_basket_is_validc             C   s,   |j js(| j s(tjtdtddd S )Nzcheckout:indexz1Please either sign in or enter your email address)r   r%   )useris_authenticatedr   get_guest_emailr   r   r   r1   )r    r!   r'   r'   r(   check_user_email_is_captured   s    
z1CheckoutSessionMixin.check_user_email_is_capturedc             C   sB   |j  s.| j| jj s*tjtddd S |   | 	  d S )Nzcheckout:shipping-method)r   )
r0   is_shipping_requiredr   is_shipping_method_setr!   r   r   r   *check_a_valid_shipping_address_is_captured)check_a_valid_shipping_method_is_captured)r    r!   r'   r'   r(   check_shipping_data_is_captured   s    

z4CheckoutSessionMixin.check_shipping_data_is_capturedc             C   sN   | j  s tjtdtdd| j| jjd}|sJtjtdtddd S )Nzcheckout:shipping-addressz Please choose a shipping address)r   r%   )r0   zVYour previously chosen shipping address is no longer valid.  Please choose another one)	r   Zis_shipping_address_setr   r   r   r1   get_shipping_addressr!   r0   )r    shipping_addressr'   r'   r(   rB      s    
z?CheckoutSessionMixin.check_a_valid_shipping_address_is_capturedc             C   sf   | j | jjs&tjtdtdd| j| jjd}| j	| jj|d}|sbtjtdtddd S )Nzcheckout:shipping-methodzPlease choose a shipping method)r   r%   )r0   )r0   rF   zUYour previously chosen shipping method is no longer valid.  Please choose another one)
r   rA   r!   r0   r   r   r   r1   rE   get_shipping_method)r    rF   shipping_methodr'   r'   r(   rC      s    
z>CheckoutSessionMixin.check_a_valid_shipping_method_is_capturedc             C   s   d S )Nr'   )r    r!   r'   r'   r(   check_payment_data_is_captured   s    z3CheckoutSessionMixin.check_payment_data_is_capturedc             C   s   |j  stjtddd S )Nzcheckout:shipping-method)r   )r0   r@   r   r   r   )r    r!   r'   r'   r(   $skip_unless_basket_requires_shipping   s    
z9CheckoutSessionMixin.skip_unless_basket_requires_shippingc             C   s   |  |j}| |j|}|r,||j}ntj|jjtdtdd}t|j	|j|d}| 
|j||}|jtdkrtjtddd S )Nz0.00)currencyexcl_taxZtax)r0   shipping_chargezcheckout:preview)r   )rE   r0   rG   	calculater   ZPricerK   Dr   get_applicable_surchargesget_order_totalsrL   r   r   r   )r    r!   rF   rH   rM   
surchargestotalr'   r'   r(   skip_unless_payment_is_required   s    
z4CheckoutSessionMixin.skip_unless_payment_is_requiredc                s8   t   }|| jf | || ||d  |S )Norder_kwargs)r   get_context_dataupdatebuild_submission)r    r#   ctx)r&   r'   r(   rV      s
    

z%CheckoutSessionMixin.get_context_datac             K   s   | d| jj}| |}| ||}| |}| jj||||i i d}|sZd } }}	n<||}t| j|j	| jj|d}	| j
|f||	d|}||d< ||d< |	|d< |r||d	 d
< || |d }
|
jsd|d kr| j }||d d< |S )z
        Return a dict of data that contains everything required for an order
        submission.  This includes payment details (if any).

        This can be the right place to perform tax lookups and apply them to
        the basket.
        r0   )r<   r0   rF   rH   billing_addressrU   payment_kwargsN)rM   )rM   rR   rM   Zorder_totalrR   r[   rZ   r<   Zguest_emailrU   )popr!   r0   rE   rG   get_billing_addressr<   rN   r   rP   rQ   rW   r=   r   r>   )r    r#   r0   rF   rH   rZ   Z
submissionrS   rM   rR   r<   emailr'   r'   r(   rX     s>    





z%CheckoutSessionMixin.build_submissionc             C   st   |  sdS | j }|r$tf |S | j }|rpytjj|d}W n tjk
rZ   dS X t }|	| |S dS )a  
        Return the (unsaved) shipping address for this checkout session.

        If the shipping address was entered manually, then we instantiate a
        ``ShippingAddress`` model with the appropriate form data (which is
        saved in the session).

        If the shipping address was selected from the user's address book,
        then we convert the ``UserAddress`` to a ``ShippingAddress``.

        The ``ShippingAddress`` instance is not saved as sometimes you need a
        shipping address instance before the order is placed.  For example, if
        you are submitting fraud information as part of a payment request.

        The ``OrderPlacementMixin.create_shipping_address`` method is
        responsible for saving a shipping address when an order is placed.
        N)pk)
r@   r   Znew_shipping_address_fieldsr   Zshipping_user_address_idr   _default_managergetDoesNotExistpopulate_alternative_model)r    r0   	addr_dataaddr_idr   shipping_addrr'   r'   r(   rE   B  s    



z)CheckoutSessionMixin.get_shipping_addressc             K   sF   | j |}t j|| jj|| jd}x|D ]}|j|kr,|S q,W dS )z
        Return the selected shipping method instance from this checkout session

        The shipping address is passed as we need to check that the method
        stored in the session is still valid for the shipping address.
        )r0   r<   rf   r!   N)r   Zshipping_method_coder   Zget_shipping_methodsr!   r<   code)r    r0   rF   r#   rg   methodsmethodr'   r'   r(   rG   l  s    

z(CheckoutSessionMixin.get_shipping_methodc             C   s   | j  sdS | j  r0|r0t }|| |S | j  }|rHtf |S | j  }|rytjj	|d}W n tj
k
r~   dS X t }|| |S dS )a  
        Return an unsaved instance of the billing address (if one exists)

        This method only returns a billing address if the session has been used
        to store billing address information. It's also possible to capture
        billing address information as part of the payment details forms, which
        never get stored in the session. In that circumstance, the billing
        address can be set directly in the build_submission dict.
        N)r_   )r   Zis_billing_address_setZ#is_billing_address_same_as_shippingr   rc   Znew_billing_address_fieldsZbilling_user_address_idr   r`   ra   rb   )r    rF   r   rd   re   Zuser_addressrZ   r'   r'   r(   r]   {  s&    







z(CheckoutSessionMixin.get_billing_addressc             K   s   t | jj|||f|S )zF
        Returns the total for the order with and without tax
        )r   r!   rN   )r    r0   rM   rR   r#   r'   r'   r(   rQ     s    
z%CheckoutSessionMixin.get_order_totals)N)N)__name__
__module____qualname____doc__r,   r/   r   r   r)   r   r.   r2   r;   r?   rD   rB   rC   rI   rJ   rT   rV   rX   rE   rG   r]   rQ   __classcell__r'   r'   )r&   r(   r      s.   
		
	
	;*
,r   N)decimalr   rO   Zdjangor   Zdjango.contribr   Zdjango.core.exceptionsr   Zdjango.urlsr   Zdjango.utils.translationr   r1   Z
oscar.corer   Zoscar.core.loadingr	   r
    r   r   r   r   r   r   r   r   objectr   r'   r'   r'   r(   <module>   s$   




