
    sojK                     t   d dl m Z  d dlmZ d dlmZ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 d d	lmZ d d
lmZ d dlmZmZmZ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$ 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/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6 d dl7m8Z8 d dl9m:Z: 	 dOdedede&de ddf
d Z;	 	 	 	 	 	 dPded"ej<        d#e=d$e=d%e=d&e=d'e=ddfd(Z>	 	 	 	 	 dQd)ed*e?d+e,d,e@d-edefd.ZA	 dRd"ej<        d/ed0e=ddfd1ZBd"ej<        ddfd2ZCd"ej<        ddfd3ZDdeEe         fd4ZFd)ed5e?ddfd6ZG	 	 	 	 dSded7eEe
         d8e=d9e=fd:ZH	 dTd"ej<        ded;ed<eddf
d=ZId"ej<        ded>e(d?e?d@e"dAeddfdBZJdedAedCe$dDe?ddf
dEZK	 dTded5e?dCe$dFedGeddfdHZLdUded)edJe=de@fdKZMdUdedLe=de@fdMZNd"ej<        fdNZOdS )V    )datetime)ContextTypes)phrasesEnvironment)Crew)CrewAbility)CrewChestSpendingRecord)CrewMemberChestContribution)DavyBackFight)User)Emoji)CrewDisbandNotificationCrewDisbandWarningNotificationCrewLeaveNotificationCrewMemberRemoveNotificationNotification CrewAbilityActivatedNotificationCrewConscriptionEndNotification)ReservedKeyboardKeys)Screen)CrewAbilityAcquiredMethod)CrewChestSpendingReason)CrewRole)DevilFruitAbilityType)ChatWarning)Keyboard)get_remaining_durationget_datetime_in_future_daysget_elapsed_duration)update_location)get_deeplink)send_notification)get_value_from_percentage)get_belly_formattedNcrew_membercrewroleconscription_end_datereturnc                    K   |t           j        u r|t          d          || _        || _        t          j                    | _        || _        t          | d           d{V  | 
                                 |                                 dS )z
    Adds a member to a crew

    :param crew_member: The user
    :param crew: The crew
    :param role: The role
    :param conscription_end_date: The conscription end date
    Nz6Conscription end date must be provided for a conscriptT)should_passive_update)r   	CONSCRIPT
ValueErrorr&   	crew_roler   nowcrew_join_dater(   r    saveset_is_full)r%   r&   r'   r(   s        /app/src/service/crew_service.py
add_memberr4   *   s       x!!!&;&CQRRRK K!)K(=K%
+T
B
B
BBBBBBBB    Fcontextsend_notification_to_captainsend_notification_to_memberdisable_user_can_join_crew#disable_crew_can_accept_new_membersfrom_davy_back_fight_conscriptc                   K   | j         }|sZ|                                rt          t          j                  |                                rt          t          j                  d| _         d| _        d| _        d| _	        |rd| _
        t          | dd           d{V  |                                  |                                 |rd|_        |                                 |rpt          ||                                t#          |                      d{V  |                                }|$t          ||t#          |                      d{V  |r&t          || t'          |                      d{V  dS dS )a'  
    Removes a member from a crew

    :param context: The context
    :param crew_member: The user
    :param send_notification_to_captain: Whether to send a notification to the captain
    :param send_notification_to_member: Whether to send a notification to the member
    :param disable_user_can_join_crew: Whether to set user can_join_crew to False
    :param disable_crew_can_accept_new_members: Whether to set crew can_accept_new_members to False
    :param from_davy_back_fight_conscript: Whether the user is a conscript
    :return: None
    NFT)r+   can_scale_down)r&   has_active_davy_back_fightr   r   )CREW_REMOVE_MEMBER_ACTIVE_DAVY_BACK_FIGHThas_penalty_davy_back_fight*CREW_REMOVE_MEMBER_DAVY_BACK_FIGHT_PENALTYr.   crew_promotion_dater0   can_join_crewr    r1   r2   can_accept_new_membersr"   get_captainr   get_first_mater   )	r%   r6   r7   r8   r9   r:   r;   r&   
first_mates	            r3   remove_memberrH   D   s     , !D) R**,, 	QgOPPP ++-- 	RgPQQQK K&*K#!%K! *$)!
+TRV
W
W
WWWWWWWW* &+#		 $ ])9)9););=RS^=_=_````````` ((**
!#GZ9N{9[9[\\\\\\\\\ # a6RS^6_6_```````````a ar5   usercrew_idinbound_keyboardcrew_id_keyvalidate_against_crewc                 \   | ||t          d          ||t          d          | t          j        |j        |                   }n| | j        }nt          j        |          }||j        st          t          j                  |||k    rt          t          j	                  |S )a3  
    Get crew

    :param user: The target user
    :param crew_id: The crew id
    :param inbound_keyboard: The inbound keyboard
    :param crew_id_key: The crew id key
    :param validate_against_crew: The crew to validate against and make sure the user is in the
    same crew

    :return: The crew
    Nz;Either user or crew_id or inbound_keyboard must be providedz<crew_id_key must be provided if inbound_keyboard is provided)
r-   r   logical_getinfor&   	is_activer   r   CREW_NOT_FOUNDCREW_NOT_SAME)rI   rJ   rK   rL   rM   r&   s         r3   get_crewrT      s    ( |,<,DVWWW#(;WXXX#%&6&;K&HII		Y%g.. |4>|'0111 (T5J-J-J'/000Kr5   captainshould_notify_captainc                 :  K   |j         }|                                rt          t          j                  |                                rt          t          j                  |                                }|D ]m}|j        |j        k    }|rd|_	        t          |           d{V  nt          |           d{V  |r|r#t          | |t                                 d{V  nd|_        t          j                    |_        |                                 dS )z
    Disbands a crew

    :param context: The context
    :param captain: The captain, necessary to directly update the user object
    :param should_notify_captain: Whether to notify the captain
    :return: None
    FN)r&   r>   r   r   #CREW_DISBAND_ACTIVE_DAVY_BACK_FIGHTr@   $CREW_DISBAND_DAVY_BACK_FIGHT_PENALTYget_membersidcan_create_crewrH   r"   r   rQ   r   r/   disband_dater1   )r6   rU   rV   r&   crew_membersmember
is_captains          r3   disband_crewra      sF      D &&(( G'EFFF '')) H'FGGG#//11L 
P 
PY'*,
 	(&+G#((((((((((''''''''' 	P2 	P#GV5L5N5NOOOOOOOOODN DIIKKKKKr5   c                 `   K   t                      }|D ]}t          | |d           d{V  dS )z[
    Disbands inactive crews

    :param context: The context object
    :return: None
    T)rV   N)get_inactive_captainsra   )r6   inactive_crew_captainsrU   s      r3   disband_inactive_crewsre      s]       344 * I I7G4HHHHHHHHHHHI Ir5   c                 v   K   t                      }|D ]%}t          | |t                                 d{V  &dS )z
    Warns inactive captains which Crew will be disbanded in the next leaderboard

    :param context: The context object
    :return: None
    N)rc   r"   r   )r6   inactive_captainsrU   s      r3   warn_inactive_captainsrh      s_       .//$ T T2P2R2RSSSSSSSSSST Tr5   c                      g S )zz
    Find captains of a Crew that have not been active since the last bounty reset
    :return: The inactive captains
     rj   r5   r3   rc   rc      s	     Ir5   amountc                    |                                  st          d          | j        }|xj        |z  c_        |xj        |z  c_        |                                 t          j        t          j        |k    t          j        | k    z            }|t                      }||_        | |_        |xj	        |z  c_	        t          j                    |_        |                                 |                                }|k|dz  }|j        |k    r|xj        |z  c_        n|xj        |z  c_        |                                 |xj        |z  c_        |                                 dS |                                }|t%          |t&          j                                                  }|                    |          }|xj        |z  c_        |xj        |z  c_        |xj        |z  c_        |xj        |z  c_        |                                 |                                 |                                 dS dS )zk
    Adds to the crew chest

    :param user: The user
    :param amount: The amount
    :return: None
    zUser is not a crew memberN   )is_crew_memberr-   r&   chest_amounttotal_gained_chest_amountr1   r
   get_or_nonerI   rk   r   r/   last_contribution_dateget_in_progress_davy_back_fightchallenger_crewchallenger_chestopponent_chestget_penalty_davy_back_fightr#   Env&DAVY_BACK_FIGHT_LOSER_CHEST_PERCENTAGEget_intget_opponent_crewpenalty_payout)	rI   rk   r&   contribution
active_dbfamount_to_freezepenalty_dbfpenalty_amountopponent_crews	            r3   add_to_crew_chestr   
  s]       64555D""f,""IIKKK 1L0W	$	)T	16Q6VZ^6^_1 1L 244  6!*2,..L' !% D D F FJ!Q;%--''+;;'''%%)99%%--		 &*%E%E%G%G"6BJJLL N (99$??M&&.8&&33~E33/&&.8&&IIKKK    #"r5   active_abilitiesadd_duration	add_emojic                    ||                                  }t          |          dk    rt          j        }ng }|rt          j        j        nd}|D ]}t          j                            ||	                                |
                                          }|r4|t          j                            t          |j                            z  }|                    |           |rdnd                    |          }|S )a  
    Returns the crew abilities text
    :param crew: The crew
    :param active_abilities: The active abilities
    :param add_duration: Whether to add the duration
    :param add_emoji: Whether to add the positive log emoji
    :return: The crew abilities text
    Nr    
)get_active_abilitieslenr   CREW_ABILITY_NO_ABILITIESr   LOG_POSITIVEvalueCREW_ABILITY_ITEM_TEXTformatget_descriptionget_value_with_signCREW_ABILITY_ITEM_TEXT_DURATIONr   expiration_dateappendjoin)	r&   r   r   r   abilities_textactive_abilities_text_list
emoji_textabilitytexts	            r3   get_crew_abilities_textr   I  s    4466
!! :%'"1:BU'--
' 		4 		4G188G3355w7R7R7T7T D  ?FF*7+BCC   '--d3333".6$$B<<=WXXr5   notificationexclude_userc                    K   |                                 D ])}|j        |j        k    rt          | ||           d{V  *dS )z
    Notifies crew members

    :param context: The context
    :param crew: The crew
    :param notification: The notification
    :param exclude_user: The user to exclude
    :return: None
    N)rZ   r[   r"   )r6   r&   r   r   r_   s        r3   notify_crew_membersr   p  se        ""$$ C C9''#GV\BBBBBBBBBC Cr5   ability_typeability_valueacquired_methodacquired_userc                 j  K   t          j                    }t                      }||_        ||_        ||_        ||_        ||_        t          t          j
                                        |          |_        |                                 t          | |t          |          |           d{V  dS )a(  
    Adds a crew ability

    :param context: The context
    :param crew: The crew
    :param ability_type: The ability type
    :param ability_value: The ability value
    :param acquired_method: The acquired method
    :param acquired_user: The acquired user
    :return: The crew ability
    )
start_time)r   N)r   r/   r   r&   r   r   r   r   r   rx   CREW_ABILITY_DURATION_DAYSrz   r   r1   r   r   )r6   r&   r   r   r   r   r/   r   s           r3   add_crew_abilityr     s      ( ,..C&==GGL'G!GM-G)G9&..00S  G LLNNN 7@@}           r5   reasonpricec                    |t           j        u r?|                                  |                                 D ]}|                                 | xj        |z  c_        |                                  t          | |||           dS )z
    Adds a powerup to a crew

    :param crew: The crew
    :param acquired_user: The user who acquired the powerup
    :param reason: The reason
    :param price: The price
    :return: None
    N)r   LEVEL_UPlevel_uprZ   reduce_tax_bracketro   r1   add_chest_spending_record)r&   r   r   r   r_   s        r3   add_powerupr     s     (111 &&(( 	( 	(F%%''''IIKKK dE6=AAAAAr5   by_userto_userc                     t                      }| |_        ||_        ||_        ||_        ||_        |                                 dS )a  
    Adds a chest spending record

    :param crew: The crew
    :param amount: The amount
    :param reason: The reason
    :param by_user: User who spent the amount
    :param to_user: User who received the amount, in case of a transfer
    :return: None
    N)r	   r&   rk   r   r   r   r1   )r&   rk   r   r   r   records         r3   r   r     sC     '>&?&?FFKFMFMFNFN
KKMMMMMr5   Tfrom_searchc                 H   ddl m} d}d}d}d}d}d}	d}
|r| j        st          j        S | j        dk    r1t          j                            t          | j                            }t          j	                            t          |                                           | j                  }n|                                 }|1t          j                            |                                          }t          j                            t          | j                            }t          j                            t'          |                     }| j        s't          j                             |                      }	|                                 }|1t          j                            t1          |j                            }
|                                 }t          j                            |                                 | j        | j        |                                 nt          j         |                                ||!                    | j"                  tG          | j"                  t          | $                                          | j%        |||||	|
          }|S )z
    Get the crew overview text

    :param crew: The crew
    :param user: The user
    :param from_search: Whether the crew overview is from search, if so show basic info only
    :return: The crew overview text
    r   )&get_remaining_time_to_next_leaderboardr   N)r&   )&src.service.leaderboard_servicer   allow_view_in_searchr   CREW_SEARCH_NOT_ALLOWED_TO_VIEWrequired_bountyCREW_OVERVIEW_REQUIRED_BOUNTYr   r$   $CREW_OVERVIEW_ACTIVE_ABILITIES_COUNTr   r   max_abilitiesrF   CREW_OVERVIEW_FIRST_MATEget_markdown_mentionCREW_OVERVIEW_TREASURE_CHESTro   CREW_OVERVIEW_ACTIVE_ABILITIESr   rD   $CREW_OVERVIEW_NO_NEW_MEMBERS_ALLOWEDrw   ,CREW_OVERVIEW_DAVY_BACK_FIGHT_PENALTY_ACTIVEr   penalty_end_daterE   CREW_OVERVIEWget_name_escapedleveldescriptionget_description_escaped!CREW_OVERVIEW_DESCRIPTION_NOT_SETget_date_formatteddater   rZ   max_members)r&   rI   r   r   active_abilities_count_textrequired_bounty_textfirst_mate_texttreasure_chest_textactive_abilities_textno_new_members_allowed_textdavy_back_fight_penalty_activerG   dbf_penaltyrU   ot_texts                  r3   get_crew_overview_textr     s    WVVVVV #% O"$%'" ( 	;::!###*#H#O#O#D$899$ $  '.&R&Y&Y))++,,d.@'
 '
##  ..00
!%>EE//11 O &BII 122
 
 !( F M M#...!
 !

 * 	*1*V*]*]6688+ +'
 "&!A!A!C!CK@GG&{'CDD  	' $$&&G#**
 + ((***:$$&&	**TY''D##&' G, Nr5   	add_levelc                    t          t          j        | j        it          j                  }|                                 }|r&t          j        	                    ||| j
                  S t          j        	                    ||          S )z
    Get the crew name with deeplink

    :param crew: The crew
    :param add_level: Whether to add the level
    :return: The crew name with deeplink
    )rP   screen)r!   r   DEFAULT_PRIMARY_KEYr[   r   PVT_CREW_SEARCH_DETAILr   r   CREW_NAME_WITH_LEVEL_DEEPLINKr   r   	ITEM_LINK)r&   r   deeplinknames       r3   get_crew_name_with_deeplinkr   8  s}     "6@,  H   ""D X4;;D(DJWWW##D(333r5   c                   K   t          j                                        t           j        t          j        k    t           j                            d          t           j        t          j	                    k               }|D ]A}d|_        |
                                 t          | |t          |                     d{V  BdS )zQ
    Ends all conscription
    :param context: The context
    :return: None
    FN)r   selectwherer.   r   r,   r(   is_nullr   r/   r1   r"   r   )r6   
conscripts	conscripts      r3   end_all_conscriptionr   M  s       $$(,,"**511"X\^^3 J   ` `	"	  4ST]4^4^__________` `r5   )NN)NFFFFF)NNNNN)F)NNFF)N)T)Pr   src.tg_compat.extr   	resourcesr   r   rx   src.model.Crewr   src.model.CrewAbilityr   !src.model.CrewChestSpendingRecordr	   %src.model.CrewMemberChestContributionr
   src.model.DavyBackFightr   src.model.Userr   src.model.enums.Emojir   src.model.enums.Notificationr   r   r   r   r   r   r   $src.model.enums.ReservedKeyboardKeysr   src.model.enums.Screenr   .src.model.enums.crew.CrewAbilityAcquiredMethodr   ,src.model.enums.crew.CrewChestSpendingReasonr   src.model.enums.crew.CrewRoler   1src.model.enums.devil_fruit.DevilFruitAbilityTyper   src.model.error.ChatWarningr   src.model.pojo.Keyboardr   src.service.date_servicer   r   r   src.service.location_servicer    src.service.message_servicer!    src.service.notification_servicer"   src.utils.math_utilsr#   src.utils.string_utilsr$   r4   DEFAULT_TYPEboolrH   intstrrT   ra   re   rh   listrc   r   r   r   r   r   r   r   r   r   rj   r5   r3   <module>r     s         * * * * * * < < < < < < < <       - - - - - - E E E E E E M M M M M M 1 1 1 1 1 1       ' ' ' ' ' '                  F E E E E E ) ) ) ) ) ) T T T T T T P P P P P P 2 2 2 2 2 2 S S S S S S 3 3 3 3 3 3 , , , , , ,         
 9 8 8 8 8 8 4 4 4 4 4 4 > > > > > > : : : : : : 6 6 6 6 6 6 ]a !)1QY	   8 *.).(-',05+0=a =a=a&=a #'=a "&	=a
 !%=a *.=a %)=a 
=a =a =a =aB !%"&) )
)) ) 	)
  ) 
) ) ) )Z V[% %&%15%NR%	% % % %PI,*C I I I I I T,*C T T T T TtDz    (<D <# <$ < < < <@ *.	$ $
$;'$ $ 	$ $ $ $V 	C C&C
C C 	C
 
C C C C*#&#
# (# 	#
 /# # 
# # # #LB
B#B-DBMPB	B B B B: ^b 
%<GKVZ	   .W W WT W WPS W W W Wt4 4d 4t 4s 4 4 4 4*`(A ` ` ` ` ` `r5   