
    Ci,                         d Z ddlmZ ddlmZ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mZ dd	lmZ dd
lmZ ddlmZ ddlZ G d d      Z e       Zy)u3   
Service métier pour la gestion des prescriptions
    )Session)ListDictAnyOptional)PrescriptionPrescriptionStatus)PrescriptionProduct)PrescriptionSearch)PharmacyStock)PartnerPartnerType)Product)
ai_service)datetimeNc                       e Zd Zedefd       Zedededededef
d       Zeded	e	d
e
eef   ddfd       Ze	 	 	 dded	e	dee   dee   dedee
eef      fd       Zy)PrescriptionServicereturnc                  j    t        j                         } | j                  d       d| j                   S )uG   
        Génère une référence unique pour une prescription
        z%Y%m%d%H%M%S_)r   nowstrftimemicrosecond)r   s    I/home/www/lebenam.kofcorporation.com/app/services/prescription_service.pygenerate_referencez&PrescriptionService.generate_reference   s/    
 lln,,~./q0ABB    lat1lon1lat2lon2c                 v   d}t        j                  || z
        }t        j                  ||z
        }t        j                  |dz        t        j                  |dz        z  t        j                  t        j                  |             t        j                  t        j                  |            z  t        j                  |dz        z  t        j                  |dz        z  z   }dt        j                  t        j
                  |      t        j
                  d|z
              z  }||z  }	t        |	d      S )ux   
        Calcule la distance en kilomètres entre deux coordonnées GPS
        Utilise la formule de Haversine
        i        )mathradianssincosatan2sqrtround)
r   r   r   r    Rdlatdlonacdistances
             r   calculate_distancez&PrescriptionService.calculate_distance   s     ||D4K(||D4K(XXdQh$((4!8"44XXdll4()DHHT\\$5G,HHXXdQh "&((4!8"455 

499Q<1q5)9::q5Xq!!r   dbprescriptionai_extracted_dataNc           
        K   |j                  d      |_        |j                  d      |_        |j                  d      r	 t        j                  |d   d      |_        | j                  t              j                  t        j                  dk(        j                         }|D cg c]9  }|j                  |j                  |j                  xs d|j                  xs dd; }}|j                  dg       D ]p  }t        j                   |d	   |       d
{   }t#        |j                  ||d	   |j                  dd      |j                  d            }| j%                  |       r | j'                          y
#  Y "xY wc c}w 7 qw)ub   
        Traite les données extraites d'une prescription et crée les produits associés
        patient_namedoctor_nameprescription_datez%Y-%m-%dT )idnamedosageformproductsr;   Nquantityr#   r<   )prescription_id
product_idproduct_name_extractedr?   r<   )getr6   r7   r   strptimer8   queryr   filter	is_activeallr:   r;   r<   r=   r   match_product_to_databaser
   addcommit)	r2   r3   r4   all_productspproducts_for_matchingproduct_datamatched_product_idprescription_products	            r   process_prescriptionz(PrescriptionService.process_prescription/   s     %6$9$9.$I!#4#8#8#G    !45191B1B%&9:2. xx(//0A0AT0IJNNP "!
  dd((.b"	!
 !
 .11*bA 	)L'1'K'KV$%( "
 $7 ,-'3F';%))*a8#''1$  FF'(	)  			A!
"s7   >FE< AF&>F$3FF	A$F<F>Fuser_latuser_lon	radius_kmc                 	  K   | j                  t              j                  t        j                  |j                  k(        j                         }|sg S | j                  t              j                  t        j                  t        j                  k(  t        j                  dk(        j                         }g }d}d}	d}
d}|D ]^  }g }d}d}|D ]}  }|j                  sd}| j                  t              j                  t        j                  |j                  k(  t        j                  |j                  k(  t        j                  |j                  k\        j                         }|r| j                  t               j                  t         j                  |j                  k(        j                         }|j#                  |j                  |j$                  |j                  |j                  |j&                  |j&                  |j                  z  |j(                  |j*                  d       ||j&                  |j                  z  z  }|d} d}|rF|rD|j,                  r8|j.                  r,t0        j3                  |||j,                  |j.                        }|j                  |j$                  |j                  j4                  |j6                  |j,                  |j.                  ||||d
}|d   r|sd}|}	|st9        |d	         }||
kD  r|}
|}	|j#                  |       a | j                  t              j                  t        j                  |j                  k(        j;                         }t=               }|D ]   }|d	   D ]  }|j?                  |d
           " t9        |      }d}|D ]  }|d	   s	|dz  } |}|	r.tA        |j                  |	d   |	d	   |	d   |	d   |	d   |||	      }ntA        |j                  dg ddd|||	      }| j?                  |       tC        d |D              }|stD        jF                  |_$        n9tC        d |D              }|rtD        jJ                  ntD        jL                  |_$        tO        jP                         |_)        | jU                          |r|r|jW                  d        |S |jW                  d        |S w)u   
        Recherche les médicaments de la prescription dans les pharmacies
        
        Returns:
            Liste des pharmacies avec disponibilité et prix
        TNFg        )rA   product_namequantity_requestedquantity_available
unit_pricetotal_pricer<   r=   )

partner_idpartner_namepartner_typepartner_addresslatitude	longitudedistance_kmproducts_foundr\   all_products_availablere   rd   rA   r   r#   r]   r\   rc   )	r@   r]   rd   r\   rc   re   total_products_foundtotal_products_searchedtotal_pharmacies_foundc              3   >   K   | ]  }t        |d          dkD    yw)rd   r   N)len.0rs     r   	<genexpr>z;PrescriptionService.search_in_pharmacies.<locals>.<genexpr>   s      ']A.>,?(@1(D']s   c              3   &   K   | ]	  }|d      yw)re   N rk   s     r   rn   z;PrescriptionService.search_in_pharmacies.<locals>.<genexpr>  s     T": ;Ts   c                 6    | d   | d   n
t        d      | d   fS )Nrc   infr\   )floatxs    r   <lambda>z:PrescriptionService.search_in_pharmacies.<locals>.<lambda>  s)    $%m$4$@- eEl- / r   )keyc                     | d   S )Nr\   rp   rt   s    r   rv   z:PrescriptionService.search_in_pharmacies.<locals>.<lambda>  s    a.> r   ),rE   r
   rF   r@   r:   rH   r   r_   r   PHARMACYrG   rA   r   r]   r?   firstr   appendr;   r[   r<   r=   ra   rb   r   r1   valuephysical_addressrj   countsetrJ   r   anyr	   	NOT_FOUNDstatusFOUNDPARTIALLY_FOUNDr   utcnowsearch_completed_atrK   sort)r2   r3   rS   rT   rU   prescription_products
pharmaciessearch_resultssingle_search_to_save"best_pharmacy_for_single_save_datamax_products_found_countfound_all_in_one_pharmacypharmacyrd   r\   all_availablepresc_productstockproductr0   pharmacy_result_dictcurrent_products_found_countrg   unique_products_found_idsresultproduct_foundrf   pharmacies_with_productsrh   any_product_found_overall	all_founds                                  r   search_in_pharmaciesz(PrescriptionService.search_in_pharmaciese   s     !#)< = D D//<??B!

#% 	 %I XXg&--  K$8$88%
 #% 	
  $-1*#% $)!" B	8HNK M "7 *$//$)M /66!,,;!,,0H0HH!**m.D.DD %'	   hhw/66wzz]E]E]7]^ddfG"))&-jj(/.;.D.D.3nn&+&6&6','7'7-:P:P'P").. '	+ 	  5#3#3m6L6L#LLK$)M5*: HH):):x?Q?Q.AAh%%x'9'9 'kk ( ( 5 5 ; ;#+#<#<$--%//'"0**7$  $$<=F_,0)5I2,/23GHX3Y/Z,/2JJ/K,9M6!!"67EB	8L #%((+>"?"F"F//<??B#

%' 	  %(E!$ 	KF!'(8!9 K)--mL.IJK	K  ##<=#$ $ 	.F&'(A-(	. ": .$6 ,=lKABRS>}M>}M'IJb'c%9(?'=
%! %7 ,! ',%9(?'=
%! 	$% %(']n']$]!(&8&B&B#T^TT	09&,,+;; #
 ,4??+<(
		 %   $>?s   N6S9D"S)NNg      $@)__name__
__module____qualname__staticmethodstrr   rs   r1   r   r   r   r   rR   r   r   r   rp   r   r   r   r      s   C C C " "e "5 " "RW " "& 33"3  S>3 
	3 3j  %)$(ll"l 5/l 5/	l
 l 
d38n	l lr   r   )__doc__sqlalchemy.ormr   typingr   r   r   r   app.models.prescriptionr   r	   app.models.prescription_productr
   app.models.prescription_searchr   app.models.pharmacy_stockr   app.models.partnerr   r   app.models.productr   app.services.ai_servicer   r   r$   r   prescription_servicerp   r   r   <module>r      sH    # , , D ? = 3 3 & .  A AF +, r   