o
    'jKn                    @   s  d dl Z d dlZd dlZd dlmZ d dlZd dlZd dlZd dlm	Z	m
Z
mZ d dlmZmZ d dlmZmZmZmZmZmZ d dlmZ d dlmZ d dl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%m&Z&m'Z' d dl(m)Z)m*Z* d dl+m,Z, d dl-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZP d dlQmRZRmSZSmTZTmUZU d dlVmVZVmWZW d dlXmYZY d dlZm[Z[ ddl\m]Z]m^Z^m_Z_m`Z`maZambZbmcZcmdZd d dlemfZf d dlgZgd dlhZhd dliZid dljZjd dlkmlZl d dlmmnZn d dlompZp d dlqmrZr d dlsmtZtmuZu d dlvZvd dlwmxZx d dlmZ ddlymzZz G d d! d!Z{G d"d# d#e{eZ|G d$d% d%e{eZ}G d&d' d'e{eZ~G d(d) d)e{eZd*d+ ZG d,d- d-eZG d.d/ d/e{eZG d0d1 d1e{eZG d2d3 d3e{eZG d4d5 d5eZG d6d7 d7ee{ZG d8d9 d9eZG d:d; d;eZG d<d= d=eZG d>d? d?eZd@dA ZG dBdC dCeZG dDdE dEeZG dFdG dGeZG dHdI dIeZG dJdK dKeZG dLdM dMeZG dNdO dOeZG dPdQ dQe{eZG dRdS dSeZG dTdU dUeZdVdW ZG dXdY dYeZG dZd[ d[eZG d\d] d]eZdvd^d_ZG d`da daeZd dblmZ eepdcddG dedf dfeZG dgdh dheZG didj djeZdkZdlZdmZG dndo doeZdpdq Zdrds Zdtdu ZdS )w    N)	urlencode)send_whatsapp_messagecheck_and_verify_order_statussend_whatsapp_order_message)	EmailSendNotificationInit)calculate_cart_weightget_delhivery_chargeget_delivery_infoget_expected_delivery_timeget_full_address_from_latlngget_pincode_from_latlng)	localtime)parse)ROUND_HALF_UPDecimal)APIView)Responsestatus)get_object_or_404redirectrender)ProductionUnitShop)order_confirmed)CustomProductProductImageProductsWishlistSalesUnitProductSelectionCustomProductImage   )AdditionalDetails
BillEditedCartCartItemSKUCartItemCustomizationCustomCouponSettingsCustomOrderTracking	DelhiveryDeliveryBoysDeliveryMatrixDeliveryOTPDeliverySlotDiscountOrderProductCustomizationOrdersDropaddressOrderProductsCouponsCustomCouponPaymentAdsOrderDeliveryNotificationStatPaymentModesSomeOneElseDeliverySettingsDeliveryDiscount)UserLocationAddressReferralUsers)datetime	timedelta)timezone)transaction)CustomOrderCreateSerializerOrderSerializerPastOrderListSerializerAdSerializerOrderSerializer2CourierDetailsSerializerCustomOrderSerializerOrderBillDetailsSerializer)CustomProductSerializer)settings)View)csrf_exempt)Q)FileResponseJsonResponse)template_writer)r   )billdesk_utilsc                   @   s.   e Zd ZdddZdd Zdd Zdd	 Zd
S )CartViewMixinr   c                    s  t j }|stddfS tt|}tt  |jtdkrN|jtdkrN||jkrN |jkr7tddfS |j  }|jtdtd}|j	d| dfS |j	}|j
}|j}||krf|| }|||  }	n|}	tjd}
d	}d }|
D ]} |jkrt|jtd
 }||	 }|	|8 }	|} nqt fdd|
D }|r|d }|j  }|jtdtd}d| d|j d}n|
 }|r|j d}nd}t|	d|fS )N0.0!Delivery settings not configured.Free delivery applied!0.01rounding   Add ₹ more to get free delivery.-min_order_value 100.0c                       g | ]	} |j k r|qS  min_order_value.0dsubtotalre   @/var/www/html/collabkart/collabkart.saasvaap.com/orders/views.py
<listcomp>       z@CartViewMixin.calculate_dynamic_delivery_fee.<locals>.<listcomp> more to get % off on delivery.% discount applied on delivery.No delivery discount available.   r=   objectsfirstr   strfree_delivery_max_distancefree_delivery_min_order_valuequantizer   base_feebase_km
per_km_feer>   order_byrg   discount_percentround)selfrl   distance_kmrP   	remainingr}   r~   r   extra_kmdelivery_fee	discountsmessageapplied_discountdiscountr   discount_amountnext_discountsnext_discountre   rk   rm   calculate_dynamic_delivery_fee   sT   





z,CartViewMixin.calculate_dynamic_delivery_feec                 C   sZ   t jj|d }|r"td|jr|jnd|jr|jnddtjdS tddddtj	dS )Ncartr"   rb   )r   namephone_numberr   r   )
r<   rw   filterrx   r   r   r   r   HTTP_200_OKHTTP_404_NOT_FOUND)r   r   some_one_detailsre   re   rm   order_for_someone_else_details   s    	z,CartViewMixin.order_for_someone_else_detailsc           4      C   s  |j  }i }d}d}d}d}|D ]U}	|	j}
|
j}|
j}||vrK|
j|
j|
j|
j|
j|
j	|j
|j r;|j jjnd|
jg |
jdd|	jdd||< d}tjtd|jgdtd|jgdB td	|gd
B td|
gdB }|D ]D}|jdkr|j|j v r|} n2|jdkr|j|j v r|} n!|jd	kr||j v r|} n|jdkr|
|j v r|} nqq|
j}|r|j}tt|dt|d   d}| d}n|}d}|j pd|j!pd|j"pdd}d}|  D ]\}}|tt|t|d  d7 }q||| d< ||| d< || d  |	j#7  < |tt||	j# d7 }|t||	j# 7 }|tt|t| |	j# d7 }|
jrg|	j$ D ]!}|| d %|	j|j|j&|j'r[|j'jnd|j(|) d qEqt*|+ }d}|j,rt-|j,t.rt.jj|j,j/d }|r| 0|||j1}n|j2r|j2}| 0|||j1}nd}d}d}d}d} d}!i }"t3jj|j1d4d }#|#st5dddddS |#j6}$d}%d}&|$s|j1rd }%t7jj8d!d d" }'t9|}&t:|#j;|#j<}(t=|'|(|&d#d$} t=|'|(|&d#d%}!t=|'|(|&d&d$}t=|'|(|&d&d%}d'})t>|(}"n&|j1r2t3jj|j1d4d }#|#r2|#j?dur2|#j?}| j@||d(\}})t|}*t|}+t|t| },|%rSt|!}nt|}t|*|+ |, | d}-t|t| },|*|+ |, }.t|dt|dt|dt|dt|| dt|d|-|j,r|j,j/n|j2t|.dd)	}/| |!|||"Ad*|"Ad+|&d,}0tBjj|d- }1|1r|1jCr|1jCnd'|1jDr|1jDnd'd.}2ni }2tEjjd d+d/d0}3t5d|||/|2|)t*|3|0|%d1	tFjGdS )2z3Helper method to format cart items into a response.r   Nz0%)sku_idsame_day_deliverysku_namesku_codesku_unitsku_quantityproduct_nameproduct_imagecustomization_availablecustomization_items	sku_priceoffer_priceoffercart_item_idquantityCategory)
DiscountOnApplicableCategory__inSubCategory)r   ApplicableSubCategory__inProduct)r   ApplicableProduct__inSku)r   ApplicableSku__inr"   d   ru   %)s_gstc_gstcessr   r   r   r   )r   	custom_idcustom_notecustom_imagecustom_image_idhas_customization)
CouponCode        userz-created_atzUser location not found.r   r     r   FTpin_codeflatzPre-paidESCODrb   )r   )	rl   taxes_and_chargesr   r   total_savingscoupon_savingsgrand_totalcoupon_codetotal_without_deliverytat_surfacetat_express)delivery_fee_online_expressdelivery_fee_online_surfacedelivery_fee_cod_expressdelivery_fee_cod_surfaceexpected_tat_surfaceexpected_tat_expresscart_weightr   )r   r   	mode_nameid)	r   r   data
price_datasome_one_else_orderdelivery_discount_messageavailable_payment_modeslong_distance_chargeslong_distance)Hitemsallskuproductr   r   r   r   r   r   	item_nameimagesexistsrx   imageurlr   sku_mrpr0   rw   r   rS   item_categoryitem_sub_categoryr   ApplicableCategoryApplicableSubCategoryApplicableProductApplicableSkuDiscountPercentager   floatr   r   r   r   customizationsappendr   r   r   r   listvaluescoupon
isinstancer5   r   calculate_coupon_savingsr   custom_couponr?   r   r   shopr   values_listr   r   latitude	longituder	   r
   distancer   getr<   r   r   r;   r   r   )4r   r   r   
cart_itemsgrouped_itemssubtotal_sumgst_charges_sumr   r   itemr   r   r   applicable_discountr   r   r   discount_percentager   r   
gst_values
gst_amountgst_typegst_percentcustomization
items_datar   
coupon_objr   r   r   r   r   r   expected_deliveryuser_location	shop_uuidr   r   pickup_pincodeaddress_pin_coder   rl   gstsavingsr   r   r   r   r   some_one_orderpayment_modesre   re   rm   get_cart_items_response   sX  


  	

z%CartViewMixin.get_cart_items_responsec           	   
   C   s2  d}zjt |tr-|jdkr"|jpdd | }|jr!t||jpd}nI|jdkr,|jp+d}n>t |trktj	j
|d }|rP|j|krPtj	j
|d }|sOd}ntj	j
|d	 }|rk|j|krk|jjri|jj}nd}W n ty } zt| W Y d }~nd }~ww ztt|d
W S  ttfy   Y dS w )Nr   
percentager   r   amountreferral_code	user_uuidg      Y@r   ru   )r   r5   
CouponTyper   MaxDiscountAmountForPercentageminDiscountAmountry   rA   rw   r   rx   r   r2   r   r6   r   r   	Exceptionloggingerrorr   r   	TypeError
ValueError)	r   r   rl   r   r  referralhas_previous_ordersr   ere   re   rm   r     sD   






z&CartViewMixin.calculate_coupon_savingsNr   )__name__
__module____qualname__r   r   r  r   re   re   re   rm   rX   z   s    
= QrX   c                   @      e Zd Zdd ZdS )AddOrUpdateCartViewc              
   C   s  |j d}zt|trt|n|}W n tjy(   tdddtj	d Y S w |j d}|j dd}|sF|sF|sFtdd	dtj	dS |j
jrW|j
}d }tjj|d
}n|j d}d }tjj|d}tjj|rm|nd |sr|nd d\}	}
|rtjj|t d }|r||	_|	  | |	dS tjj|d }|r|j
|krtjj|d }|s||	_|	  | |	dS tdddtj	dS tdddtj	dS tjj|d }|r|j
|krtdddtj	dS ||	_|	  | |	dS tdddtj	dS |rd |	_d|	_|	  | |	dS |D ]}|d}|dd}|dg }|r3|dkr?tdddtj	d  S tt|d }tjj|	|d!\}}t |}||_!|  g }|D ]}|d"}|d#}|d$}|rx|j"|nd }|rz=t#jj||d%}|d&v r|d&v r|s|$  W q^||_%||_&|r||_'|d u rd |_'|  |(|j) W q^ t#j*y   Y q^w |d&v r|s|sԐq^t#jj+|||d'}|r||_'|  |(|j) q^t#jj|d(j,|d)$  q| |	d*S )+Nskusr   z%Invalid JSON format for 'skus' field.r   r   r   remove_couponFz)SKU data or coupon code must be provided.r   anonymous_idr2  )r   r2  )r   validity_end_date__gtezCoupon added successfully!r  r  z#Referral code applied successfully!z1Referral code is only valid for first-time users.z&You cannot use your own referral code.r  z-Coupon code is only valid for approved users.z!Coupon code applied successfully!z(Invalid or expired coupon/referral code.rb   zCoupon removed successfully!r   r   r"   customisationz;SKU ID and quantity must be provided and greater than zero.r   )r   r   r   r   r   )r   	cart_item)rb   N)r7  r   r   )r7  )id__inzCart Updated Successfully!)-r   r   r   ry   jsonloadsJSONDecodeErrorr   r   HTTP_400_BAD_REQUESTr   is_authenticatedr?   rw   r%   get_or_creater5   r   rE   nowrx   r   saver  rA   r2   r   r   r6   r   r'   r&   lenr   FILESr(   deleter   r   r   r   r   DoesNotExistcreateexclude)r   requestsku_data_rawsku_datar   r1  r   r2  locationr   createdr   r'  r(  r   sku_infor   r   customization_datar   r7  _total_custom_entriesexisting_custom_idscustomr   r   r   r   r
  
new_customre   re   rm   post  s   









	

zAddOrUpdateCartView.postNr+  r,  r-  rS  re   re   re   rm   r/        r/  c                   @   r.  )RemoveFromCartViewc                 C   sh   t t|d}|j}|  tjj|d}|r|  |j s.|  t	ddd dt
jdS | |dS )Nr6  r   r"   zCart is now empty.r   r   r   r   z$Item removed from cart successfully!)r   r&   r   rC  r<   rw   r   r   r   r   r   r   r  )r   rG  r   r7  r   some_one_elsere   re   rm   rC    s$   
	zRemoveFromCartView.deleteN)r+  r,  r-  rC  re   re   re   rm   rV    rU  rV  c                   @   r.  )FlushCartViewc                 C   s   |j jrtjj|j d }nz|jd}tjj|d }W n   d }Y |s4tddd dt	j
dS tjj|d}|rA|  |j   |j sQ|  tdd	d dt	j
dS )
Nr   r2  r3  r"   No cart found for this user.rW  r   r   zCart flushed successfully.)r   r=  r%   rw   r   rx   r   r   r   r   r   r<   rC  r   r   r   )r   rG  r   r2  rX  re   re   rm   rS    s,   


zFlushCartView.postNrT  re   re   re   rm   rY    rU  rY  c                   @   r.  )GetCartViewc                 C   st   |j jrtjj|j d }nz|jd}tjj|d }W n   d }Y |s4tddd dt	j
dS | |dS )	Nr   r2  r3  r"   rZ  rW  r   zCart retrieved successfully!)r   r=  r%   rw   r   rx   r   r   r   r   r   r  )r   rG  r   r2  re   re   rm   rS    s   
zGetCartView.postNrT  re   re   re   rm   r[    rU  r[  c                   C   s   t jjddddS )z-Retrieve active and available delivery slots.Tactive)is_availabler   
start_time)r/   rw   r   r   re   re   re   rm   get_available_delivery_slots  s   r_  c                   @   r.  )DeliverySlotSelectionViewc              
   C   s`  z|j jstdddtjdW S tjj|j d }|s(tdddtjdW S t	jj|d}|
 s>tdddtjdW S td	d
 |D }d }|sMd}tjj|j d }d}d }|rs|jrsd}|j}	d|	j|	j|	j|	j|	jd}t }
g }t }tt }|rdnd}|
D ]h}t||d D ]^}|t|d }ttt| |j}ttt| |j}|dkr||krq|j | f}||v rq|!| |"d d|"d }|#||j |"d|$ d qq|j%dd d |d d }tdd||||dtj&dW S  t'y/ } ztddt(|dtjdW  Y d }~S d }~ww )Nr   zUser is not authenticated.r   r   r   zCart not found.r   zGCart is empty. Please add items to cart before selecting delivery slot.c                 s   s    | ]
}t |jd dV  qdS )r   FN)getattrr   ri   r  re   re   rm   	<genexpr>$  s
    
z0DeliverySlotSelectionView.get.<locals>.<genexpr>z}One or more products in your cart are not eligible for same-day delivery. Your order will be delivered from tomorrow onwards.FTzNavya Bakers)r   	shop_name
shop_phoneshop_locationr   r   r"      )daysz%d %b %Y %I:%M %p to %I:%M %p%Y-%m-%d)delivery_slotslot_iddater^  c                 S   s   | d | d fS )Nrn  r^  re   xre   re   rm   <lambda>q  s    z/DeliverySlotSelectionView.get.<locals>.<lambda>keyz0Available delivery slots retrieved successfully!)r   r   r   pickup_availableshop_detailssame_day_messageAn unexpected error occurred.r   r   	exception))r   r=  r   r   r<  r%   rw   r   rx   r&   r   r   r?   r   	unit_name
contact_nounit_locationr   r   r_  setrE   r   r?  rangerD   
make_awarerC   combinern  r^  end_timer   addstrftimer   	isoformatsortr   r"  ry   )r   rG  r   r   allow_same_dayrv  r  rt  ru  r   available_slots
slots_dataseencurrent_time	start_dayslot
day_offsetfuture_dater^  r  rs  rl  r)  re   re   rm   r     s   	


'zDeliverySlotSelectionView.getNr+  r,  r-  r   re   re   re   rm   r`    rU  r`  c                   @   r.  )!AddOrUpdateSomeOneElseOrderDetailc              
   C   s  |j dd}|j dd}|j dd}tjj|jd }|j dd}|s4|s4tddd	tj	d
S |rt
jj|d }|r|jdkrPtddd	tj	d
S z/tjj|d\}}	|r^|nd|_|re|nd|_|rl|nd|_|  tdd||dtjd
W S  ty }
 ztddt|
dtjd
W  Y d }
~
S d }
~
ww d S |s|s|stddd	tj	d
S |stddd	tjd
S z/tjj|d\}}	|r|nd|_|r|nd|_|r|nd|_|  tdd||dtjd
W S  ty }
 ztddt|
dtjd
W  Y d }
~
S d }
~
ww )Nr   rb   r   r   r   order_idr   z%other person details should be given.r   r   uuidCustom Ordersz,Invalid Order type please check order detail)ordersr"   z(Some one else data created successfully!r   r   r   r   z"Some one else data creation failedr   r   r$  z5Cart detail and other person details should be given.z,Cart couldn't found please check cart numberr   )r   r   r%   rw   r   r   rx   r   r   r<  r2   
order_typer<   r>  r   r   r   r@  HTTP_201_CREATEDr"  ry   HTTP_500_INTERNAL_SERVER_ERRORr   )r   rG  r   r   r   r   r  ordersome_onerK  r)  re   re   rm   rS    s   
z&AddOrUpdateSomeOneElseOrderDetail.postNrT  re   re   re   rm   r    rU  r  c                   @   r.  )GetSomeOneElseOrderDetailc                 C   sr   t jj|jd }|r/tjj|d }|r%tdd|j|jdt	j
dS tddd	t	jdS tdd
d	t	jdS )Nr   r   r"   z*Some one else data retrieved successfully!r  r   r   Some one else data not foundr   Cart not found)r%   rw   r   r   rx   r<   r   r   r   r   r   HTTP_204_NO_CONTENTr   )r   rG  r   some_one_datare   re   rm   r     s0   zGetSomeOneElseOrderDetail.getNr  re   re   re   rm   r    rU  r  c                   @   r.  )DeleteGetSomeOneElseOrderDetailc                 C   s   t jj|jd }|r9tjj|d}| }|j}|j}|r/|  t	dd||dt
jdS t	ddd	t
jdS t	dd
d	t
jdS )Nr   r   r"   z(Some one else data deleted successfully!r  r   r   r  r   r  )r%   rw   r   r   rx   r<   r   r   rC  r   r   r   r   )r   rG  r   r  r  r   r   re   re   rm   rS    s8   z$DeleteGetSomeOneElseOrderDetail.postNrT  re   re   re   rm   r    rU  r  c                   @      e Zd Zdd Zdd ZdS )CheckoutAPIViewc                 C   D   	 dt dd t tj t tj }tjj|d s!|S qzGenerate a unique order ID.TIDr   i  order_ID	randomrandintchoicestringascii_uppercaser2   rw   r   r   r   r  re   re   rm   generate_unique_order_id  
   *z(CheckoutAPIView.generate_unique_order_idc           6      O   s  z|j }|jdd}t|}|jj}td|  d}|dks.|dks.|dks.|dkr1d	}n|d
kr8d}n|dks@|dkrCd}nd}tt	|d}	|j
dd}
d }d }|
s|j
d}tt|d}tjtjd}d|j d|j d| }t|}|jdkr| }|d dkr|d d d }d } } }}|D ]"}|d }|d }d |v r|}d!|v r|}d"|v r|}d#|v r|}qntdd$t| d%tjd&W S tdd'd(tjd&W S |j
d)}tt|d}|j}|j
d*}tt|d}|j}|
rd+nd,}|jsd-}d } |
s*tjj|j  d.|j! |j"|j#|||||j|j|j$|j%d/} | & }!t' }"|"(|	d0}#|#j
d1 }$|$d2 }%|$d3 }&|$d4 }'|$d5 }(|$d6 })|$d7 }*|$d8 }+t)* ; z	t+jjd[i d9|!d:|d;d<d=|d>| rw| nd d?|j
d?dd@|j
d@ddA|dB|
s|ndCd7|*d3|&dD|+dE|%d5|(d6|)d4|'dFdGdHt,- dI|},t.jj/|	dJ0 }-|-r|,|-_1|-2  |,j3d,ks|,j3d+kr||,_4|,2  n*|,j3d-krzt5j0 }.W n t6y }/ zd }.W Y d }/~/nd }/~/ww |.|,_7|,2  |	j89 D ]}0|0j:}1|0j;}2|1j<|2 }3t=jj|1j>j?|,|1|2|3dK qt@jtjAtjBfdL}4|4jCtD|*dM dNdOdP}5tEjj|,|5dQ dRdS tdOdT|,jF|5dQ |5dU |*dVdWtjGd&W W  d    W S  t6y }/ z"dX|,_H|,2  tddYt|/dZtjd&W  Y d }/~/W  d    W S d }/~/ww 1 sw   Y  W d S  t6y }/ ztddYt|/dZtjd&W  Y d }/~/S d }/~/ww )\NHTTP_USER_AGENTrb   Platform : OtherWindowsMac OS XLinuxUbuntuWebAndroidAndriodiOSFlutter Mobile App / iOSIOSr   pickupF
address_idr6  rr  z9https://maps.googleapis.com/maps/api/geocode/json?latlng=,z&key=   r   OKresultsr   address_componentstypes	long_nameroutelocalityadministrative_area_level_1postal_codez1Unable to fetch address details from Google Maps.r   r   excr   z$Error connecting to Google Maps API.r   rl  deliver_datePick UpLocal OrdersLong Distance Orders r   house_number_or_name	land_markstreetcitystate_or_provincer   r   r   address_typecontact_numberCart data fetched successfullyr   rl   r   r   r   r   r   r   r  r  order_status	New Orderr  drop_addressdelivery_instructioncooking_instructiondelivery_slot_datedelivery_slot_timez19:00delivery_charges	sub_totalcolor_statusWhitecolor_status_updation_timeplatformr   r   r  r   r   priceauthr   INRr"   )r  currencypayment_capturer   pending)r  razorpay_order_idpayment_statuszOrder Created Successfullyreceipt)r  r  razorpay_payment_linkr  rW  Failedrw  rx  re   )Ir   METAr   r   osfamilyr#  infor   r%   r   r@   
googlemapsClientrP   GOOGLE_MAPS_API_KEYr   r   requestsstatus_coder9  r   ry   r   r<  r/   r^  r?   r   r3   rw   rE  
first_name	last_nameflat_nolandmarkr  r   r  rX   r  rF   atomicr2   rC   r?  r<   r   rx   r  r@  r  
store_uuidr   r"  pu_uuidr   r   r   r   r   r4   r   r   razorpayRAZORPAY_KEY_IDRAZORPAY_KEY_SECRETr  intr7   r  r  r  )6r   rG  argskwargsr   	ua_string
user_agentr  platform_datar   r  addressrl  r  google_maps_api_keygeocode_urlresponser   r  r  r  stater   	componentr  r  delivery_slot_idr  r  r  r  r  r  r  
cart_mixincart_responser   rl   r   r   r   r   r   r   r  rX  pur)  r7  r   r   r  razorpay_clientrazorpay_orderre   re   rm   rS    s   	

 
	





TT`zCheckoutAPIView.postNr+  r,  r-  r  rS  re   re   re   rm   r        r  c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	CouponsListViewzf
    View to list all available valid coupons and calculate the savings based on the user's cart.
    c                 C   s  z|j jrtjj|j d }nz|jd}tjj|d }W n   d }Y |s5tdddt	j
dW S | |d}|jd	i d
d}tjj|d}tjjt d}g }|D ]G}	| |	|}
d}d}|
rq| |	|
|}d}||	j|	j|	j|	j|	j|	jdkr|	jnd |	jdkr|	jnd |	j|	jr|	jjnd |	j||d qZtdd|dt	jdW S  ty } ztddt |dt	j
dW  Y d }~S d }~ww )Nr   r2  r3  r   zNo cart found for the user.r   r   zCart detailsr   rl   r   )r4  FTr  r  )coupon_namer   coupon_descriptioncoupon_typeminimum_bill_amountr  r  max_discount_amounticonterms_and_conditionsr  
applicabler"   z%Valid coupons retrieved successfully.)r   r   couponsrw  r   r   r"  )!r   r=  r%   rw   r   rx   r   r   r   r   r<  r  r&   r5   rE   r?  get_applicable_itemscalculate_savingsr   
CouponNamer   CouponDescriptionr  TotalBillAmountr!  r   r  Iconr   TermsAndConditionsr   r"  ry   )r   rG  r   r2  price_data_response
cart_totalr   valid_couponsapplicable_couponsr   applicable_itemsr  is_applicabler)  re   re   rm   rS    sv   zCouponsListView.postc                    s   g } j dkr fdd|D }|S  j dkr" fdd|D }|S  j dkr2 fdd|D }|S  j dkr@ fd	d|D }|S )
zw
        Check if any items in the cart match the applicable categories, subcategories, or SKUs of the coupon.
        r   c                    s    g | ]}|j  j v r|qS re   )r   r   r   rb  r   re   rm   rn   Y  s    z8CouponsListView.get_applicable_items.<locals>.<listcomp>r   c                    $   g | ]}|j jj j v r|qS re   )r   r   r   r   r   rb  r6  re   rm   rn   _  s
    r   c                    r7  re   )r   r   r   r   r   rb  r6  re   rm   rn   e  s    r   c                    s"   g | ]}|j j j v r|qS re   )r   r   r   r   rb  r6  re   rm   rn   l  s
    )CouponOn)r   r   r   r4  re   r6  rm   r)  Q  s*   







z$CouponsListView.get_applicable_itemsc                 C   sX   d}||j kr%|jdkr|j}n|jdkr%|jd | }|jr%t||j}t|d}|S )zu
        Calculate the savings for the user based on the coupon type (DiscountAmount or DiscountPercentage).
        r   r  r  r   ru   )r-  r  r!  r   r  r   r   )r   r   r4  r1  r  re   re   rm   r*  u  s   



z!CouponsListView.calculate_savingsN)r+  r,  r-  __doc__rS  r)  r*  re   re   re   rm   r    s
    O$r  c                   @      e Zd Zg Zg Zdd ZdS )VerifyDeliveryOTPc                 C   sp  |j d}|j d}tjj|d }|stddiS tjj|d }|s.tddiS |j|kr9tddiS |j	rBtdd	iS d
|_	|
  d|_d|_t |_|
  zU|j}tjj|d }|rs|jdkrsd|_|
  tj }|j|jkr|j|jkrdttdd }	tjj|	||jd}
d}d|	 d}t|jj||||j W n   Y tddiS )N
order_uuidotpr  r$  Order not foundr  zOTP not foundzInvalid OTPzOTP already usedT	Deliveredr  pkassignedznot assigned	NavyaCoup  i )r   r   r   zEligible for Coupon!zYou are eligible for Coupon (z).r   zOrder Delivered Successfully)r   r   r2   rw   r   rx   r   r.   r=  is_verifiedr@  r  r  rC   r?  r  delivery_boyr,   delivery_boy_statusr)   r   lower_limit_pricehigher_limit_pricery   r  r  r6   rE  r  r   	fcm_token)r   rG  r<  r=  r  delivery_otpshipper_uuidshippercustom_coupon_checkcoupon_code_generationr   notification_titlenotification_descriptionre   re   rm   rS    s^   


zVerifyDeliveryOTP.postNr+  r,  r-  authentication_classespermission_classesrS  re   re   re   rm   r;        r;  c                   @   r.  )VerifyPayBillDeskc                 O   s   z|j d}tjj|d}tjj|d}|j}|j }z$|jdks+|jdkrd}d}	d|jj	 d	|j
 d
}
t|jj||	|
|j t|	|
|jjgd |jjdkrftj|jj|j
|jj	|gdd |jrr|jj}|jj}n|jj}|jj}|j}|jj}d}|jr|jrtjj|jd }|rt |jt!rt"#|jd}n|j}|$d}|j%$d}|j&$d}| d| d| }|j'dkr|j'}|dkrd}|j(r|j(}|j) d|j* d|j+ d|j, d|j- d|j. }n5d}n2t/jj|d j0}|dkr"|j(r!|j(}|j) d|j* d|j+ d|j, d|j- d|j. }nd}t1j|||j
|jj	|jj|||||g
d |j'dkr[|j}t2t3|d}|4  |j5}|r[t6jj|d4  |j'dksg|j'dkrt7j8d|j
|jj9|j:|j'd  t;d!d"t<|j d#d$d%W W S |j'dkrzt=jj|d }|r|j>nd}W n t?y } zt@Ad&|  d}W Y d }~nd }~ww t;d!d"tB|||d'd(j d#d$d%W W S |j'd)krt;d!d"tC|j d#d$d%W W S t;d!d"t<|j d#d$d%W W S d*}d+}	d,|j
 d-}
t|jj||	|
|j t|	|
|jjgd |jjdkr+tj|jj|j
|jj	|gdd t@Ad.|j
 d/tDE   t;d0d1d2d3d%W W S  t?y } zXd*}d+}	d,|j
 d-}
t|jj||	|
|j t|	|
|jjgd |jjdkrtj|jj|j
|jj	|gdd t@Ad4|j
 d5| d6tDE   t;d0d7d2d3d%W  Y d }~W S d }~ww  t?y } zZd*}d+}	d,|j
 d-}
t|jj||	|
|j t|	|
|jjgd |jjdkrtj|jj|j
|jj	|gdd t@Ad4|j
 d5| d6tDE   t;d0d1t!|d8d3d%W  Y d }~S d }~ww )9Nr  r  r?  paidPaidorder_confirmation_general   Your Order is Confirmed 🎉Hi z",

                    Your order u    has been successfully confirmed.
                    We’ve started processing it and will keep you updated on the next steps.
                    Thank you for choosing Navya Bakers!FTru   r  	countdownN/Ar^  rk  %d %b %Yrj   |  - r  r  Home Delivery, r  r  r   r  r  Order Creationsenderr  store_idr  r  r"   Payment Verified Successfullyr   r   order_detailsr  r   0Error occurred while fetching bill edit status: rG  	is_editedcontextr  deliveryfailedcase_generalPayment FailedzYour payment for  order z= could not be processed at this time. Please try again later.zPayment Failed  for z:
r   rw  r   r    Payment Verification Failed for : 
Payment verification failedrx  )Fr   r   r2   rw   r7   r  r  lowerr  r   r  r   rK  r   emailopt_inr   apply_asyncr   r  rz  r{  r  pu_namer   payment_moder   r  r  r/   r   rx   r   ry   rC   strptimer  r^  r  r  r  r   r  r  r  r  r   r*   delivery_typer   r   r%   rC  r   r6   r   sendr  r  r   rH   r$   rq  r"  r#  r$  rM   rK   	traceback
format_exc)r   rG  r  r  r  r  paymenttest	temp_nametitledescriptionrd  r   r   payment_methoddelivery_timer  delivery_date_objdelivery_dater^  r  delivery_moderj   r  r   r   r   	bill_editedittedr)  re   re   rm   rS    s|  
 



*



	
	 
	  zVerifyPayBillDesk.postNrT  re   re   re   rm   rW    rU  rW  c                   @   r.  )VerifyPaymentAPIViewc              
   O   s  |j }|jd}|jd}|jd}z/tjj|d}|j}	tjtj	tj
fd}
|||d}z|
j| d|_||_|  d|	_|	  tt|d	}|  |j}|ratjj|d
  ztjd|	j|	jjd W n   Y |	jdkrtddt|	jdddW W S |	jdkrztjj|	d  }|r|j!nd}W n t"y } zt#$d|  d}W Y d }~nd }~ww tddt%|	||ddjdW W S |	jdkrtddt&|	jdddW W S tddt|	jdddW W S  tj'j(y   d|	_|	  t#$d|	j d tdddd d Y W S  t"yE } z#d|	_)|	  t#$d!|	j d"|  tdddd dW  Y d }~W S d }~ww  t"y } z/tjj|d}|j}	d|	_|	  t#$d|	j d"|  tdd#t*|d$d dW  Y d }~S d }~ww )%Nr  razorpay_payment_idrazorpay_signature)r  r  )r  r  r  rY  	Confirmedr   r  rh  )rj  r  rk  r  r"   rl  rm  r  r   r  r?  Fro  rp  rr  r  r  zPayment Failed for z : Signature Verification Failed r   ry  r   r   rv  rw  rw  rx  )+r   r   r   r7   rw   r  r  r  rP   r  r	  utilityverify_payment_signaturer  r  r@  r  r   r%   rC  r   r6   r   r   r  r  r  r  r  r   rH   r$   rx   rq  r"  r#  r$  rM   rK   errorsSignatureVerificationErrorr   ry   )r   rG  r  r  r   r  r  r  r  r  r  paramsr   r   r  r  r)  re   re   rm   rS    s   





	



zVerifyPaymentAPIView.postNrT  re   re   re   rm   r    rU  r  c                   @   r.  )PastOrdersListAPIViewc                 O   s   |j }tjj|djddd}t|ddj}|D ]2}|d dkr,|d	 d
kr,d|d	< |d dkr7d|d< q|d dkrBd|d< q|d dkrLd|d< qtdd|dt	j
dS )Nr  r  )r  -created_dateTmanyr  r  r  r@  Order collectedr  homeHomeworkWorkothersOthersr"   z Past orders fetched successfully)r   r   r  r   )r   r2   rw   r   rF  r   rI   r   r   r   r   )r   rG  r  r  r   r  
serializerire   re   rm   r   =  s*   

zPastOrdersListAPIView.getNr  re   re   re   rm   r  <  rU  r  c                 C   s   d|  d| S )Nzhttps://www.google.com/maps?q=r  re   )latlngre   re   rm   get_google_maps_linkY  s   r  c                   @   r.  )PastOrderDetailAPIViewc              
   C   s  zd}d }t jj||jd}tjj|d }|r.|jdkr.d}|jj	}|jj
}t||}n|jdkrBd}|jj	}|jj
}t||}|jdkrMt|j}	n|jdkrxt|j}	|	dd	kse|	dd
krwtjj|d }
t|
j}||	d< nY|jdkrztjj|d }|r|jnd}W n ty } ztd|  d}W Y d }~nd }~ww t|||ddj}	n|jdkrt|j}	|	d d
krd|	d< nt|j}	tjjdddd}tdd|	t|d|rd|ini tjdW S  t jy
   tddttdtjd Y S w )NF)r  r  rf  r  Tr  r  r  
Despatchedr@  r?  courier_detailsr  ro  rp  rr  r  r   r   r   r"   z"Order details fetched successfully)r   r   rn  r   delivery_linkr   z"Error while fetching order detailsr  ) r2   rw   r   r   r*   r   rx   r  r  r   r   r  r  rH   r   rK   r9   rL   r$   rq  r"  r#  r$  rM   r;   r   r   r   r   r   rD  ry   )r   rG  r<  r  r  r  custom_orderr  r  r  order_deliveryr  r  r  r)  r  re   re   rm   r   _  s   











zPastOrderDetailAPIView.getNr  re   re   re   rm   r  ^  rU  r  c                   @   r.  )AddressChangeViewc              
   C   s  |j jstdddddS |j }|jd}|s!tdddddS z
tjj||d	}W n tjy>   tdd
ddd Y S w |jrE|j	sNtdddddS t
|jt
|j	f}tjj|d }|rf|jnd }|rm|j	nd }|rt|jnd }	tjjdddd}
|	stdddd ddS tjtjd}dd |
D }z|j|g|dd}W n  ty } ztddt| dddW  Y d }~S d }~ww |dg d dg }g }t|
|D ]&\}}|ddkrq|d d d  }|t|j|jt|d!|jd" q|stdd#ddd$S |jd%d& d |d }|
j|d' d(}|d) }|d* }|r4||_||_|  |rI||krItdd+d|d, |dd-S |	j|jkr_td.d/d|	j|d, |dd0S tdd1d|	ri|	jnd |d, |dd0S )2Nr   Unauthorizedr   i  r   r  zAddress ID requiredr   )r   r   zInvalid addresszInvalid coordinatesr   FOpen)latitude__isnulllongitude__isnullr   z2No shops available. Delivery from production unit.T)r   r   proceednearest_shopr   rr  c                 S   s   g | ]}|j |jfqS re   )r   r   )ri   r   re   re   rm   rn   !  s    z*AddressChangeView.post.<locals>.<listcomp>driving)originsdestinationsmodezGoogle API error: i  rowselementsr   r  r   valuerE  ru   )r  rd  r   radiuszNo reachable shops)r   r   r  r   c                 S   s   | d S )Nr   re   ro  re   re   rm   rq  P  s    z(AddressChangeView.post.<locals>.<lambda>r  r  r   r  zOutside delivery radiusrd  )r   r   r  r  r   r   r"   zSame shop - allowed)r   r   r  current_shopr  r   r   z"Nearest shop changed - not allowed) r   r=  r   r   r   r@   rw   rD  r   r   r   r?   r   rx   r   r   r  r  rP   r  distance_matrixr"  ry   zipr   r  rz  r   delivery_radiusr  r   r@  )r   rG  r   r  r  
new_coordsr  user_latitudeuser_longituder  shopsgmapsr  resultr)  r  	distancesr   elementr   nearestr  nearest_distancenearest_radiusre   re   rm   rS    s   

zAddressChangeView.postNrT  re   re   re   rm   r    rU  r  c                   @   r.  )CustomOrderCheckoutAPIViewc           4      O   s  zb|j jr\|j }|jd}tjj|d }|jd}|j}z	t	jj|d}	W n t	j
y?   tddddd	 Y W S w |jd
d}
|jdd }|rW|dkrWd}n8|r`|dkr`d}n/t|
}td|
  |jj}td|  d}|dks|dks|dks|dkrd}nd}|jdkrtdddW S |stdddW S t  d|_|jdd|_|jdd|_|	|_||_|  tj|jfdd  |	jd!krStjj|d"d t |d#d$ d%|_|  t!j"d&|j|j#j$|d'd( d)}d*}d+|j%j& d,|j d-}t'|j%j(||||j% t)|||j%j*gd. |j%j+d/kr5t,j|j%j-|j|j%j&|gd0d1 |j#rB|j#j.}|j#j/}n|j0j1}|j0j/}|j}|jj2}d2}|j3r|j4rt5jj|j3d3 }|rt6|j4t rwt78|j4d4}n|j4}|9d5}|j:9d6}|j;9d6}| d7| d8| }t<jj|d9 j=}|d:kr|j>r|j>}|j? d;|j@ d;|jA d;|jB d;|jC d8|jD }nd2}tEj|||j|j%j&|j%j-|||||g
d< ztFjj|d=}td>|  |G  W n tFj
y   td? Y nw ztHjj|d@ }|r|jInd.} W n tJy2 }! ztKdA|!  d.} W Y d }!~!nd }!~!ww td!dB|||	jtL||| dCdDjdEdFdGd	W  d    W S |	jd0kr?tjj|d"dHt |dI dJ}"dK}#|}$|}%tM|dL}&dM}'|j&pzd}(|j*pd})|j-NdNdO dOd  }*|jPdPd}+d },|+QdQr|+RdQd! O },|,stSjT dR}-tSjT dR}.ntSjT dS|, }-tSjT dS|, }.dM}'dTdU|$ dV|&dWdXidY}/tUjV|/dZd[}0|" d\|$ d\|& d\|' d\|( d\|) d]|# d\|0 }1tWX|1Yd^Z }2t[|2d_ks	J |"|$|&|'|(pd|)pd|*|-|.|2|0|1d`}3|r,|\ dav r,|#|3db< td!dcdd|3dedfd	W  d    W S tddgddd	W  d    W S 1 sTw   Y  W d S tddhdW S  tJy }! ztddit |!djt]j^d	W  Y d }!~!S d }!~!ww )kNr  r  r  r6  r   Invalid payment mode.r   r   r   r  rb   r  Flutter Web AppFlutter_web_appFlutter Mobile Appr  $Platform for the user agent string: r  r  r  r  r  r  r  Bill CreatedzPayment not allowed!zOrder not found!r  r  r  i,  )r^  r"   r  r   r  r  bill_desk_order_idr  payment_method_typer  rh  r  ri  custom_order_confirmationr[  r\  %,
                        Your order     has been successfully confirmed.
                        We’ve started processing it and will keep you updated on the next steps.
                        Thank you for choosing Navya Bakers!FTru   r]  r_  r`  rk  ra  rj  rb  rc  rf  rd  re  rg  r   The cart value is .No cart found for user, skipping cart deletionr?  ro  #Order placed successfully with COD.rp  rr  r  r  r  rn  rW     Online Paymentr  r  r  r  oEOB0P IJB9iqgsiUw879xSB1XGfqSM3hzDSaO7.2fzNavya Bakers Custom Order+AuthorizationToken orders/payu/return/orders/payu/return/?token=absoluteX4Y55z_10.00aggregatorSubTxnIdaggregatorSubAmtaggregatorChargestype	splitInfor  :
separators||||||||||||utf-8   rs  txnidr  productinfo	firstnamer{  phonesurlfurlhashsplitRequesthash_stringandroidiossaltPayU payment initiatedhttps://test.payu.in/_paymentr   r   payu_urlr  r  zInvalid payment mode selected.User not Authenticatedrw  rx  )_r   r=  r   r   r2   rw   r   rx   r   r;   rD  r   r  r   r#  r  r  r  r  rF   r  r  r  r  r  r@  r   r}  r  r   r7   rE  ry   r   r  r  r  r  r   r   rK  r   r{  r|  r   r   rz  r{  r  r~  r   r  r  r/   r   rC   r  r  r^  r  r*   r  r  r   r  r  r  r  r   r   r%   rC  r$   rq  r"  r$  rM   r   replacestripheaders
startswithsplitrP   DOMAINr9  dumpshashlibsha512encode	hexdigestrA  rz  r   r<  )4r   rG  r  r  r   r  r  delivery_mode_idr   r  r  pf_typer  r  r  r  r  r  rd  r   r  r  r  r  r  r^  r  r  rj   r  r   r  r  r)  payu_key	payu_saltr  split1r  r   r  r{  r  auth_headertokenr  r  split_requestsplit_request_strr  	payu_hashr  re   re   rm   rS    s  
 
 


*~	  o * wzCustomOrderCheckoutAPIView.postNrT  re   re   re   rm   r        r  c                   @   r.  )AdListAPIViewc              
   C   st   zt j }t|dd}tddd|jidtjdW S  ty9 } ztdd	t	|d
tj
dW  Y d }~S d }~ww )NTr  r"   zAd Listed SuccessfullyadsrW  r   r   rw  rx  )r8   rw   r   rJ   r   r   r   r   r"  ry   r<  )r   rG  r(  ad_serializerr)  re   re   rm   r   	  s*   
zAdListAPIView.getNr  re   re   re   rm   r'  	  r&  r'  c                   @      e Zd ZdZdd ZdS )DiscountDetailViewz_
    View to retrieve the details of a selected discount and list the associated products.
    c                    s  z9|j jrtjj|j d n|jd}tjj|d r:jr:jj	}t
jj|dd}dd |D  tt|d}g }|jd	krT|j }tjj|d
}	n0|jdkrf|j }
tjj|
d}	n|jdkrs|j }|}	n|jdkr|j }tjj|d}	|	D ]}tjj|d }|r|jjnd }rjrtjj|ddgd}ntjj|ddgdd}|j|j|j|jr|jnd|j r|j jnd |j rt !|j jd|jd   nd || r| j"nd | r| j#nd | r| j$nd  fdd|D |j jr!|jdd t%jj|j dD v ndd}|&| qt'dd|j(|j)|dt*j+d W S  t,yZ } zt'dd!t-|d"t*j.d W  Y d }~S d }~ww )#Nr   r2  r3  )sales_unit__uuidr   c                 S   s   i | ]}|j r|j j|jqS re   )r   r   shop_admin_status)ri   	selectionre   re   rm   
<dictcomp>	  s    
z*DiscountDetailView.get.<locals>.<dictcomp>r6  r   )item_category__inr   )item_sub_category__inr   r   )skus__in)r   VisiblezOut of Stock)r   sku_status__in   )r   r4  sku_expiry_duration__gtr   r"   r   c                    s0   g | ]}|j rjr |jn|jd qS ))r   
sku_status)r   r   r   r   r7  )ri   r   sku_status_mapr  re   rm   rn   0
  s    z*DiscountDetailView.get.<locals>.<listcomp>c                 S   s   g | ]}|j jqS re   )r   r   )ri   wishlistre   re   rm   rn   7
  s    F)
product_idr   product_typer   r  
offerpriceproduct_imgr   r   r   r0  r:  z5Discount details and products retrieved successfully.)r   r   discount_namediscount_codeproductsr   rw  r(  )/r   r=  r?   rw   r   rx   r   r   r   r  r    select_relatedr   r0   r   r   r   r   r   r   r   r   r   r   r'   r   r   veg_or_non_veg_statusr   r0  r   r   r   
from_floatr   r   r   r   r   r   DiscountNameDiscountCoder   r   r"  ry   r<  )r   rG  discount_idr2  shop_idproduct_selectionsr   product_info_listapplicable_categoriesrA  applicable_subcategoriesapplicable_productsapplicable_skusr   r   product_image_urlr0  product_infor)  re   r8  rm   r   	  s   









,,
zDiscountDetailView.getNr+  r,  r-  r9  r   re   re   re   rm   r+  	      r+  c                   @   r*  )DiscountsListViewzI
    View to list all discounts with DiscountName and StandardImage.
    c              
   C   s  zd }|j jrtjj|j d }n|jdd}|r%tjj|d }d}|rA|jrAt	
d t	
d|jj d |j}d	}ztj }W n   g }Y g }|d	kr|D ]}|jd
kr|jj|gd r||j|j|jru|jjnd |jr}|jjnd d qW|jdkr|jj|gd r||j|j|jr|jjnd |jr|jjnd d qW|jdkr|jj|gd r||j|j|jr|jjnd |jr|jjnd d qW|jj|gd r||j|j|jr|jjnd |jr|jjnd d qWn|D ]}|jd
kr3|j D ]%}	|	jr0||j|j|jr |jjnd |jr)|jjnd d  nqq|jdkre|j D ]%}
|
jrb||j|j|jrR|jjnd |jr[|jjnd d  nq>q|jdkr|j D ]%}|jr||j|j|jr|jjnd |jr|jjnd d  nqpq|j D ]%}|jr||j|j|jr|jjnd |jr|jjnd d  nqqtdd|dtjdW S  ty } ztddt|dtj dW  Y d }~S d }~ww )Nr   r2  rb   r3  r   zQ////////////////....User Location Fetched................////////////////////////z////////////////////////////.......Shop Found : z........./////////r   r   )sales_unit__in)r   rE  WebImageMobileImager   r   r"   z!Discounts retrieved successfully.)r   r   r   r   r   rw  r(  )!r   r=  r?   rw   r   rx   r   r   r   r#  r  rz  r0   r   r   r   r   r   r   rE  StandardImager   BannerImager   r   r   long_distance_availabilityr   r   r   r"  ry   r<  )r   rG  r  r2  r  rH  r   discounts_datar   categorysub_categoryr   r0  r)  re   re   rm   rS  U
  s   




%
	zDiscountsListView.postNr+  r,  r-  r9  rS  re   re   re   rm   rS  Q
      rS  c                   @   r  )Customorder_placingc                 C   r  r  r  r  re   re   rm   r  
  s
   *z,Customorder_placing.generate_unique_order_idc                 C   s  zY|j }|jdd}t|tr| dk}|j|kr&||_|jdgd tt	|d}|jd}|jd}|d u r>d}|j
d	d}t|}	td
|  |	jj}
td|
  d}|
dkso|
dkso|
dkso|
dkrrd}n|
dkryd}n|
dks|dkrd}nd}|stdditjdW S |jstdditjdW S tt|d}|stdditjdW S |j}|stdditjdW S |jd}|stdd d!tjdW S ztt|d"}W n  ty } ztdd#t|d$tjdW  Y d }~W S d }~ww tjj|j d%|j |j|jd&d'd(d|j |j!|j"d)
}| # }t$jj||d*||||d+d,||d-}t$jj|d.}|jd/}|rFt%jj||d0 nt%jj|d1 td2d3t&|jd4d5dW S  tyz } ztdd6t|d7tj'dW  Y d }~S d }~ww )8Nr|  Ftrueupdate_fieldsrA  r  r   rb   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r$  zDescription field is required!r   zUser is not authenticatedr   zPlease add your locationzNo shops found at your locationr  r   +Address ID is required for delivery orders.r   r6  Failed to fetch address.rx  r  r  r  r  )
r   r  r  r  r  r  r   r   r   r  r  Enquiryr  )r  custom_productr  r  r  r  r   r  r  r  r  r  r   )r  r   rf  r"   z"Custom order created successfully!rm  r  rw  r  )(r   r   r   r   ry   rz  r|  r@  r   r   r  r   r#  r  r  r  r   r   r<  r=  HTTP_401_UNAUTHORIZEDr?   r   r@   r"  r3   rw   rE  r   r  r  r  r   r   r  r  r2   r*   rG   r  )r   rG  r   r   r|  rf  r  r   r  r  r  r  rJ  r   r  r  r)  r  r  	new_orderr  r   re   re   rm   rS  
  s   

 zCustomorder_placing.postNr  re   re   re   rm   r_  
  s    r_  c                   @   r*  )NotificationListViewz0
    View to list all notification history.
    c                 C   sh  z|j jrztjd}|j|j d }W n   g }Y g }|D ]_}|jdkr\t|j	}t
|j	j}||j|j|j|j	j|j	j|j	jt|jdt|jdd|j|jd q!||j|j|j|j	j|j	j|j	jt|jdt|jddd	 q!td	d
|dtjdW S tdddW S  ty } ztddt|dtjdW  Y d }~S d }~ww )Nr  )sendTor  rk  z%H:%M:%S)r   SendmsgDescriptionOrderIDr  r<  rn  timenotification_typeproduct_detailsbill_detailsNormal)	r   rk  rl  rm  r  r<  rn  rn  ro  r"   z,Notification history retrieved successfully.)r   r   notification_listr   r   r  r   rw  r(  )r   r=  r:   rw   r   r   r   rk  rN   rm  rO   rf  r   r   rl  r  r  r  r   created_dater  r   r   r   r   r"  ry   r<  )r   rG  rs  notification_list_datanotificationrq  rf  r)  re   re   rm   r   X  sr   



	
zNotificationListView.getNrQ  re   re   re   rm   ri  T  r^  ri  c                   @   r*  )ExcelWriterz;
    View for user login (also used for registration).
    c              
   C   sb   d}zt ||}tdddtjdW S  ty0 } ztdt|dtjdW  Y d }~S d }~ww )N(bill_writer/navya_bill_template2new.xlsxr"   zPdf bill created successfullyr   r   r   )rV   r   r   r   r"  ry   r<  )r   rG  r  tempate_pathoutputr)  re   re   rm   rS    s   
zExcelWriter.postNr]  re   re   re   rm   rw    rR  rw  c                   @   r.  )DownloadBillc              
   C   s   |  }d}zGt|| tjd| d}tj|r*tt|dd| ddW S t|| tj|rCtt|dd| ddW S tddd	t	j
d
W S  tyk } ztdt|d	t	jd
W  Y d }~S d }~ww )Nrx  media/output/pdfz.pdfrbT)as_attachmentfilenamer   zFile Not Foundr   r   )r  rV   r  pathjoinr   rT   openr   r   r   r"  ry   r<  )r   rG  r  template_path	file_pathr)  re   re   rm   rS    s$   

zDownloadBill.postNrT  re   re   re   rm   r{    r&  r{  c                 C   sH   t | D ]}t j| |}t j|r!t | td|  qd S )Nz	Deleted: )r  listdirr  r  isfileremover#  r  )folder_pathr  r  re   re   rm   delete_all_files  s   
r  c                   @   r.  )DeleteBillsc              
   C   sd   zt d t d tdddtjdW S  ty1 } ztdt|dtjdW  Y d }~S d }~ww )Nr|  zmedia/output/excelr"   zFiles Deletedr   r   r   )r  r   r   r   r"  ry   r<  )r   rG  r)  re   re   rm   rS    s   zDeleteBills.postNrT  re   re   re   rm   r    r&  r  c                   @   r.  )BillPaymentAPIc                    s  |j dd }|jdd}|jdd }|jdd }|jdd }|r(d}	n9z-t|}
|
jj}td|  |d	v r@d
}	n|dkrGd}	n|dksO|dkrRd}	nd}	W n t	y`   d}	Y nw tdt
|j  |s|	dv r|tdddtjdS tjj|d }tjj|d }|rtj d| }ntj d}|jdkrd|_d|_|  |  t|dd|dddS t|tj  d d}tjj|d}tjj|d}g d!} d"d#krd$}d%}nd}d&} fd'd(|D }||d)< |jd5i | tj d*}|jd+v rtj d| }n<|jd,v r2 d"d#kr+tj d-}n'tj d}n |jdv rR|d$krGtd. dtj dS tdd/ d0tj!dS t||| d1d|d$krbd2nd3|d4S )6Ntransaction_responsez
User-Agentrb   r  r"  r  r  zDetected OS Platform: )r  r  r  r  r  r  r  r  r  r  zREQUEST HEADERS: r  r  r   zNo transaction data received.r   r   r  r?  z
web?token=checkoutr  r  r  zpayment_failure.html)r   checkout_urlr   orderid)bank_ref_nobankidcharge_amountr  itemcodepayment_categoryr  transaction_error_codetransaction_error_desctransaction_error_typetransactionidtxn_process_type	surcharger  r  successrY  zpayment_success.htmlzpayment_failed2.htmlc                    s   i | ]	}|  |d qS )rb   )r   )ri   fieldr   re   rm   r/  7  ro   z'BillPaymentAPI.post.<locals>.<dictcomp>r  zweb/)r  )r  r  zorder-confirmationr"   zTransaction Failed)r   r   detailsr  zPayment Successful!zPayment Failed!)r  r  r   r  re   )"r   r   r  GETr   r  r  r#  r  r"  dictr   r   r<  r2   rw   r   rx   r7   rP   domain2domain1r  r  r  r@  r   rW   decryptBILLDESK_ENCRYPTION_KEYupdater  r   r  )r   rG  r  r  r  r  r  r"  r  platform_typer  r  r  r  r  extract_fieldsr  templateupdate_datare   r  rm   rS    s   



zBillPaymentAPI.postNrT  re   re   re   rm   r    rU  r  c                   @   r.  )VerifyPaymentAPIViewBillDeskc              
   O   s  |j d}|stdddtjdS z*tjj|d}tjj|d}|j	 dkr6td	d
|j
dtjdW S d}tt ddd d }ttt }	dd||	d}
tj|j
d}tj|dd}t|tjtjtj}t|tjtjtj}tj||
|dd}z
t|j tj}W n t!y   i }Y nw |d}|dpd	 }|dv sd|v rd|_d|_"|#  |#  tdd|j
|dtjdW S |ddkrd |_d!|_"|#  |#  td	d"|j
|dtjdW S d|_d|_"|#  |#  d#}d$}d%|j
 d&}t$|j%j&||||j% t'|||j%j(gd' |j%j)r0t*j+|j%j,|j
|j%j-|gd(d) tdd*|j
|dtjdW S  tj.yR   tdd+dtj/d Y S  tj.yf   tdd,dtj/d Y S  t!y } ztdd-t|d.tj0dW  Y d }~S d }~ww )/Nr  r   zorder_id is requiredr   r   r  r?  rX  r"   zPayment already confirmed)r   r   r  z<https://uat1.billdesk.com/u2/payments/ve1_2/transactions/get-rb      zapplication/jose)zContent-TypeAcceptz
BD-TraceidzBD-Timestamp)mercidr  r  r  r5  )r  r   timeout
error_coder   )	TRNFE0001	TRIRE0012ztransaction not foundr  zJOrder ID not found in BillDesk server (payment not initiated or UI closed))r   r   r  trace_idauth_status0300rY  r  Payment successfulrt  ru  zYour payment for order z* could not be processed. Please try again.Fru   r]  zPayment failed or cancelledr>  Payment record not foundzUnexpected error occurredrx  )1r   r   r   r   r<  r2   rw   r7   r  rz  r  r   ry   r  uuid4r  r
  rn  rP   BILLDESK_MERCHANT_IDr9  r  rW   encrypt_jwe_billdeskr  BILLDESK_KEY_IDBILLDESK_CLIENT_IDsign_jws_billdeskBILLDESK_SIGNING_KEYr  rS  decrypt_jwe_billdesktextr"  r  r@  r   r  rK  r   r{  r|  r   r}  r   r   rD  r   r  )r   rG  r  r  r  r  r  r   r  	timestampr  payloadpayload_jsonencrypted_datasigned_encrypted_datar  decrypted_datar  error_messager  r  r  r)  re   re   rm   rS  d  s
  






z!VerifyPaymentAPIViewBillDesk.postNrT  re   re   re   rm   r  c  rU  r  c                    s  t j }|stddfS tt|}tt  |jtdkrN|jtdkrN||jkrN |jkr7tddfS |j  }|jtdtd}|j	d| dfS |j	}|j
}|j}||krf|| }|||  }n|}tjd}	d	}
d }|	D ]} |jkrt|jtd
 }|| }||8 }|} nqt fdd|	D }|r|d }|j  }|jtdtd}d| d|j d}
n|	 }|r|j d}
nd}
t|dS )NrY   rZ   r[   r\   r]   r_   r`   ra   rb   rc   c                    rd   re   rf   rh   rk   re   rm   rn   P  ro   z2calculate_dynamic_delivery_fee.<locals>.<listcomp>rp   rq   rr   rs   rt   ru   rv   )rl   r   rP   r   r}   r~   r   r   r   r   r   r   r   r   r   r   r   re   rk   rm   r   #  sT   






r   c                   @   r  )CheckoutAPIViewBillc                 C   r  r  r  r  re   re   rm   r  f  r  z,CheckoutAPIViewBill.generate_unique_order_idc           c      O   s   zn|j }|jd}z	tjj|d}W n tjy(   tddddd Y W S w |r.|js9tdddtj	dW S |j
d	d
}|jdd }|jdd}	|jdd
}
|jdd
}t|	trg|	 dk}	|j|	krv|	|_|jdgd |r|dkrd}n8|r|dkrd}n/t|}td|  |jj}td|  d}|dks|dks|dks|dkrd}nd}ztt|d}W n  ty } ztddt d tjdW  Y d }~W S d }~ww |jd!d}d }d }d }d }d
}d
}d }z9tt|d}|j}|rd"nd#}|sd$}|d$kr-|jd%}|jd&d
}|jd'd
}|r-|jd(}W n! tyO } ztdd)t d tjdW  Y d }~W S d }~ww |s|jd*}|sgtdd+dtjdW S ztt|d}W n! ty } ztdd,t d tjdW  Y d }~W S d }~ww tjjd-d.d/  }|j!}|j"}t#||} t$||}!|!d0 pd0}"|!d1 pd1}#|!d2 pd2}$| stdd3dddW S t%jj&|j' d4|j( |j)|j*|"|#|$t+| |j!|j"|j,|j-d5}|d#kr|jd6}%tt.|%d}|j/}z| 0 }&W n! t1y( } ztdd7t|d tjdW  Y d }~W S d }~ww zt2 }'|'3|d8}(|(jd9 })|(jd: }*|)d; }+|)d< },|)d= }-|)d> }.|)d? }/|)d@ }0|)dA }1|)dB }2|*dC }3|*dD }4|*dE }5|*dF }6|*dG }7|d"krt4|0t4|1 }0dH}1|d$kr|jdI}8|j5dJkr|8dKkr|4}9n|8dLkr|5}9n|8dKkr|6}9n|8dLkr|7}9t4|2t4|9 }0|9}1W n# t6t7fy } ztddMt|d tjdW  Y d }~W S d }~ww t89  zUt:jj&di dN|&dO|dPdQdR|dS|r|nd d'|d&|dT|dU|d@t;|0dVd<|,dW|1dX|+d>|.d?|/d=|-dYdZd[t<= d|d\|}:zt>jj?|d]  };|;rH|:|;_@|;  W n) tyr } ztdd^t|d tjdW  Y d }~W W  d    W S d }~ww z0|:jAd_v r~||:_Bn |:jAd$krtCjj&|:|3|8|jDd` tj  }<|<st1da|<|:_E|:  W n) ty } ztddbt|d tjdW  Y d }~W W  d    W S d }~ww ztFjj&|:dc}=|
|=_G||=_H|=  W n) ty	 } ztdddt|d tjdW  Y d }~W W  d    W S d }~ww zs|jIJ D ]k}>|>jK}?|>jLM rh|>jLJ D ]$}@tNjj&|?jOjP|:|?dJ|?jQde}AtRjj&|A|@jS|@jTr=|@jTnd |@jUdf q |>jLV }Bt+|>jW|B }C|CdkrftNjj&|?jOjP|:|?|C|?jQ|C de qtNjj&|?jOjP|:|?|>jW|?jQ|>jW de qW n) ty } ztddgt|d tjdW  Y d }~W W  d    W S d }~ww |j5dJkr>tXjj&|:dhd t|0didj dk|:_Y|:  |:jAd$krtZj[dl|:j\|:jBj]||:jAdm ntZj[dl|:j\|:jEj]||:jAdm dn}Ddo}Edp|:j^j' dq|:j\ dr}Ft_|:j^j`|:|E|F|:j^ ta|E|F|:j^jbgd |:j^jd.kr tcjd|:j^j-|:j\|:j^j'|DgdVds |:jBr-|:jBje}G|:jBjf}Hn|:jEjg}G|:jEjf}H|:jh}0|:jijD}Idt}J|:jjr|:jkrt.jj?|:jjdu  }K|Krt|:jktrbt<l|:jkdv}Ln|:jk}L|Lmdw}M|Kj/mdx}N|Kjnmdx}O|M dy|N dz|O }J|:jA}8|8d#krd{}8|:jor|:jo}P|Pjp d||Pjq d||Pjr d||Pjs d||Pjt dz|Pju }ndt}td}|:j\ d~|H d|G d|8 d|J 
 tvjd|H|G|:j\|:j^j'|:j^j-||0|I|8|Jg
dVds ztjj|d}td|  |w  W n tjy   td Y nw |:jAd$kr!tdJd|:j\|0|j5tx|:jddddW W  d    W S tdJd|:j\|0|j5ty|:jddddW W  d    W S |j5dVkr,tXjj&|:dhdt|0d d}Qd}R|:j\}S|0}Ttz|0d}Ud}V|j'pfd
}W|jbpld
}X|j-{dd
| dd  }Y|j}dd
}Zd }[|Z~dr|ZddJ | }[|[stj d}\tj d}]ntj d|[ }\tj d|[ }]d}Vdd|S d|Uddid}^tj|^dd}_|Q d|S d|U d|V d|W d|X d|R d|_ }`t|`d }at|adksJ |Q|S|U|V|Wpd
|Xpd
|Y|\|]|a|_|`d}b|r| dv r|R|bd< tdJdd|bdddW W  d    W S tdddW W  d    W S  tyc } ztddt|d tjdW  Y d }~W  d    W S d }~ww 1 shw   Y  W d S  ty } ztddt|d tjdW  Y d }~S d }~ww )Nr  r6  r   r  r   r   r   zUser not authenticated.r  rb   r  r|  Fadditional_infophone_nor`  ra  r  r  r  r  r  r  r  r  r  r  r  r  r   zFailed to fetch cart.rx  r  r  r  r  r  r  r  pickup_timezFailed to fetch user location.r  rc  rd  r   Tr   r  r  r  z&Pincode not available for this addressr  r  rl  zFailed to generate order ID.r  r   r   rl   r   r   r   r   r   r   r   r   r   r   r   r   r   longdistance_delivery_moder"   r   r   z Failed to fetch cart price data.r  r  r  r  r  r  r  r  ru   r  r  r  r  r  r  r   zFailed to update SomeOneElse.)r  r  )r  weight_gramsr  r  z0No production unit found for long distance orderz*Failed to assign store or production unit.r?  z"Failed to save additional details.r  )order_productr   r   r   z Failed to create order products.r  r   r  r  rh  ri  rZ  r[  r\  r  r  r]  r_  r`  rk  ra  rj  rb  rc  rd  re  z&Scheduling WhatsApp message for order ri  z
 for shop z with delivery mode z and delivery time r  r  r  r  rW  r  r  r  r  r  r  zNavya Bakers Order r  r  r  r  r  r  zNavya Bakers Orderr  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  zFailed to create order.rw  re   )r   r   r   r;   rw   rD  r   r=  r   rg  r  r   ry   rz  r|  r@  r   r#  r  r  r  r   r%   r"  r  r  r<  r?   r   r@   r   r   rx   r   r   r   r   r3   rE  r   r  r  r  r
  r  r   r/   r^  r  r&  rX   r  r   r   KeyErrorr%  rF   r  r2   r   rC   r?  r<   r   r  r  r  r+   r   r  r#   r  mobile_numberr   r   r   r   r   r4   r   r   r   r1   r   r   r   countr   r7   r  r   r  r  r  r  r   rK  r   r{  r   r}  rz  r{  r~  r   r  r  r  r  r  r  r  r   r  r  r  r  r   r   rC  rH   rK   r   r  r  r  r  r  rP   r  r9  r  r  r  r  r  rA  )cr   rG  r  r  r   r  r  r  r  r|  r  r  r  r  r  r   r)  r  r  rl  r  r  r  r  r  r  r  r  r  r  r   r   r  loc_detailsr  r  r  r  r  r  r  r   r   rl   r   r   r   r   r   r   r   r   cod_surface_delivery_feecod_express_delivery_feeonline_surface_delivery_feeonline_express_delivery_feer  longdistance_delivery_feer  rX  r  additional_infosr7  r   r
  r  customized_countremaining_qtyr  r  r  rd  r   r  r  r  r  r  r^  r  rj   r  r  r  r   r  r   r  r{  r  r!  r"  r  r  r#  r$  r  r%  r  re   re   rm   rS  n  s.  


 











	

"
3=


	



1t
 


*,	  l	  w	    h    k    k    qzCheckoutAPIViewBill.postNr  re   re   re   rm   r  d  r  r  )method_decoratordispatch)r   c                   @   r:  )PayUWebhookc                 C   s   |   }|dv rd}n|dv rd}|j}|d}tjj|d }|s.tddid	d
S t	jj|d }|sAtddid	d
S |dkrLd|_
d|_n|dkrWd|_
d|_n|dkr^d|_
|  |  tddid	d
S )N)
successfulr  sucessr  )failedfailurer  r  r  r$  r>  r  r   r?  zPayment not foundrY  r  r  ru  refundRefundedr   r  )rz  r  r   r   r2   rw   r   rx   r   r7   r  r  r@  )r   rG  eventr   r  r  r  re   re   rm   rS    s0   
zPayUWebhook.postNrS  re   re   re   rm   r    rV  r  c                   @   r:  )PayUPaymentResultAPIViewc                 O   s   |j }|d}|d}td| d|  tjj|d }|s+tddidd	S t	jj|d
 }|rO|dkrAd|_
d|_nd|_
d|_|  |  |jd}	|jpYd}
|
dv rlt|dkrednd|ddS t|d||
|	dS )Nr  r   zPayU Return | txnid=z
 | status=r  r$  r>    r   r?  r  rY  r  r  ru  r"  r  r  r"   r   zPayment processed)r   r  r   zpayment_processing.html)r  r  r"  )r   r   r#  r  r2   rw   r   rx   r   r7   r  r  r@  r  r  r   )r   rG  r  r  r   r  payu_statusr  r  r"  r  re   re   rm   rS    s:   


zPayUPaymentResultAPIView.postNrS  re   re   re   rm   r    s    r  c                   @   r:  )OrderPaymentStatusAPIViewc                 C   sX   t jj|d }|stddiddS tjj|d }|s$tddiS t||jd	S )
Nr  r$  r>  r  r   r?  r  Pending)r  r  )r2   rw   r   rx   r   r7   r  )r   rG  r  r  r  re   re   rm   r   n  s   zOrderPaymentStatusAPIView.getN)r+  r,  r-  rT  rU  r   re   re   re   rm   r  k  s    r  z0https://test.payu.in/merchant/postservice?form=2r  r  c                   @   r*  )VerifyPayUPaymentAPIViewz8
    Verify PayU payment and update DB immediately.
    c              
   C   s  |j d}|stdddtjdS ztjj|d}tjj|d}W n' tjy6   tdddtj	d Y S  tjyI   tdd	dtj	d Y S w |j
d
kr[tdd|jdtjdS zHt d| dt }t|  }td||d}tjt|dd}|  | }	td| d|	  |	di |}
|
stdd|jdddtjdW S |
d}|
dpd }|
dpd}|d kr|d!krt - d"|_
d#|_||_|
d$|_|j g d%d& d'|_||_!|j d(d)gd& W d    n1 sw   Y  tdd"d'd*ddd+tjdW S |d,krat / d
|_
|
d-|_"|
d.|_#|
d/|_$|j g d0d& d1|_|j d(gd& W d    n	1 sOw   Y  tdd
d1d2d3tjdW S t ) d"|_
|
d4|_|
d$|_|j g d5d& d6|_|j d(gd& W d    n	1 sw   Y  tdd"d6d7ddtjdW S  t%y } zt&d8 tdd9t'|d:tj(dW  Y d }~S d }~ww );Nr  r   ztxnid is requiredr   r   r  r?  r>  r  rX  r"   zPayment already successful)r   r   r  z|verify_payment|r  verify_payment)rs  commandvar1r     )r   r  z[PayU VERIFY] txnid=z
 response=transaction_detailsr  z"Payment not initiated or abandonedT)r   r  r  r   	can_retryr   unmappedstatusrb   field9zPayment cancelled by userr  usercancelledr  userCancelledr  )r  r  r  r  ra  	Cancelledr  r   USER_CANCELLED)r   r  r  failure_reasonr   r  r  mihpayidbank_ref_numamt)r  r  r  r  r  r  )r   r  r  r   error_Message)r  r  r  r  zPayment failedz[PayU VERIFY] Unexpected errorzFailed to verify PayU paymentr  ))r   r   r   r   r<  r2   rw   r7   rD  r   r  r  r   r  r  r  r  r  r  r  rS  PAYU_VERIFY_URLraise_for_statusr9  r#  r  rz  rF   r  r  r  r  r@  r   r  r  r  r"  ry  ry   r  )r   rG  r  r  r  r  
hash_valuer  r  r   tx_datar  unmapped
cancel_msgr)  re   re   rm   rS    s  


		






zVerifyPayUPaymentAPIView.postNr]  re   re   re   rm   r    rR  r  c                 C   s   t jj|d }|jdkrt| dddiS |j}d}|r*|j d|jp%d 	 }d}t
jj|d }|rB|j d	|jp?d }|j|j||d
}t| d|S )Nr  r@  zdelivery_error.htmlr$  zOrder already deliveredrb   r  r   re  )r<  r  customer_namer  zdelivery_confirm.html)r2   rw   r   rx   r  r   r  r   r  r  r@   r  r  r  r  )rG  r<  r  r   r  r  customer_addressrs  re   re   rm   delivery_confirm_page?  s&   
r  c                 C   
   t | dS )Nzdelivery_success.htmlr   rG  re   re   rm   delivery_successb     
r	  c                 C   r  )Nzdelivery_failed.htmlr  r  re   re   rm   delivery_failede  r
  r  r*  )r  rn  r  urllib.parser   r  r  r#  adminportal.tasksr   r   r   adminportal.viewsr   r   orders.delhiveryr   r	   r
   r   r   r   django.utils.timezoner   user_agentsr   r9  decimalr   r   rest_framework.viewsr   rest_framework.responser   rest_frameworkr   django.shortcutsr   r   r   shops.modelsr   r   orders.signals.custom_signalsr   products.modelsr   r   r   r   r    r!   modelsr#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   accounts.modelsr?   r@   rA   rB   rC   rD   django.utilsrE   	django.dbrF   serializersrG   rH   rI   rJ   rK   rL   rM   rN   products.serializersrO   r  r  r  r  django.confrP   django.viewsrQ   django.views.decorators.csrfrR   django.db.modelsrS   django.httprT   rU   r  bill_writer.BillWriterrV   rb   rW   rX   r/  rV  rY  r[  r_  r`  r  r  r  r  r  r;  rW  r  r  r  r  r  r  r'  r+  rS  r_  ri  rw  r{  r  r  r  r  r   r  django.utils.decoratorsr  r  r  r  r  r  r  r  r  r	  r  re   re   re   rm   <module>   s      x(-  h K H s U T  
 #  :t xD      
AA    6
# 0 @#