§
    ï‰›jy  ã                  ón   — d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ  G d„ d	e¦  «        Zd
S )z˜Concrete PostgreSQL Equipment Repository implementing EquipmentRepositoryPort.
Strict Zero-Tolerance Synthetic Data & Hexagonal Architecture COMPLIANT.
é    )Úannotations)Údate)ÚDecimal)ÚAny)ÚProjectCrudRepository)ÚEquipmentRepositoryPortc                  óh   — e Zd ZdZd#d$d„Zd„ Z	 d#d%d„Zd&d„Zd'd„Zd(d„Z	d)d„Z
d)d„Zd*d„Zd+d,d"„ZdS )-ÚPostgresEquipmentRepositoryz>PostgreSQL database adapter for equipment and telematics logs.NÚdb_repoúProjectCrudRepository | NoneÚreturnÚNonec                ó0   — |pt          ¦   «         | _        d S ©N)r   Údb)Úselfr   s     ú]C:\Projects\DSCons\app\modules\operations\infrastructure\repositories\equipment_repository.pyÚ__init__z$PostgresEquipmentRepository.__init__   s   € ØÐ4Õ2Ñ4Ô4ˆŒˆˆó    c                ó4   — | j                              ¦   «         S )zLContext manager yielding a database connection (for backward compatibility).)r   Úget_connection)r   s    r   r   z*PostgresEquipmentRepository.get_connection   s   € àŒw×%Ò%Ñ'Ô'Ð'r   Úequipment_idÚstrÚ	fill_dater   Úfuel_quantity_litersr   Úunit_price_vndÚtotal_cost_vndÚodometer_hoursÚsource_invoice_idú
str | Noneúdict[str, Any]c                óX  — d}| j                              ¦   «         5 }	|	                     ¦   «         5 }
|
                     ||||||||f¦  «         |
                     ¦   «         }|	                     ¦   «          |rtt          |d         ¦  «        t          |d         d¦  «        r|d                              d¦  «        nt          |d         ¦  «        dœcddd¦  «         cddd¦  «         S i cddd¦  «         cddd¦  «         S # 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )z?Record an equipment fuel fill entry in erp_equipment_fuel_logs.a6  
            INSERT INTO erp_equipment_fuel_logs (
                equipment_id, fill_date, fuel_quantity_liters, unit_price_vnd,
                total_cost_vnd, odometer_hours, source_invoice_id
            ) VALUES (
                %s, %s, %s, %s, %s, %s, %s
            ) RETURNING id, created_at;
        ÚidÚ
created_atÚstrftimez%Y-%m-%d %H:%M:%S)r#   r$   N)	r   r   ÚcursorÚexecuteÚfetchoneÚcommitr   Úhasattrr%   )r   r   r   r   r   r   r   r   ÚsqlÚconnÚcurÚress               r   Úrecord_fuel_logz+PostgresEquipmentRepository.record_fuel_log   s  € ðˆð ŒW×#Ò#Ñ%Ô%ð 	¨¨t¯{ª{©}¬}ð 	ÀØ�KŠKØà ØØ(Ø"Ø"Ø"Ø%ðñô ð ð —,’,‘.”.ˆCØ�KŠK‰MŒMˆMØð å˜c $œi™.œ.å˜s <Ô0°*Ñ=Ô=ð#0 # lÔ"3×"<Ò"<Ð=PÑ"QÔ"QÐ"Qå˜S Ô.Ñ/Ô/ð	ð ð!	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð, ð-	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	sA   œD±B#DÃDÃ-DÃ.DÄD	ÄDÄD	ÄDÄD#Ä&D#Ú
identifierúdict[str, Any] | Nonec                ó6  — d}| j                              ¦   «         5 }|                     ¦   «         5 }|                     |||f¦  «         |                     ¦   «         cddd¦  «         cddd¦  «         S # 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )z<Fetch equipment details by either UUID id or equipment_code.zå
            SELECT e.*, p.project_name AS current_project_name
            FROM erp_equipment e
            LEFT JOIN projects p ON e.current_project_id = p.id
            WHERE e.id::text = %s OR e.equipment_code = %s;
        N©r   r   r&   r'   r(   )r   r0   r+   r,   r-   s        r   Úget_equipment_by_id_or_codez7PostgresEquipmentRepository.get_equipment_by_id_or_codeD   s+  € ðˆð ŒW×#Ò#Ñ%Ô%ð 	"¨¨t¯{ª{©}¬}ð 	"ÀØ�KŠK˜˜j¨*Ð5Ñ6Ô6Ð6Ø—<’<‘>”>ð	"ð 	"ð 	"ð 	"ñ 	"ô 	"ð 	"ð 	"ð 	"ð 	"ð 	"ñ 	"ô 	"ð 	"ð 	"ð 	"ð 	"ð 	"ð 	"øøøð 	"ð 	"ð 	"ð 	"ð 	"ð 	"ð 	"ñ 	"ô 	"ð 	"ð 	"ð 	"ð 	"ð 	"ð 	"ð 	"øøøð 	"ð 	"ð 	"ð 	"ð 	"ð 	"s4   œB±,A6ÁBÁ6A:	Á:BÁ=A:	Á>BÂBÂBúlist[dict[str, Any]]c                óR  — d}| j                              ¦   «         5 }|                     ¦   «         5 }|                     |t	          |¦  «        f¦  «         |                     ¦   «         pg cddd¦  «         cddd¦  «         S # 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )z;Fetch fuel logs for an equipment ordered by fill_date desc.a  
            SELECT f.*, i.invoice_number, i.invoice_series
            FROM erp_equipment_fuel_logs f
            LEFT JOIN erp_invoices i ON f.source_invoice_id = i.id
            WHERE f.equipment_id::text = %s
            ORDER BY f.fill_date DESC, f.created_at DESC;
        N)r   r   r&   r'   r   Úfetchall)r   r   r+   r,   r-   s        r   Úget_fuel_logs_by_equipmentz6PostgresEquipmentRepository.get_fuel_logs_by_equipmentP   s6  € ðˆð ŒW×#Ò#Ñ%Ô%ð 	(¨¨t¯{ª{©}¬}ð 	(ÀØ�KŠK˜�c ,Ñ/Ô/Ð1Ñ2Ô2Ð2Ø—<’<‘>”>Ð' Rð	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(s4   œB±:BÁ+BÂB	ÂBÂB	ÂBÂB Â#B c                ó  — d}| j                              ¦   «         5 }|                     ¦   «         5 }|                     |t	          |¦  «        f¦  «         |                     ¦   «         }|rO|                     d¦  «        �:t          t	          |d         ¦  «        ¦  «        cddd¦  «         cddd¦  «         S t          d¦  «        cddd¦  «         cddd¦  «         S # 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )u4   Calculate total operational hours from ca mÃ¡y logs.zŽ
            SELECT SUM(hours_operated) AS total_hours
            FROM erp_equipment_logs
            WHERE equipment_id::text = %s;
        Útotal_hoursNz0.0000)r   r   r&   r'   r   r(   Úgetr   )r   r   r+   r,   r-   r.   s         r   Úget_total_operated_hoursz4PostgresEquipmentRepository.get_total_operated_hours]   s¼  € ðˆð
 ŒW×#Ò#Ñ%Ô%ð 	%¨¨t¯{ª{©}¬}ð 	%ÀØ�KŠK˜�c ,Ñ/Ô/Ð1Ñ2Ô2Ð2Ø—,’,‘.”.ˆCØð 8�s—w’w˜}Ñ-Ô-Ð9Ý�s 3 }Ô#5Ñ6Ô6Ñ7Ô7ð		%ð 	%ð 	%ð 	%ñ 	%ô 	%ð 	%ð 	%ð 	%ð 	%ð 	%ñ 	%ô 	%ð 	%ð 	%õ
 ˜8Ñ$Ô$ð	%ð 	%ð 	%ð 	%ñ 	%ô 	%ð 	%ð 	%ð 	%ð 	%ð 	%ñ 	%ô 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%øøøð 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%ñ 	%ô 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%øøøð 	%ð 	%ð 	%ð 	%ð 	%ð 	%sA   œC:±A1C"Â"C:Â;C"Ã	C:Ã"C&	Ã&C:Ã)C&	Ã*C:Ã:C>ÄC>c                ó4  — d}| j                              ¦   «         5 }|                     ¦   «         5 }|                     |¦  «         |                     ¦   «         pi cddd¦  «         cddd¦  «         S # 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )zAFetch summary counts for trucks, excavators, and active machines.aÖ  
            SELECT
                count(id) as total_equipment,
                count(id) FILTER (WHERE equipment_code LIKE 'EQ-TRUTH-TRU-%') as total_trucks,
                count(id) FILTER (WHERE equipment_code LIKE 'EQ-TRUTH-EXC-%') as total_excavators,
                count(id) FILTER (WHERE status = 'operating') as operating_count,
                count(id) FILTER (WHERE license_plate IS NOT NULL) as identified_plates
            FROM erp_equipment;
        Nr3   ©r   r+   r,   r-   s       r   Úget_fleet_countsz,PostgresEquipmentRepository.get_fleet_countsk   s)  € ðˆð ŒW×#Ò#Ñ%Ô%ð 	(¨¨t¯{ª{©}¬}ð 	(ÀØ�KŠK˜ÑÔÐØ—<’<‘>”>Ð' Rð	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ó4   œB±+A5ÁBÁ5A9	Á9BÁ<A9	Á=BÂBÂBc                ó4  — d}| j                              ¦   «         5 }|                     ¦   «         5 }|                     |¦  «         |                     ¦   «         pi cddd¦  «         cddd¦  «         S # 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )z=Fetch summary totals of all fuel fills from GDT tax invoices.aq  
            SELECT
                count(id) as total_fills,
                sum(fuel_quantity_liters) as total_liters,
                sum(total_cost_vnd) as total_cost,
                avg(unit_price_vnd) as avg_price,
                min(fill_date) as start_date,
                max(fill_date) as latest_fill_date
            FROM erp_equipment_fuel_logs;
        Nr3   r>   s       r   Úget_fleet_fuel_totalsz1PostgresEquipmentRepository.get_fleet_fuel_totalsz   s)  € ð	ˆð ŒW×#Ò#Ñ%Ô%ð 	(¨¨t¯{ª{©}¬}ð 	(ÀØ�KŠK˜ÑÔÐØ—<’<‘>”>Ð' Rð	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(r@   c                ó4  — d}| j                              ¦   «         5 }|                     ¦   «         5 }|                     |¦  «         |                     ¦   «         pg cddd¦  «         cddd¦  «         S # 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )zDFetch aggregated equipment list with fuel totals and odometer stats.a  
            SELECT
                e.id, e.equipment_code, e.equipment_name, e.license_plate,
                e.fuel_norm_per_hour, e.status,
                count(fl.id) as fill_count,
                sum(fl.fuel_quantity_liters) as total_liters,
                sum(fl.total_cost_vnd) as total_cost,
                max(fl.odometer_hours) as max_odo,
                min(fl.odometer_hours) as min_odo
            FROM erp_equipment e
            LEFT JOIN erp_equipment_fuel_logs fl ON fl.equipment_id = e.id
            WHERE e.license_plate IS NOT NULL OR e.equipment_code LIKE 'EQ-TRUTH-EXC-%'
            GROUP BY e.id, e.equipment_code, e.equipment_name, e.license_plate, e.fuel_norm_per_hour, e.status
            ORDER BY total_liters DESC NULLS LAST;
        N©r   r   r&   r'   r7   r>   s       r   Úget_fleet_equipment_summaryz7PostgresEquipmentRepository.get_fleet_equipment_summaryŠ   s)  € ðˆð ŒW×#Ò#Ñ%Ô%ð 	(¨¨t¯{ª{©}¬}ð 	(ÀØ�KŠK˜ÑÔÐØ—<’<‘>”>Ð' Rð	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(r@   é
   ÚlimitÚintc                ó8  — d}| j                              ¦   «         5 }|                     ¦   «         5 }|                     ||f¦  «         |                     ¦   «         pg cddd¦  «         cddd¦  «         S # 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )z\Fetch active equipment along with their actual fuel and hour stats for telematics dashboard.aî  
            SELECT
                e.id, e.equipment_code, e.equipment_name, e.license_plate,
                e.fuel_norm_per_hour, e.status,
                count(fl.id) as fill_count,
                COALESCE(sum(fl.fuel_quantity_liters), 0) as total_liters,
                COALESCE(max(fl.odometer_hours), 0) as max_odo,
                COALESCE(min(fl.odometer_hours), 0) as min_odo
            FROM erp_equipment e
            LEFT JOIN erp_equipment_fuel_logs fl ON fl.equipment_id = e.id
            WHERE e.status = 'operating' OR fl.id IS NOT NULL
            GROUP BY e.id, e.equipment_code, e.equipment_name, e.license_plate, e.fuel_norm_per_hour, e.status
            ORDER BY total_liters DESC NULLS LAST
            LIMIT %s;
        NrD   )r   rG   r+   r,   r-   s        r   Ú#get_active_equipment_for_telematicsz?PostgresEquipmentRepository.get_active_equipment_for_telematicsŸ   s-  € ðˆð ŒW×#Ò#Ñ%Ô%ð 	(¨¨t¯{ª{©}¬}ð 	(ÀØ�KŠK˜˜e˜XÑ&Ô&Ð&Ø—<’<‘>”>Ð' Rð	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð 	(ð 	(s4   œB±-A7ÁBÁ7A;	Á;BÁ>A;	Á?BÂBÂBr   )r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r    r   r!   )r0   r   r   r1   )r   r   r   r5   )r   r   r   r   )r   r!   )r   r5   )rF   )rG   rH   r   r5   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r/   r4   r8   r<   r?   rB   rE   rJ   © r   r   r
   r
      sò   € € € € € ØHÐHð5ð 5ð 5ð 5ð 5ð(ð (ð (ð )-ð)ð )ð )ð )ð )ðV
"ð 
"ð 
"ð 
"ð(ð (ð (ð (ð%ð %ð %ð %ð(ð (ð (ð (ð(ð (ð (ð (ð (ð (ð (ð (ð*(ð (ð (ð (ð (ð (ð (r   r
   N)rN   Ú
__future__r   Údatetimer   Údecimalr   Útypingr   Ú)app.core.postgres.project_crud_repositoryr   Ú=app.modules.operations.domain.ports.equipment_repository_portr   r
   rO   r   r   ú<module>rV      s¼   ððð ð #Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à KÐ KÐ KÐ KÐ KÐ KØ aÐ aÐ aÐ aÐ aÐ aðc(ð c(ð c(ð c(ð c(Ð"9ñ c(ô c(ð c(ð c(ð c(r   