o
    ^jx-                     @  s  d Z ddlmZ ddlZddlmZmZ ddlmZm	Z	m
Z
mZmZ ddlmZ dLddZdMddZdNddZdNddZdNddZdNddZdOddZdPd"d#Zddd$dQd.d/Zdddd0dRd7d8Zd9d:dSd=d>ZdTd@dAZdddddBdCdDdUdGdHZddddIdVdJdKZdS )Wz?Per-business minute allocation history and incremental top-ups.    )annotationsN)DecimalInvalidOperation)AnyDictListOptionalTuple)get_monthly_minute_limit
table_namestrcolumn_namereturnboolc                 C  s   |  d||f |  d uS )Nz
        SELECT 1
        FROM information_schema.columns
        WHERE table_schema = DATABASE()
          AND table_name = %s
          AND column_name = %s
        LIMIT 1
        executefetchone)cursorr   r    r   C/home/aiteam/pcaa-dev/dashboard-backend/usage_allocation_history.py_column_exists   s
   r   c                 C  s   |  d|f |  d uS )Nz
        SELECT 1
        FROM information_schema.tables
        WHERE table_schema = DATABASE() AND table_name = %s
        LIMIT 1
        r   )r   r   r   r   r   _table_exists   s
   	r   Nonec                 C     t | dds| d d S d S )Npca_business_allocationsdefault_cost_per_minutez
            ALTER TABLE pca_business_allocations
            ADD COLUMN default_cost_per_minute DECIMAL(12, 4) NULL
            r   r   r   r   r   r   !ensure_allocation_billing_columns(   
   r   c                 C  sJ   t | dds| d t | dds| d t | dds#| d d S d S )Nr   validity_monthsz}
            ALTER TABLE pca_business_allocations
            ADD COLUMN validity_months SMALLINT NULL DEFAULT 0
            usage_alert_sent_atz
            ALTER TABLE pca_business_allocations
            ADD COLUMN usage_alert_sent_at DATETIME NULL DEFAULT NULL
            validity_alert_sent_atz
            ALTER TABLE pca_business_allocations
            ADD COLUMN validity_alert_sent_at DATETIME NULL DEFAULT NULL
            r   r   r   r   r   "ensure_allocation_validity_columns2   s   r#   c                 C  r   )Npca_allocation_historyamount_paidz
            ALTER TABLE pca_allocation_history
            ADD COLUMN amount_paid DECIMAL(14, 2) NULL,
            ADD COLUMN cost_per_minute DECIMAL(12, 4) NULL,
            ADD COLUMN currency VARCHAR(8) NULL DEFAULT 'INR'
            r   r   r   r   r   _ensure_history_billing_columnsJ   r   r&   c                 C  s&   |  d t|  t|  t|  d S )Na  
        CREATE TABLE IF NOT EXISTS pca_allocation_history (
            id BIGINT AUTO_INCREMENT PRIMARY KEY,
            bid VARCHAR(64) NOT NULL,
            minutes_added INT NOT NULL,
            total_before INT NOT NULL DEFAULT 0,
            total_after INT NOT NULL DEFAULT 0,
            action_type VARCHAR(32) NOT NULL DEFAULT 'add',
            amount_paid DECIMAL(14, 2) NULL,
            cost_per_minute DECIMAL(12, 4) NULL,
            currency VARCHAR(8) NULL DEFAULT 'INR',
            notes TEXT NULL,
            created_by VARCHAR(255) NULL,
            created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
            INDEX idx_allocation_history_bid_created (bid, created_at DESC)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
        )r   r&   r   r#   r   r   r   r   ensure_allocation_history_tableV   s   r'   r%   floatcost_per_minuteintc                 C  s2   | dks|dkrt dttt| t| S )Nr   z0amount_paid and cost_per_minute must be positive)
ValueErrorr*   mathfloorr(   )r%   r)   r   r   r   compute_minutes_from_paymento   s   r.   payloadDict[str, Any]1Tuple[int, Optional[float], Optional[float], str]c              
   C  s"  t | dpd pd}| d}| d}|duo"t | dk}|duo.t | dk}|s3|ru|r7|s;tdzttt |}ttt |}W n tttfya } ztd|d}~ww t||}	|	d	krotd
|	|||fS t	| dp| dpd	}
|
d	krtd|
dd|fS )u>   Resolve minutes from direct count or amount ÷ rate (floored).currencyINRr%   r)   N z5amount_paid and cost_per_minute must both be providedz5amount_paid and cost_per_minute must be valid numbersr   z.Payment amount is too small for the given rateminutes_to_addminutesz:Provide minutes_to_add or amount_paid with cost_per_minute)
r   getstripr+   r(   r   r   	TypeErrorr.   r*   )r/   r2   
amount_rawrate_raw
has_amounthas_rater%   r)   excr6   r5   r   r   r   resolve_allocation_minutesu   s.   



r?   )r   r    bid	new_limitnotesOptional[str]
updated_byr   Optional[float]r    Optional[int]c             
   C  s:   t |  t|  | dt|t|t|||||f d S )Na  
        INSERT INTO pca_business_allocations (
            bid, monthly_call_limit, monthly_minute_limit, notes, updated_by,
            default_cost_per_minute, validity_months
        )
        VALUES (%s, %s, %s, %s, %s, %s, %s)
        ON DUPLICATE KEY UPDATE
            monthly_call_limit = VALUES(monthly_call_limit),
            monthly_minute_limit = VALUES(monthly_minute_limit),
            notes = COALESCE(VALUES(notes), notes),
            updated_by = VALUES(updated_by),
            default_cost_per_minute = COALESCE(VALUES(default_cost_per_minute), default_cost_per_minute),
            validity_months = COALESCE(VALUES(validity_months), validity_months)
        )r   r#   r   r   r*   )r   r@   rA   rB   rD   r   r    r   r   r   _upsert_allocation_row   s   
rG   )r%   r)   r2   minutes_addedtotal_beforetotal_afteraction_type
created_byr2   c       	         C  sJ   |  dt|t|t|t|t|pd||	|
pd||f
 t| jp#dS )Nz
        INSERT INTO pca_allocation_history
        (bid, minutes_added, total_before, total_after, action_type,
         amount_paid, cost_per_minute, currency, notes, created_by)
        VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
        addr3   r   )r   r   r*   	lastrowid)r   r@   rH   rI   rJ   rK   rB   rL   r%   r)   r2   r   r   r   _insert_history_row   s   
rO   d   limitrR   List[Dict[str, Any]]c                C  sJ   t | dsg S tdtt|pdd}| dt||f t|  p#g S )Nr$      rP   i  a  
        SELECT
            id,
            bid,
            minutes_added,
            total_before,
            total_after,
            action_type,
            amount_paid,
            cost_per_minute,
            currency,
            notes,
            created_by,
            created_at
        FROM pca_allocation_history
        WHERE bid = %s
        ORDER BY created_at DESC, id DESC
        LIMIT %s
        )r   maxminr*   r   r   listfetchall)r   r@   rR   
safe_limitr   r   r   get_allocation_history   s   

rZ   Optional[Dict[str, Any]]c                 C  s   t | |dd}|r|d S d S )NrT   rQ   r   )rZ   )r   r@   rowsr   r   r   get_latest_allocation_event   s   r]   r3   T)rB   rL   r%   r)   r2   save_default_rater5   r^   c                C  s   t |  t|pd}	|	dkrtdt| |}
|
|	 }|r#|d ur#|nd }t| |||||d t| ||	|
|d|||||d}t||	|||pGd|
|||d	S )Nr   z)minutes_to_add must be a positive integer)r   rM   )	rH   rI   rJ   rK   rB   rL   r%   r)   r2   r3   )	r@   rH   r%   r)   r2   rI   rJ   monthly_minute_limit
history_id)r'   r*   r+   r
   rG   rO   r   )r   r@   r5   rB   rL   r%   r)   r2   r^   deltarI   rJ   default_rater`   r   r   r   add_allocation_minutes   sL   
rc   )rB   rD   r    c             
   C  s   t |  t| |}tdt|pd}|| }t| |||||d d}	|dkr3t| ||||d||d}	n|d us;|d urF| d||t|f | dt|f |  pTi }
t||||||	t|
	dpdddS )	Nr   )r    set)rH   rI   rJ   rK   rB   rL   z
            UPDATE pca_business_allocations
            SET notes = COALESCE(%s, notes), updated_by = %s
            WHERE bid = %s
            zKSELECT validity_months FROM pca_business_allocations WHERE bid = %s LIMIT 1r    )r@   rH   rI   rJ   r_   r`   r    )
r'   r
   rU   r*   rG   rO   r   r   r   r7   )r   r@   rA   rB   rD   r    rI   rJ   ra   r`   rowr   r   r   set_allocation_minutes4  sJ   	

	rf   )r   r   r   r   r   r   )r   r   r   r   )r   r   )r%   r(   r)   r(   r   r*   )r/   r0   r   r1   )r@   r   rA   r*   rB   rC   rD   rC   r   rE   r    rF   r   r   )r@   r   rH   r*   rI   r*   rJ   r*   rK   r   rB   rC   rL   rC   r%   rE   r)   rE   r2   rC   r   r*   )r@   r   rR   r*   r   rS   )r@   r   r   r[   )r@   r   r5   r*   rB   rC   rL   rC   r%   rE   r)   rE   r2   rC   r^   r   r   r0   )r@   r   rA   r*   rB   rC   rD   rC   r    rF   r   r0   )__doc__
__future__r   r,   decimalr   r   typingr   r   r   r   r	   usage_allocation_utilr
   r   r   r   r#   r&   r'   r.   r?   rG   rO   rZ   r]   rc   rf   r   r   r   r   <module>   sD    








"1%

;