§
    ´=ÃjÙ  ã                  ó   — d dl mZ d dlZd dlmc mZ d dlZd dl	m
Z
 d dlmZ d dlZd dlmZ d dlmZ d dlmZ  ed¦  «        Zed	z  d
z  Zed	z  dz  Zedz  dz  Zd„ Zd„ Zd„ Zd„ Zej        j        d„ ¦   «         ZdS )é    )ÚannotationsN)ÚDecimal)ÚPath)ÚErpDatabaseClient)Úget_drawing_takeoff_service)ÚTriSourceTruthGroundingug   C:\Projects\DSCons\HÄ�-2026\PhÃ²ng KT xÃ£ Kiáº¿n Minh-2026\Cá»‘ng há»™p Ã´ng Ä�Ã¨n Ä‘áº¿n nhÃ  bÃ  LanhÚHSMTzKenh Ong Den_ban ve.pdfu   Biá»ƒu_máº«u_má»�i_tháº§u.pdfu	   GÃ³i TCXLúphu luc 01&02.xlsxc                 óÚ  — t           j        }  | ¦   «         }|s²t          j        dt           › �¦  «        dz   dt	          j        ¦   «         v st          j        t           ¦  «        rt          j        t           ¦  «        ndt          j        | ¦  «        t          j        |¦  «        dœz  }t          t          j	        |¦  «        ¦  «        ‚dx} }t          j        }  | ¦   «         }|s²t          j        dt          › �¦  «        dz   dt	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        ndt          j        | ¦  «        t          j        |¦  «        dœz  }t          t          j	        |¦  «        ¦  «        ‚dx} }t          j        }  | ¦   «         }|s²t          j        dt          › �¦  «        dz   d	t	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nd	t          j        | ¦  «        t          j        |¦  «        dœz  }t          t          j	        |¦  «        ¦  «        ‚dx} }dS )
zPVerify that genuine design drawing and contract files for Ong Den culvert exist.z!Design drawing PDF must exist at úC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}ÚDWG_PDF©Úpy0Úpy2Úpy4NzHSMT PDF must exist at ÚHSMT_PDFz"HSMT Excel contract must exist at Ú	HSMT_XLSX)r   ÚexistsÚ
@pytest_arÚ_format_assertmsgÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanationr   r   )Ú@py_assert1Ú@py_assert3Ú@py_format5s      úCC:\Projects\DSCons\tests\test_ong_den_drawing_and_hsmt_grounding.pyÚ#test_ong_den_dataset_files_presencer!      sR  € åŒ>ÐJˆ>ˆ>ÑÔÐJÐÐJÕJÔJÐJÅÐJÐJÑJÔJÐJÑJÐJÕJÔJÑJÔJÐJÐJÕJÔJ�7ÑJÔJÐJÕJÔJ�7ÑJÔJÐJÐJÕJÔJˆ>ÑJÔJÕJÔJÐÑJÔJÐJÐJÑJÐJÕJÕJÔJÐJÑJÔJÑJÔJÐJÐJÐJÐJÐJÝŒ?ÐBˆ?ˆ?ÑÔÐBÐÐBÕBÔBÐB½ÐBÐBÑBÔBÐBÑBÐBÕBÔBÑBÔBÐBÐBÕBÔB�8ÑBÔBÐBÕBÔB�8ÑBÔBÐBÐBÕBÔBˆ?ÑBÔBÕBÔBÐÑBÔBÐBÐBÑBÐBÕBÕBÔBÐBÑBÔBÑBÔBÐBÐBÐBÐBÐBÝÔÐOÐÐÑÔÐOÐÐOÕOÔOÐOÅIÐOÐOÑOÔOÐOÑOÐOÕOÔOÑOÔOÐOÐOÕOÔO�9ÑOÔOÐOÕOÔO�9ÑOÔOÐOÐOÕOÔOÐÑOÔOÕOÔOÐÑOÔOÐOÐOÑOÐOÕOÕOÔOÐOÑOÔOÑOÔOÐOÐOÐOÐOÐOÐOÐOó    c            
     ó®  — ddl } t          j        } |¦   «         }|s²t          j        dt          › �¦  «        dz   dt          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          t          j
        |¦  «        ¦  «        ‚dx}}|                      t          ¦  «        }t          |¦  «        }d}||k    }|�st          j        d|fd	||f¦  «        d
t          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nd
dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          j        dt          |¦  «        › �¦  «        dz   d|iz  }	t          t          j
        |	¦  «        ¦  «        ‚dx}x}}|d         }
|
j        }|j        }|d         }|j        }|j        }||k    }|s¸t          j        d|fd||f¦  «        t          j        |
¦  «        t          j        |¦  «        t          j        |¦  «        t          j        |¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}
x}x}x}x}x}}t#          t          |¦  «        ¦  «        D �]}||         }
|
j        }|j        }||         }|j        }|j        }||k    }|sÔt          j        d|fd||f¦  «        t          j        |
¦  «        t          j        |¦  «        t          j        |¦  «        t          j        |¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }t          j        d|dz   › d�¦  «        dz   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}
x}x}x}x}x}}�ŒdS )zQVerify that the 28-sheet drawing book contains key geometric and rebar schedules.r   NzDrawing PDF missing at r   r   r   é   ©ú==©z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sÚlenÚdoc©r   Úpy1Úpy3Úpy6z)Expected 28 sheets in drawing set, found ú
>assert %(py8)sÚpy8©ú>)z€%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.rect
}.width
} > %(py12)s
{%(py12)s = %(py10)s
{%(py10)s = %(py8)s.rect
}.height
})r+   r,   Úpy5r/   Úpy10Úpy12zassert %(py14)sÚpy14zSheet é   z must be landscape A3/A4z
>assert %(py14)s)Úpymupdfr   r   r   r   r   r   r   r   r   r   Úopenr(   Ú_call_reprcompareÚrectÚwidthÚheightÚrange)r7   r   r   r   r)   Ú@py_assert2Ú@py_assert5Ú@py_assert4Ú@py_format7Ú@py_format9Ú@py_assert0Ú@py_assert7Ú@py_assert9Ú@py_assert11Ú@py_assert6Ú@py_format13Ú@py_format15Úis                     r    Ú%test_ong_den_drawing_sheets_structurerK      s£  € à€N€N€NåŒ>Ð@ˆ>ˆ>ÑÔÐ@ÐÐ@Õ@Ô@Ð@µwÐ@Ð@Ñ@Ô@Ð@Ñ@Ð@Õ@Ô@Ñ@Ô@Ð@Ð@Õ@Ô@�7Ñ@Ô@Ð@Õ@Ô@�7Ñ@Ô@Ð@Ð@Õ@Ô@ˆ>Ñ@Ô@Õ@Ô@ÐÑ@Ô@Ð@Ð@Ñ@Ð@Õ@Õ@Ô@Ð@Ñ@Ô@Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ø
�,Š,•wÑ
Ô
€CÝˆs‰8Œ8ÐQ�rÐQˆ8�rŠ>ÐQÐQÑQÕQÔQÐQÐQÐQÐQˆ8�rÐQÑQÔQÐQÕQÔQÑQÔQÐQÐQÕQÔQ�3ÑQÔQÐQÕQÔQ�3ÑQÔQÐQÐQÐQÕQÔQÑQÔQÐQÐQÕQÔQˆsÑQÔQÐQÕQÔQˆsÑQÔQÐQÐQÕQÔQˆ8ÑQÔQÕQÔQ�rÑQÔQÐQÐQÑQÐQÕQÔQÐQÅsÈ3ÁxÄxÐQÐQÑQÔQÐQÑQÐQÐQÐQÑQÐQÕQÕQÔQÐQÑQÔQÑQÔQÐQÐQÐQÐQÐQÐQÐQð ˆqŒ6Ð1ˆ6Œ;Ð1ˆ;ÔÐ1˜s 1œvÐ1˜vœ{Ð1˜{Ô1Ð1ÐÐ1Ò1Ð1Ð1Ð1Õ1Ô1Ð1Ð1Ð1Ð1ÐÐ1Ð1Ñ1Ô1Õ1Ô1ˆ6Ñ1Ô1Õ1Ô1ˆ;Ñ1Ô1Õ1Ô1ÐÑ1Ô1Õ1Ô1˜vÑ1Ô1Õ1Ô1˜{Ñ1Ô1Õ1Ô1Ð1Ñ1Ô1Ð1Ð1Ñ1Ð1Ð1Ð1Ð1Ð1Ñ1Ð1Õ1Õ1Ô1Ð1Ñ1Ô1Ñ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1õ •3�s‘8”8‰_Œ_ð ^ñ ^ˆØ�1ŒvÐ]ˆvŒ{Ð]ˆ{Ô Ð] 3 q¤6Ð] 6¤;Ð] ;Ô#5Ð]Ð Ð#5Ò5Ð]Ð]Ð]Õ]Ô]Ð]Ð]Ð]Ð]Ð Ð#5Ð]Ñ]Ô]Õ]Ô]ˆvÑ]Ô]Õ]Ô]ˆ{Ñ]Ô]Õ]Ô]Ð Ñ]Ô]Õ]Ô] 6Ñ]Ô]Õ]Ô] ;Ñ]Ô]Õ]Ô]Ð#5Ñ]Ô]Ð]Ð]Ñ]Ð]Õ]Ô]Ð7]ÀÀ!ÁÐ7]Ð7]Ð7]Ñ]Ô]Ð]Ñ]Ð]Ð]Ð]Ñ]Ð]Õ]Õ]Ô]Ð]Ñ]Ô]Ñ]Ô]Ð]Ð]Ð]Ð]Ð]Ð]Ð]Ð]Ð]Ð]Ð]Ð]Ð]Ð]Ð]Ñ]ð^ð ^r"   c                 ó"  — t          ¦   «         } |                      t          ¦  «        }t          |¦  «        }d}||k    }|�st	          j        d|fd||f¦  «        dt          j        ¦   «         v st	          j        t          ¦  «        rt	          j	        t          ¦  «        nddt          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        ndt	          j	        |¦  «        t	          j	        |¦  «        dœz  }t	          j
        dt          |¦  «        › �¦  «        dz   d	|iz  }t          t	          j        |¦  «        ¦  «        ‚d
x}x}}d}|d         d         }||v }|slt	          j        d|fd||f¦  «        t	          j	        |¦  «        t	          j	        |¦  «        dœz  }	dd|	iz  }t          t	          j        |¦  «        ¦  «        ‚d
x}x}}|d         d         }d}||k    }|slt	          j        d|fd||f¦  «        t	          j	        |¦  «        t	          j	        |¦  «        dœz  }	dd|	iz  }t          t	          j        |¦  «        ¦  «        ‚d
x}x}}d„ |D ¦   «         }
t          |
¦  «        }d}||k    }|sòt	          j        d|fd||f¦  «        dt          j        ¦   «         v st	          j        t          ¦  «        rt	          j	        t          ¦  «        nddt          j        ¦   «         v st	          j        |
¦  «        rt	          j	        |
¦  «        ndt	          j	        |¦  «        t	          j	        |¦  «        dœz  }dd	|iz  }t          t	          j        |¦  «        ¦  «        ‚d
x}x}}d
S )uK   Verify statutory extraction of 66 items from Biá»ƒu_máº«u_má»�i_tháº§u.pdf.éB   r%   r'   r(   Úitemsr*   z'Expected exactly 66 items in HSMT, got r.   r/   Nu   PhÃ¡t quangr   Ú	item_name)Úin)z%(py1)s in %(py4)s©r+   r   úassert %(py6)sr-   Úquantityg¸…ëQø%@©z%(py1)s == %(py4)sc                óJ   — g | ] }d |d                               ¦   «         v ¯|‘Œ!S )ÚlarsenrO   )Úlower©Ú.0Úits     r    ú
<listcomp>z4test_ong_den_hsmt_pdf_extraction.<locals>.<listcomp>3   s2   € ÐNÐNÐN˜2¨(°b¸´o×6KÒ6KÑ6MÔ6MÐ*MÐ*M�BÐ*MÐ*MÐ*Mr"   é   ©ú>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)sÚlarsen_itemsúassert %(py8)s)r   Úextract_hsmt_items_from_pdfr   r(   r   r9   r   r   r   r   r   r   r   )ÚservicerN   r>   r?   r@   rA   rB   rC   r   r   r_   s              r    Ú test_ong_den_hsmt_pdf_extractionrc   )   sî  € å)Ñ+Ô+€GØ×/Ò/µÑ9Ô9€Eåˆu‰:Œ:ÐS˜ÐSˆ:˜ÒÐSÐSÑSÕSÔSÐSÐSÐSÐSˆ:˜ÐSÑSÔSÐSÕSÔSÑSÔSÐSÐSÕSÔS�3ÑSÔSÐSÕSÔS�3ÑSÔSÐSÐSÐSÕSÔSÑSÔSÐSÐSÕSÔSˆuÑSÔSÐSÕSÔSˆuÑSÔSÐSÐSÕSÔSˆ:ÑSÔSÕSÔS˜ÑSÔSÐSÐSÑSÐSÕSÔSÐSÅsÈ5ÁzÄzÐSÐSÑSÔSÐSÑSÐSÐSÐSÑSÐSÕSÕSÔSÐSÑSÔSÑSÔSÐSÐSÐSÐSÐSÐSÐSàÐ1˜E !œH [Ô1Ð1ˆ=Ð1Ð1Ð1Ð1Ð1Õ1Ô1Ð1Ð1Ð1Ð1ˆ=Ð1Ð1Ñ1Ô1Õ1Ô1ˆ=Ñ1Ô1Õ1Ô1Ð1Ñ1Ô1Ð1Ð1Ñ1Ð1Ð1Ð1Ð1Ð1Ñ1Ð1Õ1Õ1Ô1Ð1Ñ1Ô1Ñ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ø�Œ8�JÔÐ) 6Ð)Ð 6Ò)Ð)Ð)Ð)Õ)Ô)Ð)Ð)Ð)Ð)Ð 6Ð)Ñ)Ô)Õ)Ô)ÐÑ)Ô)Õ)Ô) 6Ñ)Ô)Ð)Ð)Ñ)Ð)Ð)Ð)Ð)Ð)Ñ)Ð)Õ)Õ)Ô)Ð)Ñ)Ô)Ñ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)àNÐN ÐNÑNÔN€LÝˆ|ÑÔÐ! Ð!Ð Ò!Ð!Ð!Ð!Õ!Ô!Ð!Ð!Ð!Ð!Ð Ð!Ñ!Ô!Ð!Õ!Ô!Ñ!Ô!Ð!Ð!Õ!Ô!�3Ñ!Ô!Ð!Õ!Ô!�3Ñ!Ô!Ð!Ð!Ð!Õ!Ô!Ñ!Ô!Ð!Ð!Õ!Ô!ˆ|Ñ!Ô!Ð!Õ!Ô!ˆ|Ñ!Ô!Ð!Ð!Õ!Ô!ÐÑ!Ô!Õ!Ô! Ñ!Ô!Ð!Ð!Ñ!Ð!Ð!Ð!Ð!Ð!Ñ!Ð!Õ!Õ!Ô!Ð!Ñ!Ô!Ñ!Ô!Ð!Ð!Ð!Ð!Ð!Ð!Ð!Ð!Ð!r"   c                 ó  — t          ¦   «         } |                      t          ¦  «        }t          |¦  «        }d}||k    }|�st	          j        d|fd||f¦  «        dt          j        ¦   «         v st	          j        t          ¦  «        rt	          j	        t          ¦  «        nddt          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        ndt	          j	        |¦  «        t	          j	        |¦  «        dœz  }t	          j
        dt          |¦  «        › �¦  «        dz   d	|iz  }t          t	          j        |¦  «        ¦  «        ‚d
x}x}}|d         d         }d}||k    }|slt	          j        d|fd||f¦  «        t	          j	        |¦  «        t	          j	        |¦  «        dœz  }	dd|	iz  }t          t	          j        |¦  «        ¦  «        ‚d
x}x}}|d         d         }d}||k    }|slt	          j        d|fd||f¦  «        t	          j	        |¦  «        t	          j	        |¦  «        dœz  }	dd|	iz  }t          t	          j        |¦  «        ¦  «        ‚d
x}x}}|d         d         }d}t          |¦  «        }
||
k    }|sÇt	          j        d|fd||
f¦  «        t	          j	        |¦  «        dt          j        ¦   «         v st	          j        t          ¦  «        rt	          j	        t          ¦  «        ndt	          j	        |¦  «        t	          j	        |
¦  «        dœz  }dd|iz  }t          t	          j        |¦  «        ¦  «        ‚d
x}x}x}}
|d         d         }d}t          |¦  «        }
||
k    }|sÇt	          j        d|fd||
f¦  «        t	          j	        |¦  «        dt          j        ¦   «         v st	          j        t          ¦  «        rt	          j	        t          ¦  «        ndt	          j	        |¦  «        t	          j	        |
¦  «        dœz  }dd|iz  }t          t	          j        |¦  «        ¦  «        ‚d
x}x}x}}
t          d„ |D ¦   «         ¦  «        }d }t          |¦  «        }||z
  }t          |¦  «        }d!}t          |¦  «        }||k     }|�s»t	          j        d"|fd#||f¦  «        d$t          j        ¦   «         v st	          j        t          ¦  «        rt	          j	        t          ¦  «        nd$d%t          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        nd%dt          j        ¦   «         v st	          j        t          ¦  «        rt	          j	        t          ¦  «        ndt	          j	        |¦  «        t	          j	        |¦  «        t	          j	        |¦  «        dt          j        ¦   «         v st	          j        t          ¦  «        rt	          j	        t          ¦  «        ndt	          j	        |¦  «        t	          j	        |¦  «        d&œ	z  }d'd(|iz  }t          t	          j        |¦  «        ¦  «        ‚d
x}x}x}x}x}x}}d
S ))zZVerify extraction of 66 items with authentic contract unit prices from phu luc 01&02.xlsx.rM   r%   r'   r(   Úexcel_itemsr*   z Expected 66 contract items, got r.   r/   Nr   Ú	norm_codezAA.11143rT   rQ   rR   r-   ÚunitÚ100m2rS   z10.9850)z0%(py1)s == %(py7)s
{%(py7)s = %(py3)s(%(py5)s)
}r   )r+   r,   r2   Úpy7zassert %(py9)sÚpy9Úbid_ratez	700000.00r0   )z/%(py1)s > %(py7)s
{%(py7)s = %(py3)s(%(py5)s)
}c              3  ó&   K  — | ]}|d          V — ŒdS )Útotal_amountN© rX   s     r    ú	<genexpr>z9test_ong_den_contract_excel_extraction.<locals>.<genexpr>D   s'   è è € ÐEÐE°2˜B˜~Ô.ÐEÐEÐEÐEÐEÐEr"   z6482295000.00z1000.00)ú<)z{%(py9)s
{%(py9)s = %(py0)s((%(py1)s - %(py6)s
{%(py6)s = %(py2)s(%(py4)s)
}))
} < %(py15)s
{%(py15)s = %(py11)s(%(py13)s)
}ÚabsÚtotal_direct_cost)	r   r+   r   r   r-   rj   Úpy11Úpy13Úpy15zassert %(py17)sÚpy17)r   Úextract_hsmt_tender_itemsr   r(   r   r9   r   r   r   r   r   r   r   r   Úsumrq   )Ú
tri_enginere   r>   r?   r@   rA   rB   rC   r   r   rG   Ú@py_format8Ú@py_format10rr   rD   Ú@py_assert8Ú@py_assert12Ú@py_assert14Ú@py_assert10Ú@py_format16Ú@py_format18s                        r    Ú&test_ong_den_contract_excel_extractionr‚   7   sÿ  € å(Ñ*Ô*€JØ×6Ò6µyÑAÔA€Kåˆ{ÑÔÐX˜rÐXÐ˜rÒ!ÐXÐXÑXÕXÔXÐXÐXÐXÐXÐ˜rÐXÑXÔXÐXÕXÔXÑXÔXÐXÐXÕXÔX�3ÑXÔXÐXÕXÔX�3ÑXÔXÐXÐXÐXÕXÔXÑXÔXÐXÐXÕXÔXˆ{ÑXÔXÐXÕXÔXˆ{ÑXÔXÐXÐXÕXÔXÐÑXÔXÕXÔX˜rÑXÔXÐXÐXÑXÐXÕXÔXÐ#XÅcÈ+ÑFVÔFVÐ#XÐ#XÑXÔXÐXÑXÐXÐXÐXÑXÐXÕXÕXÔXÐXÑXÔXÑXÔXÐXÐXÐXÐXÐXÐXÐXà�qŒ>˜+Ô&Ð4¨*Ð4Ð&¨*Ò4Ð4Ð4Ð4Õ4Ô4Ð4Ð4Ð4Ð4Ð&¨*Ð4Ñ4Ô4Õ4Ô4Ð&Ñ4Ô4Õ4Ô4¨*Ñ4Ô4Ð4Ð4Ñ4Ð4Ð4Ð4Ð4Ð4Ñ4Ð4Õ4Õ4Ô4Ð4Ñ4Ô4Ñ4Ô4Ð4Ð4Ð4Ð4Ð4Ð4Ð4Ø�qŒ>˜&Ô!Ð, WÐ,Ð! WÒ,Ð,Ð,Ð,Õ,Ô,Ð,Ð,Ð,Ð,Ð! WÐ,Ñ,Ô,Õ,Ô,Ð!Ñ,Ô,Õ,Ô, WÑ,Ô,Ð,Ð,Ñ,Ð,Ð,Ð,Ð,Ð,Ñ,Ð,Õ,Õ,Ô,Ð,Ñ,Ô,Ñ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,Ø�qŒ>˜*Ô%Ð;°Ð;­°Ñ);Ô);Ð;Ð%Ð);Ò;Ð;Ð;Ð;Õ;Ô;Ð;Ð;Ð;Ð;Ð%Ð);Ð;Ñ;Ô;Õ;Ô;Ð%Ñ;Ô;Ð;Õ;Ô;Ñ;Ô;Ð;Ð;Õ;Ô;­Ñ;Ô;Ð;Õ;Ô;­Ñ;Ô;Ð;Ð;Õ;Ô;°Ñ;Ô;Õ;Ô;Ð);Ñ;Ô;Ð;Ð;Ñ;Ð;Ð;Ð;Ð;Ð;Ñ;Ð;Õ;Õ;Ô;Ð;Ñ;Ô;Ñ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ø�qŒ>˜*Ô%Ð<°Ð<­°Ñ(<Ô(<Ð<Ð%Ð(<Ò<Ð<Ð<Ð<Õ<Ô<Ð<Ð<Ð<Ð<Ð%Ð(<Ð<Ñ<Ô<Õ<Ô<Ð%Ñ<Ô<Ð<Õ<Ô<Ñ<Ô<Ð<Ð<Õ<Ô<­Ñ<Ô<Ð<Õ<Ô<­Ñ<Ô<Ð<Ð<Õ<Ô<°Ñ<Ô<Õ<Ô<Ð(<Ñ<Ô<Ð<Ð<Ñ<Ð<Ð<Ð<Ð<Ð<Ñ<Ð<Õ<Õ<Ô<Ð<Ñ<Ô<Ñ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<õ ÐEÐE¸ÐEÑEÔEÑEÔEÐØ+:ÐQ¥7¨?Ñ#;Ô#;ÐQÐ Ð#;Ñ;ÐQ�3Ð;Ñ<Ô<ÐQÀyÐQ½wÀyÑ?QÔ?QÐQÐ<Ð?QÒQÐQÐQÑQÕQÔQÐQÐQÐQÐQÐ<Ð?QÐQÑQÔQÐQÕQÔQÑQÔQÐQÐQÕQÔQ�3ÑQÔQÐQÕQÔQ�3ÑQÔQÐQÐQÐQÕQÔQÑQÔQÐQÐQÕQÔQÐ ÑQÔQÐQÕQÔQÐ ÑQÔQÐQÐQÐQÕQÔQÑQÔQÐQÐQÕQÔQ¥7ÑQÔQÐQÕQÔQ¥7ÑQÔQÐQÐQÕQÔQ¨?ÑQÔQÕQÔQÐ#;ÑQÔQÕQÔQÐ<ÑQÔQÐQÕQÔQÑQÔQÐQÐQÕQÔQ½wÑQÔQÐQÕQÔQ½wÑQÔQÐQÐQÕQÔQÀyÑQÔQÕQÔQÐ?QÑQÔQÐQÐQÑQÐQÐQÐQÐQÐQÑQÐQÕQÕQÔQÐQÑQÔQÑQÔQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQr"   c               ƒ  ó<  K  — t          ¦   «         } t          ¦   «         }t          }|                      ||j        dt
          d¬¦  «        ƒ d{V —†}|d         }d}||k    }|slt          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        d	œz  }d
d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}x}}|d         }	|d         }
|	d         }d}||k    }|slt          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        d	œz  }d
d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}x}}|	d         }d}||k    }|slt          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        d	œz  }d
d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}x}}t          |
¦  «        }d}||k    }|sòt          j        d|fd||f¦  «        dt          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nddt          j        ¦   «         v st          j        |
¦  «        rt          j        |
¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}x}}|	d         }d}||k    }|slt          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        d	œz  }d
d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}x}}|                     |	d         ¦  «         dS )zAVerify full end-to-end pipeline execution with clean DB teardown.u2   Cá»‘ng há»™p kÃªnh Ã´ng Ä�Ã¨n Ä‘áº¿n nhÃ  bÃ  Lanhr
   )Ú	file_pathÚfilenameÚdrawing_hintÚattached_hsmt_pathÚattached_hsmt_filenameNÚstatusÚsuccessr%   rT   rQ   rR   r-   ÚtakeoffrN   Úconfidence_scoreéb   r]   )z%(py1)s >= %(py4)sÚconfidence_levelÚhsmt_verifiedrM   r'   r(   r*   r`   r/   Útotal_estimated_cost_vndg   °­úõAr0   )z%(py1)s > %(py4)sÚid)r   r   r   Úprocess_drawing_fileÚnamer   r   r9   r   r   r   r(   r   r   r   Údelete_drawing_takeoff)rb   ÚdbÚdwg_pathÚresultrC   r   r>   r   rA   r‹   rN   r?   r@   rB   s                 r    Ú(test_ong_den_end_to_end_takeoff_pipeliner˜   H   sc  è è € õ *Ñ+Ô+€GÝ	Ñ	Ô	€Bå€Hà×/Ò/ØØ”ØIÝ$Ø3ð 0ñ ô ð ð ð ð ð ð €Fð �(ÔÐ(˜yÐ(Ð˜yÒ(Ð(Ð(Ð(Õ(Ô(Ð(Ð(Ð(Ð(Ð˜yÐ(Ñ(Ô(Õ(Ô(ÐÑ(Ô(Õ(Ô(˜yÑ(Ô(Ð(Ð(Ñ(Ð(Ð(Ð(Ð(Ð(Ñ(Ð(Õ(Õ(Ô(Ð(Ñ(Ô(Ñ(Ô(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ø�YÔ€GØ�7ŒO€EàÐ%Ô&Ð,¨"Ð,Ð&¨"Ò,Ð,Ð,Ð,Õ,Ô,Ð,Ð,Ð,Ð,Ð&¨"Ð,Ñ,Ô,Õ,Ô,Ð&Ñ,Ô,Õ,Ô,¨"Ñ,Ô,Ð,Ð,Ñ,Ð,Ð,Ð,Ð,Ð,Ñ,Ð,Õ,Õ,Ô,Ð,Ñ,Ô,Ñ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,ØÐ%Ô&Ð9¨/Ð9Ð&¨/Ò9Ð9Ð9Ð9Õ9Ô9Ð9Ð9Ð9Ð9Ð&¨/Ð9Ñ9Ô9Õ9Ô9Ð&Ñ9Ô9Õ9Ô9¨/Ñ9Ô9Ð9Ð9Ñ9Ð9Ð9Ð9Ð9Ð9Ñ9Ð9Õ9Õ9Ô9Ð9Ñ9Ô9Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ýˆu‰:Œ:Ð˜Ðˆ:˜ÒÐÐÐÕÔÐÐÐÐˆ:˜ÐÑÔÐÕÔÑÔÐÐÕÔ�3ÑÔÐÕÔ�3ÑÔÐÐÐÕÔÑÔÐÐÕÔˆuÑÔÐÕÔˆuÑÔÐÐÕÔˆ:ÑÔÕÔ˜ÑÔÐÐÑÐÐÐÐÐÑÐÕÕÔÐÑÔÑÔÐÐÐÐÐÐÐØÐ-Ô.Ð@°Ð@Ð.°Ò@Ð@Ð@Ð@Õ@Ô@Ð@Ð@Ð@Ð@Ð.°Ð@Ñ@Ô@Õ@Ô@Ð.Ñ@Ô@Õ@Ô@°Ñ@Ô@Ð@Ð@Ñ@Ð@Ð@Ð@Ð@Ð@Ñ@Ð@Õ@Õ@Ô@Ð@Ñ@Ô@Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@Ð@ð ×Ò˜g dœmÑ,Ô,Ð,Ð,Ð,r"   )Ú
__future__r   Úbuiltinsr   Ú_pytest.assertion.rewriteÚ	assertionÚrewriter   ÚasyncioÚdecimalr   Úpathlibr   ÚpytestÚapp.core.postgres.erp_clientr   Ú'app.modules.takeoff.application.servicer   Ú:app.modules.takeoff.application.tri_source_truth_groundingr   ÚONG_DEN_DIRr   r   r   r!   rK   rc   r‚   ÚmarkÚanyior˜   rn   r"   r    ú<module>r¨      sM  ðØ "Ð "Ð "Ð "Ð "Ð "à  € € € € € € € € € € € € €€€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø €€€à :Ð :Ð :Ð :Ð :Ð :Ø OÐ OÐ OÐ OÐ OÐ OØ ^Ð ^Ð ^Ð ^Ð ^Ð ^àˆdÐ}Ñ~Ô~€Ø
˜Ñ
Ð!:Ñ
:€Ø˜ÑÐ"AÑA€Ø˜+Ñ%Ð(<Ñ<€	ðPð Pð Pð^ð ^ð ^ð "ð "ð "ðRð Rð Rð" „Ôð-ð -ñ Ôð-ð -ð -r"   