§
    $­hÊ-  ã                   óx   — d dl Z d dlZd dlZd dlmZ d dlmZmZmZmZ d dl	Z	d dl
mZ d dlZ G d„ d¦  «        ZdS )é    N)Údatetime)ÚDictÚAnyÚOptionalÚTuple)ÚImagec                   óê   — e Zd ZdZd„ Zdedeeeef         e	f         fd„Z
dedefd„Zdefd„Zdedeeef         fd	„Zd
eeef         deeef         fd„Zd
eeef         de	fd„Zddededefd„ZdS )Ú
OCRServicezDServicio para procesamiento OCR de facturas usando OpenAI Vision APIc                 ó6   — t          j        ¦   «         | _        d S ©N)ÚopenaiÚOpenAIÚclient©Úselfs    ú</home/ubuntu/invoice-606-backend/src/services/ocr_service.pyÚ__init__zOCRService.__init__   s   € Ý”m‘o”oˆŒˆˆó    Ú
image_pathÚreturnc           	      óÆ  — 	 |                       |¦  «        }|                      ¦   «         }| j        j        j                             ddd|dœddd|› �idœgd	œgd
d¬¦  «        }|j        d         j        j        }|  	                    |¦  «        }|  
                    |¦  «        }||fS # t          $ r-}t          dt          |¦  «        › �¦  «         i dfcY d}~S d}~ww xY w)zê
        Procesa una imagen de factura y extrae los datos relevantes
        
        Args:
            image_path: Ruta de la imagen a procesar
            
        Returns:
            Tuple con (datos_extraidos, confianza)
        zgpt-4oÚuserÚtext)Útyper   Ú	image_urlÚurlzdata:image/jpeg;base64,)r   r   ©ÚroleÚcontentiè  çš™™™™™¹?©ÚmodelÚmessagesÚ
max_tokensÚtemperaturer   zError en OCR: ç        N)Ú_encode_imageÚ_create_extraction_promptr   ÚchatÚcompletionsÚcreateÚchoicesÚmessager   Ú_parse_ocr_responseÚ_calculate_confidenceÚ	ExceptionÚprintÚstr)	r   r   Úencoded_imageÚpromptÚresponser   Úextracted_dataÚ
confidenceÚes	            r   Úprocess_invoice_imagez OCRService.process_invoice_image   s@  € ð*	à ×.Ò.¨zÑ:Ô:ˆMð ×3Ò3Ñ5Ô5ˆFð ”{Ô'Ô3×:Ò:Øð !'ð )/Ø(.ðð ð
 )4à$)Ð+TÀ]Ð+TÐ+Tð."ðð ð$ðð ðð"  Øð) ;ñ ô ˆHð0 Ô& qÔ)Ô1Ô9ˆGØ!×5Ò5°gÑ>Ô>ˆNð ×3Ò3°NÑCÔCˆJà! :Ð-Ð-øåð 	ð 	ð 	ÝÐ+¥3 q¡6¤6Ð+Ð+Ñ,Ô,Ð,Ø�s�7ˆNˆNˆNˆNˆNˆNøøøøð	øøøs   ‚B&B) Â)
C Â3"CÃC ÃC c                 óv  — 	 t          j        |¦  «        5 }|j        dk    r|                     d¦  «        }d}t	          |j        ¦  «        |k    r'|                     ||ft           j        j        ¦  «         t          j
        ¦   «         }|                     |dd¬¦  «         |                     d¦  «         t          j        |                     ¦   «         ¦  «                             d¦  «        cddd¦  «         S # 1 swxY w Y   dS # t"          $ r$}t#          d	t%          |¦  «        › �¦  «        ‚d}~ww xY w)
zCodifica una imagen en base64ÚRGBi   ÚJPEGéU   )ÚformatÚqualityr   zutf-8NzError al codificar imagen: )r   ÚopenÚmodeÚconvertÚmaxÚsizeÚ	thumbnailÚ
ResamplingÚLANCZOSÚioÚBytesIOÚsaveÚseekÚbase64Ú	b64encodeÚreadÚdecoder0   r2   )r   r   ÚimgÚmax_sizeÚbufferr8   s         r   r'   zOCRService._encode_imageF   s„  € ð	Då”˜JÑ'Ô'ð G¨3à”8˜uÒ$ð -ØŸ+š+ eÑ,Ô,�Cð  �Ý�s”x‘=”= 8Ò+ð RØ—M’M 8¨XÐ"6½Ô8HÔ8PÑQÔQÐQõ œ™œ�Ø—’˜¨¸�Ñ;Ô;Ð;Ø—’˜A‘”�õ Ô'¨¯ª©¬Ñ6Ô6×=Ò=¸gÑFÔFð!Gð Gð Gð Gñ Gô Gð Gð Gð Gð Gð Gð Gøøøð Gð Gð Gð Gð Gð Gøõ$ ð 	Dð 	Dð 	DÝÐB½#¸a¹&¼&ÐBÐBÑCÔCÐCøøøøð	Døøøs;   ‚D
 –CC=Ã0D
 Ã=DÄD
 ÄDÄD
 Ä

D8ÄD3Ä3D8c                 ó   — dS )u@   Crea el prompt para extracciÃ³n de datos de facturas dominicanasu*  
Analiza esta factura dominicana y extrae los siguientes datos en formato JSON. Si algÃºn campo no estÃ¡ visible o no es claro, usa null.

IMPORTANTE: Responde ÃšNICAMENTE con el JSON, sin texto adicional.

{
  "supplier_name": "Nombre del proveedor/empresa",
  "supplier_rnc": "RNC del proveedor (formato: 101-12345-6)",
  "ncf": "NÃºmero de Comprobante Fiscal (NCF)",
  "invoice_date": "Fecha de la factura (formato: YYYY-MM-DD)",
  "invoiced_amount": "Monto total facturado (nÃºmero decimal)",
  "itbis_invoiced": "ITBIS facturado (nÃºmero decimal)",
  "itbis_rate": "Tasa de ITBIS aplicada (generalmente 18%)",
  "subtotal": "Subtotal antes de impuestos",
  "description": "DescripciÃ³n de productos/servicios",
  "expense_type_suggestion": "Tipo de gasto sugerido (01-11 segÃºn clasificaciÃ³n DGII)",
  "confidence_notes": "Notas sobre la calidad de la imagen y legibilidad"
}

Tipos de gasto DGII para referencia:
01 - Gastos de Personal
02 - Gastos por Trabajos, Suministros y Servicios
03 - Arrendamientos
04 - Gastos de Activos Fijo
05 - Gastos de RepresentaciÃ³n
06 - Otras Deducciones Admitidas
07 - Gastos Financieros
08 - Gastos Extraordinarios
09 - Compras y Gastos que Formaran Parte del Costo de Venta
10 - Adquisiciones de Activos
11 - Gastos de Seguros

Extrae los datos con la mayor precisiÃ³n posible:
© r   s    r   r(   z$OCRService._create_extraction_prompt_   s   € ð!ð !r   r   c                 ó*  — 	 |                      ¦   «         }|                     d¦  «        r
|dd…         }|                     d¦  «        r
|dd…         }|                      ¦   «         }t          j        |¦  «        }|                      |¦  «        }|S # t          j        $ r=}t          dt          |¦  «        › �¦  «         t          d|› �¦  «         i cY d}~S d}~wt          $ r+}t          dt          |¦  «        › �¦  «         i cY d}~S d}~ww xY w)	z<Parsea la respuesta del OCR y la convierte en un diccionarioz```jsoné   Nz```éýÿÿÿzError al parsear JSON: zContenido recibido: z!Error al procesar respuesta OCR: )
ÚstripÚ
startswithÚendswithÚjsonÚloadsÚ_clean_extracted_dataÚJSONDecodeErrorr1   r2   r0   )r   r   ÚdataÚcleaned_datar8   s        r   r.   zOCRService._parse_ocr_response„   s:  € ð	à—m’m‘o”oˆGØ×!Ò! )Ñ,Ô,ð &Ø! ! " "œ+�Ø×Ò Ñ&Ô&ð 'Ø! # 2 #œ,�Ø—m’m‘o”oˆGõ ”:˜gÑ&Ô&ˆDð  ×5Ò5°dÑ;Ô;ˆLàÐøåÔ#ð 	ð 	ð 	ÝÐ4­C°©F¬FÐ4Ð4Ñ5Ô5Ð5ÝÐ2¨Ð2Ð2Ñ3Ô3Ð3ØˆIˆIˆIˆIˆIˆIøøøøÝð 	ð 	ð 	ÝÐ>µc¸!±f´fÐ>Ð>Ñ?Ô?Ð?ØˆIˆIˆIˆIˆIˆIøøøøð	øøøs0   ‚BB ÂDÂ"2CÃDÃDÃ' DÄDÄDr_   c                 ó  — i }g d¢}|D ]E}|                      |¦  «        }|r,t          |t          ¦  «        r|                     ¦   «         ||<   ŒF|                      d¦  «        }|rLt          |t          ¦  «        r7d                     d„ |D ¦   «         ¦  «        }t          |¦  «        dk    r||d<   |                      d¦  «        }|rk	 t          |t          ¦  «        rDdD ]A}		 t          j        ||	¦  «        }
|
                     d¦  «        |d<    n# t          $ r Y Œ>w xY wn# t          $ r Y nw xY wg d	¢}|D ]±}|                      |¦  «        }|�˜	 t          |t          ¦  «        rP|                     dd¦  «                             dd¦  «                             dd¦  «                             ¦   «         }t          |¦  «        }|dk    r|||<   Œš# t          t          f$ r Y Œ­w xY wŒ²|                      d¦  «        }|rst          |t          ¦  «        r^d                     d„ |D ¦   «         ¦  «        d
d…         }|r5dt          |¦  «        cxk    rdk    rn n|                     d¦  «        |d<   |                      d¦  «        }|�z	 t          |t          ¦  «        r(|                     dd¦  «                             ¦   «         }t          |¦  «        }d|cxk    rdk    rn n||d<   n# t          t          f$ r Y nw xY w|S )u$   Limpia y valida los datos extraÃ­dos)Úsupplier_nameÚncfÚdescriptionÚconfidence_notesÚsupplier_rncÚ c              3   óN   K  — | ] }|                      ¦   «         s|d k    ¯|V — Œ!dS )ú-N©Úisdigit©Ú.0Úcs     r   ú	<genexpr>z3OCRService._clean_extracted_data.<locals>.<genexpr>®   s8   è è € ÐJÐJ a°!·)²)±+´+ÐJÀÀcÂÐJ ÐJÐJÐJÐJÐJÐJr   é	   Úinvoice_date)ú%Y-%m-%dz%d/%m/%Yz%d-%m-%Yrr   )Úinvoiced_amountÚitbis_invoicedÚsubtotalNú$ú,ÚRDr   Úexpense_type_suggestionc              3   óB   K  — | ]}|                      ¦   «         ¯|V — Œd S r   rj   rl   s     r   ro   z3OCRService._clean_extracted_data.<locals>.<genexpr>Ø   s/   è è € Ð%MÐ%M¨AÀÇÂÁÄÐ%M aÐ%MÐ%MÐ%MÐ%MÐ%MÐ%Mr   é   é   é   Ú
itbis_rateú%éd   )ÚgetÚ
isinstancer2   rX   ÚjoinÚlenr   ÚstrptimeÚstrftimeÚ
ValueErrorr0   ÚreplaceÚfloatÚ	TypeErrorÚintÚzfill)r   r_   ÚcleanedÚtext_fieldsÚfieldÚvalueÚrncÚ	rnc_cleanrq   ÚfmtÚparsed_dateÚamount_fieldsÚamountÚexpense_typeÚexpense_numr~   Úrates                    r   r]   z OCRService._clean_extracted_dataŸ   sà  € àˆð RÐQÐQˆØ ð 	/ð 	/ˆEØ—H’H˜U‘O”OˆEØð /� E­3Ñ/Ô/ð /Ø!&§¢¡¤�˜‘øð �hŠh�~Ñ&Ô&ˆØð 	4•:˜c¥3Ñ'Ô'ð 	4àŸšÐJÐJ¨3ÐJÑJÔJÑJÔJˆIÝ�9‰~Œ~ Ò"ð 4Ø*3�˜Ñ'ð —x’x Ñ/Ô/ˆØð 	ðå˜l­CÑ0Ô0ð %àCð %ð %˜ð%Ý*2Ô*;¸LÈ#Ñ*NÔ*N˜KØ6A×6JÒ6JÈ:Ñ6VÔ6V˜G NÑ3Ø!˜EøÝ)ð %ð %ð %Ø$˜Hð%øøøøøåð ð ð Ø�ðøøøð JÐIÐIˆØ"ð 	ð 	ˆEØ—H’H˜U‘O”OˆEØð 
ð	å! %­Ñ-Ô-ð bØ %§¢¨c°2Ñ 6Ô 6× >Ò >¸sÀBÑ GÔ G× OÒ OÐPTÐVXÑ YÔ Y× _Ò _Ñ aÔ a˜å" 5™\œ\�FØ ’{ð 0Ø)/˜ ™øøÝ"¥IÐ.ð ð ð Ø�Dðøøøð
ð —x’xÐ 9Ñ:Ô:ˆØð 	Nå˜,­Ñ,Ô,ð NØ ŸgšgÐ%MÐ%M°Ð%MÑ%MÔ%MÑMÔMÈbÈqÈbÔQ�Øð N 1­¨KÑ(8Ô(8ð Nð Nò Nð N¸Bò Nð Nð Nð Nð NØ9D×9JÒ9JÈ1Ñ9MÔ9M�GÐ5Ñ6ð —X’X˜lÑ+Ô+ˆ
Øð 	ðÝ˜j­#Ñ.Ô.ð EØ!+×!3Ò!3°C¸Ñ!<Ô!<×!BÒ!BÑ!DÔ!D�JÝ˜ZÑ(Ô(�Ø˜ð 1ð 1ò 1ð 1 ò 1ð 1ð 1ð 1ð 1Ø,0�G˜LÑ)øøÝ¥	Ð*ð ð ð Ø�ðøøøð ˆs\   Ã
D$ Ã$-DÄD$ Ä
D ÄD$ ÄD Ä D$ Ä$
D1Ä0D1ÅA?GÇG(Ç'G(ÊA!K0 Ë0LÌLc                 óÌ   — |sdS ddddddœ}d}|                      ¦   «         D ]\  }}||v r||         �||z  }Œg d¢}d}|D ]}||v r||         �||z  }Œt          |d	¦  «        S )
u<   Calcula el nivel de confianza basado en los datos extraÃ­dosr&   gš™™™™™É?g333333Ã?g      Ð?)rb   rf   rc   rq   rs   N)rt   ru   rd   gš™™™™™©?g      ð?)ÚitemsÚmin)r   r_   Úcritical_fieldsr7   r�   ÚweightÚbonus_fieldsÚbonus_per_fields           r   r/   z OCRService._calculate_confidenceê   sÈ   € àð 	Ø�3ð !ØØØ Ø#ð
ð 
ˆð ˆ
Ø,×2Ò2Ñ4Ô4ð 	%ð 	%‰MˆE�6Ø˜ˆ}ð %  e¤ð %Ø˜fÑ$�
øð EÐDÐDˆØˆØ!ð 	.ð 	.ˆEØ˜ˆ}ð .  e¤ð .Ø˜oÑ-�
øå�:˜sÑ#Ô#Ð#r   rg   rd   rb   c                 óJ  — 	 d|› d|› d�}| j         j        j                             dd|dœgdd¬	¦  «        }|j        d
         j        j                             ¦   «         }|                     ¦   «         r2dt          |¦  «        cxk    rdk    rn n| 
                    d¦  «        S t          |¦  «        dk    r3|                     ¦   «         rdt          |¦  «        cxk    rdk    rn n|S dS # t          $ r*}t          dt          |¦  «        › �¦  «         Y d}~dS d}~ww xY w)u1  
        Clasifica automÃ¡ticamente el tipo de gasto basado en la descripciÃ³n
        
        Args:
            description: DescripciÃ³n del producto/servicio
            supplier_name: Nombre del proveedor (opcional)
            
        Returns:
            CÃ³digo del tipo de gasto (01-11)
        u_   
Clasifica el siguiente gasto segÃºn los tipos oficiales de la DGII dominicana.

DescripciÃ³n: z
Proveedor: uÊ  

Tipos disponibles:
01 - Gastos de Personal
02 - Gastos por Trabajos, Suministros y Servicios
03 - Arrendamientos
04 - Gastos de Activos Fijo
05 - Gastos de RepresentaciÃ³n
06 - Otras Deducciones Admitidas
07 - Gastos Financieros
08 - Gastos Extraordinarios
09 - Compras y Gastos que Formaran Parte del Costo de Venta
10 - Adquisiciones de Activos
11 - Gastos de Seguros

Responde ÃšNICAMENTE con el nÃºmero de dos dÃ­gitos (01-11) del tipo mÃ¡s apropiado.
zgpt-4o-minir   r   é
   r    r!   r   r|   r}   r{   Ú06u%   Error en clasificaciÃ³n automÃ¡tica: N)r   r)   r*   r+   r,   r-   r   rX   rk   r‹   rŒ   r„   r0   r1   r2   )r   rd   rb   r4   r5   Úresultr8   s          r   Úclassify_expense_typez OCRService.classify_expense_type  sš  € ð*	ðð ðð ð ð	ð ð ˆFð, ”{Ô'Ô3×:Ò:Ø#Ø#)°fÐ=Ð=Ð>ØØð	 ;ñ ô ˆHð Ô% aÔ(Ô0Ô8×>Ò>Ñ@Ô@ˆFð �~Š~ÑÔð  A­¨V©¬ð ð ò ð ¸ò ð ð ð ð Ø—|’| A‘”Ð&Ý�V‘” Ò!ð  f§n¢nÑ&6Ô&6ð ¸1ÅÀFÁÄð ð ò ð Èrò ð ð ð ð Ø�à�tøåð 	ð 	ð 	ÝÐB½#¸a¹&¼&ÐBÐBÑCÔCÐCØ�4�4�4�4�4øøøøð	øøøs   ‚B#C. Â&AC. Ã.
D"Ã8DÄD"N)rg   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r2   r   r   r   r‰   r9   r'   r(   r.   r]   r/   r¥   rT   r   r   r
   r
   
   s^  € € € € € ØNÐNð&ð &ð &ð4°ð 4¸¸dÀ3ÈÀ8¼nÈeÐ>SÔ8Tð 4ð 4ð 4ð 4ðlD¨ð D°ð Dð Dð Dð Dð2#¨3ð #ð #ð #ð #ðJ¨3ð °4¸¸S¸´>ð ð ð ð ð6I¨$¨s°C¨x¬.ð I¸TÀ#ÀsÀ(¼^ð Ið Ið Ið IðV$¨$¨s°C¨x¬.ð $¸Uð $ð $ð $ð $ð85ð 5°ð 5ÀSð 5ÐRUð 5ð 5ð 5ð 5ð 5ð 5r   r
   )ÚosrL   r[   r   Útypingr   r   r   r   r   ÚPILr   rH   r
   rT   r   r   ú<module>r­      s¶   ðØ 	€	€	€	Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ø €€€Ø Ð Ð Ð Ð Ð Ø 	€	€	€	ðqð qð qð qð qñ qô qð qð qð qr   