
    P1isr                     V   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mZmZmZmZmZmZmZmZmZmZmZ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)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 d dl7m7Z7 d dl8m9Z9 d dl:m;Z; d dl<m=Z= d dlmZ>  G d	 d
ej~                        Z@y)    )models)settings)getDateTimeGodEarthStemgGodstem
gEarthstemgEarthElementfindGodI
findEarthI	calc10GodfindEarthstemGodcalcEarthstem10GodcalcEarthEmptycalcLifeNumbercalcLifePalacecalc12ChangSengByGodgGodstem5Elementcalc10YearsFatecalcNominalAgecalcYearFatefindGodstem5EcalcFiveElementStrengths)calcBaziShaGodsgShagodNames	gGoodGodsgod_at
tian_yi_attaiji_at	lushen_atwenchang_at	fuxing_at
yangren_atyinchayangcuo_at	feiren_at	shieda_at	liuxiu_atjinyu_atyima_at	taohua_atjiangxing_at	huagai_at	jiesha_atwangshen_at	gejiao_at
tian_de_at	yue_de_at	tianyi_athongluan_at	tianxi_at	guchen_at	guashu_at	zaisha_at)datetime)timezone)NumberPower)make_json_serializablec                       e Zd ZdZg dZg dZg dZg dZg dZ e	j                  d      Z e	j                  d	ed
d      Z e	j                         Z e	j                  dd      Z e	j"                  edddd      Z e	j                  ddd      Z e	j                  ddd      Z e	j*                  ej.                  e	j0                  dd      Z e	j"                  ddd      Z e	j6                  dd      Z e	j:                  d      Z e	j:                  d      Z e	j@                  d      Z! e	jD                  ddd      Z# e	jD                  ddd      Z$ e	jD                  ddd       Z% e	j:                  ddd!      Z& e	j                  d"eddd#$      Z' e	j6                  dd%      Z( e	j                  d&eddd'$      Z) e	j@                  ddd(d)*      Z* e	j:                  ddd+      Z+ e	j                  d"eddd,$      Z, e	j@                  ddd-      Z- e	j*                  ej.                  e	j0                  ddd.d/0      Z. e	j:                  ddd1      Z/ e	j6                  dd2      Z0 e	jD                  ddd3      Z1 e	j:                  ddd4      Z2 e	j                  d"eddd5$      Z3 e	j6                  dd6      Z4 e	j                  d&eddd7$      Z5 e	j@                  ddd8d)*      Z6 e	j:                  ddd9      Z7 e	j                  d"eddd,$      Z8 e	j@                  ddd:      Z9 e	j*                  ej.                  e	j0                  ddd;d<0      Z: e	j:                  ddd=      Z; e	j6                  dd>      Z< e	j6                  dd?d@A      Z= e	jD                  dddB      Z> e	jD                  dddC      Z? e	j"                  dD      Z@ e	j"                  dD      ZA e	j:                  dd      ZBdZC G dE dF      ZDdG ZEdTdHZFdUdIZGdJ ZHdK ZIdL ZJ fdMZKdN ZLdO ZMdVdPZNdVdQZOdR ZPdS ZQ xZRS )WPersonz5Model representing a person whose bazi is calculated.))Mu   男)Fu   女)Nu	   不指定))r   u   正常)   u   双大)   u   双小))pendingu	   处理中)	completedu	   已完成)erroru   错误))rA   u	   待处理)resolvedu	   已解决)	dismissedu	   已忽略))inappropriate_contentu   内容不当)inaccurate_analysisu   分析不准确)offensive_languageu   语言冒犯)technical_erroru   技术错误)otheru   其他d   )
max_lengthr?   r>   u   性别)rL   choicesdefaultverbose_nameT)nullblankr   u   双胞胎选项)rM   rP   rQ   rN   rO   u   父亲生日)rP   rQ   rO   u   母亲生日)	on_deleterP   rQ   z Original user ID before deletion)rP   rQ   	help_textFu   是否用户本人)rN   rO   )auto_now_add)auto_now)rQ   u   八字结果u   数字能量结果u   八字AI分析结果u   八字分析时间   u   八字分析状态)rL   rM   rP   rQ   rO   u   八字分析已举报   u   八字分析举报类别u   八字分析举报留言i  )rP   rQ   rO   rL   u   八字分析举报时间u   分析举报状态u!   八字分析举报管理员备注resolved_bazi_reportsu   八字分析举报处理人)rR   rP   rQ   related_namerO   u   八字分析举报处理时间u'   八字分析举报解决邮件已发送u   数字AI分析结果u   数字分析时间u   数字分析状态u   数字分析已举报u   数字分析举报类别u   数字分析举报留言u   数字分析举报时间u!   数字分析举报管理员备注resolved_number_reportsu   数字分析举报处理人u   数字分析举报处理时间u'   数字分析举报解决邮件已发送u   临时用户创建u'   标识此记录是由临时用户创建)rN   rO   rS   zCompact good reasons vs ownerzCompact bad reasons vs owner)rN   c                       e Zd ZdgZy)Person.Metaz-created_atN)__name__
__module____qualname__ordering     -/home/cursorai/projects/iching/bazi/models.pyMetar\   {   s	    !?rb   rd   c                      | j                    dS )Nz's BaZi Chart)nameselfs    rc   __str__zPerson.__str__~   s    ))M**rb   c                     | j                   syd| _        t        j                         | _        | j                  ddg       y)a[  
        Request AI analysis for this person's chart.
        Sets the analysis status to pending and prepares for async processing.
        
        Args:
            analysis_type: Type of analysis to perform ('bazi', 'number', 'combined')
        
        Returns:
            bool: True if the analysis request was successfully queued
        FrA   analysis_statusanalysis_timestampupdate_fieldsT)bazi_resultrk   r7   nowrl   save)rh   analysis_types     rc   request_analysiszPerson.request_analysis   sB       )"*,,.		!24H I	J rb   c                     |t        | j                        vry|| _        |dk(  r	|r|| _        t	        j
                         | _        | j                  g d       y)a5  
        Update the analysis status and store results if provided.
        
        Args:
            status: New status ('pending', 'completed', 'error')
            result: JSON analysis result (if status is 'completed')
        
        Returns:
            bool: True if the update was successful
        FrB   )rk   ai_analysisrl   rm   T)dictANALYSIS_STATUS_CHOICESrk   ru   r7   rp   rl   rq   )rh   statusresults      rc   update_analysis_statuszPerson.update_analysis_status   sT     d::;;%[ V%D"*,,.		 X	Yrb   c                    | j                         }| j                  r| j                  nd}| j                  | j                         | j                  j                         | j                  r| j                  j                         ndd||d}|S )z
        Get the complete data needed for AI analysis.
        
        Returns:
            dict: Combined data for analysis including BaZi and personal info
        N)rf   gender
birth_date
birth_time)personal_info	bazi_datanumber_data)calculate_bazinumber_resultrf   get_gender_displayr}   	isoformatr~   )rh   r   r   analysis_datas       rc   get_analysis_datazPerson.get_analysis_data   s     '')	 -1,>,>d((D
 		113"oo779=A__doo779RV	 #&	
 rb   c                   <= | j                   sy| j                   j                  }| j                   j                  }| j                   j                  }t	        | j
                        }|rC| j
                  j                  }| j
                  j                  }| j
                  j                  }nd}d}d}t        ||||||      }t        ||||||      }	d<|d   r|d   d   <t        |d   d   |d   d         =<=fd}
 |
|d   d      } |
|d   d      } |
|d   d      }|r |
|j                  d	      d	      nd}t        |      }t        |      }|j                         D ci c]'  \  }}|d
|D cg c]  \  }}t         |   |d c}}i) }}}}}|sd
g i|d	<   d}d}d}| j"                  dk7  r>| j"                  dk(  rdnd}t%        |||||||      }t'        |||||||      }|dk(  rdnd}d}d}d}| j"                  dk7  rt)        d||||||      \  }}}} |d   d   }!g }"t+        |       D ]  \  }#}$|$d   }%|%dz   }&|%|	cxk  xr |&k  nc }'|'r|#}t-        |!|$d         }(g })t/        |$d         }*|*rJt1        |!|$d         }+|*D ]6  },t2        |*|,      }-|+j                  |*|,         }.|)j5                  |-|.d       8 |"j5                  |% d|& t2        |$d      t6        |$d      |'|(|)d        ||||"|d}||"|   }d}/t9        j:                         j                  }0t=        d|0dz
        }1<g }2d}3|1D ]  }4t?        |4jA                               d   }5|4|5   }6|5|0k(  }7t-        <|6d         }(g })t/        |6d         }*|*rJt1        <|6d         }+|*D ]6  },t2        |*|,      }-|+j                  |*|,         }.|)j5                  |-|.d       8 |5t2        |6d      t6        |6d      |7|(|)|6d   |6d   d}8|2j5                  |8       |7s|8}3 d|2i}/g d}9tC        |9|      }:|d   |d   d |d   |d   d |d   |d   d d!};|r|d   |d   d |;d	<   |;| _"        ||||||:||||/3||;|	|d"S c c}}w c c}}}}w )#z)Calculate the BaZi chart for this person.Nr   daygec                    | sy | d   }| d   }t         |   }t        |   }dddddd}t        |   d   }t        |      nd }g }	t	        |      }
|
rGt        |      }|
D ]6  }t         |
|      }|j                  |
|         }|	j                  ||d	       8 d
}|dk7  r|j                         v }d }t        |      }t        ||      }|||||	|||t        |   d   ||dS )Nr   r   u   木u   火u   土u   金u   水)woodfireearthmetalwatergodten_godFr   )r   r   earth_elementr   hidden_godsemptygod_idx	earth_idxgod_elementstar_luck_idxself_luck_idx)r   r   r   r   r   r   getappendvaluesr   r   )pillarpillar_namestem_idx
branch_idxstembranchelement_mapr   r   r   
earth_godshidden_gods_relr   r   ten_god_relr   r   r   day_stemempty_earthss                     rc   process_pillarz-Person.calculate_bazi.<locals>.process_pillar   sX   c{HJH%D
+F K **5c:M 8@7Ki(3QUG K)*5J"4Xz"J  *G":g#67C"1"5"5j6I"JK&&"#.(   * Ee#"l&9&9&;; !M# 4Xz J 1:FM !."*#'/9#>!.!. rb   yearmonthhourgods)rf   kindnessr>   r<   mfu	   东四命u	   西四命
   y	   r   -)	age_ranger   r   
is_currentr   r   )
start_year	directiondayscolumnscurrent_column_index   r@   )r   r   r   r   r   r   r   r   r   )tian_yiwenchangtian_deyue_detaijiyimalushentaohuatianxihongluanhuagaifuxingliuxiujinyu	jiangxingtianyir   r   )r   r   )r   r   r   )r   r   r   r   sha_godssha_god_locationslife_numberlife_palaceten_year_fate	year_fatecurrent_yearcurrent_10yearro   nominal_ageelement_strengths)#r}   r   r   r   boolr~   r   minutesecondr   r   r   r   r   r   itemsr   r|   r   r   r   	enumerater   r   r   r   r   r   r6   rp   r   listkeysr   ro   )>rh   r   r   r   has_hourr   r   r   bazir   r   	year_data
month_dataday_data	hour_datasha_gods_resultr   r   r   idxr   r   r   r   life_palace_text
gender_valr   r   current_10year_datar   r   r   r   day_stem_idxformatted_columnsicol	age_startage_endr   r   r   r   r   r   r   r   r   r   year_fate_columnsformatted_year_fatecurrent_year_datacolumnyear_numberyear_fate_datais_current_yearformatted_datagod_listr   ro   r   r   s>                                                               @@rc   r   zPerson.calculate_bazi   s   ##%%oo!! (??''D__++F__++FDFF&tUCvvN %T5#tVVL ;E{3'H &d5k#&6UC8HI@	F #4<8	#DM7;
!$u+u5@HN488F#3V<d	 *$/ 5T: !0 5 5 7	
 !8 `de`d}sT\,s"3J`de  !8	 	 
  &|HV ;;# $s 2J(T5#tVU[\K(T5#tVU[\K.9Q.>{K #";;#3B	40J	4  ;s+L !##G,3H	#a-&+@@
+,( $L#c(; !-c#h7
&8s3x&PO $.&z'':;&5&9&9*W:M&N#**#&'2,  $. "(($-;ay!9#CH-'C1",&#.* 5 -H )&,(<M $/&78L&M# 	||~**(\A-=> "$ $+"6;;=1!4!'!4"-"= $HnS.AB !-nS.AB
&8>RUCV&WO $.&z'':;&5&9&9*W:M&N#**#&'2,  $. (#N3$78's(;<"1&#.-c2!/!4	" $**>:"(6%M ,R .I

 #8T2
 !+";/
 "),#K0
  	*!+.
  +";/#K '  !2&+*"-1&&!2
 	
e f
s   *Q5
9Q/Q5
/Q5
c                    | j                   sy| j                   j                  d      }d}| j                  r| j                  j                  d      }||| j                  | j                  r| j                  j                  d      nd| j
                  r| j
                  j                  d      ndd}t               }|j                  |      }t        |      }|S )z6Calculate number_result for this person without savingNz%Y-%m-%dz%H:%M)dobdobtimetwinfdobmdob)	r}   strftimer~   	twin_type
father_dob
mother_dobr8   	calculater9   )rh   r   r   np_data
calculatorry   s         rc   calculate_number_resultzPerson.calculate_number_result  s     oo&&z2 ??oo..w7G NN<@OODOO,,Z8QU<@OODOO,,Z8QU
 !]
%%g. (/rb   c                     t        | dd      sd| _        | j                          d| _        | j                  r| j	                         | _        t        |   |i | y )N_skip_bazi_calculationFT)getattrr
  r   r}   r  r   superrq   )rh   argskwargs	__class__s      rc   rq   zPerson.save   sY    t5u=*.D'!*/D' ??!%!=!=!?D 	d%f%rb   c                 t    | j                   r| j                  dk(  sy| j                  sy| j                  dv ryy)z'Check if BaZi analysis can be reported.rB   FTrD   rE   )ru   rk   bazi_analysis_reportedbazi_report_statusrg   s    rc   can_report_bazi_analysiszPerson.can_report_bazi_analysis.  s<      T%9%9[%H**""&??rb   c                 t    | j                   r| j                  dk(  sy| j                  sy| j                  dv ryy)z)Check if Number analysis can be reported.rB   FTr  )number_ai_analysisnumber_analysis_statusnumber_analysis_reportednumber_report_statusrg   s    rc   can_report_number_analysisz!Person.can_report_number_analysis8  s<    ''D,G,G;,V,,$$(AArb   c                 $   | j                         sy| j                  r#| j                  dv rd| _        d| _        d| _        d| _        || _        || _        t        j                         | _
        d| _        d| _        | j                  g d       y)z&Report BaZi analysis as inappropriate.Fr  NTrA   )	r  bazi_report_categorybazi_report_messagebazi_report_timestampr  !bazi_report_resolution_email_sentbazi_report_admin_notesbazi_report_resolved_bybazi_report_resolved_atrm   )r  r  r  r   r!  r"  r  r  r7   rp   r  r  rq   rh   categoryuser_messagereported_bys       rc   report_bazi_analysiszPerson.report_bazi_analysisB  s    ,,. &&4+B+BF_+_+/D(+/D(+/D(&*#$,!#/ %-\\^""+16.		 !
	 	
 rb   c                 $   | j                         sy| j                  r#| j                  dv rd| _        d| _        d| _        d| _        || _        || _        t        j                         | _
        d| _        d| _        | j                  g d       y)z(Report Number analysis as inappropriate.Fr  NTrA   )	r  number_report_categorynumber_report_messagenumber_report_timestampr  #number_report_resolution_email_sentnumber_report_admin_notesnumber_report_resolved_bynumber_report_resolved_atrm   )r  r  r  r-  r.  r/  r)  r*  r7   rp   r+  r,  rq   r#  s       rc   report_number_analysiszPerson.report_number_analysisZ  s    ..0 ((T-F-FJc-c-1D*-1D*-1D*(,%&.#%1"'/||~$$-!380		 !
	 	
 rb   c                     d| _         d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _	        d| _
        d| _        | j                  g d       y)z/Reset BaZi analysis and clear reporting status.NF)ru   rl   rk   r  r  r  r  r  r   r!  r"  r  rm   )ru   rl   rk   r  r  r  r  r  r   r!  r"  r  rq   rg   s    rc   reset_bazi_analysiszPerson.reset_bazi_analysisr  su    "&#&+#$(!#' %)""&'+$'+$'+$16.		 !
	 	rb   c                     d| _         d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _	        d| _
        d| _        | j                  g d       y)z1Reset Number analysis and clear reporting status.NF)r  number_analysis_timestampr  r  r)  r*  r+  r  r-  r.  r/  r,  rm   )r  r4  r  r  r)  r*  r+  r  r-  r.  r/  r,  rq   rg   s    rc   reset_number_analysiszPerson.reset_number_analysis  su    "&)-&&*#(-%&*#%)"'+$$(!)-&)-&)-&380		 !
	 	rb   )r   )N)NN)Sr]   r^   r_   __doc__GENDER_CHOICESTWIN_CHOICESrw   REPORT_STATUS_CHOICESREPORT_CATEGORY_CHOICESr   	CharFieldrf   r|   	DateFieldr}   	TimeFieldr~   IntegerFieldr  r  r  
ForeignKeyr   AUTH_USER_MODELSET_NULL
created_byori_userBooleanFieldownerDateTimeField
created_at
updated_at	TextFieldnotes	JSONFieldro   r   ru   rl   rk   r  r  r  r  r  r   r!  r"  r  r  r4  r  r  r)  r*  r+  r  r-  r.  r/  r,  created_by_temp_userrelation_goodrelation_badrelation_good_countrelation_bad_countrelation_updated_atr
  rd   ri   rs   rz   r   r   r  rq   r  r  r'  r0  r2  r5  __classcell__)r  s   @rc   r;   r;      s<   ?NL 6s+DVNC^fgF!!!#J!!!t48J###Lt4YZiz{I!!!t4nUJ!!!t4nUJ"""8#;#;v]aimnJ"v""DDfgHF<PQE%%%48J%%%t4JF4(E"&""D~VK$F$$$dI]^M #&""DG]^K---4tRfg&f&&">U\`hl  |P  QO 1V00Mde+6++rCZaemq  A[  \*&**DOivz{0F00d$Uop)))RAV]aim  }Q  R.f..DSvw/f//0H0HTZTcTcjnvz  Ja  pM  N2f22DWwx(;(;(;E  YB  )C% *))t4Nde 4 4 4$dYm n-V--E\cgos  CW  X  3v225Ofg-V--E\cgos  C]  ^,F,,$dQkx|}2f22DWqr+6++rCX_cko  S  T 0 0 0d$Ux y 1 1 1(2J2JV\VeVelpx|  Le  tQ  !R 4 4 4$dYy z*=&*=*=e  [D  +E' /6..); %F$$$dFefM#6##TEcdL-&--a8,,,Q7.&..DE"# #+0.6t
l	>&00,rb   r;   N)A	django.dbr   django.confr   iching.utils.bzr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   iching.utils.bzshagodr   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   django.utilsr7   iching.utils.numberpowerr8   iching.utils.serializersr9   django_settingsModelr;   ra   rb   rc   <module>r\     st                    ! 0 ; 3A
V\\ A
rb   