
    P1i                        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  e       Z G d
 dej&                        Z G d dej&                        Z G d dej,                        Z G d dej,                        Z G d dej,                        Z G d dej&                        Z G d dej&                        Z G d dej&                        Z G d dej&                        Z G d dej&                        Z G d dej&                        Z G d  d!ej&                        Z  G d" d#ej,                        Z! G d$ d%ej,                        Z" G d& d'ej,                        Z# G d( d)ej,                        Z$ G d* d+ej,                        Z% G d, d-ej,                        Z& G d. d/ej,                        Z' G d0 d1ej,                        Z( G d2 d3ej,                        Z) G d4 d5ej,                        Z* G d6 d7ej,                        Z+ G d8 d9ej,                        Z, G d: d;ej,                        Z- G d< d=ej&                        Z. G d> d?ej,                        Z/ G d@ dAej,                        Z0 G dB dCej,                        Z1 G dD dEej,                        Z2 G dF dGej&                        Z3 G dH dIej&                        Z4 G dJ dKej&                        Z5d dLl6m7Z7m8Z8m9Z9  G dM dNej&                        Z: G dO dPej&                        Z; G dQ dRej&                        Z< G dS dTej,                        Z= G dU dVej,                        Z> G dW dXej,                        Z?yY)Z    )serializers)get_user_model)validate_passwordValidationErrorUserProfile)liuyao)datetime)RegexValidator)Personc                      e Zd Z ej                  dd      Z ej                  dd      Z ej                  dd      Z	 ej                  dd      Z
 ej                  dd      Z ej                  ddd	      Z G d
 d      Zy)!UserProfileRegistrationSerializerF*Birth date (optional) - format: YYYY-MM-DDrequired	help_textz(Birth time (optional) - format: HH:MM:SSzPTwin type (optional) - choices: 0 (Not a twin), 1 (Elder twin), 2 (Younger twin)4Father date of birth (optional) - format: YYYY-MM-DD4Mother date of birth (optional) - format: YYYY-MM-DDzBAI regeneration permission (optional) - boolean, defaults to False)r   defaultr   c                   B    e Zd ZeZg dZddiddiddiddiddiddidZy)&UserProfileRegistrationSerializer.Meta
birth_date
birth_time	twin_type
father_dob
mother_dobcan_regenerate_air   FN__name__
__module____qualname__r	   modelfieldsextra_kwargs     1/home/cursorai/projects/iching/api/serializers.pyMetar   (   sC    k%u-%u-$e,%u-%u-",e!4
r(   r*   N)r!   r"   r#   r   	DateFieldr   	TimeFieldr   IntegerFieldr   r   r   BooleanFieldr   r*   r'   r(   r)   r   r      s    &&&>J '&&<J )((dI '&&HJ '&&HJ 100V

 

r(   r   c                       e Zd Z ej                  ddddi      Z ej                  ddidd      Z ed      Z ej                  d      Z	 G d d	      Z
d
 Zd Zy)UserRegistrationSerializerT
input_typepassword)
write_onlyr   styleF)r4   r3   r   r   c                   6    e Zd ZeZg dZddiddiddiddidZy)UserRegistrationSerializer.Metaphoneemailr2   	password2
first_name	last_namegenderprofiler3   Tr   F)r2   r<   r=   r>   Nr!   r"   r#   Userr$   r%   r&   r'   r(   r)   r*   r7   :   s3    l%t,%u-$e,!5)	
r(   r*   c                    d|v r"|d   |d   k7  rt        j                  ddi      	 t        |d          |j                  di       }|j                  d      }|dk(  r+|j                  d      st        j                  dddgii      |d	k(  r+|j                  d
      st        j                  dd
dgii      |S # t        $ r/}t        j                  dt        |j                        i      d }~ww xY w)Nr;   r2   Password fields didn't match.r?   r      r   $   双大需要填写父亲出生日期   r   $   双小需要填写母亲出生日期r   r   r   listmessagesgetselfdataeprofile_datar   s        r)   validatez#UserRegistrationSerializer.validateD   s   $4
#3tK7H#H--{<[.\]]	Nd:./
 xx	2. $$[1	>,"2"2<"@--y<JpIq:r.stt!^L$4$4\$B--y<JpIq:r.stt  	N--z4

;K.LMM	Ns   B; ;	C3*C..C3c                 @   |j                  dd        |j                  dd       }t        j                  j                  di |}|rXt        j                  j                  |      \  }}|j                         D ]  \  }}t        |||        |j                          |S )Nr;   r?   userr'   )	poprA   objectscreate_userr	   get_or_createitemssetattrsave)rM   validated_datarP   rT   r?   createdfieldvalues           r)   createz!UserRegistrationSerializer.createW   s    ;- &)))T: ||''9.9 *22@@d@KGW !- 2 2 4u. !5LLNr(   N)r!   r"   r#   r   	CharFieldr2   r;   r   r?   r>   r*   rQ   r`   r'   r(   r)   r0   r0   4   sk    ${$$tLZdKefH%%%\:,FSWbghI/?G"[""E2F
 
&r(   r0   c                   Z    e Zd Z ej                  d      Z ej                  dd      Zy)LoginSerializerTr5   r   r3   N)r!   r"   r#   r   ra   r9   r2   r'   r(   r)   rc   rc   m   s(    !K!!40E${$$dtDHr(   rc   c                   2    e Zd Z ej                  d      Zy)PasswordResetRequestSerializerTr5   N)r!   r"   r#   r   ra   r:   r'   r(   r)   rf   rf   q   s    !K!!40Er(   rf   c                       e Zd Z ej                  d      Z ej                  d      Z ej                  dd      Z ej                  dd      Zd Z	y)PasswordResetConfirmSerializerTr5   )r3   r   c                 J    |d   |d   k7  rt        j                  ddi      |S )Nr2   r;   rC   r   r   rM   attrss     r)   rQ   z'PasswordResetConfirmSerializer.validatez   s0    k 22--z;Z.[\\r(   N)
r!   r"   r#   r   ra   uidb64tokenr2   r;   rQ   r'   r(   r)   rh   rh   t   sS    "[""D1F!K!!40E${$$tDH%%%EIr(   rh   c                        e Zd Z G d d      Zy)UserProfileSerializerc                   >    e Zd ZeZdZddiddiddiddiddiddidZy)UserProfileSerializer.Metar   r   F	read_onlyTNr    r'   r(   r)   r*   rr      sC    k%u-%u-$e,%u-%u-"-t!4
r(   r*   N)r!   r"   r#   r*   r'   r(   r)   rp   rp      s    

 

r(   rp   c                   8    e Zd Z ed      Z G d d      Zd Zy)UserSerializerFr5   c                   8    e Zd ZeZdZddiddiddiddiddidZy)UserSerializer.Meta)idr9   r:   r<   r=   r>   r?   is_temporary_userr   Fr9   r:   r<   r=   r>   Nr@   r'   r(   r)   r*   rw      s;    n %( %(%u-$e,!5)
r(   r*   c                 L   |j                  dd       }|j                         D ]  \  }}t        |||        |j                          |Zddlm} |j                  j                  |      \  }}|j                         D ]  \  }}t        |||        |j                          |S )Nr?   r   r   rS   )rU   rY   rZ   r[   accounts.modelsr	   rV   rX   )	rM   instancer\   rP   attrr_   r	   r?   r]   s	            r)   updatezUserSerializer.update   s    %)))T: *//1KD%HdE* 2 #3*22@@h@OGW+113eu-  4LLNr(   N)r!   r"   r#   rp   r?   r*   r   r'   r(   r)   ru   ru      s    #U3G	
 	
r(   ru   c                   F    e Zd Z ej                  d      Z G d d      Zy)LiuyaoSerializerzContains the complete calculation result with the same structure as returned by the /api/liuyao/calc endpoint. See the /api/liuyao/calc endpoint documentation for the detailed structure.r   c                       e Zd ZeZdZdZy)LiuyaoSerializer.Meta__all__)rT   uuid
created_atlast_modified_atNr!   r"   r#   r
   r$   r%   read_only_fieldsr'   r(   r)   r*   r      s    Mr(   r*   N)r!   r"   r#   r   	JSONFieldrN   r*   r'   r(   r)   r   r      s&     ;  _D
N Nr(   r   c                   L    e Zd ZdZ ej
                  dd      Z G d d      Zy)LiuyaoRequestSerializerz@Serializer for request documentation - excludes read-only fieldsFz3JSON data containing calculation results (optional)r   c                       e Zd ZeZg dZy)LiuyaoRequestSerializer.Meta)qdatequestiony1y2y3y4y5y6readingfeedbackrN   Nr!   r"   r#   r
   r$   r%   r'   r(   r)   r*   r      s    ir(   r*   N)r!   r"   r#   __doc__r   r   rN   r*   r'   r(   r)   r   r      s)    J ;  GD
j jr(   r   c                      e Zd Z ej                  dd      Z ej                  ddd      Z ej                  ddd      Z ej                  ddd      Z	 ej                  d	d ed
d      g      Z G d d      Zd Zy)LiuyaoCalculatorSerializerF)r   r   i'    )	max_value	min_valuer      rD         z^\d{2}:\d{2}$!Invalid time format. Use 'HH:MM'.)regexmessage)
max_lengthr   
validatorsc                       e Zd ZeZg dZy)LiuyaoCalculatorSerializer.Meta)r   r   r   r   r   r   r   usecuryearmonthdaytimeNr   r'   r(   r)   r*   r      s    kr(   r*   c                 Z   |j                  dd      }|j                  d      }|j                  d      }|j                  d      }|j                  dd      }|s|||	 t        |||       	 t        t        |j                  d            \  }}d|cxk  rdk  rn t        d|cxk  r
dk  st         t        	 |S # t        $ r> t        j                  d| d	|d
d	|d
dd| d	|d
d	|d
dd| d	|d
d	|d
dd      w xY w# t        $ r t        j                  ddi      w xY w)Nr   Fr   r   r   r   z00:00zInvalid date (-02dz).)r   r   r   :r      ;   r   )rK   r   
ValueErrorr   r   mapintsplit)	rM   rl   r   r   r   r   r   hoursminutess	            r)   rQ   z#LiuyaoCalculatorSerializer.validate   sw   8U+yy 		'"iiyy) 4+0Acouc*	 djjo6NE7$"$   *+g););   *<   *< #  !11,TF!E#;aCyK-dV1U3KqS	L+D65+Qs3irJ3    	--;/  	s   !B? /AD	 ?AD	!D*N)r!   r"   r#   r   r.   r   r-   r   r   r   ra   r   r   r*   rQ   r'   r(   r)   r   r      s    %[%%ueDF#;##ddUSD$K$$rQOE
"+
"
"R1u
MC ;  &;
	Dl lr(   r   c                   $    e Zd ZdZ G d d      Zy)BaziSerializerz1Serializer for Bazi Person model with full fieldsc                       e Zd ZeZdZdZy)BaziSerializer.Meta)relation_good_countrelation_bad_count)
created_byr   
updated_atbazi_resultN)r!   r"   r#   
BaziPersonr$   excluder   r'   r(   r)   r*   r      s    ?Tr(   r*   Nr!   r"   r#   r   r*   r'   r(   r)   r   r      s    ;U Ur(   r   c                   $    e Zd ZdZ G d d      Zy)BaziRequestSerializerzESerializer for Bazi request documentation - excludes read-only fieldsc                       e Zd ZeZg dZy)BaziRequestSerializer.Meta)namer>   r   r   r   r   r   notesN)r!   r"   r#   r   r$   r%   r'   r(   r)   r*   r     s    qr(   r*   Nr   r'   r(   r)   r   r      s    Or rr(   r   c                       e Zd ZdZ ej
                  dd      Z ej
                  dd      Z ej
                  dd      Zy)TongshuCalendarQuerySerializerz%Serializer for querying calendar dataFz/Year (defaults to current year if not provided)r   z7Month (1-12, defaults to current month if not provided)zNumber of extra days to include before/after the month (default varies based on month layout, maximum 100, negative values treated as 0)N)	r!   r"   r#   r   r   r-   r   r   
extra_daysr'   r(   r)   r   r     sK    /#;##U>opD$K$$e?xyE)))5  EO  PJr(   r   c                       e Zd ZdZ ej
                  d      Z ej
                  d      Z ej
                  d      Z ej                  dd      Z
y	)
LunarDateSerializerzSerializer for lunar date dataz
Lunar yearr   zLunar monthz	Lunar dayFzWhether this is a leap monthr   N)r!   r"   r#   r   r   r-   ymdr.   leapr'   r(   r)   r   r     sP    (   <8A   =9A   ;7A#;##U>\]Dr(   r   c                   \    e Zd ZdZ ej
                  d      Z ej
                  d      Zy)BaziPillarForTongshuSerializerz)Serializer for Bazi pillar in Tongshu APIu!   Heavenly stem (天干) in Chineser   u"   Earthly branch (地支) in ChineseN)r!   r"   r#   r   r   ra   godearthr'   r(   r)   r   r     s+    3
+

*M
NC!K!!,PQEr(   r   c                   X    e Zd ZdZ ed      Z ed      Z ed      Z ed      Zy)BaziForTongshuSerializerz'Serializer for Bazi data in Tongshu APIzYear pillarr   zMonth pillarz
Day pillarzHour pillarN)	r!   r"   r#   r   r   r   r   r   hourr'   r(   r)   r   r     s-    1)MBD*^DE
(<
@C)MBDr(   r   c                   "   e Zd ZdZ ej
                  d      Z ej                  d      Z ej                  d      Z
 ej                  d      Z ed      Z ed      Z ej
                  d	      Z ej
                  d
      Z ej
                  d      Z ej
                  d      Z ej
                  d      Z ej                  d      Z ej                  d      Z ej
                  d      Z ej
                  d      Zy)DayDataSerializerz Serializer for detailed day datazDate in YYYY-MM-DD formatr   zDay of monthz*Whether this day belongs to adjacent monthzWhether this day is todayzFour pillars informationzRaw lunar date informationz*Formatted lunar date in Chinese characterszLunar month or solar term namezLunar day or solar term timez$Leap month indicator (if applicable)u'   Jianchu (建除) cycle value in Chinesez!Whether this day has a solar termIndex of the solar term (0-23)z!Month's earthly branch in ChinesezMonth's five element in EnglishN)r!   r"   r#   r   r   ra   dater-   r   r.   is_adjacent_monthis_todayr   bazir   lunarlunar_formattedlunar_title
lunar_desc
lunar_leapjianchuhas_solar_termsolar_term_indexmonth_earthmonth_elementr'   r(   r)   r   r     s   * ;  +FGD
"+
"
"^
<C000;gh'{''2MNH#.HID*FGE+k++6bcO'+''2RSK&&&1OPJ&&&1WXJ#k##.WXG-[--8[\N/{//:Z['+''2UVK)K))4UVMr(   r   c                       e Zd ZdZ ej
                  d      Z ej
                  d      Z ej                  d      Z	y)SolarTermSerializerzSerializer for solar term dataz!Name of the solar term in Chineser   z-Date and time of the solar term in ISO formatr   N)
r!   r"   r#   r   r   ra   r   r   r-   indexr'   r(   r)   r   r   1  s>    ( ;  +NOD ;  +Z[D$K$$/OPEr(   r   c                      e Zd ZdZ ej
                  d      Z ej
                  d      Z ej                   ej                   e	       d      d      Z
 ej                   e       d      Z ed	      Z ed
      Zy)CalendarMonthSerializerz'Serializer for full month calendar dataGregorian yearr   zGregorian monthzArray of days in a weekchildr   z2Two-dimensional array of days (organized by weeks)zSolar terms in this monthzPrevious month referencezNext month referenceN)r!   r"   r#   r   r   r-   r   r   	ListFieldr   daysr   solar_termsr   
prev_month
next_monthr'   r(   r)   r   r   7  s    1#;##.>?D$K$$/@AE ;  #k###%/
 GD (+''!#-K 0:TUJ/:PQJr(   r   c                   8    e Zd ZdZ ej
                  dd      Zy)Calendar10kQuerySerializerz(Serializer for querying calendar10k dataTz5Year to retrieve calendar data for (range: 1900-2100)r   N)r!   r"   r#   r   r   r-   r   r'   r(   r)   r   r   I  s    2#;##T=tuDr(   r   c                       e Zd ZdZ ej
                  d      Z ej
                  d      Z ej
                  d      Zy)YearDataSerializerz'Serializer for year data in Calendar10kz7Year's element in English (wood/fire/earth/metal/water)r   zChinese zodiac animalzFlying starN)	r!   r"   r#   r   r   ra   elementanimalstarr'   r(   r)   r   r   M  s=    1#k##.ghG"[""-DEF ;  =9Dr(   r   c                       e Zd ZdZ ej
                  d      Z ej
                  d      Z ej                  d      Z	 ej                  d      Zy)MonthCycleSerializerz3Serializer for a monthly cycle with two solar termsz"First solar term data of the monthr   z#Second solar term data of the monthzCount of days in this monthzFlying star for this monthN)r!   r"   r#   r   r   	DictFieldfirstsecondr-   countra   r  r'   r(   r)   r  r  S  sQ    =!K!!,PQE"[""-RSF$K$$/LME ;  +GHDr(   r  c                   d    e Zd ZdZ ej
                  ddd      Z ej
                  ddd      Zy)PaginationSerializerz%Serializer for pagination informationFTz-Previous year (or false if at lower boundary)r   
allow_nullr   z)Next year (or false if at upper boundary)N)r!   r"   r#   r   r   r-   prevnextr'   r(   r)   r
  r
  Z  s3    /#;##UtO~D#;##UtOz{Dr(   r
  c                       e Zd ZdZ ej
                  d      Z ed      Z ej                   e
       d      Z ed      Zy)	Calendar10kSerializerz)Serializer for full year calendar10k datar   r   zInformation about the yearzMonthly cycles with solar termsr   zPagination informationN)r!   r"   r#   r   r   r-   r   r   	year_datar   r  cyclesr
  paginater'   r(   r)   r  r  _  sG    3#;##.>?D"-IJI"["")=)?KlmF#.FGHr(   r  c                   ^    e Zd ZdZ ej
                  d      Z ej
                  dd      Zy)TempLoginSerializerzm
    Serializer for temporary user login endpoint.
    Migrates temp user data to existing user account.
    Tr5   rd   N)r!   r"   r#   r   r   ra   r9   r2   r'   r(   r)   r  r  f  s/     "K!!40E${$$dtDHr(   r  c                       e Zd ZdZ ej
                  ddddid      Z ej
                  ddiddd	      Z edd
      Z	 G d d      Z
d Zd Zd Zy)TempRegisterSerializerz
    Serializer for temporary user registration endpoint.
    Converts temporary user to permanent user (only phone & email required).
    TFr1   r2   zIPassword (optional) - if provided, password2 is required for confirmation)r3   r   r4   r   zXPassword confirmation (optional) - required if password is provided, must match password)r4   r3   r   r   z\Profile data (optional) - contains birth_date, birth_time, twin_type, father_dob, mother_dobr   c                   B    e Zd ZeZg dZddiddidddddddd	dd
Zy)TempRegisterSerializer.Metar8   r   z+Phone number (required) - max 16 charactersz<Email address (required) - max 50 characters, must be uniqueFz*First name (optional) - max 150 charactersr   z)Last name (optional) - max 150 characterszDGender (optional) - choices: M (Male), F (Female), N (Not specified)rz   Nr@   r'   r(   r)   r*   r    s@    l!#PQ!#ab',;gh&+:ef#(7}~
r(   r*   c                    d|v r:|d   r5d|v r"|d   |d   k7  rt        j                  ddi      	 t        |d          |j                  di       }|j                  d      }|dk(  r+|j                  d      st        j                  dddgii      |d	k(  r+|j                  d
      st        j                  dd
dgii      |S # t        $ r/}t        j                  dt        |j                        i      d }~ww xY w)Nr2   r;   rC   r?   r   rD   r   rE   rF   r   rG   rH   rL   s        r)   rQ   zTempRegisterSerializer.validate  s   $z"2d"tJ'74;L'L!11;@_2`aaR!$z"23
 xx	2. $$[1	>,"2"2<"@--y<JpIq:r.stt!^L$4$4\$B--y<JpIq:r.stt # R!11:tAJJ?O2PQQRs   C 	C<*C77C<c                    | j                   j                  d      }|r]t        j                  j	                  |      j                  |j                        j                         rt        j                  d      |sCt        j                  j	                  |      j                         rt        j                  d      |S )z:Check if phone number is not already taken by another userrT   )r9   rx   u   此电话号码已被使用)
contextrK   rA   rV   filterr   rx   existsr   r   rM   r_   rT   s      r)   validate_phonez%TempRegisterSerializer.validate_phone  s     ||'DLL''e'4<<<HOOQ--.KLL$,,--E-:AAC--.KLLr(   c                    ddl m} ddlm} 	  ||       | j
                  j                  d      }|r]t        j                  j                  |      j                  |j                        j                         rt	        j                  d      |sCt        j                  j                  |      j                         rt	        j                  d      |S # |$ r t	        j                  d      w xY w)	z=Check if email is valid and not already taken by another userr   )validate_emailr   u$   请输入有效的电子邮箱地址rT   )r:   r  u   此电子邮箱已被使用)django.core.validatorsr#  django.core.exceptionsr   r   r  rK   rA   rV   r  r   rx   r  )rM   r_   r#  DjangoValidationErrorrT   s        r)   r#  z%TempRegisterSerializer.validate_email  s     	:S	V5!
 ||'DLL''e'4<<<HOOQ--.KLL$,,--E-:AAC--.KLL % 	V--.TUU	Vs   C C2N)r!   r"   r#   r   r   ra   r2   r;   r   r?   r*   rQ   r!  r#  r'   r(   r)   r  r  n  s|     %{$$Z(]	H &%%Z(l	I 0pG
	
 	
*r(   r  c                       e Zd ZdZ ej
                  ddddi      Z ej
                  ddddi      Z ej
                  ddddi      Zd Z	d Z
y)	PasswordChangeSerializerzx
    Serializer for password change endpoint.
    Requires the current password and new password with confirmation.
    Tr1   r2   )r   r3   r4   c                     | j                   d   j                  }|j                  |      st        j                  d      |S )NrequestzCurrent password is incorrect.)r  rT   check_passwordr   r   r   s      r)   validate_current_passwordz2PasswordChangeSerializer.validate_current_password  s;    ||I&++""5)--.NOOr(   c                 J    |d   |d   k7  rt        j                  ddi      |S )Nnew_passwordnew_password2rC   rj   rk   s     r)   rQ   z!PasswordChangeSerializer.validate  s0     E/$::--~?^._``r(   N)r!   r"   r#   r   r   ra   current_passwordr.  r/  r,  rQ   r'   r(   r)   r(  r(    sx     -{,,Z(
 );((Z(L
 *K))Z(Mr(   r(  c                   <    e Zd ZdZ ej
                  dddd      Zy) AccountDeletionRequestSerializerz=
    Serializer for initiating account deletion request.
    FTi  z$Optional reason for account deletion)r   allow_blankr   r   N)r!   r"   r#   r   r   ra   reasonr'   r(   r)   r2  r2    s'     #[""8	Fr(   r2  c                      e Zd ZdZ ej
                  ddd      Z ej
                  ddd      Z ej                  dd	      Z	 ej                  dd
	      Z ej                  dddd      Z ej                  dd	      Z ej                  dd	      Z ej
                  ddd      Z ej
                  ddd      Zd Zd Zy)TempUserCreateSerializerzz
    Serializer for creating temporary users.
    All fields are optional and will be used for user profile creation.
    F   zGFull name (optional) - will be split into first/last name automaticallyr   r   r   rD   zAGender (optional) - M for male, F for female, N for not specifiedr   r   z%Birth time (optional) - format: HH:MMr   rF   zDTwin type (optional) - 0: not a twin, 1: elder twin, 2: younger twin)r   r   r   r   r   r   zBirth city (optional)2   z)Timezone (optional) - e.g., Asia/Shanghaic                 H   d|v rt        j                  ddi      d|v rt        j                  ddi      |j                  d      }|dk(  r(|j                  d      st        j                  ddi      |d	k(  r(|j                  d
      st        j                  d
di      |S )Nr9   zSPhone field is not allowed. Phone numbers are system-generated for temporary users.r:   zUEmail field is not allowed. Email addresses are system-generated for temporary users.r   rD   r   z/Father's birth date is required for elder twin.rF   r   z1Mother's birth date is required for younger twin.)r   r   rK   )rM   rN   r   s      r)   rQ   z!TempUserCreateSerializer.validate  s    d?--n/   d?--p/  
 HH[)	>$((<"8--O/   !^DHH\$:--Q/   r(   c                 <    |r|dvrt        j                  d      |S )N)MFNz@Gender must be 'M' (male), 'F' (female), or 'N' (not specified).rj   rM   r_   s     r)   validate_genderz(TempUserCreateSerializer.validate_gender6  s)    U/1--R  r(   N)r!   r"   r#   r   r   ra   r   r>   r+   r   r,   r   r-   r   r   r   
birth_citytimezonerQ   r@  r'   r(   r)   r6  r6    s    !;  [D
 #[""UF
 '&&>J '&&9J )((X	I '&&HJ '&&HJ '&&)J
 %{$$=H2r(   r6  c                   ~    e Zd ZdZ ej
                  ej                  d      Z ej                  dddd      Z
d	 Zy
)ReportSubmissionSerializerz-Serializer for submitting AI analysis reportsz3Report category - reason for reporting the analysis)choicesr   r   FTz9Optional message with additional details about the report)r   r   r3  r   c                     t         j                  D cg c]  }|d   	 }}||vrt        j                  d|       |S c c}w )z:Validate the report category is one of the allowed choicesr   z"Invalid category. Must be one of: )r   REPORT_CATEGORY_CHOICESr   r   )rM   r_   choicevalid_categoriess       r)   validate_categoryz,ReportSubmissionSerializer.validate_categoryN  sR    4>4V4VW4V&F1I4VW((--0RScRd.eff Xs   ?N)r!   r"   r#   r   r   ChoiceFieldr   rG  categoryra   r   rJ  r'   r(   r)   rD  rD  @  sH    7&{&&22GH $k##M	Gr(   rD  c                       e Zd ZdZ ej
                  dd      Z ej
                  dd      Z ej
                  dd      Z G d d      Z	y	)
BaziReportSerializerz3Serializer for viewing BaZi analysis report details get_bazi_report_category_displayTsourcers   get_bazi_report_status_displayz%bazi_report_resolved_by.get_full_namec                        e Zd ZeZg dZg dZy)BaziReportSerializer.Meta)rx   r   bazi_analysis_reportedbazi_report_categorycategory_displaybazi_report_messagebazi_report_timestampbazi_report_statusstatus_displaybazi_report_admin_notesbazi_admin_actionresolved_by_namebazi_report_resolved_at)rx   r   rY  rW  r[  r^  r_  Nr!   r"   r#   r   r$   r%   r   r'   r(   r)   r*   rT  ]      


r(   r*   N
r!   r"   r#   r   r   ra   rW  r[  r^  r*   r'   r(   r)   rN  rN  V  sS    =,{,,4Vbfg*[**2R^bcN,{,,4[gkl

 

r(   rN  c                       e Zd ZdZ ej
                  dd      Z ej
                  dd      Z ej
                  dd      Z G d d      Z	y	)
NumberReportSerializerz5Serializer for viewing Number analysis report details"get_number_report_category_displayTrP   get_number_report_status_displayz'number_report_resolved_by.get_full_namec                        e Zd ZeZg dZg dZy)NumberReportSerializer.Meta)rx   r   number_analysis_reportednumber_report_categoryrW  number_report_messagenumber_report_timestampnumber_report_statusr[  number_report_admin_notesnumber_admin_actionr^  number_report_resolved_at)rx   r   rl  rW  r[  r^  rp  Nr`  r'   r(   r)   r*   rh  q  ra  r(   r*   Nrb  r'   r(   r)   rd  rd  j  sS    ?,{,,4Xdhi*[**2T`deN,{,,4]imn

 

r(   rd  c                       e Zd ZdZ ej
                  dd      Z ej
                  dd      Z ej
                  dd      Z G d d      Z	y	)
LiuYaoReportSerializerz5Serializer for viewing LiuYao analysis report detailsget_report_category_displayTrP  get_report_status_displayz report_resolved_by.get_full_namec                        e Zd ZeZg dZg dZy)LiuYaoReportSerializer.Meta)rx   r   analysis_reportedreport_categoryrW  report_messagereport_timestampreport_statusr[  report_admin_notesadmin_actionr^  report_resolved_at)rx   r   rz  rW  r[  r^  r~  Nr   r'   r(   r)   r*   rv    s    


r(   r*   Nrb  r'   r(   r)   rr  rr  ~  sS    ?,{,,4Q]ab*[**2MY]^N,{,,4Vbfg

 

r(   rr  )ConversationMessageConversationConfigc                   $    e Zd ZdZ G d d      Zy)MessageSerializerzSerializer for Message modelc                        e Zd ZeZg dZddgZy)MessageSerializer.Meta)	rx   rolecontentr   providerr$   metastatuserror_messagerx   r   N)r!   r"   r#   r  r$   r%   r   r'   r(   r)   r*   r    s    p ,/r(   r*   Nr   r'   r(   r)   r  r    s    &0 0r(   r  c                       e Zd ZdZ ej
                         Z ej
                         Z ej                  dd      Z	 ej
                         Z
 ej                  dd      Z edd      Z G d d      Zd	 Zd
 Zd Zy)ConversationSerializerz/Serializer for Conversation model with messagesget_message_countTrP  r   )manyrs   c                        e Zd ZeZg dZg dZy)ConversationSerializer.Meta)
rx   	person_idperson_nametitlelast_messagelast_message_atmessage_countr   r   rJ   rx   r   r   Nr!   r"   r#   r  r$   r%   r   r'   r(   r)   r*   r        
 >r(   r*   c                     |j                   r/|j                   j                  dk(  r|j                   j                  S |j                  r|j                  j                  S yz1Get person ID from subject or legacy person fieldr   Nsubjectcontent_type	object_idpersonrx   rM   objs     r)   get_person_idz$ConversationSerializer.get_person_id  B    ;;3;;33v=;;(((ZZ::== r(   c                     |j                   rN|j                   j                  dk(  r5|j                   j                         }|rt        |d      r|j                  S y|j
                  r|j
                  j                  S yz3Get person name from subject or legacy person fieldr   r   Nr  r  
get_objecthasattrr   r  rM   r  subject_objs      r)   get_person_namez&ConversationSerializer.get_person_name  c    ;;3;;33v=++002Kw{F;"'''  ZZ::??"r(   c                     |j                         }|r*t        |j                        dkD  r|j                  dd dz   S |r|j                  S dS zGet the last message contentd   Nz... get_last_messagelenr  rM   r  last_msgs      r)   r  z'ConversationSerializer.get_last_message  _    '')19c(BRBR>SVY>Yx%-  	Ft|`h`p`p  	F  CE  	Fr(   N)r!   r"   r#   r   r   SerializerMethodFieldr  r  r-   r  r  DateTimeFieldr  r  rJ   r*   r  r  r  r'   r(   r)   r  r    s    91113I3+335K,K,,4GSWXM4;446L/k//|tTO dd;H> >Fr(   r  c                       e Zd ZdZ ej
                         Z ej
                         Z ej                  dd      Z	 ej
                         Z
 ej                  dd      Z G d d      Zd Zd	 Zd
 Zy)ConversationListSerializerz<Serializer for listing conversations (without full messages)r  TrP  r   c                        e Zd ZeZg dZg dZy)ConversationListSerializer.Meta)	rx   r  r  r  r  r  r  r   r   r  Nr  r'   r(   r)   r*   r    r  r(   r*   c                     |j                   r/|j                   j                  dk(  r|j                   j                  S |j                  r|j                  j                  S yr  r  r  s     r)   r  z(ConversationListSerializer.get_person_id  r  r(   c                     |j                   rN|j                   j                  dk(  r5|j                   j                         }|rt        |d      r|j                  S y|j
                  r|j
                  j                  S yr  r  r  s      r)   r  z*ConversationListSerializer.get_person_name  r  r(   c                     |j                         }|r*t        |j                        dkD  r|j                  dd dz   S |r|j                  S dS r  r  r  s      r)   r  z+ConversationListSerializer.get_last_message  r  r(   N)r!   r"   r#   r   r   r  r  r  r-   r  r  r  r  r*   r  r  r  r'   r(   r)   r  r    sy    F1113I3+335K,K,,4GSWXM4;446L/k//|tTO> >Fr(   r  c                       e Zd ZdZy)CreateConversationSerializerz*Serializer for creating a new conversationN)r!   r"   r#   r   r'   r(   r)   r  r    s    4r(   r  c                       e Zd ZdZ ej
                  ddd      Z ej                  ddgdd	d
      Z ej                  ddgddd      Z	 ej
                  ddd      Z
d Zy)SendMessageSerializerz2Serializer for sending a message in a conversationT  z'User message text (max 2000 characters)r8  )zh-hanszChinese (Simplified))enEnglishFr  zLanguage for response)rE  r   r   r   )groqGroq)openaiOpenAIz;AI provider override (requires can_regenerate_ai privilege))rE  r   r  r   z8AI model override (requires can_regenerate_ai privilege)r  c                     t        |j                               dk(  rt        j                  d      t        |      dkD  rt        j                  d      |j                         S )zValidate message lengthr   zMessage cannot be emptyr  z%Message cannot exceed 2000 characters)r  stripr   r   r?  s     r)   validate_messagez&SendMessageSerializer.validate_message  sQ    u{{}"--.GHHu:--.UVV{{}r(   N)r!   r"   r#   r   r   ra   r   rK  languager  r$   r  r'   r(   r)   r  r    s    <#k##;G
 '{&&46GH)	H '{&&!#78O	H "K!!LEr(   r  c                   8    e Zd ZdZ ej
                  dd      Zy)ConversationConfigSerializerz)Serializer for conversation configurationTz\Maximum number of messages allowed per conversation (only messages with status="sent" count))rs   r   N)r!   r"   r#   r   r   r-   max_messagesr'   r(   r)   r  r    s    3+;++pLr(   r  N)@rest_frameworkr   django.contrib.authr   'django.contrib.auth.password_validationr   r%  r   r|   r	   liuyao.modelsr
   r   r$  r   bazi.modelsr   r   rA   ModelSerializerr   r0   
Serializerrc   rf   rh   rp   ru   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r
  r  r  r  r(  r2  r6  rD  rN  rd  rr  	ai.modelsr  r  r  r  r  r  r  r  r  r'   r(   r)   <module>r     s#   & . E 2 '    1 ,%
(C(C %
N7!<!< 7rEk,, E1[%;%; 1
[%;%; 

K77 
[00 B	N{22 	N	jk99 	j0!<!< 0fU[00 UrK77 rP[%;%; P^+00 ^R[%;%; R
C{55 CW.. W$Q+00 QRk44 R$v!7!7 v:// :I;11 I|;11 |
HK22 HE+00 EP[88 Pd{55 B	{'='= 	N{55 Nf!7!7 ,
;66 
(
[88 
(
[88 
* @ ?033 0'F[88 'FT&F!<!< &FR	;#9#9 	
 K22  F;#9#9 r(   