
    AjE.                        U d Z ddlmZmZmZ ddlmZmZ ddlZddl	Z	ddl
mZmZ ddlmZ 	 ddlmZmZ  edd	d
      Zi Zeeef   ed<   g Zee   ed<   g Zee   ed<   d Z e         G d de      Z G d de      Zej;                  d      d        Zej;                  d      d        ZejA                  d      defd       Z!ej;                  d      d        Z"ej;                  d      defd       Z#ejA                  d      ded efd!       Z$ejA                  d"      d#        Z%ej;                  d$      d%        Z&d&ed'ed(efd)Z'y# e$ r Y !w xY w)*u@  
Main FastAPI Application for DispoManager - Flottenmanagement & Tourenplanung
==============================================================================
Kernfunktionalität:
- Fahrzeugverwaltung
- Auftragseingang & Tourenplanung
- Optimierungsalgorithmen (Route Planning)
- Live-Tracking Simulation
- Berichtswesen
    )FastAPIHTTPExceptionQuery)	BaseModelFieldN)ListOptional)datetime)Vehiclecreate_vesselsDispoManager APIuD   Flottenmanagement & Tourenplanungs-System für Contado/Cargo Supportz1.0.0)titledescriptionversionvehiclesorderstoursc                      dddddddddd	d
dddddg} t        |       D ]N  \  }}t        d      D ];  }d|dz  |z   dz   d}||d    d|dz    |d   |d   |d   ddddddd	t        |<   = P y)zErstellt Demo-Fahrzeuge	Schlepper   g333333?)namecapacitycost_per_kmz
Laster-4x2   gQ?zLaster-3.5tg      @g{Gz?Kleintransporterg333333?g?   zvhc-   03dr   z #r   r   
verfuegbar2   )xyNr   )	idr   typer   r   statuscurrent_locationcurrent_ordertotal_distance)	enumerateranger   )vessel_typesivtypejvids        /tmp/main.pycreate_demo_vesselsr1   ,   s     "TB1TBCE#TJ	L l+ 5q 	A1Qq&C =/AaC51f!*-$]3&*,2$6!%"#
HSM	    c                       e Zd ZU eed<    edd      Zeeef   ed<    ed      Z	eeef   ed<   e
ed<    edd	
      Zeed<   dZee   ed<   y)OrderCreater   .z{'x': float, 'y': float})r   pickup_locationdelivery_locationquantitynormalz^(low|normal|high)$)defaultpatternpriorityNdeadline)__name__
__module____qualname__str__annotations__r   r5   dictintr6   floatr;   r<   r	    r2   r0   r4   r4   J   s]    
I&+C=W&XOT#s(^X(-c
tCH~2O(4IJHcJ"Hhsm"r2   r4   c                   (    e Zd ZU eed<   ee   ed<   y)
TourCreate
vehicle_idr   N)r=   r>   r?   r@   rA   r   rE   r2   r0   rG   rG   R   s    OIr2   rG   /c                  r   K   ddg dt        t              t        t              t        t              ddS w)zAPI Status & Infor   running)z /orders - Bestellungen verwaltenz/vehicles - Fahrzeuge verwaltenz/tours - Touren planenz/optimize - Touren optimierenz'/status/heatmap - Live-Tracking Heatmap)vehicles_countorders_counttours_count)servicer%   	endpoints	demo_data)lenr   r   r   rE   r2   r0   rootrS   Y   s9      &
 "(mKu:
 s   57z/ordersc                  6   K   t         t        t               dS w)zBestellungen auflisten)r   total_count)r   rR   rE   r2   r0   list_ordersrV   n   s      6{ s   orderc                 x  K   dt        j                         j                  dd  }|| j                  | j                  | j
                  | j                  | j                  | j                  dddt        j                         j                         d}t        j                  |       d| j                   d||dS w)	zNeue Bestellung anlegenzord-Nr   pending)r#   r   r5   r6   r7   r;   r<   r%   assigned_vehicleroute
created_atBestellung 'z
' angelegt)messageorder_iddetails)uuiduuid4hexr   r5   r6   r7   r;   r<   r
   now	isoformatr   append)rW   r_   	new_orders      r0   create_orderrh   w   s      djjl&&r*+,H 

 00"44NNNNNN lln..0I MM) "%**Z8 s   B8B:z	/vehiclesc                     K   t         j                         t        d t         j                         D              t        t               t        d t         j                         D              z
  dS w)zFahrzeuge auflistenc              3   2   K   | ]  }|d    dk(  sd  ywr%   r   r   NrE   .0vs     r0   	<genexpr>z list_vehicles.<locals>.<genexpr>   s     [Qq{l?Zq[   c              3   2   K   | ]  }|d    dk(  sd  ywrk   rE   rl   s     r0   ro   z list_vehicles.<locals>.<genexpr>   s     +h!AhK[gLgA+hrp   )r   available_countin_use_count)r   valuessumrR   rE   r2   r0   list_vehiclesrv      sO      OO%[(//*;[[H+hx7H+h(hh s   A-A/z/vehicles/{vehicle_id}rH   c                 R   K   | t         vrt        dd|  d      dt         |    iS w)zEinzelnes Fahrzeug details  
Fahrzeug '' nicht gefundenstatus_codedetailvehicle)r   r   )rH   s    r0   get_vehicler      s7      !jL\4]^^x
+,,s   %'z/vehicles/{vehicle_id}/assign
order_namec                    K    t         vrt        dd  d      t        fdt        D        d      st        dd d      t             }t	         fdd	D              }d
}d   r-t        fdt        D        d      }|r|j                  dd
      }|d   z   |d   kD  r#t        dd|d    d|d    d| dd    d	      d|d<    d<   dd<   d|d    dt             dS w)z"Fahrzeug einer Bestellung zuweisenrx   ry   rz   r{   c              3   4   K   | ]  }|d    k(  s|  yw)r   NrE   )rm   or   s     r0   ro   z*assign_vehicle_to_order.<locals>.<genexpr>   s     ?qyJ'>!?s   Nr]   c              3   T   K   | ]  }t        fd t        D              d    ! yw)c              3   8   K   | ]  }|d    k(  r|d     yw)rZ   r7   NrE   )rm   r   rH   s     r0   ro   z4assign_vehicle_to_order.<locals>.<genexpr>.<genexpr>   s*      5q$%3 z] 5s   r7   N)nextr   )rm   _rH   s     r0   ro   z*assign_vehicle_to_order.<locals>.<genexpr>   s5        	 5F 5 	55?	As   %()r   r   rZ   c              3   :   K   | ]  }|d    d   k(  s|  yw)r#   rZ   NrE   )rm   r   rW   s     r0   ro   z*assign_vehicle_to_order.<locals>.<genexpr>   s"     YQAdGuEW?X4XqYs   r7   r   i  r   u   ' hat Kapazität 'z', aktuelle Last: 'z' + Neulast: 'z' > Max!in_user%   assignedz' zugewiesen)r^   r~   rW   )r   r   r   r   ru   get)rH   r   r~   current_loadactual_loadassigned_orderrW   s   ``    @r0   assign_vehicle_to_orderr      s[     !jL\4]^^ ?V?FEl:,N^4_``z"G    L
 K Y&Y[_`(,,Z;KeJ'''**==00B7:CVBW X''3nN5CTBUU]_
 	
 !GH *E
 E(O  0=J' s   C+C0z	/optimizec                  b  K   t         j                         D  cg c]  \  } }|d   dk(  r
|d   dkD  r|  }} }t        D cg c]  }|d   dk(  s| }}|r|sdt        |      t        |      dS ddd	d
|j	                  fd       g }|D ]  } t         |    }|sd}d}t        |      D ]+  \  }	}
|d   |j                  dd      z
  |
d   k\  }|s'|
}|	} n |sO|t        |      k  s^|j                  |       d|d<   | |d<   d|d<   |d   |d<   t        |d   |d   |d         }dt        |      dz   d| |d   |d   g|d   |d   |j                  dd      |j                  dd      dd	}|j                  |        t        |       d|t        |      d S c c}} w c c}w w)!z6Optimiert Tourenplanung (Einfacher Greedy-Algorithmus)r%   r   r   r   rY   u<   Keine verfügbaren Fahrzeuge oder Bestellungen zu optimieren)r^   available_vehicles_countpending_orders_countr      )highr8   lowc                 :    j                  | d   d      | d    fS )Nr;   r   r7   )r   )r   priority_orders    r0   <lambda>z!optimize_routes.<locals>.<lambda>   s$    ~'9'9!J-'KaPZm^&\ r2   )keyNr   r7   r   rZ   r   r   r'   r&   r5   r6   ztour-r   r#   distancecost	scheduled)	r#   rH   vehicle_namer   r5   r6   r(   estimated_costr%   z Touren optimiert)r^   r   remaining_orders)
r   itemsr   rR   sortr)   r   popcalculate_routerf   )r/   rn   available_vehiclesr   pending_ordersoptimized_toursr~   	order_idx
best_orderr,   rW   can_fulfillr[   tourr   s                 @r0   optimize_routesr      sI    
 #..*QX;,&1Z=1+< 	 
 "(DA1X;)+CaDND^U(+,>(?$'$7
 	
  1Q7N\]O! --3- IJ &n5 5&z2W[[QR5SSX]^hXii!&J !I i#n*==""9-$,!14
-.'1
8$+5f+=( (./0123 "#o"6q"8!=>"%$+FO)$/0'12C'D)34G)H&+ii
A&>&+ii&:)
  &&t,[--` /*++<= / G
 Es;   F/F$F/F*F*AF/ 5F/	F/ F//C F/z/status/heatmapc            	        K   g } t         j                         D ]i  \  }}|d   s|d   }|d   dk(  rdn|j                  d      rdnd}| j                  |j                  dd	      |j                  d
d	      |||d   d       k g }t        D ]  }|d   s	|d   }|d   }ddddj                  |j                  d      d      }	|r.|j                  ddi||d   |j                  dd      |	d       |sk|j                  ddi||d   |j                  dd      |	d        t        j                         j                         | |ddddddS w)zLive-Tracking Heatmap Datenr&   r%   r   greenr'   orangeredr!   r    r"   )r!   r"   rH   colorr%   r5   r6   grayyellow)rY   r   in_progressbluer$   pickupr#   rY   )r_   r%   r   deliveryu   Fahrzeug verfügbarzFahrzeug ausgelastetzFahrzeug unbelastbarzOrder-Pickup/Lieferung)r   r   r   r   )	timestampr   r   legend)r   r   r   rf   r   r
   rd   re   )
vehicle_locationsr/   rn   locr   order_locationsrW   r   r   status_colors
             r0   status_heatmapr   !  s     .." 
Q &'C {l:GQUUSbMcinE$$WWS"%WWS"%!H+& 	
 O "#,-F01H "$' c%))H%v.	  &&H(( !&d#ii)<)(  &&J(( !&d#ii)<)( +< \\^--/%!*,),	
	
 
s   "EA0EA!E8AEstartvia1via2c                     |d   | d   z
  }|d   | d   z
  }|dz  |dz  z   dz  }|d   |d   z
  }|d   |d   z
  }|dz  |dz  z   dz  }||z   }	t         |	z  dz  }
t        |	d      t        |
d      | ||gdS )z.Berechnet einfache Route (Euklidische Distanz)r!   r"   r   g      ?d   )r   r   	waypoints)vehicle_avg_cost_per_kmround)r   r   r   dx1dy1dist1dx2dy2dist2r(   r   s              r0   r   r   ]  s     s)eCj
 C
s)eCj
 C!Vc1f_s"E s)d3i
C
s)d3i
C!Vc1f_s"EU]N"^3c9D .!,dAT4( r2   )(__doc__fastapir   r   r   pydanticr   r   jsonra   typingr   r	   r
   r~   r   r   ImportErrorappr   rB   r@   rA   r   listr   r1   r4   rG   r   rS   rV   postrh   rv   r   r   r   r   r   rE   r2   r0   <module>r      s  	 2 1 %   ! 	/
 
V $sDy/  T
  tDz 2  
#) #   (   )k  6   	!"-# - #- 
)*)c )s ) +)X +J JZ 	8 8v4 t 4 O
  		s   E EE