3

\                 @   s  d dl 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mZmZ d d	lmZmZmZ d d
lmZmZ d dlmZ d dlmZ d dlmZm Z m!Z!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.m/Z/ d dl0m1Z1 d dl2m3Z3 d dlmZ e,ddZ4e,ddZ5e,ddZ6e,ddZ7e,ddZ8e,ddZ9e,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@e+d$d(ZAe+d$d)ZBe,d*d+ZCd,d- ZDd.d/ ZEG d0d1 d1e ZFG d2d3 d3e3e!ZGG d4d5 d5eGZHG d6d7 d7eGZIG d8d9 d9eGZJG d:d; d;eGZKG d<d= d=eGZLG d>d? d?eGZMG d@dA dAeZNG dBdC dCeZOdJdDdEZPdFdG ZQG dHdI dIe"ZRdS )K    N)OrderedDict)Decimal)InvalidOperation)settings)messages)ObjectDoesNotExist)CountQSumfields)Http404HttpResponseHttpResponseRedirect)get_object_or_404redirect)reverse)gettext_lazy)
DetailViewFormViewListView
UpdateView)
exceptions)PaymentError)UnicodeCSVWriter)	get_class	get_model)datetime_combineformat_datetime)sort_queryset)BulkEditMixin)r   partnerPartnerpaymentTransaction
SourceTypeorderOrder	OrderNoteShippingAddressLineShippingEventTypePaymentEventTypezorder.processingEventHandlerzdashboard.orders.formsOrderStatsFormOrderSearchFormOrderNoteFormShippingAddressFormOrderStatusForm	catalogueProductClassc             C   sH   t jjdddddjdd}| jr&|S tjj| d}|j|d	j S d
S )z
    Returns a queryset of all orders that a user is allowed to access.
    A staff user may access all orders.
    To allow access to an order for a non-staff user, at least one line's
    partner has to have the user in the partner's list.
    billing_addressZbilling_address__countryshipping_addressZshipping_address__countryuserlinesstatus_changes)users)Zlines__partner__inN)r&   _default_managerselect_relatedprefetch_relatedis_staffr!   filterdistinct)r6   querysetpartners rB   </var/www/html/oscar2019/oscar/apps/dashboard/orders/views.pyqueryset_orders_for_user,   s    rD   c             C   s0   yt | j|dS  tk
r*   t Y nX d S )N)number)rD   getr   r   )r6   rE   rB   rB   rC   get_order_for_user_or_404?   s    rG   c                   sL   e Zd ZdZdZeZdd Zdd Z fddZ	 fd	d
Z
dd Z  ZS )OrderStatsViewz[
    Dashboard view for order statistics.
    Supports the permission-based dashboard.
    z dashboard/orders/statistics.htmlc             O   s   | j |f||S )N)post)selfrequestargskwargsrB   rB   rC   rF   N   s    zOrderStatsView.getc             C   s   | j ||j d}| j|S )N)formfilters)get_context_dataget_filtersrender_to_response)rJ   rN   ctxrB   rB   rC   
form_validQ   s    zOrderStatsView.form_validc                s   t  j }| jj|d< |S )Ndata)superget_form_kwargsrK   GET)rJ   rM   )	__class__rB   rC   rW   V   s    
zOrderStatsView.get_form_kwargsc                s>   t  jf |}|jdi }|j| j| |d j |d< |S )NrO   rN   title)rV   rP   rF   update	get_statsZget_filter_description)rJ   rM   rS   rO   )rY   rB   rC   rP   [   s
    zOrderStatsView.get_context_datac             C   sf   t | jjjf |}|j tjj|dj |jtdd pBt	d|j
djdjtddd}|S )	N)	order__intotal_incl_taxtotal_incl_tax__sumz0.00statusid)freq)total_orderstotal_linestotal_revenueorder_status_breakdown)rD   rK   r6   r>   countr)   objects	aggregater
   Dorder_byvaluesannotater   )rJ   rO   ordersstatsrB   rB   rC   r\   b   s    
zOrderStatsView.get_stats)__name__
__module____qualname____doc__template_namer-   
form_classrF   rT   rW   rP   r\   __classcell__rB   rB   )rY   rC   rH   F   s   rH   c                   s   e Zd ZdZeZdZdZeZ	e
jZdZ fddZ fdd	Zd
d Zdd Z fddZdd Zdd Z fddZdd Zdd Zdd Zdd Z  ZS )OrderListViewz[
    Dashboard view for a list of orders.
    Supports the permission-based dashboard.
    rn   z dashboard/orders/order_list.htmldownload_selected_orderschange_order_statusesc                s&   t |jjd| _t j|f||S )Nz-date_placed)rD   r6   rk   base_querysetrV   dispatch)rJ   rK   rL   rM   )rY   rB   rC   r{   {   s    zOrderListView.dispatchc                sn   d|j krZ|j jdddkrZy| jj|j d d}W n tjk
rJ   Y nX td|jdS t j|f||S )Norder_numberresponse_formathtml)rE   zdashboard:order-detail)rX   rF   rz   r&   DoesNotExistr   rE   rV   )rJ   rK   rL   rM   r%   )rY   rB   rC   rF      s    zOrderListView.getc             C   sj  t | j| jddg}| j| jj| _| jj s2|S | jj}|d rT| jj|d d}|d r$|d j	 }t
tdd}t|dkr|d |d g}n|d	 |dd
 g}t|d	 d}|t|d dO }|r|t|d	 dO }|t|d	 dO }|t|d dO }|t|d dO }|j|j }|d rB|j|d dj }|d r\|j|d d}|d rv|j|d d}|d r|d rt|d tjj}t|d tjj}|j||d}nR|d rt|d tjj}|j|d}n(|d rt|d tjj}|j|d}|d r.|j|d dj }|d rL|j|d dj }|d  rf|j|d  d!}|S )"z3
        Build the queryset for this list.
        rE   r^   r|   )Znumber__istartswithnameOSCAR_ALLOW_ANON_CHECKOUTF   r   N)Zuser__first_name__istartswith)Zuser__last_name__istartswith)Z(billing_address__first_name__istartswith)Z)shipping_address__first_name__istartswith)Z'billing_address__last_name__istartswith)Z(shipping_address__last_name__istartswithproduct_title)Zlines__title__istartswithupc)Z
lines__upcpartner_sku)Zlines__partner_sku	date_fromdate_to)date_placed__gtedate_placed__lt)r   )r   voucher)Zdiscounts__voucher_codepayment_method)Zsources__source_type__coder`   )r`   )r   rz   rK   ru   rX   rN   is_validcleaned_datar>   splitgetattrr   lenr	   r?   r   datetimetimemaxmin)rJ   r@   rU   partsZ
allow_anonr>   r   r   rB   rB   rC   get_queryset   sd    











zOrderListView.get_querysetc             C   s  g }t | jdd}|dkr|S |jdrB|jtdj|d d |jdrf|jtdj|d d |jd	r|jtd
j|d	 d |jdr|jtdj|d d |jdr|jtdj|d d |jdo|jdr
|jtdj|d |d d n^|jdr2|jtdj|d d n6|jdrh|d tjdd }|jtdj|d |jdr|jtdj|d d |jdrtj	j|d d }|jtd!j|j
d" |jd#r|jtd$j|d# d% |S )&zDescribe the filters used in the search.

        These are user-facing messages describing what filters
        were used to filter orders in the search query.

        Returns:
            list of unicode messages

        r   Nr|   z)Order number starts with "{order_number}")r|   r   z'Customer name matches "{customer_name}")Zcustomer_namer   z%Product name matches "{product_name}")Zproduct_namer   z!Includes an item with UPC "{upc}")r   r   z1Includes an item with partner SKU "{partner_sku}")r   r   r   z*Placed between {start_date} and {end_date})
start_dateend_datezPlaced after {start_date})r   r   )dayszPlaced before {end_date})r   r   z"Used voucher code "{voucher_code}")voucher_coder   )codezPaid using {payment_method})r   r`   zOrder status is {order_status})order_status)r   rN   rF   append_formatr   	timedeltar$   rh   r   )rJ   descriptionsrU   r   payment_typerB   rB   rC   get_search_filter_descriptions   sf    





z,OrderListView.get_search_filter_descriptionsc                s4   t  jf |}| j|d< tj |d< | j |d< |S )NrN   Zorder_statusesZsearch_filters)rV   rP   rN   r&   all_statusesr   )rJ   rM   rS   )rY   rB   rC   rP   Q  s
    
zOrderListView.get_context_datac             C   s   | j jjdd dkS )Nr}   csv)rK   rX   rF   )rJ   rB   rB   rC   is_csv_downloadX  s    zOrderListView.is_csv_downloadc             C   s   | j  rd S | jS )N)r   paginate_by)rJ   r@   rB   rB   rC   get_paginate_by[  s    zOrderListView.get_paginate_byc                s*   | j  r| j| j|d S t j|f|S )Nobject_list)r   rx   rK   rV   rR   )rJ   contextresponse_kwargs)rY   rB   rC   rR   ^  s    
z OrderListView.render_to_responsec             C   s   dS )Nz
orders.csvrB   )rJ   rK   rB   rB   rC   get_download_filenamef  s    z#OrderListView.get_download_filenamec          
   C   sN  t dd}d| j| |d< t|d}dtdfdtd	fd
tdfdtdfdtdfdtdfdtdfdtdff}t }x|D ]\}}|||< qW |j|j  x|D ]}	|j }
|	j|
d< |	j	|
d< t
|	jd|
d
< |	j|
d< |	j|
d< |	j|
d< |	jr|	jj|
d< nd|
d< |	jr0|	jj|
d< nd|
d< |j|
j  qW |S )Nztext/csv)content_typezattachment; filename=%szContent-Disposition)	open_filerE   zOrder numbervaluezOrder valuedatezDate of purchase	num_itemszNumber of itemsr`   zOrder statuscustomerzCustomer email addressZshipping_address_namezDeliver to nameZbilling_address_namezBill to nameDATETIME_FORMAT )r   r   r   r   r   writerowrl   copyrE   r^   r   date_placedr   r`   emailr5   r   r4   )rJ   rK   rn   responsewriter	meta_datacolumnskvr%   rowrB   rB   rC   rx   i  s@    














z&OrderListView.download_selected_ordersc             C   s"   x|D ]}| j || qW tdS )Nzdashboard:order-list)change_order_statusr   )rJ   rK   rn   r%   rB   rB   rC   ry     s    
z#OrderListView.change_order_statusesc             C   s   |j d j }|s(tj|td|  n||j krJtj|td|  nt|j}|j}y|j	|| W n6 t
k
r } ztj|td|  W Y d d }~X n6X td||d }tj|| |jj|j|tjd d S )N
new_statusz The new status '%s' is not validz/The new status '%s' is not valid for this orderz6Unable to change order status due to payment error: %sz>Order status changed from '%(old_status)s' to '%(new_status)s')
old_statusr   )r6   message	note_type)POSTstripr   errorr   available_statusesr,   r6   r`   handle_order_status_changer   infonotescreater'   SYSTEM)rJ   rK   r%   r   handlerr   emsgrB   rB   rC   r     s(    



z!OrderListView.change_order_status)rx   ry   )rp   rq   rr   rs   r&   modelcontext_object_namert   r.   ru   r   OSCAR_DASHBOARD_ITEMS_PER_PAGEr   actionsr{   rF   r   r   rP   r   r   rR   r   rx   ry   r   rv   rB   rB   )rY   rC   rw   o   s&   Iy'rw   c                   s(   e Zd Z fddZ fddZ  ZS )CoffeeOrderListViewc                s   t t| j }|jddS )Nz
coffee-bag)#lines__product__product_class__slug)rV   r   r   r>   )rJ   qs)rY   rB   rC   r     s    z CoffeeOrderListView.get_querysetc                s   t t| jf |}d|d< |S )NZcoffees
active_tab)rV   r   rP   )rJ   rM   cd)rY   rB   rC   rP     s    z$CoffeeOrderListView.get_context_data)rp   rq   rr   r   rP   rv   rB   rB   )rY   rC   r     s   r   c                   s(   e Zd Z fddZ fddZ  ZS )PodsOrderListViewc                s   t t| j }|jddS )Nzcoffee-pods)r   )rV   r   r   r>   )rJ   r   )rY   rB   rC   r     s    zPodsOrderListView.get_querysetc                s   t t| jf |}d|d< |S )NZpodsr   )rV   r   rP   )rJ   rM   r   )rY   rB   rC   rP     s    z"PodsOrderListView.get_context_data)rp   rq   rr   r   rP   rv   rB   rB   )rY   rC   r     s   r   c                   s(   e Zd Z fddZ fddZ  ZS )HookBagsOrderListViewc                s   t t| j }|jddS )Nz	hook-bags)r   )rV   r   r   r>   )rJ   r   )rY   rB   rC   r     s    z"HookBagsOrderListView.get_querysetc                s   t t| jf |}d|d< |S )Nz	hook-bagsr   )rV   r   rP   )rJ   rM   r   )rY   rB   rC   rP     s    z&HookBagsOrderListView.get_context_data)rp   rq   rr   r   rP   rv   rB   rB   )rY   rC   r     s   r   c                   s(   e Zd Z fddZ fddZ  ZS )GearsOrderListViewc                s    t t| j }|jdddgdS )Nzessential-gearszcoffee-machineszstarter-kits)Z'lines__product__product_class__slug__in)rV   r   r   r>   )rJ   r   )rY   rB   rC   r     s    zGearsOrderListView.get_querysetc                s   t t| jf |}d|d< |S )NZgearsr   )rV   r   rP   )rJ   rM   r   )rY   rB   rC   rP     s    z#GearsOrderListView.get_context_data)rp   rq   rr   r   rP   rv   rB   rB   )rY   rC   r     s   r   c                   s(   e Zd Z fddZ fddZ  ZS )MultipleOrderListViewc                s   t t| j }|S )N)rV   r   r   )rJ   r   )rY   rB   rC   r     s    z"MultipleOrderListView.get_querysetc                s   t t| jf |}d|d< |S )Nmultipler   )rV   r   rP   )rJ   rM   r   )rY   rB   rC   rP     s    z&MultipleOrderListView.get_context_data)rp   rq   rr   r   rP   rv   rB   rB   )rY   rC   r     s   r   c                   s(   e Zd Z fddZ fddZ  ZS )DeclinedOrderListViewc                s   t t| j }|S )N)rV   r   r   )rJ   r   )rY   rB   rC   r     s    z"DeclinedOrderListView.get_querysetc                s   t t| jf |}d|d< |S )NZdeclinedr   )rV   r   rP   )rJ   rM   r   )rY   rB   rC   rP     s    z&DeclinedOrderListView.get_context_data)rp   rq   rr   r   rP   rv   rB   rB   )rY   rC   r     s   r   c                   s   e Zd ZdZeZdZdZd0Zd1Z	d2ddZ
dd Zdd Zdd Zdd Zd3d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d4d.d/Z  ZS )5OrderDetailViewza
    Dashboard view to display a single order.

    Supports the permission-based dashboard.
    r%   z"dashboard/orders/order_detail.html	save_notedelete_noter   create_order_payment_eventchange_line_statusescreate_shipping_eventcreate_payment_eventNc             C   s   t | jj| jd S )NrE   )rG   rK   r6   rM   )rJ   r@   rB   rB   rC   
get_object  s    zOrderDetailView.get_objectc             C   s   | j jj S )N)objectr7   all)rJ   rB   rB   rC   get_order_lines  s    zOrderDetailView.get_order_linesc             O   sZ   | j   }| _d|jkr,| j|||jd S d|jkrJ| j|||jd S | jtddS )NZorder_actionZline_actionzNo valid action submitted)r   )r   r   r   handle_order_actionhandle_line_actionreload_pager   )rJ   rK   rL   rM   r%   rB   rB   rC   rI     s    

zOrderDetailView.postc             C   s*   || j kr| jtddS t| |||S )NzInvalid action)r   )order_actionsr   r   r   )rJ   rK   r%   actionrB   rB   rC   r   "  s    
z#OrderDetailView.handle_order_actionc             C   s:  || j kr| jtddS |jjd}t|dkrB| jtddS | j }|j|d}t|t|krv| jtddS g }x|D ]}|jjd|j	 }yt
|}W n tk
r   d }Y nX |d ks|dkrtd	}	| j|	|j	 dS ||jkrtd
}	|j	|jd}
| j|	|
 dS |j| qW t| |||||S )NzInvalid action)r   Zselected_liner   z$You must select some lines to act on)id__inzInvalid lines requestedzselected_line_qty_%sz.The entered quantity for line #%s is not validzQThe entered quantity for line #%(line_id)s should not be higher than %(quantity)s)line_idquantity)line_actionsr   r   r   getlistr   r   r>   rF   ra   int
ValueErrorr   r   r   )rJ   rK   r%   r   Zline_idsr7   line_quantitieslineqty	error_msgrM   rB   rB   rC   r   '  s8    



z"OrderDetailView.handle_line_actionc             C   s>   t dd| jjid}|r$|d| 7 }|r6tj| j| t|S )Nzdashboard:order-detailrE   )rM   #)r   r   rE   r   r   rK   r   )rJ   fragmentr   urlrB   rB   rC   r   M  s    zOrderDetailView.reload_pagec                sz   t  jf |}|jdd|d< | j |d< | j |d< | j |d< tj |d< tj	j
 |d< tj	j
 |d< | j |d< |S )	Nr   r7   	note_formZorder_status_formZline_statusesZshipping_event_typesZpayment_event_typesZpayment_transactions)rV   rP   rF   get_order_note_formget_order_status_formr   r)   r   r*   rh   r   r+   get_payment_transactions)rJ   rM   rS   )rY   rB   rC   rP   V  s    z OrderDetailView.get_context_datac             C   s   t jj| jdS )N)Zsource__order)r#   rh   r>   r   )rJ   rB   rB   rC   r  i  s    z(OrderDetailView.get_payment_transactionsc             C   sf   | j | jjd d}| jjdkr*| jj|d< | jjdd }|r\tt| j |d}|j	 r\||d< t
f |S )N)r%   r6   rU   r   rU   note_id)r%   ra   instance)r   rK   r6   methodr   rM   rF   r   r'   is_editabler/   )rJ   rM   r  noterB   rB   rC   r   m  s    z#OrderDetailView.get_order_note_formc             C   s&   d }| j jdkr| j j}t| j|dS )Nr   )r%   rU   )rK   r  r   r1   r   )rJ   rU   rB   rB   rC   r   |  s    z%OrderDetailView.get_order_status_formc             C   sN   | j  }|j r6|j  tj| jtd | jddS | j|dd}| j	|S )Nz
Note savedr   )r   )r   r   )
r   r   saver   successrK   r   r   rP   rR   )rJ   rK   r%   rN   rS   rB   rB   rC   r     s    zOrderDetailView.save_notec             C   sb   y|j j|jjdd d}W n$ tk
r@   tj|td Y nX tj|td |j  | j	 S )Nr  )ra   zNote cannot be deletedzNote deleted)
r   rF   r   r   r   r   r   r   deleter   )rJ   rK   r%   r  rB   rB   rC   r     s    zOrderDetailView.delete_notec       	      C   s   | j  }|j s | jtddS |j|jd  }}t|j}td||d }y|j|||d W nh t	k
r } zt
j|td|  W Y d d }~X n@ tjk
r } zt
j|td W Y d d }~X nX t
j|| | j S )	NzInvalid form submission)r   r   z>Order status changed from '%(old_status)s' to '%(new_status)s')r   r   )Znote_msgz6Unable to change order status due to payment error: %szFUnable to change order status as the requested new status is not valid)r   r   r   r   r`   r   r,   r6   r   r   r   r   order_exceptionsInvalidOrderStatusr   )	rJ   rK   r%   rN   r   r   r   Zsuccess_msgr   rB   rB   rC   r     s*    

z#OrderDetailView.change_order_statusc             C   sR   |j jdd}yt|}W n( tk
rB   tj|td | j S X | j|||S )z<
        Create a payment event for the whole order
        amountNzPlease choose a valid amount)	r   rF   rj   r   r   r   r   r   _create_payment_event)rJ   rK   r%   
amount_strr  rB   rB   rC   r     s    
z*OrderDetailView.create_order_payment_eventc             C   s   |j d j }|s.tj|td|  | j S g }x2|D ]*}||j kr8|jtd||jd  q8W |rtj|dj	| | j S g }x8|D ]0}td|j|j
|d }	|j|	 |j| qW dj	|}
tj||
 |jj|j|
tjd | j S )	Nr   z The new status '%s' is not validz;'%(status)s' is not a valid new status for line %(line_id)d)r`   r   
zMStatus of line #%(line_id)d changed from '%(old_status)s' to '%(new_status)s')r   r   r   )r6   r   r   )r   r   r   r   r   r   r   r   ra   joinr`   
set_statusr   r   r   r6   r'   r   )rJ   rK   r%   r7   
quantitiesr   errorsr   msgsr   r   rB   rB   rC   r     s6    






z$OrderDetailView.change_line_statusesc       	      C   s2  |j d }ytjj|d}W n. tjk
rJ   tj|td|  | j S X |j jdd }yt	 j
|||||d W n tjk
r } ztj|td|  W Y d d }~X n~ tjk
r } ztj|td|  W Y d d }~X nH tk
r } ztj|td|  W Y d d }~X nX tj|td | j S )	NZshipping_event_type)r   z The event type '%s' is not valid	reference)r  z#Unable to create shipping event: %sz8Unable to create shipping event due to payment error: %szShipping event created)r   r*   r:   rF   r   r   r   r   r   r,   Zhandle_shipping_eventr
  InvalidShippingEventInvalidStatusr   r  )	rJ   rK   r%   r7   r  r   
event_typer  r   rB   rB   rC   r     s.    

z%OrderDetailView.create_shipping_eventc             C   sn   |j jdd}|s&tdd |D }n6yt|}W n( tk
rZ   tj|td | j S X | j	|||||S )zD
        Create a payment event for a subset of order lines
        r  Nc             S   s   g | ]
}|j qS rB   )line_price_incl_tax).0r   rB   rB   rC   
<listcomp>  s    z8OrderDetailView.create_payment_event.<locals>.<listcomp>zPlease choose a valid amount)
r   rF   sumrj   r   r   r   r   r   r  )rJ   rK   r%   r7   r  r  r  rB   rB   rC   r     s    
z$OrderDetailView.create_payment_eventc       	      C   s   |j jd}ytjj|d}W n. tjk
rL   tj|td|  | j S X yt	 j
||||| W nl tk
r } ztj|td|  W Y d d }~X nH tjk
r } ztj|td|  W Y d d }~X nX tj|td | j S )Npayment_event_type)r   z The event type '%s' is not validz7Unable to create payment event due to payment error: %sz"Unable to create payment event: %szPayment event created)r   rF   r+   r:   r   r   r   r   r   r,   Zhandle_payment_eventr   r
  InvalidPaymentEventr   )	rJ   rK   r%   r  r7   r  r   r  r   rB   rB   rC   r    s$    
"z%OrderDetailView._create_payment_event)r   r   r   r   )r   r   r   )N)NN)NN)rp   rq   rr   rs   r&   r   r   rt   r   r   r   r   rI   r   r   r   rP   r  r   r   r   r   r   r   r   r   r   r  rv   rB   rB   )rY   rC   r     s6     
&
	

 r   c                   s6   e Zd ZdZeZdZdZd	ddZ fddZ	  Z
S )
LineDetailViewzh
    Dashboard view to show a single line of an order.
    Supports the permission-based dashboard.
    r   z!dashboard/orders/line_detail.htmlNc             C   sL   t | jj| jd }y|jj| jd dS  | jjk
rF   t Y nX d S )NrE   r   )pk)	rG   rK   r6   rM   r7   rF   r   r   r   )rJ   r@   r%   rB   rB   rC   r   /  s    zLineDetailView.get_objectc                s   t  jf |}| jj|d< |S )Nr%   )rV   rP   r   r%   )rJ   rM   rS   )rY   rB   rC   rP   7  s    zLineDetailView.get_context_data)N)rp   rq   rr   rs   r)   r   r   rt   r   rP   rv   rB   rB   )rY   rC   r  &  s   
r  c             C   st   |dkrg }i }x^| j jD ]R}t|tjtjjfs|j|kr>q|j| |j|kr|j| |j|f||j< qW |S )zB
    Return a dict of differences between two model instances
    N)	_metar   
isinstance	AutoFieldrelatedRelatedFieldr   value_from_objectverbose_name)model1model2excludeschangesfieldrB   rB   rC   get_changes_between_models=  s    
r-  c             C   sT   t | |dg}g }x6|j D ]*\}}|jtd||d |d d  qW dj|S )zF
    Generate a summary of the changes between two address models
    search_textz9%(field)s changed from '%(old_value)s' to '%(new_value)s'r   r   )r,  	old_value	new_valuer  )r-  itemsr   r   r  )r(  r)  r+  Zchange_descriptionsr,  deltarB   rB   rC   get_change_summaryP  s    
r3  c                   sN   e Zd ZdZeZdZdZeZ	dddZ
 fddZ fd	d
Zdd Z  ZS )ShippingAddressUpdateViewzl
    Dashboard view to update an order's shipping address.
    Supports the permission-based dashboard.
    addressz*dashboard/orders/shippingaddress_form.htmlNc             C   s"   t | jj| jd }t| j|dS )NrE   )r%   )rG   rK   r6   rM   r   r   )rJ   r@   r%   rB   rB   rC   r   i  s    z$ShippingAddressUpdateView.get_objectc                s   t  jf |}| jj|d< |S )Nr%   )rV   rP   r   r%   )rJ   rM   rS   )rY   rB   rC   rP   n  s    z*ShippingAddressUpdateView.get_context_datac                sZ   t jj| jjd}t j|}t|| j}|rVtd| }| jj	j
j| jj|tjd |S )N)ra   zDelivery address updated:
%s)r6   r   r   )r(   rh   rF   r   ra   rV   rT   r3  r   r%   r   r   rK   r6   r'   r   )rJ   rN   Zold_addressr   r+  r   )rY   rB   rC   rT   s  s    
z$ShippingAddressUpdateView.form_validc             C   s(   t j| jtd tdd| jjjidS )NzDelivery address updatedzdashboard:order-detailrE   )rM   )r   r   rK   r   r   r   r%   rE   )rJ   rB   rB   rC   get_success_url}  s    z)ShippingAddressUpdateView.get_success_url)N)rp   rq   rr   rs   r(   r   r   rt   r0   ru   r   rP   rT   r6  rv   rB   rB   )rY   rC   r4  _  s   

r4  )N)Sr   collectionsr   decimalr   rj   r   django.confr   django.contribr   django.core.exceptionsr   django.db.modelsr   r	   r
   r   django.httpr   r   r   django.shortcutsr   r   django.urlsr   django.utils.translationr   r   Zdjango.views.genericr   r   r   r   oscar.apps.orderr   r
  oscar.apps.payment.exceptionsr   oscar.core.compatr   oscar.core.loadingr   r   oscar.core.utilsr   r   oscar.viewsr   oscar.views.genericr   r!   r#   r$   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r3   rD   rG   rH   rw   r   r   r   r   r   r   r   r  r-  r3  r4  rB   rB   rB   rC   <module>   sp   














)  C  1
