Ë
    ÊBi/  ã                  ó¦   — d 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 dd
lmZ ddlmZ ddlmZ  G d„ de
«      Zy)z3Tests for the daily reward and commission pipeline.é    )Úannotations)Ú	timedelta)ÚDecimal)Úcall_command)ÚTestCase)Útimezone)ÚDistributeRewardsTask)Ú
InvestmentÚReward)Ú
Commission)ÚTransaction)ÚUserc                  óD   — e Zd Zdd„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zy
)ÚCalculateRewardsCommandTestsc                óÂ  — t         j                  j                  ddd¬«      | _        t         j                  j                  ddd| j                  ¬«      | _        t         j                  j                  d	d
d| j                  ¬«      | _        t         j                  j                  ddd| j
                  ¬«      | _        t        j                  t        d«      «      }t        j                  «       }t        j                  j                  | j                  t        d«      |d   |d   |d   t        j                  |t        d¬«      z
  |t        d¬«      z   ¬«      | _        y)z<Create a referral chain with one downline and three uplines.ié  ÚU1Úu1©Útelegram_user_idÚ
first_nameÚusernameiê  ÚU2Úu2©r   r   r   Úreferred_byië  ÚU3Úu3iÑ  ÚDownlineÚdownlineÚ1000ÚtierÚrateÚdurationé   ©Údaysé
   ©ÚuserÚamountr!   Údaily_reward_rateÚduration_daysÚstatusÚ
start_dateÚend_dateN)r   ÚobjectsÚcreate_userÚupline1Úupline2Úupline3r   r
   Úget_tier_infor   r   ÚnowÚcreateÚSTATUS_PENDINGr   Ú
investment)ÚselfÚ	tier_infor6   s      ú^/home/cursorai/projects/telegram-earn/backend/apps/investments/tests/test_calculate_rewards.pyÚsetUpz"CalculateRewardsCommandTests.setUp   s4  € ä—|‘|×/Ñ/Ø!ØØð 0ó 
ˆŒô
 —|‘|×/Ñ/Ø!ØØØŸ™ð	 0ó 
ˆŒô —|‘|×/Ñ/Ø!ØØØŸ™ð	 0ó 
ˆŒô Ÿ™×0Ñ0Ø!Ø!ØØŸ™ð	 1ó 
ˆŒô ×,Ñ,¬W°V«_Ó=ˆ	Ü�l‰l‹nˆÜ$×,Ñ,×3Ñ3Ø—‘Ü˜6“?Ø˜6Ñ"Ø'¨Ñ/Ø# JÑ/Ü×,Ñ,ØœY¨AÔ.Ñ.Øœ9¨"Ô-Ñ-ð 4ó 	
ˆ�ó    c                óB  — | j                   j                  t        d¬«      z   j                  «       }t	        d|j                  «       ¬«       t        |«      j                  |«       t        j                  j                  | j                   |¬«      }| j                  |j                  t        d«      «       t        j                  j                  |¬«      j!                  d«      }| j                  |j#                  «       d	«       | j%                  |D �cg c]  }|j&                  ‘Œ c}g d
¢«       | j%                  |D �cg c]  }|j                  ‘Œ c}t        d«      t        d«      t        d«      g«       | j(                  j+                  «        | j,                  j+                  «        | j.                  j+                  «        | j0                  j+                  «        | j                  | j(                  j2                  t        d«      «       | j                  | j,                  j2                  t        d«      «       | j                  | j.                  j2                  t        d«      «       | j                  | j0                  j2                  t        d«      «       t4        j                  j!                  d«      }| j                  |j#                  «       d«       | j                  |D �cg c]  }|j6                  ‘Œ c}t4        j8                  t4        j:                  t4        j:                  t4        j:                  g«       | j                   j+                  «        | j                  | j                   j<                  t>        j@                  «       yc c}w c c}w c c}w )z@Command credits reward to investor and commissions up the chain.é   r%   Úcalculate_rewards©Údate©r9   Úreward_dateú20.00000000©ÚrewardÚlevelé   )r@   r$   rJ   ú10.00000000ú
6.00000000ú
4.00000000Ú
created_até   N)!r9   r.   r   rC   r   Ú	isoformatr	   Úexecuter   r0   ÚgetÚassertEqualr*   r   r   ÚfilterÚorder_byÚcountÚassertListEqualrI   r   Úrefresh_from_dbr2   r3   r4   Úcredit_balancer   Útransaction_typeÚTYPE_REWARDÚTYPE_COMMISSIONr-   r
   ÚSTATUS_ACTIVE)r:   Útarget_daterH   ÚcommissionsÚcÚtransactionsÚts          r<   Ú0test_creates_reward_commissions_and_transactionszMCalculateRewardsCommandTests.test_creates_reward_commissions_and_transactions;   s¨  € à—‘×1Ñ1´IÀ1Ô4EÑE×KÑKÓMˆäÐ(¨{×/DÑ/DÓ/FÕGÜ˜kÓ*×2Ñ2°;Ô?ä—‘×#Ñ#¨t¯©ÈKÐ#ÓXˆØ×Ñ˜Ÿ™¬°Ó(>Ô?ä ×(Ñ(×/Ñ/°vÐ/Ó>×GÑGÈÓPˆØ×Ñ˜×*Ñ*Ó,¨aÔ0Ø×ÑÙ)Ó*™k˜ˆQ�W‹W˜kÑ*Úô	
ð 	×ÑÙ*Ó+™{˜!ˆQ�X‹X˜{Ñ+ä˜Ó&Ü˜Ó%Ü˜Ó%ðô	
ð 	�‰×%Ñ%Ô'Ø�‰×$Ñ$Ô&Ø�‰×$Ñ$Ô&Ø�‰×$Ñ$Ô&à×Ñ˜Ÿ™×5Ñ5´w¸}Ó7MÔNØ×Ñ˜Ÿ™×4Ñ4´g¸lÓ6KÔLØ×Ñ˜Ÿ™×4Ñ4´g¸lÓ6KÔLØ×Ñ˜Ÿ™×4Ñ4´g¸mÓ6LÔMô #×*Ñ*×3Ñ3°LÓAˆØ×Ñ˜×+Ñ+Ó-¨qÔ1Ø×ÑÙ)5Ó6© AˆQ×Ó¨Ñ6ä×'Ñ'Ü×+Ñ+Ü×+Ñ+Ü×+Ñ+ð	ô	
ð 	�‰×'Ñ'Ô)Ø×Ñ˜Ÿ™×/Ñ/´×1IÑ1IÕJùòM +ùò ,ùò. 7s   ÄNÅNË,Nc                óÌ  — | j                   j                  t        d¬«      z   j                  «       }t	        d|j                  «       ¬«       t        |«      j                  |«       t	        d|j                  «       ¬«       t        |«      j                  |«       | j                  t        j                  j                  | j                   |¬«      j                  «       d«       | j                  t        j                  j                  «       d«       | j                  t        j                  j                  «       d«       | j                  j!                  «        | j"                  j!                  «        | j$                  j!                  «        | j&                  j!                  «        | j                  | j                  j(                  t+        d«      «       | j                  | j"                  j(                  t+        d	«      «       | j                  | j$                  j(                  t+        d
«      «       | j                  | j&                  j(                  t+        d«      «       y)zFRunning the command twice should not duplicate rewards or commissions.r@   r%   rA   rB   rD   rJ   rO   rF   rM   rL   rK   N)r9   r.   r   rC   r   rP   r	   rQ   rS   r   r0   rT   rV   r   r   r   rX   r2   r3   r4   rY   r   ©r:   r^   s     r<   Ú#test_idempotent_for_existing_rewardz@CalculateRewardsCommandTests.test_idempotent_for_existing_rewardp   s¥  € à—‘×1Ñ1´IÀ1Ô4EÑE×KÑKÓMˆäÐ(¨{×/DÑ/DÓ/FÕGÜ˜kÓ*×2Ñ2°;Ô?ÜÐ(¨{×/DÑ/DÓ/FÕGÜ˜kÓ*×2Ñ2°;Ô?à×ÑÜ�N‰N×!Ñ!¨T¯_©_È+Ð!ÓV×\Ñ\Ó^Øô	
ð 	×Ñœ×+Ñ+×1Ñ1Ó3°QÔ7Ø×Ñœ×,Ñ,×2Ñ2Ó4°aÔ8ð 	�‰×%Ñ%Ô'Ø�‰×$Ñ$Ô&Ø�‰×$Ñ$Ô&Ø�‰×$Ñ$Ô&Ø×Ñ˜Ÿ™×5Ñ5´w¸}Ó7MÔNØ×Ñ˜Ÿ™×4Ñ4´g¸lÓ6KÔLØ×Ñ˜Ÿ™×4Ñ4´g¸lÓ6KÔLØ×Ñ˜Ÿ™×4Ñ4´g¸mÓ6LÕMr>   c                óÊ  — | j                   j                  j                  «       }t        d|j	                  «       ¬«       | j                  t        j                  j                  | j                   |¬«      j                  «       «       | j                  t        j                  j                  «       d«       | j                  t        j                  j                  «       d«       y)z=No reward/commission is created on the investment start date.rA   rB   rD   r   N)r9   r.   rC   r   rP   ÚassertFalser   r0   rT   ÚexistsrS   r   rV   r   re   s     r<   Ú"test_skips_before_first_reward_dayz?CalculateRewardsCommandTests.test_skips_before_first_reward_dayŠ   s    € à—o‘o×0Ñ0×5Ñ5Ó7ˆäÐ(¨{×/DÑ/DÓ/FÕGà×ÑÜ�N‰N×!Ñ!¨T¯_©_È+Ð!ÓV×]Ñ]Ó_ô	
ð 	×Ñœ×+Ñ+×1Ñ1Ó3°QÔ7Ø×Ñœ×,Ñ,×2Ñ2Ó4°aÕ8r>   c                ó¾  — | j                   j                  j                  «       }t        d|j	                  «       ¬«       t
        j                  j                  | j                   |¬«      }| j                  |j                  t        d«      «       | j                   j                  «        | j                  | j                   j                  t        j                  «       y)z<Status flips to completed when target_date reaches end_date.rA   rB   rD   rF   N)r9   r/   rC   r   rP   r   r0   rR   rS   r*   r   rX   r-   r
   ÚSTATUS_COMPLETED)r:   r^   rH   s      r<   Ú+test_marks_investment_completed_on_end_datezHCalculateRewardsCommandTests.test_marks_investment_completed_on_end_date–   s”   € à—o‘o×.Ñ.×3Ñ3Ó5ˆäÐ(¨{×/DÑ/DÓ/FÕGä—‘×#Ñ#¨t¯©ÈKÐ#ÓXˆØ×Ñ˜Ÿ™¬°Ó(>Ô?à�‰×'Ñ'Ô)Ø×Ñ˜Ÿ™×/Ñ/´×1LÑ1LÕMr>   c                ó\  — | j                   j                  t        d¬«      z   j                  «       }t        j
                  | j                   _        | j                   j                  dg¬«       t        d|j                  «       ¬«       | j                  t        j                  j                  | j                   |¬«      j                  «       «       | j                  t         j                  j#                  «       d«       | j                  t$        j                  j#                  «       d«       y	)
z?Completed investments are ignored even if the date is in range.r@   r%   r-   ©Úupdate_fieldsrA   rB   rD   r   N)r9   r.   r   rC   r
   rl   r-   Úsaver   rP   rh   r   r0   rT   ri   rS   r   rV   r   re   s     r<   Ú&test_skips_completed_investment_statuszCCalculateRewardsCommandTests.test_skips_completed_investment_status¢   sÓ   € à—‘×1Ñ1´IÀ1Ô4EÑE×KÑKÓMˆÜ!+×!<Ñ!<ˆ�‰ÔØ�‰×Ñ¨H¨:ÐÔ6äÐ(¨{×/DÑ/DÓ/FÕGà×ÑÜ�N‰N×!Ñ!¨T¯_©_È+Ð!ÓV×]Ñ]Ó_ô	
ð 	×Ñœ×+Ñ+×1Ñ1Ó3°QÔ7Ø×Ñœ×,Ñ,×2Ñ2Ó4°aÕ8r>   c                óö  — t        j                  «       t        d¬«      z   j                  «       }t        j
                  | j                  _        | j                  j                  dg¬«       t        j                  j                  ddd¬«      }t	        j                  t        d	«      «      }t        j                  j                  |t        d	«      |d
   |d   |d   t        j                  t        j                  «       t        j                  «       t        d¬«      z   ¬«      }t!        d|j#                  «       ¬«       t%        |«      j'                  |«       t(        j                  j+                  ||¬«      }| j-                  |j.                  t        d«      «       | j-                  t0        j                  j3                  «       d«       t4        j                  j7                  |¬«      }| j-                  |j3                  «       d«       | j-                  |j9                  «       j:                  t4        j<                  «       |j?                  «        | j-                  |j@                  t        d«      «       y)zERewards still post when the investor has no referrer; no commissions.é   r%   r-   ro   i¹  ÚSoloÚsolor   Ú100r!   r"   r#   é   r(   rA   rB   rD   z
1.00000000r   )r)   r@   N)!r   r6   r   rC   r
   rl   r9   r-   rq   r   r0   r1   r5   r   r7   r8   r   rP   r	   rQ   r   rR   rS   r*   r   rV   r   rT   ÚfirstrZ   r[   rX   rY   )r:   r^   Ú	solo_userr;   Úsolo_investmentrH   ra   s          r<   Ú6test_creates_reward_without_commissions_when_no_uplinezSCalculateRewardsCommandTests.test_creates_reward_without_commissions_when_no_upline°   sÙ  € ä—|‘|“~¬	°qÔ(9Ñ9×?Ñ?ÓAˆÜ!+×!<Ñ!<ˆ�‰ÔØ�‰×Ñ¨H¨:ÐÔ6Ü—L‘L×,Ñ,Ø!¨f¸vð -ó 
ˆ	ô ×,Ñ,¬W°U«^Ó<ˆ	Ü$×,Ñ,×3Ñ3ØÜ˜5“>Ø˜6Ñ"Ø'¨Ñ/Ø# JÑ/Ü×,Ñ,Ü—|‘|“~Ü—\‘\“^¤i°RÔ&8Ñ8ð 4ó 	
ˆô 	Ð(¨{×/DÑ/DÓ/FÕGÜ˜kÓ*×2Ñ2°;Ô?ä—‘×#Ñ#¨ÈKÐ#ÓXˆØ×Ñ˜Ÿ™¬°Ó(=Ô>Ø×Ñœ×+Ñ+×1Ñ1Ó3°QÔ7Ü"×*Ñ*×1Ñ1°yÐ1ÓAˆØ×Ñ˜×+Ñ+Ó-¨qÔ1Ø×Ñ˜×+Ñ+Ó-×>Ñ>Ä×@WÑ@WÔXØ×!Ñ!Ô#Ø×Ñ˜×1Ñ1´7¸<Ó3HÕIr>   c                óØ  — t        j                  «       t        d¬«      z   j                  «       }t        j
                  | j                  _        | j                  j                  dg¬«       t        j                  j                  ddd¬«      }t        j                  j                  d	d
d|¬«      }t	        j                  t        d«      «      }t        j                  j                  |t        d«      |d   |d   |d   t        j                  t        j                  «       t        j                  «       t        d¬«      z   ¬«      }t!        d|j#                  «       ¬«       t%        |«      j'                  |«       t(        j                  j+                  ||¬«      }| j-                  |j.                  t        d«      «       t0        j                  j3                  |¬«      }| j-                  |j5                  «       d«       |j7                  «       }| j-                  |j8                  d«       | j-                  |j.                  t        d«      «       | j-                  t:        j                  j5                  «       d«       |j=                  «        |j=                  «        | j-                  |j>                  t        d«      «       | j-                  |j>                  t        d«      «       y)zKOnly existing uplines receive commissions when the chain is shorter than 3.é   r%   r-   ro   i¡  ÚTopÚtopr   i¢  ÚDownÚdownr   r    r!   r"   r#   é   r(   rA   rB   rD   rF   rG   r@   rK   r$   N) r   r6   r   rC   r
   rl   r9   r-   rq   r   r0   r1   r5   r   r7   r8   r   rP   r	   rQ   r   rR   rS   r*   r   rT   rV   ry   rI   r   rX   rY   )	r:   r^   Úupliner   r;   Úshort_chain_investmentrH   r_   Ú
commissions	            r<   Ú:test_partial_referral_chain_only_credits_available_uplineszWCalculateRewardsCommandTests.test_partial_referral_chain_only_credits_available_uplinesÐ   sB  € ä—|‘|“~¬	°qÔ(9Ñ9×?Ñ?ÓAˆÜ!+×!<Ñ!<ˆ�‰ÔØ�‰×Ñ¨H¨:ÐÔ6Ü—‘×)Ñ)Ø!¨e¸eð *ó 
ˆô —<‘<×+Ñ+Ø!¨f¸vÐSYð ,ó 
ˆô ×,Ñ,¬W°V«_Ó=ˆ	Ü!+×!3Ñ!3×!:Ñ!:ØÜ˜6“?Ø˜6Ñ"Ø'¨Ñ/Ø# JÑ/Ü×,Ñ,Ü—|‘|“~Ü—\‘\“^¤i°RÔ&8Ñ8ð ";ó 	"
Ðô 	Ð(¨{×/DÑ/DÓ/FÕGÜ˜kÓ*×2Ñ2°;Ô?ä—‘×#Ñ#Ð/EÐS^Ð#Ó_ˆØ×Ñ˜Ÿ™¬°Ó(>Ô?Ü ×(Ñ(×/Ñ/°vÐ/Ó>ˆØ×Ñ˜×*Ñ*Ó,¨aÔ0Ø ×&Ñ&Ó(ˆ
Ø×Ñ˜×)Ñ)¨1Ô-Ø×Ñ˜×*Ñ*¬G°MÓ,BÔCØ×Ñœ×,Ñ,×2Ñ2Ó4°aÔ8Ø×ÑÔ Ø× Ñ Ô"Ø×Ñ˜×.Ñ.´¸Ó0FÔGØ×Ñ˜×0Ñ0´'¸-Ó2HÕIr>   c                ó  — t        j                  «       t        d¬«      z   j                  «       }t        j
                  | j                  _        | j                  j                  dg¬«       t        j                  j                  ddd¬«      }t        j                  j                  |t        d	«      d
t        d«      dt        j                  t        j                  «       t        j                  «       t        d¬«      z   ¬«      }t        d|j!                  «       ¬«       t#        |«      j%                  |«       t&        j                  j)                  ||¬«      }| j+                  |j,                  t        d«      «       t.        j                  j1                  |¬«      j3                  d«      }| j+                  |j5                  «       d«       |j7                  «        | j+                  |j8                  t        d«      «       y)z>Reward and commission amounts are rounded to 8 decimal places.é	   r%   r-   ro   i‰  ÚPreciseÚpreciser   z1234.56789012r@   z1.25rx   é(   r(   rA   rB   rD   z15.43209863rG   rI   r   N)r   r6   r   rC   r
   rl   r9   r-   rq   r   r0   r1   r7   r   r8   r   rP   r	   rQ   r   rR   rS   r*   r   rT   rU   rV   rX   rY   )r:   r^   Úprecise_userÚprecise_investmentrH   r_   s         r<   Ú3test_quantizes_reward_and_commissions_round_half_upzPCalculateRewardsCommandTests.test_quantizes_reward_and_commissions_round_half_up÷   s„  € ä—|‘|“~¬	°qÔ(9Ñ9×?Ñ?ÓAˆÜ!+×!<Ñ!<ˆ�‰ÔØ�‰×Ñ¨H¨:ÐÔ6Ü—|‘|×/Ñ/Ø!¨iÀ)ð 0ó 
ˆô (×/Ñ/×6Ñ6ØÜ˜?Ó+ØÜ% f›oØÜ×,Ñ,Ü—|‘|“~Ü—\‘\“^¤i°RÔ&8Ñ8ð 7ó 	
Ðô 	Ð(¨{×/DÑ/DÓ/FÕGÜ˜kÓ*×2Ñ2°;Ô?ä—‘×#Ñ#Ð/AÈ{Ð#Ó[ˆØ×Ñ˜Ÿ™¬°Ó(>Ô?ä ×(Ñ(×/Ñ/°vÐ/Ó>×GÑGÈÓPˆà×Ñ˜×*Ñ*Ó,¨aÔ0Ø×$Ñ$Ô&Ø×Ñ˜×4Ñ4´g¸mÓ6LÕMr>   N)ÚreturnÚNone)Ú__name__Ú
__module__Ú__qualname__r=   rc   rf   rj   rm   rr   r|   r‡   r�   © r>   r<   r   r      s9   „ ó%
òN3KòjNò4
9ò
Nò9òJò@%JóNNr>   r   N)Ú__doc__Ú
__future__r   Údatetimer   Údecimalr   Údjango.core.managementr   Údjango.testr   Údjango.utilsr   Úapps.investments.cron_tasksr	   Úapps.investments.modelsr
   r   Úapps.referrals.modelsr   Úapps.transactions.modelsr   Úapps.users.modelsr   r   r•   r>   r<   Ú<module>r¢      s9   ðÙ 9å "å Ý å /Ý  Ý !å =ß 6Ý ,Ý 0Ý "ôAN 8õ ANr>   