o
    ̿Si*                  	   @   s  d Z ddlmZmZmZmZmZ ddlmZm	Z	m
Z
mZ ddl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mZmZmZ e ZeeZd
ZdedefddZdede
e fddZ d5dedede	eef fddZ!ej"dddedeej#eefde	eef fddZ$ej%dddeddded d!d"d#eddd$eej#eefd%ee d&e&d'e&fd(d)Z'ej(d*d+dedeej#eefd,ede	eef fd-d.Z)ej*d*d/deej#eefd,efd0d1Z+e*d2eej#eefdefd3d4Z,dS )6a)  Portfolio routes for platform teGPT.

Reused as a simplified DAILY personal watchlist.

Rules:
- Max 10 ACTIVE symbols per user per IST day
- User can add/remove anytime
- Automatically "flushes" daily by scoping to today's IST date
- Also syncs into the global intraday watchlist (source=MANUAL)
    )	APIRouterBodyDependsHTTPExceptionQuery)AnyDictListOptionalN)datetime)ObjectId)database)get_current_userdetails)SOURCE_MANUAList_date_strremove_source_for_symbolsupsert_symbols
   symbolreturnc                 C   s   t | pd  S )N )strstripupper)r    r   E/var/www/html/Trade-python/app/v1/routers/platform/teGPT_portfolio.py_norm_symbol#   s   r   tagsc                 C   sl   | d u rg S t | tr| g} t | tsg S g }| D ]}t |ts!q|  }|r.|| qtt|S )N)
isinstancer   listr   lowerappenddictfromkeys)r   outtsr   r   r   
_norm_tags'   s   



r'   NSEexchangec                 C   s   t |}|pd  }|stddd| d ||dp&| d d|i}t|ts2tddd|d	s=tdd
d|dd u rJtddd|S )Nr(     zsymbol is requiredstatus_codedetailstocks)r   r)   r   z6symbol not found in stocks master; refresh instrumentsstock_idz0stock_id missing for symbol; refresh instrumentsinstrument_tokenz8instrument_token missing for symbol; refresh instruments)r   r   r   r   find_oner   r"   get)dbr   r)   symexstockr   r   r   _get_stock_or_4008   s   &

r7   z/portfolio/itemsz!Add/Upsert watchlist item (daily))summary.payloadc                    s  t |d}t }t| d}| dpd  }t| d}t|||d}t	 }	|d 
||dd	}
|d ||d
|d}|sX|
tkrXtddt dd||d
|d|dpg|d|||	d}|r|d d|d id|i t |d }|d}n|d i |d|	i}t |j}|	}zt|||dgt|d||did W n ty   td Y nw d||d
|d|dp||d|d|d|||	ddS )N_idr   r)   r(   r   )r)   user_portfolio_itemsACTIVEuser_idist_datestatusr/   )r>   r/   r?   r*   zMax z watchlist symbols per dayr+   )r>   r/   r   r)   r@   r   r?   
updated_at$set
created_atr   r>   r?   symbolssourcemeta_by_symbolz:Failed to sync manual watchlist item to intraday watchlistokr0   name)portfolio_item_idr/   r   r)   r0   rJ   r   r@   r?   rC   rA   r@   item)r   r2   r   r   r   r   r'   r7   r   utcnowcount_documentsr1   MAX_WATCHLIST_ITEMS_PER_USERr   
update_one
insert_oneinserted_idr   r   	Exceptionlogger	exception)r9   r3   current_userr>   r?   r   r)   r   r6   nowactive_countexistingdocitem_idrC   insertedr   r   r   upsert_portfolio_itemK   sn   


r^   zList watchlist items (daily)zFilter by tag)description2         )gele)rc   taglimitskipc                    sP  t |d}t }||dd}| r| pd  |d< |d |ddg||}t	|}	d	d
 |	D }
t	|d dd|
iiddddd}dd |D }g }|	D ]A}|d}||pei }|
t |d||d|d|d|d|d|dpg |d|d|dd qX|d |}d|||dS )Nr:   r<   r=   r   r   r;   )rA   )rC   rh   c                 S   s    g | ]}| d r| d qS r/   r2   ).0itr   r   r   
<listcomp>   s     z(list_portfolio_items.<locals>.<listcomp>r.   r/   z$inr   ra   )r:   r/   r0   rJ   c                 S   s"   i | ]}| d r| d |qS ri   rj   )rk   r&   r   r   r   
<dictcomp>   s   " z(list_portfolio_items.<locals>.<dictcomp>r   r)   r0   rJ   r@   r?   rC   rA   )rK   r/   r   r)   r0   rJ   r@   r   r?   rC   rA   rI   )r@   totalitemsr?   )r   r2   r   r   r    findsortrg   rf   r   r!   rO   )re   rf   rg   r3   rW   r>   r?   querycurrp   	stock_idsr.   by_idr$   rl   sidr6   ro   r   r   r   list_portfolio_items   s>   $&
rx   z$/portfolio/items/{portfolio_item_id}zUpdate watchlist tags (daily)rK   c                    sf  t |d}t }zt| }W n ty   tdddw |d |||d}|s2tdddt|d	}|t	 d
d}	|d 
|||dd|	i t|d}
|
rxzt|||
gt|
||did W n tyw   td Y nw |d |||dpi }dt |d|d|d|d|d|d	pg |d|d|dd	dS )Nr:   r*   Invalid portfolio_item_idr+   r;   r:   r>   r?     "Watchlist item not found for todayr   r<   )r   rA   r@   rB   r   rD   rE   z@Failed to sync manual watchlist tag update to intraday watchlistrI   r/   r)   r@   r?   rC   rA   )	rK   r/   r   r)   r@   r   r?   rC   rA   rL   )r   r2   r   r   rT   r   r1   r'   r   rN   rQ   r   r   r   rU   rV   )rK   r9   r3   rW   r>   r?   oidrZ   r   patchr4   updatedr   r   r   update_portfolio_item   s.   "\r   zDelete watchlist item (daily)c           	         s   t |d}t }zt| }W n ty   tdddw |d |||d}|s2tddd|d |||d}|jd	krHtdd
dt	|d}|rkzt
|||gtd W n tyj   td Y nw dddS )Nr:   r*   ry   r+   r;   rz   r{   r|   ra   zWatchlist item not foundr   )r?   rF   rG   z@Failed to remove manual watchlist symbol from intraday watchlistrI   Tr@   deleted)r   r2   r   r   rT   r   r1   
delete_onedeleted_countr   r   r   rU   rV   )	rK   r3   rW   r>   r?   r}   rZ   resr4   r   r   r   delete_portfolio_item   s,   

r   z#/portfolio/items/by-symbol/{symbol}c                    s   t |d}t }| pd  }|stddd|d |||ddd	d	d
}|s2dddS |d d|diddt	 di z|g}t
||d|d W n tyb   td| Y nw dddS )Nr:   r   r*   zMissing symbolr+   r;   r<   )r>   r?   r   r@   ra   )r:   r   successFr   rB   DELETED)r@   
deleted_atMANUAL)rF   rG   r?   z%Failed to remove MANUAL source for %sT)r   r2   r   r   r   r   r1   rQ   r   rN   r   rT   rU   rV   )r   r3   rW   r>   r?   r4   r[   sym_listr   r   r   delete_portfolio_item_by_symbol  s.   

r   )r(   )-__doc__fastapir   r   r   r   r   typingr   r   r	   r
   loggingr   bsonr   app.dbr   app.v1.dependencies.authr   "app.v1.services.intraday_watchlistr   r   r   r   router	getLogger__name__rU   rP   r   r   r'   r7   postget_mongo_dbr^   r2   intrx   r~   r   deleter   r   r   r   r   r   <module>   sp    
 
I

-
 