o
    >:h                     @   s   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
 de
defd	d
Zde
defddZd dlmZ 	ddefddZdS )    N)MovimientoVentaMovimientoDevolucionVenta)Decimal)ListaMateriales)ItemOrdenCompra)
Referenciarefreturnc                 C   sT   t jj| dd }|rtd| j d|j  |jS td| j d tdS )u@   Fallback: devuelve el precio_unitario de la última compra, o 0.)
referenciaz-orden__fecha_requeridau"       ↳ Fallback precio compra de z: u!       ↳ Sin compras previas para u    ⇒ 00)	r   objectsfilterorder_byfirstprintskuprecio_unitarior   )r   ultima r   "/var/www/html/public/siip/utils.pyobtener_ultimo_precio_compra   s   r   c           	      C   sJ  t d| j d| j d ztjj| dd}t d|j d| j  W n tjyA   | jp1t| }t d| d| j  | Y S w t	d	}|j
d
 D ]H}|j}|j}t d|j d|  |jrt|jdkrt|j}t d|  nt d|j d t|}|| }t d| d| d|  ||7 }qNt d| j d| d |S )u   
    Para ref tipo PT/PP recorre su BOM 'A' y suma:
      cantidad_total * costo_sub.
    Donde costo_sub = sub.precio_costo (si >0) o recursión.
    Si no hay BOM, usa precio_costo o fallback a última compra.
    u!   
⟳ costo_desde_bom: inicio SKU=z (id=)A)r
   estadou     ↳ Encontrado BOM id=z para u     ↳ Sin BOM: uso base=r   r
   u      • Componente z: qty=r   u           → usa sub.precio_costo=u          → precio_costo de u    vacío o cero, recursión...u          → contribución: u    × z = u	    ← FIN z: total BOM cost = 
)r   r   pkr   r   getDoesNotExistprecio_costor   r   componentesselect_relatedallr
   cantidad_totalcosto_desde_bom)	r   bombasetotalcompsubqty	costo_subcontribr   r   r   r#      s0   
r#   Freturn_historyc              
   C   s  t d}t d}td| j d| d|  tjj| ||fdd}td|  d |D ]$}|j|j	 }td	|j
 d
|j d|j	 d|  ||j7 }||7 }q/tjj| ||fdd}	td|	  d |	D ]$}
|
j|
j }td|
j
 d
|
j d|
j d|  ||
j7 }||7 }qmtd| d|  |dkrtd |rt d||fS t dS || }td| d |r|||fS |S )u~  
    Calcula el precio de venta ponderado para una referencia entre fecha_inicio y fecha_fin,
    incluyendo tanto ventas como devoluciones de venta.

    Si return_history=True, devuelve una tupla:
        (precio_ponderado: Decimal,
         total_unidades: Decimal,
         total_valor: Decimal)
    En caso contrario, devuelve sólo precio_ponderado (para compatibilidad).
    r   u   
▶▶ ponderado: ref=z, rango=u   →)r
   fecha__rangefechaz   Vendidos: z movimientosz	     [V] z qty=z @ u    ⇒ z   Devueltos: z	     [D] u      Totales → unidades=z, valor=r   u6      ¡No hubo movimientos en el rango! Precio pond = 0
z    Precio ponderado calculado = r   )r   r   r   r   r   r   r   countcantidadprecio_unitario_ventar.   r   precio_venta_unitario)r
   fecha_inicio	fecha_finr,   total_unidadestotal_valorventasvr+   devsdprecio_pondr   r   r   calcular_precio_venta_ponderadoE   sL   &

&


r<   )F)loggingmovimientos.modelsr   r   decimalr   lista_de_materiales.modelsr   r   referencias.modelsr   r   r#   boolr<   r   r   r   r   <module>   s   )