
    i.z                         S SK r S SKJr  S SKJrJr  S SKJrJrJr  \(       a  \r	O\r	\r
 " S S5      rS\S\S	\4S
 jrS\S\4S jrS\S	\S\S\4S jrS\S\4S jrS\S\4S jrg)    N)datetime)
ProductivoENVIRONMENT)get_connectionbdproductivoget_connectionget_connectionERPc            
          \ rS rSrS rS\S\S\4S jrS\S\S\S\4S	 jr	S\S\S\
4S
 jrS\S\S\
4S jrS\S\4S jrS\S\4S jrS\S\S\S\S\4
S jrS\S\S\S\S\4
S jrS\4S jrS\4S jrS rS\S\4S jrS\4S jrSrg)BOMExploder   c                     S U l         g )N
process_id)selfs    ڇC:\Users\victor.barrera\Documents\proyectos\elepV3\Elep\src\Consultas_SQL\SupYCtrol\GerenteSyC\UtilityMaterials\GSYCManufacBOMIngSQL.py__init__BOMExploder.__init__   s	        part_numrevisionreturnc                    [        [        R                  " 5       5      U l        [        R
                  " 5       n U R                  X5        U R                  5       nU R                  XAUSS5        [        R
                  " 5       U-
  R                  5       S-  nU R                  U5        SU R                  SS.$ ! [         a=  nU R                  [        U5      5        S[        U5      U R                  S.s S	nA$ S	nAff = f)
u?   
Explota una BOM multinivel y retorna información del proceso
r      i  TzBOM explodida exitosamente)successr   messageF)r   errorr   N)struuiduuid4r   r   now_init_process_control_get_pricingMO_explode_recursivetotal_seconds_update_process_stats	Exception_mark_process_error)r   r   r   
start_time	PricingMOprocessing_timees          r   explode_bomBOMExploder.explode_bom   s     djjl+\\^
	&&x: ++-I ##I1aH  (||~
:IIKdRO&&7  "oo7   	$$SV, Q"oo 	s   A>B9 9
D 2C;5D ;D levelorder_startc                     UnU R                  X5      nU H6  nU R                  [        U5      nU R                  XqX#XX[        5        US-  nM8     U R	                  X5      n	U	 H  n
U
S   S:X  a  U R                  U
5      nOSSSSSSSSSSSS.n[        SU5        U R                  XX#X[5        US-  nU
S   S	:X  d  M[  U R                  U
S
   5      nU(       d  Mx  U R                  [        U
S
   UUS-   U5      nM     U$ )u5   Explota un nivel específico de la BOM recursivamenter   TypePNr   	CALCULADO)TranNumTranDateMtlUnitCostLbrUnitCostBurUnitCostSubUnitCostMtlBurUnitCostExtCostPOLineStatusz$$$$MPartNum)
_get_operations_get_totalcost_operationr(   _insert_operation_get_materials_get_pricingMaterialsprint_insert_material_get_latest_revisionr"   )r   r   r   r-   r.   current_order
operationsopCost	materialsmaterialCostMatchild_revisions                r   r"   BOMExploder._explode_recursive>   s=   # ))(=
B00B?D ""2-W`aQM  '';	!H3&44X>  $ $#'#'#'#'&*  ) &'" !!(h}^QM 3&!%!:!:8I;N!O!>$($;$;! +&	%%M7 "F r   c           	         Sn[        5       nU(       d  [        S5      e UR                  5       nUR                  X1U45        UR                   Vs/ s H  ofS   PM	     nnUR                  5        Vs/ s H  n[        [        Xx5      5      PM     snUR                  5         $ s  snf s  snf ! UR                  5         f = f)-Obtiene materiales de la BOM desde Epicor ERPa  
        SELECT 
            Erp.PartMtl.MtlSeq AS Seq,
            Erp.Part.TypeCode AS [Type],
            CASE Erp.Part.TypeCode 
                WHEN 'M' THEN 'Fabricado'
                WHEN 'P' THEN 'Material' 
                ELSE Erp.Part.TypeCode 
            END AS TipoDesc,
            Erp.PartMtl.MtlPartNum AS PartNum,
            
            (
                SELECT TOP 1 Erp.PartRev.RevisionNum 
                FROM Erp.PartRev 
                WHERE Erp.PartRev.Company = Erp.PartMtl.Company 
                    AND Erp.PartRev.PartNum = Erp.PartMtl.MtlPartNum 
                ORDER BY Erp.PartRev.EffectiveDate DESC 
            ) AS Rev,

            Erp.Part.PartDescription,
            LEFT(Erp.Part.PartDescription, 35) AS ShortDescription,
            Erp.PartMtl.QtyPer,
            Erp.PartMtl.UOMCode

        FROM 
            Erp.PartMtl 
        LEFT JOIN 
            Erp.Part ON Erp.PartMtl.Company = Erp.Part.Company 
            AND Erp.PartMtl.MtlPartNum = Erp.Part.PartNum 
        WHERE 
            Erp.PartMtl.Company = 'IGSA' 
            AND Erp.PartMtl.PartNum = ?
            AND Erp.PartMtl.RevisionNum = ?
        ORDER BY 
            Erp.PartMtl.MtlSeq
           Error de conexión a ERPr   	ConexionBD_ERPr%   cursorexecutedescriptionfetchalldictzipclose	r   r   r   query
connectionrV   columncolumnsrows	            r   rC   BOMExploder._get_materialsr   s    #J $%
677	&&(FNN5X"67/5/A/AB/AVay/AGB7=7HI7HDW*+7HI CI)   1B. B$B. 3B)B. $
B. .C c           	         Sn[        5       nU(       d  [        S5      e UR                  5       nUR                  X1U45        UR                   Vs/ s H  ofS   PM	     nnUR                  5        Vs/ s H  n[        [        Xx5      5      PM     snUR                  5         $ s  snf s  snf ! UR                  5         f = f)z.Obtiene operaciones de la BOM desde Epicor ERPa-  
        SELECT 
            Erp.PartOpr.OprSeq AS Seq,
            Erp.PartOpr.SubContract AS [Type],
            CASE Erp.PartOpr.SubContract 
                WHEN 0 THEN 'Mano de Obra' 
                WHEN 1 THEN 'Subcontrato' 
            END AS TipoDesc,
            Erp.PartOpr.OpCode,
            Erp.OpMaster.OpDesc,
            LEFT(Erp.OpMaster.OpDesc, 35) AS ShortDescription,
            Erp.PartOpr.EstProdHours,
            '' AS UOMCode                         

        FROM Erp.PartOpr 
        LEFT JOIN Erp.OpMaster ON Erp.PartOpr.Company = Erp.OpMaster.Company 
            AND Erp.PartOpr.OpCode = Erp.OpMaster.OpCode 
        WHERE Erp.PartOpr.Company = 'IGSA' 
            AND Erp.PartOpr.PartNum = ?
            AND Erp.PartOpr.RevisionNum = ?
        ORDER BY Erp.PartOpr.OprSeq
        rS   r   rT   r]   s	            r   r@   BOMExploder._get_operations   s    . $%
677	&&(FNN5X"67/5/A/AB/AVay/AGB7=7HI7HDW*+7HI CIrd   c                     Sn[        5       nU(       d  g UR                  5       nUR                  X!45        UR                  5       nU(       a  US   OS UR	                  5         $ ! UR	                  5         f = f)u/   Obtiene la revisión más reciente de una partez
        SELECT TOP 1 RevisionNum 
        FROM Erp.PartRev 
        WHERE Company = 'IGSA' AND PartNum = ?
        ORDER BY EffectiveDate DESC
        Nr   )rU   rV   rW   fetchoner\   )r   r   r^   r_   rV   results         r   rG    BOMExploder._get_latest_revision   sm     $%
	&&(FNN5+.__&F &6!9D0Js   ?A' 'A9c                    Sn[        5       nU(       d  [        S5      e UR                  5       nUR                  X0R                  X45        UR                  5         UR                  5         g! UR                  5         f = f)z4Inicializa el registro de control del proceso en VPSz
        INSERT INTO BOM_Process_Control 
        (ProcessID, PartNumFather, RevisionNumFather, Status, ProcessDate)
        VALUES (?, ?, ?, 'Processing', GETDATE())
           Error de conexión a VPSN)ConexionBD_VPSr%   rV   rW   r   commitr\   )r   r   r   r^   r_   rV   s         r   r    !BOMExploder._init_process_control   so     $%
677	&&(FNN5??H"GHJs   =A. .B rM   part_father
rev_fatherorderc                    Sn[        5       nU(       d  [        S5      e UR                  5       nUR                  UU R                  X#XTUS   US   US   US   US   US   US	   US
   [
        S   [
        S   [
        S   [
        S   [
        S   [
        S   [
        S   [
        S   [
        S   [
        S   [
        S   45        UR                  5         UR                  5         g! UR                  5         f = f)z3Inserta un material en la tabla BOM_Materials (VPS)a  
        INSERT INTO BOM_Materials 
        (ProcessID, PartNumFather, RevisionNumFather, [Order], [Level], Seq, [Type], 
        PartNum, Rev, PartDescription, ShortDescription, QtyPer, UOMCode)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        rl   Seqr0   r?   RevPartDescriptionShortDescriptionQtyPerUOMCoder3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   N)rm   r%   rV   rW   r   rN   rn   r\   )	r   rM   rp   rq   r-   rr   r^   r_   rV   s	            r   rF   BOMExploder._insert_material   s    $%
677	&&(FNN5%&!18I3F*;!<+,hx.@(9BU	"GJ$79O&(>@V()79+=wv0A	# 	  Js   B7C( (C:	operationc                 n   Sn[        5       nU(       d  [        S5      e UR                  5       nUR                  UU R                  X#XTUS   US   US   SUS   US   US	   US
   [
        S   [
        S   [        45        UR                  5         UR                  5         g! UR                  5         f = f)u7   Inserta una operación en la tabla BOM_Operations (VPS)a,  
        INSERT INTO BOM_Operations 
        (ProcessID, PartNumFather, RevisionNumFather, [Order], [Level], Seq, [Type], 
        OpCode, Rev, OpDesc, ShortDescription, EstProdHours, UOMCode, LbrUnitCost, BurUnitCost, ExtCost)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        rl   rt   r0   OpCodeNOpDescrw   EstProdHoursry   r6   r7   )	rm   r%   rV   rW   r   r(   rK   rn   r\   )	r   r{   rp   rq   r-   rr   r^   r_   rV   s	            r   rB   BOMExploder._insert_operation  s     $%
677	&&(FNN5%% )F"3Yx5Hi)95G+H.)9Y+?-(-(#  Js   A1B" "B4processing_time_msc           	      H   Sn[        5       nU(       d  g UR                  5       nUR                  UU R                  U R                  U R                  [	        U5      U R                  45        UR                  5         UR                  5         g! UR                  5         f = f)u#   Actualiza estadísticas del procesoa  
        UPDATE BOM_Process_Control 
        SET Status = 'Completed',
            TotalMaterials = (SELECT COUNT(*) FROM BOM_Materials WHERE ProcessID = ?),
            TotalOperations = (SELECT COUNT(*) FROM BOM_Operations WHERE ProcessID = ?),
            MaxLevel = (SELECT ISNULL(MAX([Level]), 0) FROM BOM_Materials WHERE ProcessID = ?),
            ProcessingTime_MS = ?
        WHERE ProcessID = ?
        N)rm   rV   rW   r   intrn   r\   )r   r   r^   r_   rV   s        r   r$   !BOMExploder._update_process_stats,  s     $%
	&&(FNN5$//&'#  Js   A(B B!error_messagec                     Sn[        5       nU(       d  g UR                  5       nUR                  X!U R                  45        UR	                  5         UR                  5         g! UR                  5         f = f)u   Marca el proceso como erróneozx
        UPDATE BOM_Process_Control 
        SET Status = 'Error', ErrorMessage = ?
        WHERE ProcessID = ?
        N)rm   rV   rW   r   rn   r\   )r   r   r^   r_   rV   s        r   r&   BOMExploder._mark_process_errorF  sf     $%
	&&(FNN5$//"BCJs   =A$ $A6c                 ~   Sn[        5       nU(       d  [        S5      e UR                  5       nUR                  U5        UR	                  5       nU(       aB  UR
                   Vs/ s H  oUS   PM	     nn[        [        Xd5      5      UR                  5         $ [        S5      es  snf ! UR                  5         f = f)zObtiene desde VPS z`
        SELECT 
            LbrUnitCost, 
            BurUnitCost
        FROM CostLbr
        rl   r   z"No se encontraron datos de CostLbr)	rm   r%   rV   rW   rh   rX   rZ   r[   r\   )r   r^   r_   rV   rb   r`   ra   s          r   r!   BOMExploder._get_pricingMO[  s     $%
677
	&&(FNN5!//#C393E3EF3E!93EFC-.    DEE G
 s   AB* &B%4B* B* *B<	pricingMOc                     [        UR                  S5      =(       d    S5      n[        UR                  S5      =(       d    S5      n[        UR                  S5      =(       d    S5      nX4-  X5-  -   nU$ )Nr   r   r6   r7   )floatget)r   r   r{   	est_hourslbr_unit_costbur_unit_cost
total_costs          r   rA   $BOMExploder._get_totalcost_operationu  s`    )--7<1=	immM:?a@immM:?a@/I4MN
r   c           
         Sn[        5       nU(       d  [        S5      e UR                  5       nUR                  X!S   US   US   US   US   US   45        UR	                  5       nU(       aB  UR
                   Vs/ s H  ofS   PM	     nn[        [        Xu5      5      UR                  5         $ [        S5      es  snf ! UR                  5         f = f)rR   uj  
        SELECT
            TranNum,
            TranDate,
            MtlUnitCost,
            LbrUnitCost,
            BurUnitCost,
            SubUnitCost,
            MtlBurUnitCost,
            PONum AS PO,
            POLine AS Line,
            ([MtlUnitCost] * ? + [LbrUnitCost] * ? + [BurUnitCost] * ? + [SubUnitCost] * ? + [MtlBurUnitCost] * ?) AS ExtCost,
            CASE            
                -- Si está en los últimos 90 días 
                WHEN TranDate >= DATEADD(day, -90, GETDATE()) THEN 'COSTEADOS'
                
                -- Si está entre 90 y 180 días 
                WHEN TranDate >= DATEADD(day, -180, GETDATE())
                    AND TranDate < DATEADD(day, -90, GETDATE()) THEN 'REVISION' 

                -- Si no cumple las condiciones anteriores (sin TranNum/TranDate o más de 180 días)
                ELSE 'INSERTAR'
            END AS Status                
                    
        FROM 
            Erp.PartTran 
        WHERE 
            Erp.PartTran.Company = 'IGSA' 
            AND Erp.PartTran.PartNum = ?
        ORDER BY Erp.PartTran.TranDate DESC 
        rS   rx   r?   r   z#No se encontraron datos de PartTran)	rU   r%   rV   rW   rh   rX   rZ   r[   r\   )r   rM   r^   r_   rV   rb   r`   ra   s           r   rD   !BOMExploder._get_pricingMaterials  s    @ $%
677	&&(FNN5H#5x7I8T\K]_ghp_qs{  }E  tF  HP  QZ  H[  #\  ]//#C393E3EF3E!93EFC-.
    EFF	 G s   AC >B=C 2C Cr   N)__name__
__module____qualname____firstlineno__r   r   rZ   r+   r   r"   listrC   r@   rG   r    rF   rB   r   r$   r&   r!   rA   rD   __static_attributes__ r   r   r
   r
      s2   "C "3 "4 "H23 2# 2c 2X[ 2h1s 1c 1d 1f# #s #t #JS S *c S & C S Y\ eh @4 c s [^ gj 4 4 *4$ 4 1d 1r   r
   new_ext_costr   r   c                 \   Sn [        5       nU(       d  SSS.U(       a  UR                  5         $ $ UR                  5       nSnUR                  XPX45        UR                  nUR                  5         US:X  a#  SSU SU 3S.U(       a  UR                  5         $ $ S	S
US.U(       a  UR                  5         $ $ ! [         aJ  nU(       a  UR                  5         SS[        U5       3S.s SnAU(       a  UR                  5         $ $ SnAff = f! U(       a  UR                  5         f f = f)zDActualiza el ExtCost y cambia el Status a MANUAL en la base de datosNF%   Error de conexión a la base de datosr   r   z
        UPDATE BOM_Materials
        SET ExtCost = ?,
            Status = 'MANUAL'
        WHERE ProcessID = ?
          AND PartNum = ?
        r   u(   No se encontró el registro. ProcessID: z, PartNum: TzCosto actualizado exitosamente)r   r   updated_rowszError en la base de datos: )	rm   r\   rV   rW   rowcountrn   r%   rollbackr   )r   r   r   r_   rV   update_query	row_countr*   s           r   get_status_manualr     sC    J0#%
 @X  O ""$ 	|J%IJ OO	> CJ<{[cZde&   7%
    
!23q6(;
 	

  
  s;   B: AB: B: :
D'D	+D,D 	DD D+r   c                    SnSnSnSn[        5       nU(       d  SSS.$  UR                  5       nUR                  XU 45        0 n/ nUR                  5        H  n	U	S   n
[	        U	S	   5      [        U	S
   5      [	        U	S   5      [        U	S   5      [	        U	S   5      S.Xz'   UR                  U
[	        U	S	   5      [        U	S
   5      [	        U	S   5      [        U	S   5      [	        U	S   5      S.5        M     U(       d  SSS.U(       a  UR                  5         $ $ UR                  X@45        / nSnUR                  5        Hg  n	U	S   n
UR                  U
UR                  U
0 5      R                  SS5      [	        U	S	   5      [        U	S
   5      S.5        U[	        U	S	   5      -  nMi     UR                  X045        UR                  5       n/ nU H  u  pnUR                  U
0 5      R                  SS5      nUR                  UUX
45        UR                  U
U(       a  [	        U5      OSUSUR                  U
0 5      R                  SS5      UR                  U
0 5      R                  SS5      S.5        M     UR                  5         [        [        S UR                  5        5       5      S5      n[        [        S UR                  5        5       5      S5      nSUU[        US5      UUUU S.U(       a  UR                  5         $ $ ! [         aA  nUR                  5         S[        U5      U S.s S nAU(       a  UR                  5         $ $ S nAff = f! U(       a  UR                  5         f f = f)Nu  
    -- Materiales comprados agrupados por padre con precisión decimal
    WITH MaterialCosts AS (
        SELECT 
            PartNumFather AS PartNum,
            CAST(SUM(COALESCE(CAST(ExtCost AS DECIMAL(18,8)), 0)) AS DECIMAL(18,8)) AS MaterialCost,
            COUNT(*) AS MaterialComponents
        FROM BOM_Materials
        WHERE ProcessID = ? 
          AND Type = 'P'
        GROUP BY PartNumFather
    ),
    
    -- Costos de operaciones agrupados por padre con precisión decimal
    OperationCosts AS (
        SELECT 
            PartNumFather AS PartNum,
            CAST(SUM(COALESCE(CAST(ExtCost AS DECIMAL(18,8)), 0)) AS DECIMAL(18,8)) AS OperationCost,
            COUNT(*) AS OperationComponents
        FROM BOM_Operations
        WHERE ProcessID = ?
        GROUP BY PartNumFather
    ),
    
    -- Costos combinados con verificación de NULLs
    CombinedCosts AS (
        SELECT
            m.PartNum,
            CAST(COALESCE(m.MaterialCost, 0) AS DECIMAL(18,8)) AS MaterialCost,
            m.MaterialComponents,
            CAST(COALESCE(o.OperationCost, 0) AS DECIMAL(18,8)) AS OperationCost,
            o.OperationComponents,
            CAST(COALESCE(m.MaterialCost, 0) + COALESCE(o.OperationCost, 0) AS DECIMAL(18,8)) AS TotalCost
        FROM MaterialCosts m
        LEFT JOIN OperationCosts o ON m.PartNum = o.PartNum
        
        UNION
        
        SELECT
            o.PartNum,
            CAST(0 AS DECIMAL(18,8)) AS MaterialCost,
            0 AS MaterialComponents,
            CAST(o.OperationCost AS DECIMAL(18,8)) AS OperationCost,
            o.OperationComponents,
            CAST(o.OperationCost AS DECIMAL(18,8)) AS TotalCost
        FROM OperationCosts o
        WHERE NOT EXISTS (SELECT 1 FROM MaterialCosts m WHERE m.PartNum = o.PartNum)
    )
    
    SELECT 
        PartNum,
        MaterialCost,
        MaterialComponents,
        OperationCost,
        OperationComponents,
        TotalCost
    FROM CombinedCosts
    WHERE PartNum IS NOT NULL
    ORDER BY PartNum
    z
    UPDATE BOM_Materials
    SET ExtCost = CAST(? AS DECIMAL(18,8)),
        Status = 'CALCULADO'
    WHERE ProcessID = ?
      AND PartNum = ?
      AND Type = 'M'  -- FABRICADO
    z
    SELECT PartNum, 
           CAST(ExtCost AS DECIMAL(18,8)) AS ExtCost, 
           Status
    FROM BOM_Materials
    WHERE ProcessID = ? 
      AND Type = 'M'  -- FABRICADO
    z
    SELECT 
        PartNumFather, 
        SUM(COALESCE(CAST(ExtCost AS DECIMAL(18,8)), 0)) AS TotalMaterialCost,
        COUNT(*) AS Components
    FROM BOM_Materials 
    WHERE ProcessID = ? 
      AND Type = 'P'
    GROUP BY PartNumFather
    Fr   r   r   r               )material_costmaterial_componentsoperation_costoperation_componentsr   )partNummaterialCostmaterialComponentsoperationCostoperationComponents	totalCostz+No se encontraron componentes para calcular        r   )r   calculatedCostr   
componentsr2   r   r   )r   previousCostnewCoststatusChanger   r   c              3   *   #    U  H	  oS    v   M     g7f)r   Nr   .0vs     r   	<genexpr>(calculate_total_costs.<locals>.<genexpr>  s     )VCUaL/CU   c              3   *   #    U  H	  oS    v   M     g7f)r   Nr   r   s     r   r   r     s     (YFX+;)<FXr   T)r   updatedMaterialstotalCalculatedCosttotalMaterialCosttotalOperationCostverificationDatacostBreakdown	processId)r   r   r   )rm   rV   rW   rY   r   r   appendr\   r   rn   roundsumvaluesr%   r   r   )r   calculate_costs_queryupdate_fabricated_materialsget_fabricated_materialsverification_querydatabase_connectiondatabase_cursor	cost_datacost_breakdownrb   r   verification_datatotal_material_costfabricated_materialsupdated_materialscurrent_costcurrent_statusnew_costtotal_calculated_costtotal_operation_costr   s                        r   calculate_total_costsr     s   ;z# 	 )* +RSS](-446 	 5J7OP 	"++-C1vH!&s1v'*3q6{"'A-(+CF#CFm#I !!# %c!f&)#a&k!&s1v'*3q6{"3q6]#  .$ $/\]@ %%' { 	 2MB!"++-C1vH$$#"+--""="A"A,PQ"R %c!f!#a&k	&   5Q=0 . 	 8-H.779 6J2HN }}Xr266|QGH##+:0
 $$#7Cl 3# +&/mmHb&A&E&EF[]^&_'0}}Xr'B'F'FG]_`'a&  7K" 	""$ !&c)V9CSCSCU)V&VXY Z$S(YiFVFVFX(Y%Y[\]  1#8!&':A!>"6 1+#	
& %%'   
$$&Z#
 	
 %%' 
 %%' s7   C(L !GL 
MM;M<M! MM! !M;r   c           	      |   Sn [        5       nU(       d  [        S5      eUR                  5       nUR                  X1X XU 45        UR	                  5       nU(       d  SSS.U(       a  UR                  5         $ $ US   S   b  [        US   S   5      OSn[        U5      S	:  a  US	   S   b  [        US	   S   5      OSnS
Xx-   UUS.U(       a  UR                  5         $ $ ! [         a3  n	SS[        U	5       3S.s Sn	A	W(       a  UR                  5         $ $ Sn	A	ff = f! W(       a  UR                  5         f f = f)u-   Función con mejor manejo de errores para SQLa  
    SELECT
        SUM(COALESCE(BOM_Materials.ExtCost, 0)) AS TotalCostMaterial
    FROM
        BOM_Materials
    WHERE
        BOM_Materials.PartNumFather = ?
        AND BOM_Materials.RevisionNumFather = ?
        AND BOM_Materials.ProcessID = ?

    UNION ALL

    SELECT
        SUM(COALESCE(BOM_Operations.ExtCost, 0)) AS TotalCostOperation
    FROM 
        BOM_Operations
    WHERE
        BOM_Operations.PartNumFather = ?
        AND BOM_Operations.RevisionNumFather = ?
        AND BOM_Operations.ProcessID = ?
    z&No se pudo conectar a la base de datosFzNo se encontraron registrosr   r   Nr   r   T)r   r   r   r   zError en base de datos: )	rm   r%   rV   rW   rY   r\   r   lenr   )
r   r   r   r^   r_   rV   resultsr   r   r*   s
             r   get_total_cost_for_parentr     sJ   E,#%
DEE""$uxS]^_//#$/LM   18
10Igajm,s14W1AgajQRmF_wqz!}-eh &7)+	
    P -Ec!fX+NOO P  s7   AC! 9AC! !
D+D;D<D! DD! !D;c           	      $   SnSnSn[        5       nU(       d  SS0$  UR                  5       nUR                  X45        UR                   Vs/ s H  ofS   PM	     nnUR	                  5        Vs/ s H  n[        [        Xx5      5      PM     n	nUR                  X 45        UR                   Vs/ s H  ofS   PM	     n
nUR	                  5        Vs/ s H  n[        [        X5      5      PM     nnUR                  X045        UR                   Vs/ s H  ofS   PM	     nnUR                  5       nU(       a  [        [        X5      5      OSnU	UUS.UR                  5         $ s  snf s  snf s  snf s  snf s  snf ! UR                  5         f = f)	z,Obtiene datos completos de una BOM explodidaaJ  
    SELECT 
        [Level], [Order], Seq, [Type], PartNum, Rev, 
        PartDescription, ShortDescription, QtyPer, UOMCode, TranNum,
        TranDate, MtlUnitCost, LbrUnitCost, BurUnitCost, 
        SubUnitCost, MtlBurUnitCost, ExtCost, PO, Line, Status
    FROM BOM_Materials 
    WHERE ProcessID = ?
    ORDER BY [Order]
    a:  
    SELECT 
        [Level], [Order], Seq, [Type], OpCode, 
        OpDesc, ShortDescription, EstProdHours, UOMCode, TranNum,
        TranDate, MtlUnitCost, LbrUnitCost, BurUnitCost, 
        SubUnitCost, MtlBurUnitCost, ExtCost, PO, Line
    FROM BOM_Operations 
    WHERE ProcessID = ?
    ORDER BY [Order]
    z?
    SELECT * FROM BOM_Process_Control WHERE ProcessID = ?
    r   rl   r   N)rL   rI   control)	rm   rV   rW   rX   rY   rZ   r[   rh   r\   )r   query_materialsquery_operationsquery_controlr_   rV   r`   materials_columnsrb   rL   operations_columnsrI   control_columnscontrol_datar   s                  r   get_bom_datar     s   	O	M  !J344""$ 	65;5G5GH5G6AY5GHBH//BSTBS3T#/56BS	T 	'76<6H6HI6HFQi6HIDJOODUVDUSd3178DU
V 	}m4393E3EF3E!93EF(>J$s?9:PT #$
 	+ IT JV G 	sM   0E= E$E= /E)"E= /E.=E= E3/"E= E84E= $E= =Fr^   c           	         Sn[        5       nU(       d  / $  UR                  5       nSU  S3nUR                  XU45        UR                   Vs/ s H  oUS   PM	     nnUR	                  5        Vs/ s H  n[        [        Xg5      5      PM     snUR                  5         $ s  snf s  snf ! UR                  5         f = f)u+   Busca partes en el ERP por nombre o códigoa  
    SELECT TOP 10 
        p.PartNum, 
        p.PartDescription,
        pr.RevisionNum,
        p.TypeCode
    FROM Erp.Part p
    LEFT JOIN Erp.PartRev pr ON p.Company = pr.Company AND p.PartNum = pr.PartNum
    WHERE p.Company = 'IGSA' 
        AND p.TypeCode = 'M'  -- Solo manufacturados
        AND (p.PartNum LIKE ? OR p.PartDescription LIKE ?)
    ORDER BY p.PartNum, pr.EffectiveDate DESC
    %r   )rU   rV   rW   rX   rY   rZ   r[   r\   )r^   search_queryr_   rV   search_termr`   ra   rb   s           r   search_partsr   -  s    L  !J		""$%l|;%?@+1+=+=>+=!9+=>39??3DE3DCS&'3DE 		 ?E 	s)   7B+ B!B+ 0B&B+ !
B+ +B=)r   r   configr   r   Consultas_SQL.conexionr   r   r   rm   rU   r
   r   r   r   rZ   r   r   r   r   r   r   r   r   <module>r      s   
   * ` ` /N#N"
] ]F4E 4s 4c 4n~(c ~(d ~(B3# 3 3 3PT 3B:S :T :x  r   