o
    	èFhT ã                   @   s:  d dl 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 d dlmZmZ d dlmZ d dlmZ d	d
lT d	d
lT 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  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,T d dl-Z-d dl.Z.d dl/m0Z0 G dd„ dej1ƒZ2G dd„ dej3ƒZ4G dd„ de	ƒZ5G dd„ de	ƒZ6G d d!„ d!e	ƒZ7G d"d#„ d#e	ƒZ8G d$d%„ d%e	ƒZ9G d&d'„ d'e	ƒZ:G d(d)„ d)e	ƒZ;G d*d+„ d+e	ƒZ<G d,d-„ d-e	ƒZ=G d.d/„ d/e	ƒZ>G d0d1„ d1e	ƒZ?G d2d3„ d3e	ƒZ@G d4d5„ d5e	ƒZAG d6d7„ d7e	ƒZBG d8d9„ d9e	ƒZCG d:d;„ d;e	ƒZDG d<d=„ d=e	ƒZEG d>d?„ d?e	ƒZFG d@dA„ dAejGƒZHG dBdC„ dCe	ƒZIG dDdE„ dEe	ƒZJG dFdG„ dGe	ƒZKG dHdI„ dIe	ƒZLG dJdK„ dKe	ƒZMG dLdM„ dMe	ƒZNG dNdO„ dOe	ƒZOG dPdQ„ dQe	ƒZPG dRdS„ dSe	ƒZQG dTdU„ dUe	ƒZRG dVdW„ dWe	ƒZSdS )Xé    )ÚDecimalÚROUND_UP)ÚgenericsÚpermissions)ÚJWTAuthentication)ÚAPIView)ÚTokenAuthentication)ÚIsAuthenticatedÚIsAdminUser)ÚResponse©Ústatusé   )Ú*)Úgeodesic)ÚVehicleTypeÚVehicleÚVehicleAssignment)ÚDriverLocationÚDevice)ÚVehicleTypeSerializer)ÚValidationError)ÚDistance)ÚD)Úfromstr)ÚPoint)Útimezone)Ú	timedeltaN)Útransactionc                   @   ó(   e Zd Zej ¡ ZeZe	gZ
ejgZdS )ÚLocationListCreateAPIViewN©Ú__name__Ú
__module__Ú__qualname__ÚLocationÚobjectsÚallÚquerysetÚLocationSerializerÚserializer_classr   Úauthentication_classesr   r	   Úpermission_classes© r-   r-   ú#/var/www/html/loop/booking/views.pyr       ó
    
r    c                   @   r   )Ú$LocationRetrieveUpdateDestroyAPIViewNr!   r-   r-   r-   r.   r0   #   r/   r0   c                   @   ó$   e Zd ZdZegZegZdd„ ZdS )ÚNearbyLocationsViewz_
    View to get a list of locations within a 30 km radius of the user's current location.
    c           
      C   s¶   |j  d¡}|j  d¡}|d u s|d u rtdddœtjd�S t|ƒ}t|ƒ}||f}g }tj ¡ D ]}|j	|j
f}t||ƒj}|dkrH| |¡ q1t|dd	�}	td
d|	j dœtjd�S )NÚlatitudeÚ	longituder   ú$Latitude and longitude are required.©r   Úmessager   é   T©Úmanyr   z(Nearby locations retrieved successfully.©r   r7   Údata)r<   Úgetr   r   ÚHTTP_400_BAD_REQUESTÚfloatr%   r&   r'   r3   r4   r   Ú
kilometersÚappendr)   ÚHTTP_200_OK)
ÚselfÚrequestÚuser_latitudeÚuser_longitudeÚuser_locationÚnearby_locationsÚlocationÚlocation_coordsÚdistanceÚ
serializerr-   r-   r.   r=   2   s2   þ
€ýúzNearbyLocationsView.getN)	r"   r#   r$   Ú__doc__r   r+   r	   r,   r=   r-   r-   r-   r.   r2   *   ó
    r2   c                   @   ó    e Zd ZegZegZdd„ ZdS )ÚAvailableVehicleTypesViewc              
   C   s"  |j  d¡}|j  d¡}|j  d¡}|r|r|s"tdddœtjd�S z|d }|d	 }|d }|d	 }W n ttfyI   tdd
dœtjd� Y S w z	tj 	|d¡}W n t
yf   tdddœtjd� Y S w z	t||||ƒ}	W n tyŽ }
 ztdt|
ƒdœtjd�W  Y d }
~
S d }
~
ww td|› d|› d�dd�}t ¡ tdd� }||  kr´|tdd� krÙn n#tjjtd|ƒd� d¡d d… }tjjddd„ |D ƒddd� ¡ }ntj ¡  ¡ }g }|D ]!}|	|j }|jtdƒtd�}| |j|j |j!|jt"|ƒd œ¡ qätd!d"|d#œtj#d�S )$NÚfrom_addressÚ
to_addressÚ	ride_timer   z=From address, to address, and ride time details are required.r6   r   r3   r4   ú[Invalid address format. Latitude and longitude are required for both from and to addresses.ú%Y-%m-%dT%H:%M:%S%zzDInvalid ride time format. Use ISO format: YYYY-MM-DDTHH:MM:SS+HH:MM.úPOINT(Ú ú)éæ  ©Úsridé   ©Úminutesé   Úlast_known_location)rK   rK   é   Tc                 S   s   g | ]}|j ‘qS r-   ©Údriver)Ú.0rc   r-   r-   r.   Ú
<listcomp>™   s    ÿz2AvailableVehicleTypesView.post.<locals>.<listcomp>F)Úvehicle__statusÚ vehicle__assignments__driver__inÚvehicle__assignments__activeÚvehicle__assignments__on_rideú0.01©Úrounding)ÚidÚvehicle_typeÚseating_capacityÚper_km_chargeÚestimated_farer   zDAvailable vehicle types with estimated fares retrieved successfully.r;   )$r<   r=   r   r   r>   Ú	TypeErrorÚKeyErrorr   ÚdatetimeÚstrptimeÚ
ValueErrorÚcalculate_distancer   Ústrr   Únowr   r   r&   Úannotater   Úorder_byr   ÚfilterÚdistinctr'   rp   Úquantizer   r   rA   rm   rn   ro   r?   rB   )rC   rD   rQ   rR   rS   Úfrom_latitudeÚfrom_longitudeÚto_latitudeÚto_longituderK   ÚeÚ
from_pointÚadjusted_current_timeÚnearest_driversÚavailable_vehicle_typesÚvehicle_types_with_faresrn   rq   Úrounded_farer-   r-   r.   Úpost^   s¬   þûþ
ûÿþ
ûÿÿþ€ÿÿ
þÿþÿúù	
ûÿ
ýúzAvailableVehicleTypesView.postN©r"   r#   r$   r   r+   r	   r,   rŠ   r-   r-   r-   r.   rP   Z   ó    rP   c                   @   rO   )ÚFareEstimationViewc              
   C   s¾  t dƒ |j d¡}|j d¡}|j d¡}|j d¡}|r$|r$|r$|s2t dƒ tddd	œtjd
�S zt dƒ |d }|d }|d }|d }	W n ttfya   t dƒ tddd	œtjd
� Y S w zt dƒ t||||	ƒ}
W n" t	y‘ } zt dƒ tdt
|ƒd	œtjd
�W  Y d }~S d }~ww zt dƒ tjj|d�}W n tjy·   t dƒ tddd	œtjd
� Y S w t dƒ |
|j }|jtdƒtd�}t dƒ tddd|j|
t|ƒdœtjd
�S )NzStep 1: Retrieving request dataÚvehicle_type_idrQ   rR   rS   z0Step 2: Checking if all required data is presentr   z6Vehicle type, address details, ride time are required.r6   r   z6Step 3: Extracting latitude and longitude from addressr3   r4   z'Step 4: Handling invalid address formatrT   zStep 5: Calculating distancez!Step 6: Handling validation errorzStep 7: Retrieving vehicle type©rm   z-Step 8: Handling vehicle type not found errorúVehicle type not found.z"Step 9: Calculating estimated farerj   rk   zStep 13: Returning responser   ú'Estimated fare calculated successfully.Ú20)r   r7   Ú	base_fareÚrate_per_kmÚtotal_kmrq   )Úprintr<   r=   r   r   r>   rr   rs   rw   r   rx   r   r&   ÚDoesNotExistÚHTTP_404_NOT_FOUNDrp   r~   r   r   r?   rB   )rC   rD   rŽ   rQ   rR   rS   r   r€   r�   r‚   rK   rƒ   rn   rq   r‰   r-   r-   r.   rŠ   ½   s‚   þûþ
ûþ
ÿþ€þ
þþ
ú÷zFareEstimationView.postNr‹   r-   r-   r-   r.   r�   ¹   rŒ   r�   c                   @   rO   )ÚConfirmRideViewc                 C   s  |j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}t|||||gƒs=tdd	d
œtjd�S tjj|j	d|id�\}	}
t
jj|j	|	|td|d › d|d › d�dd�td|d › d|d › d�dd�||tj |d¡dd�	}tt|ƒ tdd|jdœtjd�S )NrŽ   Úpickup_nameÚdropoff_nameÚpickup_locationÚdropoff_locationrS   Údevice_tokenr   zeAll fields  vehicle_type_id, pickup_location, dropoff_location, ride_time, device_token are required.r6   r   ©ÚuserÚdefaultsrV   r4   rW   r3   rX   rY   rZ   rU   Úpending)	r    Úuser_devicerŽ   rœ   r�   rš   r›   rS   r   r   zRide confirmed successfully.)r   r7   Úride_id)r<   r=   r'   r   r   r>   r   r&   Úget_or_creater    ÚRideÚcreater   r   rt   ru   Úsetup_async_tasksÚprocess_new_riderm   rB   )rC   rD   rŽ   rš   r›   rœ   r�   rS   rž   r£   Ú_Únew_rider-   r-   r.   rŠ   	  sb   ûÿ	þû

ÿþþñ
ýúzConfirmRideView.postNr‹   r-   r-   r-   r.   r™     rŒ   r™   c                   @   rO   )ÚDriverRideDetailViewc                 C   s´   z	t jj|d�}W n t jy   tdddœtjd� Y S w tdd|jj› d|jj	› �|j
|j|jj|jjd	œ|jj|jjd	œ|jrGt|jƒnd |jrPt|jƒnd d
œdœtjd�S )Nr�   r   úRide not found.r6   r   r   ú$Ride details retrieved successfully.rW   ©r3   r4   )Ú	user_namerš   r›   Úpickup_coordinatesÚdropoff_coordinatesrK   rq   ©r   r7   Úride_details)r¦   r&   r=   r—   r   r   r˜   r    Ú
first_nameÚ	last_namerš   r›   rœ   ÚyÚxr�   rK   r?   rq   rB   )rC   rD   r¤   Úrider-   r-   r.   r=   J  s4   
þÿþþòýêzDriverRideDetailView.getN©r"   r#   r$   r   r+   r	   r,   r=   r-   r-   r-   r.   r¬   F  rŒ   r¬   c                   @   rO   )ÚUpdateDriverLocationViewc                 C   s¢   |j  d¡}|j  d¡}|d u s|d u rtdddœtjd�S ztjj|jdt	t
|ƒt
|ƒƒid�\}}td	d
dœtjd�W S  tyP   tdddœtjd� Y S w )Nr3   r4   Úerrorr5   r6   r   r`   )rc   r¡   ÚsuccesszLocation updated successfully.zInvalid latitude or longitude.)r<   r=   r   r   r>   r   r&   Úupdate_or_creater    r   r?   rB   rv   )rC   rD   r3   r4   Údriver_locationÚcreatedr-   r-   r.   rŠ   q  s.   þÿ
þþ
þÿzUpdateDriverLocationView.postNr‹   r-   r-   r-   r.   r»   m  rŒ   r»   c                   @   rO   )ÚAcceptRideViewc                 C   sè   |j }|jstdddœtjd�S zEtjj|d�}tjj	|dd� 
¡ }|rId|_||_|j|_| ¡  d|_| ¡  tjj||dd	� t|j |ƒ ntdd
dœtjd�W S W n tjyi   tdddœtjd� Y S w tdddœtjd�S )Nr   zOnly drivers can accept rides.r6   r   r�   T)rc   ÚactiveÚaccepted)r¹   rc   Úresponsez.No active vehicle assignment found for driver.ú,Ride request not found or already processed.r   zRide accepted successfully.)r    Ú	is_driverr   r   ÚHTTP_403_FORBIDDENr¦   r&   r=   r   r|   Úfirstrc   ÚvehicleÚsaveÚon_rideÚDriverResponseLogr§   Únotify_user_ride_acceptedr>   r—   r˜   rB   ©rC   rD   r¤   rc   r¹   Úvehicle_assignmentr-   r-   r.   rŠ   ’  sZ   þÿþýþûþ
þ
ûÿ	þzAcceptRideView.postNr‹   r-   r-   r-   r.   rÁ   Ž  rŒ   rÁ   c                   @   rO   )ÚRejectRideViewc                 C   sž   |j }|j d¡}|jstdddœtjd�S ztjj|d�}d|_| 	¡  t
jj||d|d� W n tjyD   tdd	dœtjd� Y S w td
ddœtjd�S )NÚreasonr   zOnly drivers can reject rides.r6   r   r�   Úrejected)r¹   rc   rÄ   rÑ   rÅ   r   zRide rejected successfully.)r    r<   r=   rÆ   r   r   rÇ   r¦   r&   rÊ   rÌ   r§   r—   r˜   rB   )rC   rD   r¤   rc   rÑ   r¹   r-   r-   r.   rŠ   Ê  s4   þ
ÿþ
ûÿ	þzRejectRideView.postNr‹   r-   r-   r-   r.   rÐ   Æ  rŒ   rÐ   c                   @   rO   )ÚDriverLocationViewc                 C   s    |j }z%tjj||dgd�}tjj|jd�}tdd|jj|jj	dœdœt
jd�W S  tjy<   td	d
dœt
jd� Y S  tjyO   td	ddœt
jd� Y S w )NrÃ   )rm   r    Ú
status__inrb   r   z'Driver location retrieved successfully.r¯   )r   r7   r¿   r   r   zRide not found or not active.r6   zDriver location not available.)r    r¦   r&   r=   r   rc   r   r`   r·   r¸   r   rB   r—   r˜   )rC   rD   r¤   r    r¹   r¿   r-   r-   r.   r=   ï  s0   þý÷
þ
þÿzDriverLocationView.getNrº   r-   r-   r-   r.   rÓ   ë  rŒ   rÓ   c                   @   rO   )ÚStartRideViewc                 C   sÈ   |j  d¡}|j}|stdddœtjd�S z:tjj||dd�}t|j	ƒt|ƒkrEt
 ¡ |_d|_| ¡  t|j|ƒ td	d
dœtjd�W S tdddœtjd�W S  tjyc   tdddœtjd� Y S w )NÚotpr   z"OTP is required to start the ride.r6   r   rÃ   ©rm   rc   r   Ústartedr   zRide started successfully.zInvalid OTP.z&Ride not found or already in progress.)r<   r=   r    r   r   r>   r¦   r&   rx   rÖ   r   ry   Ú
start_timerÊ   Únotify_user_ride_startedrB   r—   r˜   )rC   rD   r¤   rÖ   rc   r¹   r-   r-   r.   rŠ     s8   þ
þþ
þÿzStartRideView.postNr‹   r-   r-   r-   r.   rÕ     rŒ   rÕ   c                   @   rO   )ÚEndRideViewc                 C   s˜   |j }z4tjj||dd�}d|_t ¡ |_| ¡  t	|j |ƒ t
jj|d�}d|_| ¡  tdddœtjd	�W S  tjyK   td
ddœtjd	� Y S w )NÚin_progressr×   Ú	completedrb   Fr   zRide completed successfully.r6   r   r   z"Ride not found or not in progress.)r    r¦   r&   r=   r   r   ry   Úend_timerÊ   Únotify_user_ride_finishedr   rË   r   rB   r—   r˜   rÎ   r-   r-   r.   rŠ   5  s(   
þ
þÿzEndRideView.postNr‹   r-   r-   r-   r.   rÛ   1  rŒ   rÛ   c                   @   rO   )ÚRideDetailViewc              	   C   st   |j }z"tjj||d�}tdd|jj|jj|jj	|j
|jdœdœtjd�W S  tjy9   tddd	œtjd� Y S w )
N)rm   r    r   r®   )rn   rÉ   Údriver_namerÖ   r   r³   r   r   r­   r6   )r    r¦   r&   r=   r   rn   rÉ   Úplate_numberrc   rµ   rÖ   r   rB   r—   r˜   )rC   rD   r¤   r    r¹   r-   r-   r.   r=   P  s*   ûýô
þÿzRideDetailView.getNrº   r-   r-   r-   r.   rà   L  rŒ   rà   c                   @   rO   )ÚDriverApproachingViewc                 C   ó€   |j }|jstdddœtjd�S ztjj||dd�}t|j |ƒ W n tj	y5   tdddœtj
d� Y S w tdd	dœtjd�S )
Nr   z0Only drivers can send approaching notifications.r6   r   rÃ   r×   ú+Ride not found or not in an accepted state.r   z2Driver approaching notification sent successfully.)r    rÆ   r   r   rÇ   r¦   r&   r=   Únotify_user_driver_reachingr—   r˜   rB   ©rC   rD   r¤   rc   r¹   r-   r-   r.   rŠ   n  s.   þû
þÿþûzDriverApproachingView.postNr‹   r-   r-   r-   r.   rã   j  rŒ   rã   c                   @   rO   )ÚDriverArrivedViewc                 C   rä   )
Nr   z,Only drivers can send arrived notifications.r6   r   rÃ   r×   rå   r   z.Driver arrived notification sent successfully.)r    rÆ   r   r   rÇ   r¦   r&   r=   Únotify_user_driver_arrivedr—   r˜   rB   rç   r-   r-   r.   rŠ   �  s*   þû
þÿþzDriverArrivedView.postNr‹   r-   r-   r-   r.   rè   Œ  rŒ   rè   c                   @   r1   )ÚRideListViewz5
    View to list users with optional filtering.
    c              
   C   sx   z|j }tjjd
i |¤Ž}t|dd�}tdd|j dœtjd�W S  ty; } ztddd	œtj	d�W  Y d }~S d }~ww )NTr9   r   zRides retrieved successfullyr;   r   r   zAn unexpected error occurredr6   r-   )
r<   r¦   r&   r|   ÚRideSerializerr   r   rB   Ú	ExceptionÚHTTP_500_INTERNAL_SERVER_ERROR)rC   rD   Úfilter_paramsÚridesrL   rƒ   r-   r-   r.   rŠ   ³  s$   ýúþ€ÿzRideListView.postN©	r"   r#   r$   rM   r   r+   r
   r,   rŠ   r-   r-   r-   r.   rê   «  rN   rê   c                   @   rO   )ÚCreateSharedRideViewc                 C   sŒ  |j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}	t||||||	gƒsDtd	d
dœtjd�S t|	ƒd	krTtd	ddœtjd�S z	tjj|d�}
W n tj	yq   td	ddœtj
d� Y S w tjj|jd|id�\}}tjj|j|
td|d › d|d › d�dd�td|d › d|d › d�dd�tj |d¡|
jt|	ƒt|	ƒd|||d�}tdd|jdœtjd�S )NrŽ   rš   r›   rœ   r�   rS   rž   Úseats_requiredr   zuAll fields are required: vehicle_type_id, pickup_location, dropoff_location, ride_time, device_token, seats_required.r6   r   ú7The number of seats required must be greater than zero.r�   zInvalid vehicle type ID.rŸ   rV   r4   rW   r3   rX   rY   rZ   rU   r¢   )Úprimary_userrn   Úprimary_pickup_locationÚprimary_dropoff_locationrS   Úseats_totalÚseats_occupiedrò   r   r£   rš   r›   r   z!Shared ride created successfully.©r   r7   Úshared_ride_id)r<   r=   r'   r   r   r>   Úintr   r&   r—   r˜   r   r¥   r    Ú
SharedRider§   r   r   rt   ru   ro   rm   ÚHTTP_201_CREATED)rC   rD   rŽ   rš   r›   rœ   r�   rS   rž   rò   rn   r£   rª   Úshared_rider-   r-   r.   rŠ   Ë  sˆ   úÿ
þûþû	
þÿ

ÿþþîýúzCreateSharedRideView.postNr‹   r-   r-   r-   r.   rñ   Ç  rŒ   rñ   c                   @   rO   )ÚListAvailableSharedRidesViewc                 C   s:  |j  d¡}|j  d¡}|j  d¡}t|||gƒs#tdddœtjd�S tt|d ƒt|d	 ƒd
d�}tt|d ƒt|d	 ƒd
d�}tj	 
|d¡}|tjdd� }|tjdd� }	tjj||	f|tdd�f|tdd�fdd�}
g }|
D ]}| |j|jj|jj|j|j|j |j|j|j ¡ dœ¡ qrtdd|dœtjd�S )Nrœ   r�   rS   r   zFAll fields are required: pickup_location, dropoff_location, ride_time.r6   r   r4   r3   rY   rZ   rU   r8   r]   g      à?)Úkmr¢   )Úride_time__rangeÚ%primary_pickup_location__distance_lteÚ&primary_dropoff_location__distance_lter   )rú   rn   rŽ   rø   Úseats_remainingrš   r›   rS   r   z+Available shared rides listed successfully.)r   r7   rï   )r<   r=   r'   r   r   r>   r   r?   r   rt   ru   r   rü   r&   r|   r   rA   rm   rn   rø   r÷   rš   r›   rS   Ú	isoformatrB   )rC   rD   rœ   r�   rS   Úuser_pickup_pointÚuser_dropoff_pointÚuser_ride_timeÚtime_window_startÚtime_window_endÚavailable_ridesÚ
rides_listr¹   r-   r-   r.   rŠ   #  sb   þû	

ý

ýü
øÿýúz!ListAvailableSharedRidesView.postNr‹   r-   r-   r-   r.   rÿ     rŒ   rÿ   c                   @   rO   )ÚJoinSharedRideViewc                 C   s:  |j  d¡}|j  d¡}|j  d¡}t|||gƒs#tdddœtjd�S t|ƒdkr3tdddœtjd�S z
tjj|d	d
�}W n tj	yQ   tdddœtj
d� Y S w |jt|ƒ |jkrftdddœtjd�S tjj|jd|id�\}}tjj||j|j|jt|ƒ|d� | jt|ƒ7  _| ¡  tdd|jdœtjd�S )Nrú   rž   rò   r   zFAll fields are required: shared_ride_id, device_token, seats_required.r6   r   ró   r¢   ©rm   r   z'Shared ride not found or not available.zNot enough seats available.rŸ   )rþ   Úparticipant_userrœ   r�   rò   rž   r   z$Successfully joined the shared ride.rù   )r<   r=   r'   r   r   r>   rû   rü   r&   r—   r˜   rø   r÷   r   r¥   r    ÚSharedRideParticipantr§   rõ   rö   rÊ   rm   rB   )rC   rD   rú   rž   rò   rþ   r£   rª   r-   r-   r.   rŠ   i  sd   þû	þû	
þÿþ

ÿú
ýúzJoinSharedRideView.postNr‹   r-   r-   r-   r.   r  e  rŒ   r  c                   @   s4   e Zd ZdZegZegZdd„ Zdd„ Z	dd„ Z
dS )	ÚSharedRideListViewz<
    View to list shared rides with optional filtering.
    c                 C   s
   t j ¡ S ©N)rü   r&   r'   ©rC   r-   r-   r.   Úget_queryset·  s   
zSharedRideListView.get_querysetc                 C   s6   g }|D ]}|dd„ |j  ¡ D ƒdœ}| |¡ q|S )Nc                 S   s0   g | ]}||j |j|j|j|j|j|jd œ‘qS ))Úparticipantrž   rœ   r�   rš   r›   rò   Ú	joined_at)rž   rœ   r�   rš   r›   rò   r  )rd   r  r-   r-   r.   re   ¿  s    ÷øÿz7SharedRideListView.perform_queryset.<locals>.<listcomp>)r¹   Úparticipants)r  r'   rA   )rC   r(   Úcombined_datar¹   Ú	ride_datar-   r-   r.   Úperform_querysetº  s   õþz#SharedRideListView.perform_querysetc                 C   s   t S r  )ÚSharedRideSerializerr  r-   r-   r.   Úget_serializer_classÐ  s   z'SharedRideListView.get_serializer_classN)r"   r#   r$   rM   r   r+   r
   r,   r  r  r  r-   r-   r-   r.   r  ¯  s    r  c                   @   r1   )ÚRouteCreateViewz4
    View to add a new route and its sequences.
    c              
   C   sp  z–|j  d¡}|j  d¡}|j  d¡}tjj|d |d |d dœd�\}}tjj|d |d |d dœd�\}}g }|D ]"}	|	 d	¡}
tjj|	d |	d |	d dœd�\}}| ||
d
œ¡ q=tjj|j  d¡|j  d¡||d�}t|dd„ d�D ]}t	jj||d |d	 d� qzt
|ƒ}t|j tjd�W S  ty· } ztdt|ƒt ¡ dœtjd�W  Y d }~S d }~ww )NÚpickup_pointÚdropoff_pointÚintermediate_pointsÚnamer3   r4   r¯   ©r!  r¡   Úorder©Úpointr#  Údescription)r!  r&  r  r  c                 S   ó   | d S ©Nr#  r-   ©r¸   r-   r-   r.   Ú<lambda>	  ó    z&RouteCreateView.post.<locals>.<lambda>©Úkeyr%  ©Úrouter%  r#  r   r   ©r   r7   Út)r<   r=   Ú
RoutePointr&   r¾   rA   ÚRouter§   ÚsortedÚSequenceÚRouteSerializerr   r   rý   rì   rx   Ú	tracebackÚ
format_excr>   )rC   rD   Úpickup_point_dataÚdropoff_point_dataÚintermediate_points_datar  rÀ   r  r   Ú
point_datar#  r%  r/  Úsequence_datarL   rƒ   r-   r-   r.   rŠ   Ü  s^   þ
þþ
þ	
þ
þ

üýþ€ÿzRouteCreateView.postNrð   r-   r-   r-   r.   r  Ô  rN   r  c                   @   r1   )ÚRouteUpdateViewz=
    View to update an existing route and its sequences.
    c              
   C   sÒ  z´t jj|d�}|j d¡}|j d¡}|j d¡}|r2tjj|d |d |d dœd	�\}}||_|rJtjj|d |d |d dœd	�\}	}|	|_|r’g }
|D ]"}| d
¡}tjj|d |d |d dœd	�\}}|
 ||dœ¡ qP|j	 
¡  ¡  t|
dd„ d�D ]}tjj||d |d
 d� q‚|j d|j¡|_|j d|j¡|_| ¡  t|ƒ}t|jtjd�W S  t jyÈ   tdddœtjd� Y S  tyè } ztdt|ƒt ¡ dœtjd�W  Y d }~S d }~ww )Nr�   r  r  r   r!  r3   r4   r¯   r"  r#  r$  c                 S   r'  r(  r-   r)  r-   r-   r.   r*  V  r+  z%RouteUpdateView.put.<locals>.<lambda>r,  r%  r.  r&  r   r   úRoute not foundr6   r0  )r3  r&   r=   r<   r2  r¾   r  r  rA   Ú	sequencesr'   Údeleter4  r5  r§   r!  r&  rÊ   r6  r   r   rB   r—   r˜   rì   rx   r7  r8  r>   )rC   rD   Úroute_idr/  r9  r:  r;  r  rÀ   r  r   r<  r#  r%  r=  rL   rƒ   r-   r-   r.   Úput#  st   þ
þþ
þ
þ
þ
ÿý
þþ€ÿzRouteUpdateView.putN)	r"   r#   r$   rM   r   r+   r
   r,   rC  r-   r-   r-   r.   r>    rN   r>  c                   @   r1   )ÚRouteListViewz"
    View to list all routes.
    c              
   C   óf   zt j ¡ }t|dd�}t|jtjd�W S  ty2 } ztdt	|ƒdœtj
d�W  Y d }~S d }~ww ©NTr9   r   r   r6   )r3  r&   r'   r6  r   r<   r   rB   rì   rx   r>   )rC   rD   ÚroutesrL   rƒ   r-   r-   r.   r=   |  s   
ÿ€ÿzRouteListView.getN)	r"   r#   r$   rM   r   r+   r
   r,   r=   r-   r-   r-   r.   rD  t  rN   rD  c                   @   r1   )ÚRouteDeleteViewz!
    View to delete a route.
    c              
   C   sŽ   zt jj|d�}| ¡  tdditjd�W S  t jy)   tdddœtjd� Y S  t	yF } ztdt
|ƒdœtjd�W  Y d }~S d }~ww )Nr�   r   zRoute deleted successfullyr   r   r?  r6   )r3  r&   r=   rA  r   r   ÚHTTP_204_NO_CONTENTr—   r˜   rì   rx   r>   )rC   rD   rB  r/  rƒ   r-   r-   r.   rA  •  s$   þ
þÿ€ÿzRouteDeleteView.deleteN)	r"   r#   r$   rM   r   r+   r
   r,   rA  r-   r-   r-   r.   rH  �  rN   rH  c                   @   rO   )ÚScheduledRideMasterCreateViewc              
   C   sr  zt|j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}t||||||gƒs:tddd	œtjd
�W S tjj|d�}tjj|d�}	t	 
¡ � tjj|||||	|d�}
W d   ƒ n1 scw   Y  t|
ƒ}t|j tjd
�W S  tjyˆ   tddd	œtjd
� Y S  tjy›   tddd	œtjd
� Y S  ty¸ } ztdt|ƒd	œtjd
�W  Y d }~S d }~ww )Nr!  Ústarting_timeÚending_timer/  rÉ   r   r   úAll fields are required.r6   r   r�   )r!  rK  rL  r/  rÉ   r   úRoute not found.úVehicle not found.)r<   r=   r'   r   r   r>   r3  r&   r   r   ÚatomicÚScheduledRideMasterr§   ÚScheduledRideMasterSerializerrý   r—   r˜   rì   rx   )rC   rD   r!  rK  rL  rB  Ú
vehicle_idÚmaster_statusr/  rÉ   Úscheduled_ride_masterrL   rƒ   r-   r-   r.   rŠ   p  sX   ÿþ
úÿ

þ
þÿ€ÿz"ScheduledRideMasterCreateView.postN)r"   r#   r$   r   r+   r
   r,   rŠ   r-   r-   r-   r.   rJ  l  rŒ   rJ  c                   @   rO   )ÚScheduledRideMasterUpdateViewc              
   C   s’  zq|j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}|j  d¡}t||||||gƒs:tddd	œtjd
�W S tjj|d�}	tjj|d�}
t	jj|d�}||_
||_||_|	|_|
|_||_| ¡  t|ƒ}t|j tjd
�W S  tjy…   tddd	œtjd
� Y S  tjy˜   tddd	œtjd
� Y S  t	jy«   tddd	œtjd
� Y S  tyÈ } ztdt|ƒd	œtjd
�W  Y d }~S d }~ww )Nr!  rK  rL  r/  rÉ   r   r   rM  r6   r   r�   rN  rO  ú Scheduled Ride Master not found.)r<   r=   r'   r   r   r>   r3  r&   r   rQ  r!  rK  rL  r/  rÉ   rÊ   rR  rB   r—   r˜   rì   rx   )rC   rD   rm   r!  rK  rL  rB  rS  rT  r/  rÉ   rU  rL   rƒ   r-   r-   r.   rC  ¥  s^   ÿþ
þ
þ
þÿ€ÿz!ScheduledRideMasterUpdateView.putN)r"   r#   r$   r   r+   r
   r,   rC  r-   r-   r-   r.   rV  ¡  rŒ   rV  c                   @   rO   )ÚScheduledRideMasterDeleteViewc              
   C   s�   zt jj|d�}| ¡  tdddœtjd�W S  t jy*   tdddœtjd� Y S  t	yG } ztdt
|ƒdœtjd�W  Y d }~S d }~ww )Nr�   r   z+Scheduled Ride Master deleted successfully.r6   r   r   rW  )rQ  r&   r=   rA  r   r   rI  r—   r˜   rì   rx   r>   )rC   rD   rm   rU  rƒ   r-   r-   r.   rA  Þ  s$   þ
þÿ€ÿz$ScheduledRideMasterDeleteView.deleteN)r"   r#   r$   r   r+   r
   r,   rA  r-   r-   r-   r.   rX  Ú  rŒ   rX  c                   @   rO   )ÚScheduledRideMasterListViewc              
   C   rE  rF  )rQ  r&   r'   rR  r   r<   r   rB   rì   rx   r>   )rC   rD   Úscheduled_ridesrL   rƒ   r-   r-   r.   r=   õ  s   
ÿ€ÿzScheduledRideMasterListView.getN)r"   r#   r$   r   r+   r
   r,   r=   r-   r-   r-   r.   rY  ñ  rŒ   rY  c                   @   rO   )ÚScheduledRideMobileListViewc              
   C   sX  zt |j d¡ƒ}t |j d¡ƒ}W n ttfy'   tdddœtjd� Y S w ||f}t 	¡  
¡ }zÙtjjdd�}| ¡ sItdd	dœtjd�W S g }|D ]@}z'tjj|t 	¡  ¡ d
�}	|	jdkru|	j|	j }
|
dkru||
dœ}| |¡ W qM tjy�   ||jjjdœ}| |¡ Y qMw |s›tdd	dœtjd�W S g }|D ]=}|d }|j}|jgt|j ¡ ƒ }|D ]&}|j|jf}t ||ƒj!}|dkrÛt ||jj|jjfƒj!|_"| |¡  nqµqŸ|j#dd„ d� g }|D ]}t$|d ƒ}|j}|d |d< | |¡ qé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 )Nr3   r4   r   z'Invalid latitude or longitude provided.r6   r   rÂ   r   zNo rides available.©Úscheduled_rideÚdater¢   )r¹   Úavailable_seatsr¹   é   c                 S   s
   | d j S )Nr¹   )Údistance_to_start)Úentryr-   r-   r.   r*  ¢  s   
 z1ScheduledRideMobileListView.get.<locals>.<lambda>r,  r_  z%Scheduled Rides Fetched successfully.)r   r7   ÚRideszUnexpected error)r   r7   Ú	exception)(r?   r<   r=   rr   rv   r   r   r>   r   ry   ÚtimerQ  r&   r|   ÚexistsrB   ÚScheduledRideDayr^  Útotal_seatsÚbooked_seatsrA   r—   rÉ   rn   ro   r/  r  Úlistr   r'   r3   r4   r   r   ra  ÚsortÚScheduledRideMobileSerializerrì   rx   rí   )rC   rD   rE   rF   rG   Úcurrent_timerZ  Úfiltered_ridesr¹   Úscheduled_ride_dayr_  Ú
ride_entryÚfinal_ridesrb  r/  Úpointsr%  Úpoint_locationrK   Úresponse_dataÚride_serializerr  rƒ   r-   r-   r.   r=   b  s¤   
þÿþÿ

ÿ

€þûþþý
ú€ýúþ€ÿzScheduledRideMobileListView.getNrº   r-   r-   r-   r.   r[  ^  rŒ   r[  c                   @   rO   )ÚScheduledFareEstimationViewc              
   C   s„  |j  d¡}|j  d¡}|j  d¡}|j  dd¡}|j  d¡}|r'|r'|r'|s1tddd	œtjd
�S z|d }|d }|d }	|d }
W n ttfyX   tddd	œtjd
� Y S w z	t|||	|
ƒ}W n ty€ } ztdt	|ƒd	œtjd
�W  Y d }~S d }~ww z	t
jj|d�}W n t
jyž   tddd	œtjd
� Y S w ||j | }|jtdƒtd�}tdd|j|j||t|ƒdœtjd
�S )NrŽ   rQ   rR   rò   r   rS   r   zKVehicle type, address details, ride time, and seats required are mandatory.r6   r   r3   r4   rT   r�   r�   rj   rk   r‘   )r   r7   r“   Úrate_per_km_per_seatr•   rò   rq   )r<   r=   r   r   r>   rr   rs   rw   r   rx   r   r&   r—   r˜   Úfare_per_km_per_seatr~   r   r   r“   r?   rB   )rC   rD   rŽ   rQ   rR   rò   rS   r   r€   r�   r‚   rK   rƒ   rn   rq   r‰   r-   r-   r.   rŠ   ½  sn   þûþ
ûÿ	þ€ÿ
þÿù	öz ScheduledFareEstimationView.postNr‹   r-   r-   r-   r.   rv  ¹  rŒ   rv  c                   @   rO   )ÚJoinScheduledRideViewc              	   C   sÊ  |j  d¡}|j  dd¡}|j  d¡}|j  d¡}|r|r|s)tdddœtjd	�S z|d
 }|d }|d
 }|d }	W n ttfyP   tdddœtjd	� Y S w |j}
z
tj	j|dd�}W n tj
yr   tdddœtjd	� Y S w t ¡  ¡ }ztj	j||d�}|jdkr’tdddœtjd	�W S W n tj
yª   tj	j|||jjjdd�}Y nw |j|j }||kr¿tdddœtjd	�S | j|7  _| ¡  tj	j||
t||ƒt||	ƒ|d� tdddœtjd	�S )Nr¤   rò   r   Ú
join_pointÚ	end_pointr   z0Ride ID, join point, and end point are required.r6   r   r3   r4   zWInvalid point format. Latitude and longitude are required for both join and end points.rÂ   r  zRide not found or inactive.r\  r¢   z"Ride is not available for joining.)r]  r^  rh  ri  zNot enough available seats.)ro  r    rz  r{  rò   zSuccessfully joined the ride.)r<   r=   r   r   r>   rr   rs   r    rQ  r&   r—   r˜   r   ry   r^  rg  r§   rÉ   rn   ro   rh  ri  rÊ   ÚScheduledRideParticipantr   rB   )rC   rD   r¤   rò   rz  r{  Újoin_latitudeÚjoin_longitudeÚend_latitudeÚend_longituder    r¹   Útodayro  r_  r-   r-   r.   rŠ   ÿ  s‚   þ
þÿ
þÿ
þÿ
üÿþûþzJoinScheduledRideView.postNr‹   r-   r-   r-   r.   ry  û  rŒ   ry  )TÚdecimalr   r   Úrest_frameworkr   r   Ú'rest_framework_simplejwt.authenticationr   Úrest_framework.viewsr   Úrest_framework.authenticationr   Úrest_framework.permissionsr	   r
   Úrest_framework.responser   r   ÚmodelsÚserializersÚgeopy.distancer   Úvehiclehub.modelsr   r   r   Úaccounts.modelsr   r   Úvehiclehub.serializersr   Úrest_framework.exceptionsr   Ú&django.contrib.gis.db.models.functionsr   Údjango.contrib.gis.measurer   Údjango.contrib.gis.geosr   r   Údjango.utilsr   rt   r   ÚprocessÚasyncior7  Ú	django.dbr   ÚListCreateAPIViewr    ÚRetrieveUpdateDestroyAPIViewr0   r2   rP   r�   r™   r¬   r»   rÁ   rÐ   rÓ   rÕ   rÛ   rà   rã   rè   rê   rñ   rÿ   r  ÚListAPIViewr  r  r>  rD  rH  rJ  rV  rX  rY  r[  rv  ry  r-   r-   r-   r.   Ú<module>   st    0_LA'!8%!%"XFJ%GY `59m[B