
    gi ,                         d Z ddlZddlZddlmZmZ ddlmZmZmZm	Z	 ddl
mZ ddlZ ej        e          Z G d d          Zded	efd
ZdS )aD  
ENIGMA Inventario - Inventory Service FIXED
============================================

Service completo con:
- Token Cassanova in Flask session (PERSISTENTE)
- Integrazione con models che usano tabelle reali
- Cache prodotti locale
- Workflow completo inventario

Author: HetGi & Claude
Date: 2026-01-14 (FIXED VERSION)
    N)datetime	timedelta)OptionalDictListAny)sessionc            	           e Zd ZdZddedefdZdefdZded	edefd
Zdede	e         fdZ
ddedededefdZddedee         fdZdS )CassanovaServicez5Service per API Cassanova con token in Flask session.https://api.cassanova.comapi_keyhostnamec                 0    || _         || _        d| _        d S )Nz1.0.0)r   r   api_version)selfr   r   s      @/var/www/tmov.alphamb/tmov_inventario/service_inventory_fixed.py__init__zCassanovaService.__init__   s     "    returnc                    t          j        d          }t          j        d          }|rZ|rXt          j        |          }t          j                    |t          d          z
  k     rt                              d           |S t                              d           | j	         d}dd	d
}d| j
        i}t          j        |||d          }|                                 |                                }|d         }	|                    dd          }
|	t           d<   t          j                    t          |
          z                                   t           d<   t                              d|
 d           |	S )z|
        Ottiene token da Flask session o ne richiede uno nuovo.
        
        Returns:
            Token valido
        cassanova_tokencassanova_token_expires<   )secondszToken valido in sessione Flaskz"Richiesta nuovo token Cassanova...z/apikey/tokenapplication/json*)Content-TypezX-Requested-WithapiKey
   )headersjsontimeoutaccess_token
expires_ini  z Nuovo token ottenuto, scade tra s)r	   getr   fromisoformatnowr   loggerdebuginfor   r   requestspostraise_for_statusr!   	isoformat)r   token
expires_at
expires_dturlr    payloadresponsedata	new_tokenr$   s              r   
_get_tokenzCassanovaService._get_token!   su    -..[!:;;
 	Z 	!/
;;J|~~i.C.C.C!CDD=>>> 	8999---. #
 
 T\*=gGRPPP!!###}}(	XXlD11
 &/!"LNNYz::::
)++ 	)* 	DzDDDEEEr   methodendpointc                     |                                  }| j         | }d| j        d| d}t          j        ||f|dd|}|                                 |                                S )z
        Esegue richiesta HTTP con autenticazione.
        
        Args:
            method: GET, POST, etc.
            endpoint: /products, etc.
            **kwargs: params, json, etc.
        
        Returns:
            Response JSON
        r   zBearer )r   z	X-VersionAuthorization   )r    r"   )r8   r   r   r,   requestr.   r!   )r   r9   r:   kwargsr0   r3   r    r5   s           r   _requestzCassanovaService._requestL   s     !!***.).u..
 
 #FCW"WWPVWW!!###}}r   barcodec                     	 |                      dd|ddd          }|                    dg           }|r|d         ndS # t          $ r(}t                              d	|            Y d}~dS d}~ww xY w)
zCerca prodotto per barcode.GET	/productsr      )rA   startlimitparamsproductsNzErrore ricerca barcode: )r@   r&   	Exceptionr)   error)r   rA   r6   rJ   es        r   search_product_by_barcodez*CassanovaService.search_product_by_barcodee   s    	==Z[fg<h<h=iiDxx
B//H"*48A;;4 	 	 	LL7A7788844444	s   =A   
A2
A--A2Nr   d   descriptionrF   rG   c                     	 ||d}|r||d<   |                      dd|          S # t          $ r,}t                              d|            dg dcY d	}~S d	}~ww xY w)
zCerca prodotti.rF   rG   rP   rC   rD   rH   zErrore ricerca prodotti: r   )
totalCountrJ   N)r@   rK   r)   rL   )r   rP   rF   rG   rI   rM   s         r   search_productsz CassanovaService.search_productso   s    	5$u55F 4(3}%==F=CCC 	5 	5 	5LL8Q88999"#44444444	5s   #& 
A!AAA
batch_sizec                    g }d}	 	 |                      ||          }|                    dg           }|                    dd          }|sn]|                    |           t                              dt          |           d| d           t          |          |k    rn||z  }t                              d	t          |           d
           |S # t          $ r)}t                              d|            |cY d}~S d}~ww xY w)z$Scarica TUTTI i prodotti (paginato).r   TrR   rJ   rS   z
Scaricati /z prodotti...zDownload completato: z	 prodottizErrore download prodotti: N)rT   r&   extendr)   r+   lenrK   rL   )r   rU   all_productsrF   r6   rJ   totalrM   s           r   get_all_productsz!CassanovaService.get_all_productsz   sC   	 $++%z+JJ88J33q11 ##H---P\):):PPUPPPQQQ|$$--#$  KKLL0A0ALLLMMM 	  	  	 LL9a99:::	 s   CC 
D
!D?D
D
)r   )Nr   rO   )rO   )__name__
__module____qualname____doc__strr   r8   r   r@   r   rN   intrT   r   r\    r   r   r   r      s       ??# # #s # # # #
)C ) ) ) )Vs c     2 $    	5 	53 	5c 	5c 	5\` 	5 	5 	5 	5   3  d            r   r   	db_configcassanova_api_keyc                 Z     ddl mmm  G  fdd          } |            S )z
    Factory per creare InventoryService.
    
    Args:
        db_config: {host, user, password, database}
        cassanova_api_key: API Key Cassanova
    
    Returns:
        InventoryService instance
    r   )InventorySessionInventoryItemProductCachec                      e Zd ZdZ fdZdedeeef         fdZ		 	 ddededede
e         fd	Zddedededee         fdZdededee         fdZdededee         fdZd dedededefdZd!dedede
e         fdZ	 	 d"dedededee         dededee         fdZdedede
e         fdZdededefdZdS )#2create_inventory_service.<locals>.InventoryServicezService completo inventario.c                                | _                    | _                   | _        t                    | _        d S )N)r   )session_model
item_modelcache_modelr   	cassanova)r   rh   rg   ri   re   rd   s    r   r   z;create_inventory_service.<locals>.InventoryService.__init__   sP    !1!1)!<!<D+mI66DO+|I66D-6GHHHDNNNr   	tenant_idr   c                    t                               d|            | j                                        }d}d}|D ]x}|                    d          }|r_	 | j                            |||           |dz  }<# t          $ r/}t                               d| d|            |dz  }Y d}~pd}~ww xY wyt          |          ||d}t                               d	|            |S )
aG  
            Sincronizza TUTTI i prodotti da Cassanova alla cache locale.
            
            Args:
                tenant_id: ID tenant
            
            Returns:
                {
                    'total': int,
                    'cached': int,
                    'errors': int
                }
            z,Inizio sincronizzazione prodotti per tenant r   rA   rE   zErrore cache prodotto z: N)r[   cachederrorszSincronizzazione completata: )
r)   r+   rp   r\   r&   ro   cache_productrK   rL   rY   )	r   rq   rJ   rs   rt   productrA   rM   results	            r   sync_all_productszDcreate_inventory_service.<locals>.InventoryService.sync_all_products   s(    KKRyRRSSS~6688HFF# $ $!++i00 $$(66y'7SSS!$ $ $ $%Lg%L%L%L%LMMM!$	$ X   F KK@@@AAAMs   !A99
B2%B--B2NrA   rP   c                 h   |r{| j                             ||          }|r!t                              d| d           |gS | j                            |          }|r| j                             |||           |gS g S |r2| j                            |d          }|                    dg           S g S )a  
            Cerca prodotti per barcode o nome.
            
            Prima cerca in cache locale, poi su Cassanova API.
            
            Args:
                tenant_id: ID tenant
                barcode: Codice a barre (ricerca esatta)
                description: Nome prodotto (ricerca parziale)
            
            Returns:
                Lista prodotti trovati
            z	Prodotto z trovato in cache   )rP   rG   rJ   )	ro   get_cached_productr)   r*   rp   rN   ru   rT   r&   )r   rq   rA   rP   rs   rv   r6   s          r   search_productzAcreate_inventory_service.<locals>.InventoryService.search_product   s      )<<YPP $LL!GW!G!G!GHHH"8O .BB7KK %$229gwOOO#9$	 ~55+UW5XXxx
B/// 	r   rE   user_idsede_idc                 :    | j                             |||          S )zCrea nuova sessione.)rm   create_session)r   rq   r}   r~   s       r   start_sessionz@create_inventory_service.<locals>.InventoryService.start_session  s    %44YQQQr   c                 8    | j                             ||          S )z!Ottiene sessione aperta corrente.)rm   get_active_session)r   rq   r}   s      r   get_current_sessionzFcreate_inventory_service.<locals>.InventoryService.get_current_session  s    %88GLLLr   
session_idc                 8    | j                             ||          S )zOttiene dettagli sessione.)rm   get_sessionr   r   rq   s      r   get_session_detailszFcreate_inventory_service.<locals>.InventoryService.get_session_details  s    %11*iHHHr   notec                 :    | j                             |||          S )zChiude sessione.)rm   close_session)r   r   rq   r   s       r   r   z@create_inventory_service.<locals>.InventoryService.close_session  s    %33J	4PPPr   r   rG   c                 8    | j                             ||          S )zLista sessioni recenti.)rm   get_recent_sessions)r   rq   rG   s      r   r   zFcreate_inventory_service.<locals>.InventoryService.get_recent_sessions  s    %99)UKKKr   Fproduct_datafound_in_apiquantitac                 @    | j                             ||||||          S )zAggiunge item a sessione.)rn   add_item)r   r   rq   rA   r   r   r   s          r   r   z;create_inventory_service.<locals>.InventoryService.add_item   s,     ?++IwlH  r   c                 8    | j                             ||          S )zOttiene items di una sessione.)rn   get_session_itemsr   s      r   r   zDcreate_inventory_service.<locals>.InventoryService.get_session_items)  s    ?44ZKKKr   item_idc                 8    | j                             ||          S )zElimina item da sessione.)rn   delete_item)r   r   r   s      r   r   z>create_inventory_service.<locals>.InventoryService.delete_item-  s    ?..w
CCCr   )NN)rE   )N)r   )NFrE   )r]   r^   r_   r`   r   rb   r   ra   r   rx   r   r|   r   r   r   r   boolr   r   r   r   r   )rh   rg   ri   re   rd   s   r   InventoryServicerk      s       **	I 	I 	I 	I 	I 	I 	I 	I 	I&	s &	tCH~ &	 &	 &	 &	X AE-1%	 %	C %	# %	'*%	6:4j%	 %	 %	 %	V	R 	R3 	R 	Rs 	RS[\_S` 	R 	R 	R 	R	M 	Ms 	MxPT~ 	M 	M 	M 	M	I# 	I# 	I(SW. 	I 	I 	I 	I	Q 	QC 	QC 	Qs 	QVZ 	Q 	Q 	Q 	Q	L 	L 	LS 	L$t* 	L 	L 	L 	L OT$%	 	s 	s 	S 	"*4.	GK	!	*23-	 	 	 		L 	L 	LT
 	L 	L 	L 	L	Ds 	D 	D 	D 	D 	D 	D 	D 	Dr   r   )models_inventory_fixedrg   rh   ri   )rd   re   r   rh   rg   ri   s   `` @@@r   create_inventory_servicer      s     UTTTTTTTTTKD KD KD KD KD KD KD KD KD KD KD KD KD KDZ r   )r`   r,   r!   r   r   typingr   r   r   r   flaskr	   logging	getLoggerr]   r)   r   ra   r   rc   r   r   <module>r      s       ( ( ( ( ( ( ( ( , , , , , , , , , , , ,       		8	$	${  {  {  {  {  {  {  { |Z Z Z Z Z Z Z Zr   