
    i                         d dl mZmZmZmZ d dlmZ ddlmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZmZ  ee      Z G d d      Zy)    )ListDictAnyOptional)
get_logger   )in_placeholdersQUERY_USER_BASIC_DETAILSQUERY_USER_IDS_KEYSET/QUERY_USER_IDS_KEYSET_WITH_RECENT_ACTIVITY_LOGS!QUERY_USER_HAS_ACTIVITY_LOG_SINCEQUERY_ACTIVITY_LOGSQUERY_ORDERSQUERY_ORDER_ITEMSQUERY_IMPRESSIONSQUERY_REVIEWS_AND_RATINGSQUERY_CART_DATAQUERY_CART_ITEMS_IN_WINDOWQUERY_CART_STATS$QUERY_CART_TOP_CONSIDERED_NOT_BOUGHT,QUERY_CART_CONSIDERED_NOT_BOUGHT_BY_CATEGORYQUERY_DIETARY_PREFERENCESQUERY_DIETARY_PREFERENCE_LABELSc                      e Zd ZdZd Zddededeeee	f      fdZ
dedeee	f   fdZd	d
dededee   dee   fdZdededefdZdedededeeee	f      fdZdedededeeee	f      fdZdee   deeee	f      fdZdedededeeee	f      fdZdedededeeee	f      fdZdedededeeee	f      fdZdedededeee	f   fdZdedeee	f   fdZdee   deeee	f      fdZy	)DataFetcherz
    Handles raw SQL execution for user-centric profiling.
    Strictly follows the 'One User at a Time' principle.
    All temporal queries require start_date and end_date.
    c                     || _         y N)db)selfdb_connections     C/var/www/html/userprofiledev.eatanceapp.com/data_fetcher/fetcher.py__init__zDataFetcher.__init__"   s	        queryparamsreturnc                 :    | j                   j                  ||      S r   )r   execute)r   r$   r%   s      r!   _executezDataFetcher._execute%   s    wwuf--r#   user_idc                 r    t         j                  d|        | j                  t        |f      }|r|d   S i S )Nz Fetching basic details for User r   )loggerinfor)   r
   r   r*   resultss      r!   fetch_user_basic_detailsz$DataFetcher.fetch_user_basic_details(   s:    6wi@A-- 87*E$wqz,",r#   N)recent_activity_dayslast_id	page_sizer1   c                    ||dkD  r| j                  t        |||f      }n| j                  t        ||f      }|D cg c]  }t        |d          c}S c c}w )u   
        User ids with id > last_id, ascending, at most page_size.

        If ``recent_activity_days`` is set, only users with ≥1 ``user_activity_logs`` row
        in that many days (SQL EXISTS).
        r   id)r)   r   r   int)r   r2   r3   r1   rowsrs         r!   fetch_user_ids_keysetz!DataFetcher.fetch_user_ids_keyset-   sf      +0Dq0H==?G%9:D
 ==!6G8LMD&*+dAdGd+++s   Aactivity_daysc                     |dk  ry| j                  t        ||f      }|syt        |d   j                  d      xs d      dk(  S )uW   True if ``dbo.user_activity_logs`` has ≥1 row for user in the last ``activity_days``.r   TFhas_activityr   )r)   r   r6   get)r   r*   r:   r7   s       r!   user_has_recent_activity_logsz)DataFetcher.user_has_recent_activity_logsC   sK    A}}>-@XY47;;~.3!499r#   
start_dateend_datec                 p    t         j                  d| d| d|        | j                  t        |||f      S )Nz Fetching activity logs for User z	 between z and )r,   r-   r)   r   r   r*   r?   r@   s       r!   fetch_activity_logszDataFetcher.fetch_activity_logsL   s>    6wiyTYZbYcde}}07J2QRRr#   c                 4    | j                  t        |||f      S r   )r)   r   rB   s       r!   fetch_orderszDataFetcher.fetch_ordersP   s    }}\GZ+JKKr#   	order_idsc                     |sg S t        j                  t        t        |                  }| j	                  |t        |            S r   )r   formatr	   lenr)   tuple)r   rF   r$   s      r!   fetch_order_itemszDataFetcher.fetch_order_itemsS   s9    I!((Y)HI}}UE)$455r#   c                 4    | j                  t        |||f      S r   )r)   r   rB   s       r!   fetch_impressionszDataFetcher.fetch_impressionsY   s    }}.*h0OPPr#   c                 4    | j                  t        |||f      S r   )r)   r   rB   s       r!   fetch_reviews_and_ratingsz%DataFetcher.fetch_reviews_and_ratings\   s    }}6*h8WXXr#   c                 4    | j                  t        |||f      S r   )r)   r   rB   s       r!   fetch_cart_datazDataFetcher.fetch_cart_data_   s    }}_w
H.MNNr#   c                 h   |||f}dddddd}	 | j                  t        |      }|dz  }| j                  t        |      }|r|d   n|}	| j                  t        |dz        }
| j                  t        |dz        }|xs g |	|
xs g |xs g dS # t
        $ r t        j                  d|||        w xY w)ax  
        Runs the four add_to_cart_logs queries and returns a single dict:
        items_in_window, stats, top_considered_not_bought, considered_not_bought_by_category.
        Uses the same window as the rest of the profile. DB or schema failures propagate
        (no silent empty structure) so the pipeline can fail loudly instead of looking like no cart activity.
        g        r   )#add_to_cart_events_per_item_ordered,count_distinct_items_added_but_never_ordered1count_distinct_items_added_then_removed_from_cart"total_add_to_cart_events_in_windowtotal_items_ordered_in_window      )items_in_windowstatstop_considered_not_bought!considered_not_bought_by_categoryzAfetch_cart_add_to_cart_signals failed (user_id=%s, window=%s..%s))r)   r   r   r   r   	Exceptionr,   	exception)r   r*   r?   r@   r%   empty_statsrZ   stats_params
stats_rowsr[   r\   r]   s               r!   fetch_cart_add_to_cart_signalsz*DataFetcher.fetch_cart_add_to_cart_signalsb   s     :x036<=AB23-.
	"mm,FOO "A:L'7FJ%/JqM[E(,4fqj)% 15<fqj1-
 $3#8b-F-L"5V5\Z\	   	S	 	s   A>B #B1c                 B    | j                  t        |f      }|r|d   S i S )Nr   )r)   r   r.   s      r!   fetch_dietary_preferencesz%DataFetcher.fetch_dietary_preferences   s&    -- 9G:F$wqz,",r#   slugsc                     |sg S t        j                  t        t        |                  }| j	                  |t        |            S r   )r   rH   r	   rI   r)   rJ   )r   rf   r$   s      r!   fetch_dietary_preference_labelsz+DataFetcher.fetch_dietary_preference_labels   s8    I/66s5z7RS}}UE%L11r#   ) )__name__
__module____qualname____doc__r"   strrJ   r   r   r   r)   r6   r0   r   r9   boolr>   rC   rE   rK   rM   rO   rQ   rc   re   rh   ri   r#   r!   r   r      sO    .c .5 .$tCH~:N .- -S#X - /3,, ,
 'sm, 
c,,:S : :QU :S3 SC S3 SSWX\]`be]eXfSg SLC LS LC LDQUVY[^V^Q_L` L649 6d38n9M 6Q Q# Q QQUVZ[^`c[cVdQe QY Y# YQT YY]^bcfhkck^lYm YOs O Os OtTXY\^aYaTbOc O..(+.7:.	c3h.`- -c3h -2T#Y 24SRUXCW 2r#   r   N)typingr   r   r   r   core.logger_configr   queriesr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rj   r,   r   ri   r#   r!   <module>rs      s?    , , )    ( 
H	2 2r#   