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rn 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  qt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  zt 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	\}	}|	|_|rg }
|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	 
 }zt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 |stdd	dtjdW S g }|D ]=}|d }|j}|jgt|j  }|D ]&}|j|jf}t ||j!}|dkrt ||jj|jjfj!|_"||  nqq|j#dd d g }|D ]}t$|d }|j}|d |d< || qt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rt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rt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