U
    iw                     @   sP   d dl m Z  d dlmZmZmZmZ d dlmZ G dd dZG dd dZ	dS )	    datetime)OptionalListDictUnionget_connectionc                   @   sd   e Zd ZdZd	eeeeeeeeeeeeeeeeeeeeeeeeeeeedddZedddZ	dS )
OpportunityAndCostingDTOuI   DTO para la información unificada de Oportunidad y Encabezado de Costeo.N
costing_idcrm_opportunity_numbercrm_contact_namecrm_contact_typecrm_assigned_salespersoncrm_contact_adresscrm_contact_coloniacrm_contact_citycrm_contact_numbercrm_contact_countrycrm_contact_legal_identifiercrm_contact_zipcrm_contact_statecrm_contact_email	case_costsale_price_listsale_price_mindiscount_max_percentrun_time_numberrun_time_typetechnical_terms_and_conditionsFinancePercentTaxCodeCurrencyCodeQ_TaxRate_FrontESQ_TaxRate_FrontENQ_Currency_FrontESQ_Currency_FrontENc                 C   s   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	|| _
|| _|| _|| _|| _|| _|| _|| _|| _|| _|f| _|| _|f| _|f| _|f| _|f| _|f| _|| _d S )N	CostingIDCRM_OpportunityNumberCRM_ContactNameCRM_ContactTypeCRM_AssignedSalespersonCRM_ContactAdressCRM_ContactColoniaCRM_ContactCityCRM_ContactNumberCRM_ContactCountryCRM_ContactLegalIdentifierCRM_ContactZipCRM_ContactStateCRM_ContactEmailCaseCostSalePriceListSalePriceMinDiscountMaxPercentRunTimeNumberRunTimeTypeTechnicalTermsAndConditionsr!   r"   r#   r$   r%   r&   r'   )selfr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'    r?   hC:\Users\victor.barrera\Documents\proyectos\elepV3\Elep\src\App\api\services\quote_reception_services.py__init__   s8    z!OpportunityAndCostingDTO.__init__returnc                 C   s   | j | j| j| j| j| j| j| j| j| j	| j
| j| j| j| jt| jt| jt| j| j| j| jd | jdk	rxt| jnd| jd | jd | jd | jd | jd | jdS )z2Convierte el objeto a un diccionario serializable.r   Nr(   )r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   floatr8   r9   r:   r;   r<   r=   r!   r"   r#   r$   r%   r&   r'   )r>   r?   r?   r@   to_dict8   s:    z OpportunityAndCostingDTO.to_dict)
NNNNNNNNNN)
__name__
__module____qualname____doc__strrD   intrA   dictrE   r?   r?   r?   r@   r
      sN                           -r
   c                   @   s   e Zd ZdZeeee dddZee	e
eeeef f  dddZee	e
eef  ddd	Zeee	e
 dd
dZeeedddZeeedddZeeedddZdS )Quote_Reception_ServiceuY   Clase de servicio para manejar la lógica de recepción de datos de costeo y oportunidad.)costing_numrC   c                 C   sR  d}zt   }| }|||  | }W 5 Q R X |rt|d |d |d |d |d |d |d |d	 |d
 |d |d |d |d |d |d |d |d |d |d |d |d |d |d |d |d |d |d |d dW  5 Q R  W S W 5 Q R  W dS Q R X W n8 tk
rL } ztd |  W Y dS d}~X Y nX dS )!z{
        Consulta unificada que obtiene los datos de Q_CostingHead y Q_OpportunityCRM
        en una sola llamada.
        aO  
            SELECT TOP 1
                Q_CostingHead.CostingID,
                Q_OpportunityCRM.CRM_OpportunityNumber,
                Q_OpportunityCRM.CRM_ContactName,
                Q_OpportunityCRM.CRM_ContactType,
                Q_OpportunityCRM.CRM_AssignedSalesperson,
                Q_OpportunityCRM.CRM_ContactAdress,
                Q_OpportunityCRM.CRM_ContactColonia,
                Q_OpportunityCRM.CRM_ContactCity,
                Q_OpportunityCRM.CRM_ContactNumber,
                Q_OpportunityCRM.CRM_ContactCountry,
                Q_OpportunityCRM.CRM_ContactLegalIdentifier,
                Q_OpportunityCRM.CRM_ContactZip,
                Q_OpportunityCRM.CRM_ContactState,
                Q_OpportunityCRM.CRM_ContactEmail,
                Q_CostingHead.CaseCost,
                Q_CostingHead.SalePriceList,
                Q_CostingHead.SalePriceMin,
                Q_CostingHead.DiscountMaxPercent,
                Q_CostingHead.RunTimeNumber,
                Q_CostingHead.RunTimeType,
                Q_CostingHead.TechnicalTermsAndConditions,
                Q_CostingHead.FinancePercent,
                Q_CostingHead.TaxCode,
                Q_CostingHead.CurrencyCode,
                Q_TaxRate.FrontES as Q_TaxRate_FrontES,
                Q_TaxRate.FrontEN as Q_TaxRate_FrontEN,
                Q_Currency.FrontES as Q_Currency_FrontES,
                Q_Currency.FrontEN as Q_Currency_FrontEN
            FROM
                Q_CostingHead
            INNER JOIN
                Q_OpportunityCRM ON Q_CostingHead.CRM_OpportunityID = Q_OpportunityCRM.CRM_OpportunityID
            LEFT JOIN
                Q_TaxRate ON Q_TaxRate.TaxCode = Q_CostingHead.TaxCode 
                        AND Q_TaxRate.CurrencyCode = Q_CostingHead.CurrencyCode 
                        AND Q_TaxRate.Active >= 1
            LEFT JOIN
                Q_Currency ON Q_Currency.CurrencyCode = Q_CostingHead.CurrencyCode
                        AND Q_Currency.Active >= 1
            WHERE
                Q_CostingHead.CostingNum = ?
            ORDER BY
                Q_CostingHead.Version DESC;
        r                           	   
                                                      r   Nz#Error al obtener datos unificados: )r	   cursorexecutefetchoner
   	Exceptionprint)rN   queryconnrj   rower?   r?   r@   get_unified_data_by_costing_num_   sR    .

              z7Quote_Reception_Service.get_unified_data_by_costing_numrB   c               
   C   s   d} g }zpt  ^}| J}||  | }|D ],}||d |d t|d |d d q2W 5 Q R X W 5 Q R X |W S  tk
r } ztd|  g  W Y S d}~X Y nX dS )	ui   
        Consulta la tabla Q_TaxRate para obtener el código y la descripción de los impuestos.
        zTSELECT TaxCode, FrontES, TaxAmount, CurrencyCode    FROM Q_TaxRate WHERE Active = 1;r   rO   rP   rQ   )r"   FrontES	TaxAmountr#   z Error al obtener los impuestos: Nr	   rj   rk   fetchallappendrD   rm   rn   )ro   taxesrp   rj   rowsrq   rr   r?   r?   r@   	get_taxes   s"    

z!Quote_Reception_Service.get_taxesc               
   C   s   d} g }zft  T}| @}||  | }|D ]"}||d |d |d d q2W 5 Q R X W 5 Q R X |W S  tk
r } ztd|  g  W Y S d}~X Y nX dS )uw   
        Consulta la tabla Q_Currency para obtener el código, el nombre y el símbolo de las monedas activas.
        zJSELECT CurrencyCode, FrontES, CurrSymbol FROM Q_Currency WHERE Active = 1;r   rO   rP   )r#   rt   
CurrSymbolzError al obtener las monedas: N)r	   rj   rk   rw   rx   rm   rn   )ro   
currenciesrp   rj   rz   rq   rr   r?   r?   r@   get_currencies   s    

z&Quote_Reception_Service.get_currenciesc                 C   s   d}g }zt  z}| f}|||  | }|D ]F}||d |d |d t|d |d t|d t|d d	 q4W 5 Q R X W 5 Q R X |W S  tk
r } ztd
|  g  W Y S d}~X Y nX dS )uN   
        Consulta Q_CostingDetail para obtener las líneas de costeo.
        a  
            SELECT 
                CostingLine,
                PartNum,
                PartDescription,
                Qty,
                UOMCode,
                UnitPrice,
                Amount
            FROM Q_CostingDetail
            WHERE CostingID = (
                SELECT TOP 1 CostingID 
                FROM Q_CostingHead 
                WHERE CostingNum = ? 
                ORDER BY Version DESC
            )
            ORDER BY CostingLine ASC;
        r   rO   rP   rQ   rR   rS   rT   )CostingLinePartNumPartDescriptionQtyUOMCode	UnitPriceAmountz%Error al obtener detalles de costeo: Nrv   )rN   ro   detailsrp   rj   rz   rq   rr   r?   r?   r@   get_costing_details   s*    



	z+Quote_Reception_Service.get_costing_details)datarC   c              7   C   s  zddl m} ddlm} | d}d}t ^}| H}||| | }|d }d}	||	|f | }
|
r|
d nd}|std|  W 5 Q R  W 5 Q R  W d	S |d }|d
 r|d
 nd}|d| | }|d sd
n
|d d
 }| d}|}|r:|d| | }|r:|d r:|d }td| d|  td|d  d td|d  d td|d  d |d r|d 	 nd	}|d r|d 	 nd	}|d r|d 	 nd	}|||| d| d| d| d|d |d |d |d |d |d  |d! |d" |d# |p<d$|pDd%|pLd&| d'd| d(d| d)d||| d*d||| d+d
| d,g t
| d,g | d-| d.| jd/d0| d1d2| d3d4| d5| d6| d7| d8| d9| d:| d;| d<| d=| d>| d?| d@| dA| dBdC3}tdD|dE   |dH|}|W  5 Q R  W  5 Q R  W S Q R X W 5 Q R X W nH tk
r } z(tdG|  dd	l}|  W Y d	S d	}~X Y nX d	S )Iuw   
        Genera HTML de vista previa de la cotización SIN guardar en BD.
        Retorna el HTML renderizado.
        r   )render_templater   r)   u  
                SELECT TOP 1
                    Q_CostingHead.CostingNum,
                    Q_CostingHead.Version,
                    
                    -- Cliente
                    Q_OpportunityCRM.CRM_ContactName,
                    Q_OpportunityCRM.CRM_ContactType,
                    Q_OpportunityCRM.CRM_OpportunityNumber,
                    Q_OpportunityCRM.CRM_ContactEmail,
                    Q_OpportunityCRM.CRM_ContactNumber,
                    Q_OpportunityCRM.CRM_ContactCity,
                    Q_OpportunityCRM.CRM_ContactState,
                    Q_OpportunityCRM.CRM_ContactCountry,
                    Q_OpportunityCRM.CRM_ContactAdress,
                    
                    -- ✅ El vendedor es el UserID de la oportunidad
                    TRIM(CONCAT(
                        ISNULL(Seller.FirstName, ''), ' ',
                        ISNULL(Seller.MiddleName, ''), ' ', 
                        ISNULL(Seller.LastName, ''), ' ',
                        ISNULL(Seller.SecondLastName, '')
                    )) AS VendedorNombre,
                    ISNULL(Seller.Email, '') AS VendedorEmail,
                    ISNULL(Seller.ContactPhone, '') AS VendedorTelefono,
                    Q_CostingHead.TaxCode

                    
                FROM Q_CostingHead
                
                INNER JOIN Q_OpportunityCRM 
                    ON Q_CostingHead.CRM_OpportunityID = Q_OpportunityCRM.CRM_OpportunityID
                
                -- ✅ JOIN directo: El vendedor es Q_OpportunityCRM.UserID
                LEFT JOIN Profiles AS Seller
                    ON Q_OpportunityCRM.UserID = Seller.UserID
                
                WHERE Q_CostingHead.CostingID = ?
            r\   z
                        select TaxPercent
                        from Q_TaxRate
                        where TaxCode = ?
                    u   ❌ No se encontró CostingID: NrO   m
                        SELECT MAX(Version) FROM Q_QuotationHead WHERE QuotationNum = ?
                    r#   zk
                            SELECT FrontES FROM Q_Currency WHERE CurrencyCode = ?
                        u   💱 Moneda: z -> u   🔍 DEBUG - VendedorNombre: 'rY   'u   🔍 DEBUG - VendedorEmail: 'rZ   u    🔍 DEBUG - VendedorTelefono: 'r[   r7   r;   r<   r=   rP   rQ   rR   rS   rT   rU   rV   rW   rX   zNo asignadozventas@igsa.comzN/A	SalePriceDiscountPercentr   TotalAmountOvercostFactorQuotationLinesz%d/%m/%Yz%H:%MIGSAz"Integradora de Servicios Avanzadosproyecto_nombrezPor definirproyecto_requerimientosZNingunocaseSelectedcase1AnticipoPercentcase1FiniquitoPercentcase2AnticipoPercentcase2FrequencyTypecase2Periodicidadcase2Cantidadcase2CantidadPeriodicidadcase3FrequencyTypecase3Periodicidadcase3Cantidadcase3CantidadPeriodicidadcase4DiasFinanciamientocase5PlazoCreditoFlag)3quotation_numversionr   caso_costeor;   r<   r=   cliente_nombretipo_contactooportunidad_crmcliente_emailcliente_telefonocliente_ciudadcliente_estadocliente_paisZcliente_direccionvendedor_asignadovendedor_emailvendedor_telefonoprecio_listadescuento_porcentajeprecio_ofertaimpuesto_codigoZimpuedesto_porcentajeprecio_totalmonedamoneda_codigofactor_sobrecostolineastotal_lineasfecha_actualZhora_actualu   año_actualempresaempresa_completar   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   u    ✅ Vendedor final en template: r   *Emails/Ventas/Cotiz/PreviewCotizacion.htmlu#   ❌ Error al generar vista previa: )r   )flaskr   r   getr	   rj   rk   rl   rn   striplennowstrftimeyearrm   	traceback	print_exc)r   r   r   r   ro   rp   rj   rq   ZtaxCodequery2tax_rowZtax_percentr   Zcurrent_versionversion_resultZnext_versioncurrency_codeZcurrency_nameZcurrency_resultvendedor_nombrer   r   template_datahtmlrr   r   r?   r?   r@   generate_quotation_preview  s    
+









T
2z2Quote_Reception_Service.generate_quotation_previewc                 C   sr  z&t  }| }| d}|d| | }|s`dddW  5 Q R  W  5 Q R  W S |d }|d| | }|d sdn
|d d }| d	| }td
|  d}	||	||| d| d| dd| dd| d| d| d| d| d| d| d| d| d| d| d| d| d| d| d| d| d | d!f | d"g }
d#}|
D ]T}||||d$|d%|d&|d'|d(|d)|d*|df	 q|  td+| d, W 5 Q R X d-d.||d/W  5 Q R  W S Q R X W nD tk
rl } z$td0|  dt|d W Y S d1}~X Y nX d1S )2u   
        Crea una nueva cotización en Q_QuotationHead y Q_QuotationDetail.
        Envía notificación por correo al departamento de ingeniería.
        r)   zf
                        SELECT CostingNum FROM Q_CostingHead WHERE CostingID = ?
                    FzCostingID no encontrado)successerrorr   r   rO   -u   Creando cotización: a  
                        INSERT INTO Q_QuotationHead (
                            QuotationNum,
                            Version,
                            CaseCost,
                            SalePrice,
                            DiscountPercent,
                            OvercostFactor,
                            Amount,
                            TaxCode,
                            TotalAmount,
                            CurrencyCode,
                            Active,
                            caseSelected,
                            case1AnticipoPercent,
                            case1FiniquitoPercent,
                            case2AnticipoPercent,
                            case2FrequencyType,
                            case2Periodicidad,
                            case2Cantidad,
                            case2CantidadPeriodicidad,
                            case3FrequencyType,
                            case3Periodicidad,
                            case3Cantidad,
                            case3CantidadPeriodicidad,
                            case4DiasFinanciamiento,
                            case5PlazoCreditoFlag
                        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                    r7   r   r   r   r   r"   r   r#   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   a  
                        INSERT INTO Q_QuotationDetail (
                            QuotationID,
                            QuotationLine,
                            CostingLineID,
                            PartNum,
                            PartDescription,
                            Qty,
                            UOMCode,
                            UnitPrice,
                            Amount
                        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
                    ZQuotationLineZCostingLineIDr   r   r   r   r   u   Cotización z creada exitosamente en BDTu   Cotización creada exitosamente)r   messageZQuotationIDVersionu   Error al crear cotización: N)	r	   rj   r   rk   rl   rn   commitrm   rJ   )r   rp   rj   r   Zcosting_resultr   r   r   quotation_idinsert_head_queryZquotation_linesinsert_detail_querylinerr   r?   r?   r@   create_quotation  s    

$


z(Quote_Reception_Service.create_quotation)r   rC   c                 C   s   zddl m} | }| }|d|  | }|r|d rL|d  nd|d rb|d  nd|d rx|d  nddW  5 Q R  W  5 Q R  W S W 5 Q R X W 5 Q R X W n0 tk
r } ztd|  W 5 d}~X Y nX ddddS )	u!   Obtiene información del vendedorr   r   a  
                        SELECT TOP 1
                            TRIM(CONCAT(
                                ISNULL(Seller.FirstName, ''), ' ',
                                ISNULL(Seller.MiddleName, ''), ' ', 
                                ISNULL(Seller.LastName, ''), ' ',
                                ISNULL(Seller.SecondLastName, '')
                            )) AS VendedorNombre,
                            ISNULL(Seller.Email, '') AS VendedorEmail,
                            ISNULL(Seller.ContactPhone, '') AS VendedorTelefono
                            
                        FROM Q_CostingHead
                        INNER JOIN Q_OpportunityCRM 
                            ON Q_CostingHead.CRM_OpportunityID = Q_OpportunityCRM.CRM_OpportunityID
                        LEFT JOIN Profiles AS Seller
                            ON Q_OpportunityCRM.UserID = Seller.UserID
                        WHERE Q_CostingHead.CostingID = ?
                    NrO   rP   )nombreemailtelefonou+   ⚠️ Error al obtener info del vendedor: )Consultas_SQL.conexionr	   rj   rk   rl   r   rm   rn   )r   r	   rp   rj   rq   rr   r?   r?   r@   get_seller_infoa  s     
8 z'Quote_Reception_Service.get_seller_infoN)rF   rG   rH   rI   staticmethodrK   r   r
   rs   r   r   rJ   r   rD   r{   r~   r   rL   r   r   r   r?   r?   r?   r@   rM   \   s"   O$- S 	rM   N)
r   typingr   r   r   r   r   r	   r
   rM   r?   r?   r?   r@   <module>   s   T