o
    >:hY                     @   st  d dl mZ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mZmZmZmZmZmZmZmZmZmZ dd	lmZmZmZmZmZm Z m!Z!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,m-Z- d dl.m/Z/ d dl0m1Z1 d dl2Z2d dl3Z3d dl4m5Z5 d dl6m7Z7 edd Z8dd Z9edd Z:e2;e<Z=edd Z>edd Z?edd Z@ed d! ZAed"d# ZBed$d% ZCe2;e<Z=ed&d' ZDd(d) ZEd*d+ ZFed,d- ZGed.d Z@ed/d0 ZHe2;e<Z=ed1d2 ZId dlm	Z	 d dl
mZ d dl0m1Z1 d d3l3m3Z3 e2;e<Z=eed4d5 ZJed6d7 ZKd8d9 ZLd:d; ZMd<d= ZNdS )>    )renderredirectget_object_or_404)messages)staff_member_required)JsonResponse)require_GET)reverse   )OrdenCompraFormItemOrdenCompraManualFormSetDevolucionCompraFormDevolucionMuestraComercialFormDevolucionProduccionFormMovimientoDevolucionVentaFormAjusteInventarioFisicoFormMuestraComercialFormRecepcionProduccionFormMovimientoVentaFormPerdidaProcesoForm)	OrdenCompraDevolucionCompraDevolucionMuestraComercialDevolucionProduccionMovimientoDevolucionVentaRecepcionProduccionMovimientoVentaItemOrdenCompraMuestraComercial)Decimal)
Referencia)MaquinaReferencia)ProveedorReferencia)costo_desde_bomcalcular_precio_venta_ponderado)
parse_date)nowN)timezone)formset_factoryc                 C   s   | j dkrSt| j}| r?|jdd}| j|_t| j|d}| r8|  ||_|  t	
| d tdS t	| d nt	| d |jdd}t| j|d}n	t }tt d}t| d	||d
S )NPOSTF)commit)instancez$Orden de compra creada exitosamente.z(admin:movimientos_ordencompra_changelistu"   Corrige los errores en los ítems.z/Corrige los errores en el formulario principal.z#admin/compras/ordencompra_form.html)formformset)methodr   r)   is_validsaveuser
creada_porr   r+   r   successr   errorr   r   )requestr,   
orden_tempr-    r7   )/var/www/html/public/movimientos/views.pyordencompra_manual_view   s,   

r9   c                 C   s   t t|d}tjj|ddd}g }|D ]}||j|jt	|j
|j|j|jt	|jd qt||r=|d d d	S dd	S )
a{  
    GET /movimientos/ordencompra/api/ref/<pk>/
    JSON:
      - proveedores: [
          {
            prov_ref_id,
            proveedor_id,
            proveedor_nombre,
            lead_time_total,
            esta_certificado,
            empaque_id,
            empaque_nombre,
          },
          ...
        ]
      - proveedor_referencia_id: el primero (o None)
    pk
referencia	proveedorempaque)prov_ref_idproveedor_idproveedor_nombrelead_time_totalesta_certificado
empaque_idempaque_nombrer   r@   N)proveedoresproveedor_referencia_id)r   r    r"   objectsfilterselect_relatedappendidrA   strr>   rC   rD   rE   r?   r   )r5   r;   refqsrG   prr7   r7   r8   api_referencia_proveedor:   s&   

rR   c                 C   s\   | j dkr#t| j}| r|  t| d tdS t| d nt }t	| dd|iS )uA   
    Vista personalizada para “Add” de DevolucionCompra.
    r)   u-   Devolución de compra guardada correctamente.-admin:movimientos_devolucioncompra_changelist#Corrige los errores del formulario.&admin/devolucion_compras/add_form.htmlr,   )
r.   r   r)   r/   r0   r   r3   r   r4   r   r5   r,   r7   r7   r8   devolucion_compra_manual_view_   s   

rW   c                 C   s8   t t|d}|j}tt|jt|jt|jpddS )u   
    Devuelve JSON con:
      - stock_item:        cantidad disponible en el ítem de orden (cantidad antes)
      - stock_referencia:  stock total actual de la referencia
      - precio_ponderado:  precio de costo actual de la referencia
    r:   r   )stockstock_referenciaprecio_ponderado)r   r   r=   r   floatcantidadrX   precio_costo)r5   r;   itemrO   r7   r7   r8   api_item_info_devolucion_comprav   s   r_   c                 C   s~   t j}td|j d|j d}| jdkr3t| j}| r,|	  t
| d t|S t
| d nt }t| d||dS )	Nadmin:__changelistr)   u6   Devolución de muestra comercial creada correctamente.-Por favor corrige los errores del formulario.zRadmin/mov_devolucion_muestras_comerciales/devolucionmuestracomercial/add_form.htmlr,   
cancel_url)r   _metar	   	app_label
model_namer.   r   r)   r/   r0   r   r3   r   r4   r   r5   optsre   r,   r7   r7   r8   (devolucion_muestra_comercial_manual_view   s    

rk   c                 C   sr   t t|d}|jptd}|jdv s|dkrt|}n|}td|j d|j	 d|  t
t|j	t|dS )	Nr:   0PTPPr   zAPI muestra ref=: stock=z, costo=rX   costo_unitario)r   r    r]   r   tipor#   loggerdebugr;   rX   r   r[   r5   r;   rO   precio_directoprecior7   r7   r8   api_referencia_info_muestra   s   
 ry   c                 C   s   t j}td|j d|j d}| jdkrGt| j}td| j	  |
 r:td|j |  t| d t|S td|j t| d	 nt }t| d
||dS )Nr`   ra   rb   r)      🐞 POST DATA:u   🐞 CLEANED:u#   Devolución guardada correctamente.u   🐞 ERRORS:rT   zBadmin/mov_devolucion_produccion/devolucionproduccion/add_form.htmlrd   )r   rf   r	   rg   rh   r.   r   r)   printdictr/   cleaned_datar0   r   r3   r   errorsr4   r   ri   r7   r7   r8   !devolucion_produccion_manual_view   s"   

r   c                 C   sj   t d|  tt|d}t d|j d|j d|j  t|jt|jp&dd}t d|  t|S )	up   
    Devuelve JSON con stock y precio_costo de la referencia,
    para poblar los campos de la devolución.
    u(   🐞 api_referencia_info called with pk=r:   u   🐞 Referencia encontrada: id=z, stock=z, precio_costo=r   rX   r]   u   🐞 Data a retornar: )r{   r   r    rM   rX   r]   r[   r   )r5   r;   rO   datar7   r7   r8   api_referencia_info2   s    r   c                 C   s   t j}td|j d|j d}| jdkr<t| j}t	d| j
  | r5|  t| d t|S t| d nt }t| d||d	S )
Nr`   ra   rb   r)      🐞 POST DATA: %su,   Devolución de venta guardada correctamente.rT   zBadmin/mov_devolucion_venta/movimientodevolucionventa/add_form.htmlrd   )r   rf   r	   rg   rh   r.   r   r)   rt   ru   r|   r/   r0   r   r3   r   r4   r   ri   r7   r7   r8   devolucion_venta_manual_view   s   

r   c              	   C   s   t t|d}|j}| jd}| jd}|rt|nt  jdd}|r*t|nt  }t	|||dd\}}	}
t
|jt|jt|jt|jt|t|	t|
dS )	u  
    GET params (opcionales): inicio=YYYY-MM-DD, fin=YYYY-MM-DD
    Dado el PK de una Venta, devuelve JSON con:
      - referencia:                 pk de la referencia vendida
      - stock_venta:                cantidad originalmente vendida en esa Venta
      - stock_referencia:           stock total actual de la referencia
      - precio_venta_unitario:      precio unitario de la venta original
      - precio_venta_ponderado:     precio ponderado calculado entre inicio→fin
      - historical_unidades:        suma de cantidades devueltas en el rango
      - historical_valor:           suma de (cantidad * precio_unitario) en el rango
    r:   iniciofinr
   dayT)return_history)r=   stock_ventarY   precio_venta_unitarioprecio_venta_ponderadohistorical_unidadeshistorical_valor)r   r   r=   GETgetr%   r&   datereplacer$   r   r;   r[   r\   rX   precio_unitario_venta)r5   r;   ventarO   
inicio_strfin_strr   r   pondhist_unidades
hist_valorr7   r7   r8   api_venta_info_devolucion   s$   r   c           	      C   s   t t|d}t|jt|jpdd}tjj|dd}g }|D ]}|j	j
}|j	}||j|j|j|jd q!td| d|j d	|  ||d
< t|S )a  
    GET /movimientos/api/stock-referencia/<idreferencia>/

    Devuelve JSON con:
      - stock: float
      - precio_costo: float (opcional)
      - opciones_planta_maquina: [
          { planta_id, planta_nombre, maquina_id, maquina_nombre }, ...
        ]
    r:   r   r   r<   maquina__planta	planta_idplanta_nombre
maquina_idmaquina_nombre   🐞 API ref=rp   , opciones=opciones_planta_maquina)r   r    r[   rX   r]   r!   rI   rJ   rK   maquinaplantarL   rM   nombrer{   r   )	r5   idreferenciarO   r   rP   opcionesmrr   r   r7   r7   r8   api_stock_referencia  s,   
r   c                 C   sF   | j dkrt| j}| r|  tdS nt }t| d|ddS )Nr)   zmovimientos:ajuste_manualz*admin/inventario_fisico/ajuste_manual.htmlzAjuste de Inventario Manual)r,   titulo)r.   r   r)   r/   r0   r   r   rV   r7   r7   r8   ajuste_manual_view:  s   

r   c                 C   sb   | j dkr#t| j}| r|  t| d tdS t| d nt }t	| d|t
ddS )uu   
    Formulario propio para crear una MuestraComercial,
    con cálculos de stock y valor de salida en cliente.
    r)   z'Muestra comercial creada correctamente.z-admin:movimientos_muestracomercial_changelistrc   z:admin/mov_muestra_comercial/muestracomercial/add_form.htmlrd   )r.   r   r)   r/   r0   r   r3   r   r4   r   r	   rV   r7   r7   r8   muestra_comercial_manual_viewH  s   

r   c                 C   sN   t t|d}|jp
d}|jdv s|dkrt|}n|}tt|jt|dS )z
    API que devuelve JSON con:
      - stock actual de la referencia
      - costo unitario: si es PT/PP o tiene precio_costo=0, lo recalcula desde el BOM;
                         en caso contrario usa precio_costo directo.
    r:   r   rm   rq   )r   r    r]   rs   r#   r   r[   rX   rv   r7   r7   r8   ry   _  s   

c                 C   s   t j}td|j|jf }| jdkrDt| j}td| j	  |
 r7td|j |  t| d t|S td|j t| d nt }t| d||d	S )
Nzadmin:%s_%s_changelistr)   rz   u   🐞 CLEANED DATA:u   Recepción guardada.u   🐞 FORM ERRORS:zCorrige los errores.z6admin/mov_produccion/recepcionproduccion/add_form.htmlrd   )r   rf   r	   rg   rh   r.   r   r)   r{   r|   r/   r}   r0   r   r3   r   r~   r4   r   ri   r7   r7   r8    recepcion_produccion_manual_viewt  s"   

r   c                 C   s   t j}td|j d|j d}| jdkrJt| j}t	d| j
  | r<t	d|j |  t| d t|S t	d|j t| d	 nt }t| d
||dS )Nr`   ra   rb   r)   r   u   🐞 CLEANED: %szVenta registrada correctamente.u   🐞 ERRORES FORM: %srT   z)admin/venta/movimientoventa/add_form.htmlrd   )r   rf   r	   rg   rh   r.   r   r)   rt   ru   r|   r/   r}   r0   r   r3   r   r~   r4   r   ri   r7   r7   r8   venta_manual_view  s"   

r   )datetimec              	   C   s   t t|d}t  }dd }|| jdp|jdd}|| jdp&|}t|||}tj	j
|dd	}g }	|D ]}
|
jj}|
j}|	|j|j|j|jd
 q;td| d|j d| d|	  tt|jt|| | |	dS )u  
    GET params:
      - inicio=YYYY-MM-DD   (opcional; default: primer día del mes actual)
      - fin=YYYY-MM-DD      (opcional; default: hoy)
    Devuelve JSON con:
      - stock
      - precio_venta_ponderado
      - opciones_planta_maquina: [
            {
              planta_id,
              planta_nombre,
              maquina_id,
              maquina_nombre
            }, ...
        ]
    r:   c                 S   s(   z	t | d W S  ty   Y d S w )Nz%Y-%m-%d)r   strptimer   	Exception)sr7   r7   r8   r%     s
   z-api_referencia_info_venta.<locals>.parse_dater   r
   r   r   r<   r   r   r   rp   z, precio_pond=r   )rX   r   r   r   r   )r   r    r&   r   r   r   r   r$   r!   rI   rJ   rK   r   r   rL   rM   r   r{   rX   r   r[   	isoformat)r5   r;   rO   hoyr%   r   r   precio_pondrP   r   r   r   r   r7   r7   r8   api_referencia_info_venta  s:   

"r   c              	   C   s6  t j }| jdp| jd}ttdd}d}| jdkr_|| j}|	 rXd}|D ]}|j
dp4d}|dkrA|  |d7 }q+|rQt| | d td	S t| d
 n9t| d n2|rtt |d}|jd }	g }
t  }|	D ]}|
|j|jj||j|jd qy||
d}t| d|||dS )uO   
    Permite devolver varios ítems de una OrdenCompra de forma unificada.
    orden_selectr   )extraNr)   cantidad_devueltar
   z$ devoluciones creadas correctamente.rS   u!   No se devolvió ninguna cantidad.rT   r:   r=   )r^   r=   fechacantidad_antesprecio_unitario_devuelto)initialrU   )ordenesorden_selectedr-   )r   rI   allr)   r   r   r(   r   r.   r/   r}   r0   r   r3   r   infor4   r   itemsrK   r'   r&   r   rL   r;   r=   r\   precio_unitarior   )r5   r   r   DevolucionFormSetr-   creadasr,   dvordenr   r   r   r^   r7   r7   r8   devolver_orden_unificado  sP   




r   c                 C   s>   t t|d}|j}t|jt|jt|jt|j|j	jdS )u   
    Retorna JSON con:
      - referencia: pk de la referencia asociada
      - stock_muestra: cantidad de esta muestra
      - stock_referencia: stock total de la referencia
      - costo_unitario: costo unitario de la referencia
      - usuario: pk del usuario que creó la muestra
    r:   )r=   stock_muestrarY   rr   usuario)
r   r   r=   r   r;   r[   cantidad_entregadarX   r]   entregado_por)r5   r;   muestrarO   r7   r7   r8   muestra_info_api$  s   	r   c                 C   sD   t t|d}|j}t|jt|jt|jt|jpdt|j	dS )Nr:   r   )r=   stock_recepcionrY   r]   costo_unitario_produccion)
r   r   r=   r   r;   r[   cantidad_despuesrX   r]   r   )r5   r;   	recepcionrO   r7   r7   r8   recepcion_info_api:  s   r   c                 C   sh   t j }| jdkr"t| j}||jd _| r!|	  t
dS n	t }||jd _t| d||dS )Nr)   r=   zmovimientos:perdida_addz'admin/mov_perdida_proceso/add_form.html)r,   referencias)r    rI   r   r.   r   r)   fieldsquerysetr/   r0   r   r   )r5   r   r,   r7   r7   r8   perdida_addF  s   


r   )Odjango.shortcutsr   r   r   django.contribr   %django.contrib.admin.views.decoratorsr   django.httpr   django.views.decorators.httpr   django.urlsr	   formsr   r   r   r   r   r   r   r   r   r   r   modelsr   r   r   r   r   r   r   r   r   decimalr   r    fabricacion.modelsr!   proveedores.modelsr"   
siip.utilsr#   r$   django.utils.dateparser%   django.utils.timezoner&   loggingr   django.utilsr'   django.formsr(   r9   rR   rW   	getLogger__name__rt   r_   rk   ry   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r7   r7   r7   r8   <module>   s    4,
"%









#)





:
;