
    y{jk                        d 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 ddlmZ  G d d	ej                        Z G d
 dej                         Z G d dej                        ZddlmZ  G d dej                        Z G d dej                        Z G d dej                        ZddlmZ  G d dej                         Z G d dej                        ZddlmZ  G d dej                        Zy)z)
DRF serializers for the accounting app.
    )serializers)User)timezone   )StaffProfileAccountHeadAccountTransactionReceipt)Memberc                       e Zd Z ej                  dd      Z ej                         Z ej                         Z ej                         Z	 G d d      Z
defdZd Zd	 Zy
)StaffProfileSerializerzuser.usernameTsource	read_onlyc                        e Zd ZeZg dZddgZy)StaffProfileSerializer.Meta)idusernamenamename_taphonerole	is_active	is_member	member_id	member_no
created_at
updated_atr   r   N)__name__
__module____qualname__r   modelfieldsread_only_fields     @/var/www/kalinger_portal/trust-backend/accounting/serializers.pyMetar      s    
 ),7r&   r(   returnc                 .    t        |j                  d      S Nmember)hasattruserselfobjs     r'   get_is_memberz$StaffProfileSerializer.get_is_member   s    sxx**r&   c                 p    t        |j                  d      r |j                  j                  j                  S y r+   )r-   r.   r,   r   r/   s     r'   get_member_idz$StaffProfileSerializer.get_member_id"   s'    388X&88??%%%r&   c                 p    t        |j                  d      r |j                  j                  j                  S y r+   )r-   r.   r,   r   r/   s     r'   get_member_noz$StaffProfileSerializer.get_member_no'   s'    388X&88??,,,r&   N)r   r    r!   r   	CharFieldr   SerializerMethodFieldr   r   r   r(   boolr2   r4   r6   r%   r&   r'   r   r      sf    ${$$OtLH1113I1113I1113I8 8+D +
r&   r   c                   ,   e Zd ZdZ ej
                  ddd      Z ej
                  ddd      Z ej
                  ddd      Z ej
                  dd	ddd
      Z	 ej                  ej                  d      Z ej                  dd      Zd Zd Zy)StaffProfileCreateSerializerzRCreate a Django User + StaffProfile, or assign StaffProfile to an existing Member.   F )
max_lengthrequireddefaultT)r>   allow_blankr@         )
write_only
min_lengthr?   rA   r@   
ACCOUNTANT)choicesr@   )r?   
allow_nullc                 L   dd l }|j                  d      }|rv	 t        j                  j                  |      }||d<   t        j                  j                  |j                  d      j                         rt        j                  d      |S |j                  d	d
      j                         }|j                  dd
      j                         j                  dd
      }|j                  dd
      }|r|r|st        j                  d      |j                  d      r|dd  }n$|j                  d      rt        |      dk(  r|dd  }|j                  d|      st        j                  d      t         j                  j                  |      j                         rt        j                  d      t        j                  j                  |      j                         rt        j                  d      ||d<   |S # t        j                  $ r t        j                  d      w xY w)Nr   r   r   
member_objzSelected member does not exist.T)r.   r   z,This member is already an active accountant.r   r=   r    passwordzJName, phone, and password are required when adding an external accountant.z+91   91      z^\d{10}$z'Phone number must be exactly 10 digits.)r   z-A user with this phone number already exists.)r   z6A staff profile with this phone number already exists.)regetr   objectsDoesNotExistr   ValidationErrorr   filterr.   existsstripreplace
startswithlenmatchr   )r0   datarR   r   r,   r   r   rM   s           r'   validatez%StaffProfileCreateSerializer.validate9   s   HH[)	U++y+9%+\"
 ##**t*LSSU!112`aa* ' 88FB'--/DHHWb)//199#rBExx
B/HuH!112~&ab	!!$'CJ",<ab	88K/!112[\\||""E"299;!112abb##***7>>@!112jkk!DM5 && U!112STTUs   %G: :)H#c           
         |j                  d      }|r|j                  }|j                  xs t        |dd      xs d|j                   }t
        j                  j                  ||j                  xs t        |dd      xs d|j                   |j                  xs d||j                  dd      d	d
      \  }}|sTd	|_
        |j                  xs |j                  |_        ||_        |j                  dd      |_        |j                          |S |d   }t        j                  j                  ||d   d      }t
        j                  j                  ||d   |j                  dd      ||j                  dd            }|S )NrK   r   r=   M_
first_namezMember #r   rF   T)r   r   r   r   r   )r.   defaultsr   rM   F)r   rM   is_staffr   r   )r.   r   r   r   r   )rS   r.   r   getattrr   r   rT   get_or_creater   r   r   r   saver   create_usercreate)r0   validated_datarK   r.   
safe_phoneprofilecreatedr   s           r'   ri   z#StaffProfileCreateSerializer.create\   s   #''5
??D#))bWT:r-JbPRS]S`S`RaNbJ+33AA&OOlwt\2/NlT\]g]j]j\kRl)117R'*..v|D!%  B 	 GW $(!)>',, *-11&,GN"7+E<<++'
3 , D
 #**11#F+&**9b9#''= 2 G Nr&   N)r   r    r!   __doc__r   r7   r   r   r   rM   ChoiceFieldr   ROLE_CHOICESr   IntegerFieldr   r_   ri   r%   r&   r'   r;   r;   -   s    \ ;  C%LD#k##sbQG!K!!R%LE${$$U`dnpqH";""))<D )((%DII!F$r&   r;   c                       e Zd Z ej                         Z ej                         Z ej                         Z ej                         Z G d d      Z	d Z
d Zd Zd Zy)AccountHeadSerializerc                        e Zd ZeZg dZg dZy)AccountHeadSerializer.Meta)r   r   r   descriptiondescription_ta	head_typeaccount_typer   
created_bycreated_by_nametotal_debitstotal_creditsnet_balancer   r   )rz   r   r   r|   r}   r~   N)r   r    r!   r   r"   r#   r$   r%   r&   r'   r(   ru      s    
 vr&   r(   c                    |j                   sy 	 |j                   j                  j                  S # t        $ r Y nw xY w	 |j                   j                  j                  S # t        $ r Y nw xY w|j                   j                         S N)rz   staff_profiler   	Exceptionmember_profileget_usernamer/   s     r'   get_created_by_namez)AccountHeadSerializer.get_created_by_name   sy    ~~	>>//444 			>>00555 		~~**,,   / 	;;A 	A+*A+c                     ddl m} ddlm} |j                  j                  dd      j                   |d            d	   xs  |d
      }t        |      S )Nr   SumDecimalFDEBIT
is_deletedtransaction_typeamounttotalr   0.00django.db.modelsr   decimalr   transactionsrW   	aggregatestr)r0   r1   r   r   debitss        r'   get_total_debitsz&AccountHeadSerializer.get_total_debits   s[    (#!!((w ) 

)#h-)
(2 E5<V_ 	 6{r&   c                     ddl m} ddlm} |j                  j                  dd      j                   |d            d	   xs  |d
      }t        |      S )Nr   r   r   FCREDITr   r   r   r   r   r   )r0   r1   r   r   creditss        r'   get_total_creditsz'AccountHeadSerializer.get_total_credits   s[    (#""))x * 

)#h-)
(2 E5<V_ 	 7|r&   c                     ddl m}  || j                  |            } || j                  |            }|j                  dv rt        ||z
        S t        ||z
        S )Nr   r   )AssetExpense)r   r   r   r   ry   r   )r0   r1   r   r   r   s        r'   get_net_balancez%AccountHeadSerializer.get_net_balance   sb    #..s34$0056 33v'(( w'((r&   N)r   r    r!   r   r8   r{   r|   r}   r~   r(   r   r   r   r   r%   r&   r'   rs   rs      sb    7k779O4;446L5K557M3+335K	v 	v-
)r&   rs   TrustAccountc                       e Zd Z ej                  ddd      Z ej                  ddd      Z ej                  ddd      Z G d d      Zy	)
TrustAccountSerializermember.nameTr=   r   r   r@   zfamily_member.namezcreated_by.usernamec                        e Zd ZeZg dZg dZy)TrustAccountSerializer.Meta)
account_idaccount_namery   associated_entity_typer,   member_namefamily_memberfamily_member_nameaccount_number	bank_namebranch_namestatuscreated_datedeactivated_daterz   r{   )r   r   r   rz   N)r   r    r!   r   r"   r#   r$   r%   r&   r'   r(   r      s    
 \r&   r(   N)	r   r    r!   r   r7   r   r   r{   r(   r%   r&   r'   r   r      sX    '+''}VXYK...6JVZdfg+k++3HTXbdeO\ \r&   r   c                      e Zd ZdZ ej
                  dd      Z ej                         Z ej
                  d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d      Z ej
                  ddd      Z ej                         Z G d d      Zd Zd Zy)AccountTransactionSerializerz+Read serializer with nested display fields.zaccount_head.nameTr   r   Nr   zmember.member_idzreceipt_number.receipt_numberzreceipt_number.idztax_event.nameztrust_account.account_namec                        e Zd ZeZg dZg dZy)!AccountTransactionSerializer.Meta)#r   account_headaccount_head_name	tax_eventtax_event_nametrust_accounttrust_account_namer   r   transaction_date
tamil_datepayment_modecommodity_type
donor_namedonor_name_tadonor_contactr,   r   member_id_displaypurpose
purpose_tapaid_to
paid_to_tapurpose_descriptionpurpose_description_tabill_referenceproof_document
entered_byentered_by_namer   
change_logreceipt_number
receipt_idr   r   )r   r   r   r   r   N)r   r    r!   r	   r"   r#   r$   r%   r&   r'   r(   r      s    "
"
r&   r(   c                 2    ddl m}  ||j                        S )Nr   get_tamil_date)accounting.utilsr   r   r0   r1   r   s      r'   r   z+AccountTransactionSerializer.get_tamil_date  s    3c2233r&   c                    |j                   sy 	 |j                   j                  j                  S # t        $ r Y nw xY w	 |j                   j                  j                  S # t        $ r Y nw xY w|j                   j                         S r   )r   r   r   r   r   r   r/   s     r'   get_entered_by_namez0AccountTransactionSerializer.get_entered_by_name  sy    ~~	>>//444 			>>00555 		~~**,,r   )r   r    r!   rn   r   r7   r   r8   r   r   r   r   rq   r   r   r   r   r(   r   r   r%   r&   r'   r   r      s    5---"d 8k779O'+''dK .--!T4 +[**.$N *))"dDJ +[**4N /..+tT 3224J
 
04-r&   r   c                   <    e Zd ZdZ G d d      Zd Zd Zd Zd Zy)	"AccountTransactionCreateSerializerz!Write serializer with validation.c                       e Zd ZeZg dZy)'AccountTransactionCreateSerializer.Meta)r   r   r   r   r   r   r   r   r   r   r   r,   r   r   r   r   r   r   r   r   N)r   r    r!   r	   r"   r#   r%   r&   r'   r(   r   !  s    "
r&   r(   c                 :    |dk  rt        j                  d      |S )Nr   z!Amount must be greater than zero.)r   rV   r0   values     r'   validate_amountz2AccountTransactionCreateSerializer.validate_amount+  s&    A:--3  r&   c                 z    |t        j                         j                         kD  rt        j                  d      |S )Nz)Transaction date cannot be in the future.)r   nowdater   rV   r   s     r'   validate_transaction_datez<AccountTransactionCreateSerializer.validate_transaction_date2  s6    8<<>&&((--;  r&   c                 H    |j                   st        j                  d      |S )Nz=Cannot create a transaction under a deactivated Account Head.)r   r   rV   r   s     r'   validate_account_headz8AccountTransactionCreateSerializer.validate_account_head9  s&    --O  r&   c                    |j                  d      }|j                  d      }|j                  d      }|r|dk(  r&|j                  dk7  rt        j                  ddi      |dv r&|j                  dk7  rt        j                  ddi      |d	k(  r&|j                  d	k7  rt        j                  dd
i      |d	k(  r|st        j                  ddi      |j                  d      }|r|j                  |d<   |j
                  xs d|d<   |j                  xs d|d<   |j                  d      }|dk7  r?d }|dk(  rd}n|dv rd}n|d	k(  rd	}|r$| j                  j                  d      }|r|j                  nd }	|	rt        |	dd       nd }
|dk(  r|
n|}|s|}d }|r0t        j                  j                  ||d      j                         }|r |dk(  r|dk(  s|j                  d      s||d<   |j                  d      }|s"|dk(  rt        j                  dd| di      |S |j                  dk7  rt        j                  ddi      |j                  |k7  rt        j                  dd| di      |S )Nr   r   r   CashzFSelected trust account must be of type Cash when payment mode is Cash.zBank TransferUPIChequeBankzOSelected trust account must be of type Bank when payment mode is digital/check.CommoditieszTSelected trust account must be of type Commodities when payment mode is Commodities.z<Commodity Type is required when payment mode is Commodities.r,   r   r=   r   r   r   Creditrequestr   Activer,   ry   r   r   zPlease select an active z Trust Account.z'The selected Trust Account is inactive.z(The selected Trust Account type must be .)rS   ry   r   rV   r   r   r   contextr.   re   r   rT   rW   firstr   )r0   attrsr   r   r   r,   r   target_typer   r.   entry_member	custodianmember_accountresolved_accounts                 r'   r_   z+AccountTransactionCreateSerializer.validate@  s	   yy0		/2#34v%-*D*D*N!11?  EM  3N  O  O!CCHbHbflHl!11?  EV  3W  X  X.=3M3MQ^3^!11?  E[  3\  ]  ]=(--/?A  /A  B  B 8$"(++E,%+^^%9rE/"%+\\%7RE/"  %yy);<x'"6)"(K!%GG"(K!]2"/K"ll..y9G+27<<DLP741A4#HVZL 1<v0E6I$$*	%)N )5)=)=)D)D#,)4#+ *E *  %'	 ' & -8[F=R[`[d[det[u5CE/2 (-yy'A$++x7"-"="= /3KK=Xg1h? #   ,22h>"-"="= /1Z? #  ,88KG"-"="= /3[\g[hhi1j? #  r&   N)	r   r    r!   rn   r(   r   r   r   r_   r%   r&   r'   r   r     s$    +
 
Mr&   r   r   c                   V    e Zd Z ej                         Z ej                  dd      Zy)ReceiptTransactionSerializerrP   rQ   )
max_digitsdecimal_placesN)r   r    r!   r   rq   r   DecimalFieldr   r%   r&   r'   r  r    s&    +;++-L%[%%AFFr&   r  c                      e Zd Z ej                  ej                  j                         dd      Z ej                  ddd      Z
 ej                         Z ej                         Z ej                         Z eddd      Z ej                         Z ej                         Z G d d      Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zy)ReceiptSerializerFT)querysetr?   rH   )r?   rD   rH   )manyrD   r?   c                        e Zd ZeZg dZg dZy)ReceiptSerializer.Meta)r   r   receipt_typer,   r   member_name_tar   father_name	father_idtotal_amountreceipt_dater   r   rz   r{   generated_atpdf_filebreakupr   )r   rz   r  r  N)r   r    r!   r
   r"   r#   r$   r%   r&   r'   r(   r
    s    
 Xr&   r(   c                 N    ddl m} |j                  r ||j                        S dS )Nr   r   r=   )r   r   r  r   s      r'   r   z ReceiptSerializer.get_tamil_date  s#    3363C3C~c../KKr&   c                 f    |j                   r|j                   j                  S |j                  xs dS Nu   —)r,   r   r   r/   s     r'   get_member_namez!ReceiptSerializer.get_member_name  s&    ::::??"~~&&r&   c                 f    |j                   r|j                   j                  S |j                  xs dS r  )r,   r   r   r/   s     r'   get_member_name_taz$ReceiptSerializer.get_member_name_ta  s(    ::::%%%~~&&r&   c                     |j                   sy 	 |j                   j                  j                  S # t        $ r Y |j                   j                  S w xY wr   )rz   r   r   r   r   r/   s     r'   r   z%ReceiptSerializer.get_created_by_name  sI    ~~	>>//444 	~~&&&	s   / 	AAc           
         |j                   j                  d      D cg c]c  }|j                  |j                  j                  |j                  j                  |j                  j
                  t        |j                        de c}S c c}w )NF)r   )r   r   r   account_head_name_tar   )r   rW   r   r   r   r   r   r   )r0   r1   ts      r'   get_transactionsz"ReceiptSerializer.get_transactions  su     %%,,,>	
  dd ! 1 1%&^^%8%8()(>(>ahh-	
 		
 	
s   A(B
c                    |j                  d      }|j                  dg       }|st        j                  ddi      t        d |D              }||k7  rt        j                  ddi      |j                  dt	        | j
                  dd            }|dk(  r>|j                  d	t	        | j
                  d	d             st        j                  d	d
i      |dk(  ri|j                  d	t	        | j
                  d	d             }|j                  dt	        | j
                  dd             }|s|st        j                  ddi      |S )Nr  r  z4At least one account head breakdown row is required.c              3   J   K   | ]  }t        t        |d                  yw)r   N)r   r   ).0items     r'   	<genexpr>z-ReceiptSerializer.validate.<locals>.<genexpr>  s     J$T(^!45Js   !#non_field_errorszaThe sum of all account head breakdown items must equal the total amount specified on the receipt.r  Taxr,   z4A member must be selected for standard tax receipts.Seethanar   z>Sister / Daughter Name is required for Seethana Vari receipts.)rS   r   rV   sumre   instance)r0   r   r  r  
sum_amountr  
has_member	has_donors           r'   r_   zReceiptSerializer.validate  sM   yy0))Ir*--Q/   J'JJ
%--"  %H/   yyX]1^_5 8WT]]T\^b=c)d--P/   :%8WT]]Hd-STJ		,|UY0Z[Ii!11 "b3   r&   c                    |j                  d      }|j                  dd       }| j                  j                  d      }|r|j                  nd }||d<   |j                  dd      }|j                  d      }|j                  dd	      }|d
k(  r|s|r|r	 t        j
                  j                  |      }	t        j
                  j                  |	|dd|	j                  |	j                  ddd	      }
|
|d<   |j                  d      s|	j                  |d<   n[|r7|j                  d      s&|j                  r|j                  j                  |d<   n"|r |j                  d      s|j                  |d<   t        j
                  j                  di |}| j                  |||       | j                  |       |S # t        j                  $ r Y Zw xY w)Nr  r  r   rz   r  r%  r,   r   r=   r&  rJ   FemaleMarriedFT)	fatherr   gendermarital_statusaddress
address_tais_family_headr   
is_expiredr  r%   )popr   rS   r.   r   rT   ri   r2  r3  r   rU   r/  r
   _save_transactions_generate_pdf)r0   rj   breakup_datar  r   r.   r  r,   r   
father_obj	child_objreceipts               r'   ri   zReceiptSerializer.create  s   %)))4"&&{D9	,,""9-&w||D'+|$%)).%@##H-#''b9
:%iJ!'!3!3y!3!AJ & 5 5)'''0 * 2 2#-#8#8',"&#( !6 
!I 09N8,)--m<8B}5  2 2= Afmm060B0B}- 2 2< @/5{{|, //((:>: 	t< 	7#! ** s   BF7 7GGc                    |j                  dd       }|j                  dd        | j                  j                  d      }|r|j                  nd }|j	                         D ]  \  }}t        |||        |j                          |;|j                  j                         j                          | j                  |||       | j                  |       |S )Nr  r  r   )r6  r   rS   r.   itemssetattrrg   r   alldeleter7  r8  )r0   r(  rj   r9  r   r.   attrr   s           r'   updatezReceiptSerializer.update  s    %)))T:;-,,""9-&w||D)//1 	+KD%HdE*	+#!!%%'..0##HlDA8$r&   c                 ^   ddl m} |j                  }d }|dk(  rd}n|dv rd}n|dk(  rd}d }|r{|rt        |dd       xs t        |dd       nd }|r,|j                  j                  ||d	
      j                         }|s+|j                  j                  |d	      j                         }|D ]  }	t        j                  j                  ||	d   |	d   d|j                  |j                  ||j                  |j                  xs$ |j                  r|j                  j                  nd|
        y )Nr   r   r   r   r   r   r,   r   r   r   )ry   r   r   r   r   r=   )
r   account_head_idr   r   r   r   r   r,   r   r   )modelsr   r   re   rT   rW   r   r	   ri   r  r,   r   r   )
r0   r<  r9  r.   r   r   r   r   r   r"  s
             r'   r7  z$ReceiptSerializer._save_transactions3  sL   (++6! K?? K]*'Kei7448aGDJZ\`<aosL , 4 4 ; ;'!,# !< ! %'	  ! , 4 4 ; ;!,# !< ! %' 
 ! 	D&&--& $^ 4H~!)!(!5!5$11+~~"--`'..2E2E]_ . 	r&   c                    ddl m} ddlm} dd l}|j                  t              }|j                  r$	 |j                  j                  d       d |_        	  ||      }|j                  j                  dd       d	}|j                  j                  | ||      d
       y # t        $ r Y _w xY w# t        $ r-}|j                  d|j                   d| d
       Y d }~y d }~ww xY w)Nr   )generate_receipt_pdfr   )ContentFileF)rg   /_z.pdfTz"Receipt PDF generation failed for z: )exc_info)receipt_generatorrH  django.core.files.baserI  logging	getLoggerr   r  rA  r   r   rZ   rg   error)	r0   r<  rH  rI  rO  logger	pdf_bytesfilenameexcs	            r'   r8  zReceiptSerializer._generate_pdf_  s    ;6""8,  ''U'3  $G	n,W5I!0088cBC4HH!!(K	,B!N    	nLL=g>T>T=UUWX[W\]hlLmm	ns*   B# AB2 #	B/.B/2	C(;#C##C(N)r   r    r!   r   PrimaryKeyRelatedFieldr   rT   r@  r,   rq   r  r8   r   r  r{   r  r  r   r   r(   r   r  r  r   r  r_   ri   rC  r7  r8  r%   r&   r'   r  r    s    /[//9K9K9MX]jnoF(((%DUYZI3+335K6[668N7k779O*PTUG4;446L2224JX XL'
'
'

<.`(*Xnr&   r  )AuditLogc                   H    e Zd Z ej                  dd      Z G d d      Zy)AuditLogSerializerzperformed_by.usernameTr   c                       e Zd ZeZg dZeZy)AuditLogSerializer.Meta)r   action
model_name	record_idchangesperformed_byperformed_by_name	timestampN)r   r    r!   rW  r"   r#   r$   r%   r&   r'   r(   r[  }  s    
 "r&   r(   N)r   r    r!   r   r7   ra  r(   r%   r&   r'   rY  rY  z  s#    ---5LX\]" "r&   rY  N)rn   rest_frameworkr   django.contrib.auth.modelsr   django.utilsr   rF  r   r   r	   r
   members.modelsr   ModelSerializerr   
Serializerr;   rs   r   r   r   r   r   r   r  r  rW  rY  r%   r&   r'   <module>ri     s    ' + ! J J ![88 8S;#9#9 St9)K77 9)v !\[88 \(C-;#>#> C-Lo)D)D ol G;#9#9 GWn33 Wn| 	"44 	"r&   