
    j                         d Z ddlZddlmZmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZ ddlmZ ddlmZmZ dd	lmZmZmZmZ  G d
 d      Zy)z
Charts service for Aimantis dashboard.

Generates monthly occupancy chart data for the last 12 months
using optimized calculations.
    N)date	timedelta)DictAnyListOptional)relativedelta)Booking)Property)MONTHLY_CHART_MONTHSOCCUPANCY_ROUNDING)calculate_overlapping_nights	get_todaysafe_divideround_occupancyc                       e Zd ZdZddee   fdZdeee	f   fdZ
defdZded	edefd
Zdeeee	f      fdZdeee	f   fdZy)ChartsServicez
    Service for generating chart data for the dashboard.
    
    Currently provides monthly occupancy data for the last 12 months.
    Nstructure_idc                 0    || _         t               | _        y)z
        Initialize the charts service.
        
        Args:
            structure_id: Optional structure ID for multi-tenant filtering
        N)r   r   today)selfr   s     -/backend/dashboard/services/charts_service.py__init__zChartsService.__init__!   s     )[
    returnc                 :    | j                   rd| j                   iS i S )z&Get structure filter dict for queries.r   r   r   s    r   _get_structure_filterz#ChartsService._get_structure_filter+   s     6:6G6G 1 12OROr   c                     t         j                  j                         }| j                  r|j	                  | j                        }|j                         S )z'Get total room count for the structure.r   )r   objectsallr   filtercount)r   qss     r   _get_total_roomszChartsService._get_total_rooms/   sA    !!#(9(9:Bxxzr   month_start	month_endc                 b   | j                         }|dk(  ry||z
  j                  dz   }||z  }|dk(  ryt        j                  j                  d||d| j                         j                  ddd      }t               }|t        d      z   }|D ]f  }	t        |	j                  |      }
t        |	j                  |      }|
|k  s5|j                  |
|	j                  f       |
t        d      z  }
|
|k  r2h t        |      }t!        |dz  |d	
      }t        |d      }t#        |t$              S )a  
        Calculate occupancy percentage for a specific month.
        
        CRITICAL BUSINESS RULE:
        - Counts DISTINCT occupied properties per day (not booking rows)
        - Occupancy can NEVER exceed 100%
        - Multiple bookings for the same room on the same day = 1 occupied room
        
        Args:
            month_start: First day of the month
            month_end: Last day of the month
            
        Returns:
            Occupancy percentage (0-100), capped at 100
        r      )check_in_date__ltecheck_out_date__gtproperty_idcheck_in_datecheck_out_date)daysd   g        )default )r&   r0   r
   r!   r#   r   onlysetr   maxr.   minr/   addr-   lenr   r   r   )r   r'   r(   total_roomsdays_in_monthtotal_possible_nightsbookingsoccupied_room_nightsmonth_end_exclusivebookingcurrent_datebooking_endtotal_reserved_nights	occupancyoccupancy_cappeds                  r   _calculate_month_occupancyz(ChartsService._calculate_month_occupancy6   sa   ( ++-! #[066: +m ; A% ??)) 
(*
 ((*
 $
	 	  #u ()*;;Gw44kBLg446IJK,$((,8K8K)LM	q 11 ,   !$$8 9  !C'!
	 y#./1CDDr   c                    g }t        t        dz
  dd      D ]  }| j                  j                  d      t	        |      z
  }t        j                  |j                  |j                        d   }|j                  |      }| j                  ||      }|j                  |j                  d      |j                  d      |d        |S )z
        Generate monthly occupancy data for the last N months.
        
        Returns:
            List of dicts with month, year, and occupancy percentage
        r*   )day)monthsz%bz%Y)monthyearrD   )ranger   r   replacer	   calendar
monthrangerL   rK   rF   appendstrftime)r   monthly_datair'   last_dayr(   rD   s          r   get_monthly_occupancyz#ChartsService.get_monthly_occupancy   s      +a/R8A::--!-4}A7NNK**;+;+;[=N=NOPQRH#+++9I 77YOI$--d3#,,T2&!  9 r   c                 &    d| j                         iS )z|
        Get all chart data in a single call.
        
        Returns:
            Dict with chart data structures
        monthly_occupancy)rV   r   s    r   get_charts_datazChartsService.get_charts_data   s      !;!;!=
 	
r   )N)__name__
__module____qualname____doc__r   intr   r   strr   r   r&   r   rF   r   rV   rY   r3   r   r   r   r      s    !Xc] !PtCH~ P# PEPE PE 
	PEdtDcN'; 6	
c3h 	
r   r   )r]   rO   datetimer   r   typingr   r   r   r   dateutil.relativedeltar	   bookings.modelsr
   properties.modelsr   dashboard.constantsr   r   dashboard.services.utilsr   r   r   r   r   r3   r   r   <module>rg      s:     $ , , 0 # & H R
 R
r   