
    njS                        d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	 ddl
mZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZ ddlmZ ddlmZmZ ddl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( ddlm)Z)m*Z*  G d dejV                        Z, G d dejV                        Z- G d dejV                        Z. G d dejV                        Z/ G d dejV                        Z0d Z1d Z2ddl3m4Z4 ddl5Z5ddl6Z6ddl7m8Z8  G d d e4      Z9y)!a>  
DRF ViewSets for the accounting app.

Includes:
- StaffProfileViewSet  (Admin-only CRUD for accountant accounts)
- AccountHeadViewSet    (Accountant + Admin)
- AccountTransactionViewSet (with soft-delete, audit log, filters)
- ReceiptViewSet        (read-only + download)
- Excel export endpoints
- Summary endpoints
    N)Decimal)User)SumCountQ)HttpResponse)timezone)viewsetsstatuspermissions)action)Response)DjangoFilterBackend)SearchFilterOrderingFilter   )StaffProfileAccountHeadAccountTransactionReceiptTrustAccount)StaffProfileSerializerStaffProfileCreateSerializerAccountHeadSerializerAccountTransactionSerializer"AccountTransactionCreateSerializerReceiptSerializerTrustAccountSerializer)IsAccountantOrAdminIsAdminc                       e Zd ZdZej
                  j                  d      j                         Ze	j                  egZd Z eddg      d
d       Z eddg      d
d	       Zy)StaffProfileViewSetz:
    Admin-only CRUD for staff (accountant) profiles.
    userc                 8    | j                   dk(  rt        S t        S )Ncreate)r   r   r   selfs    :/var/www/kalinger_portal/trust-backend/accounting/views.pyget_serializer_classz(StaffProfileViewSet.get_serializer_class/   s    ;;("//%%    TpostdetailmethodsNc                     | j                         }d|_        |j                          t        d|j                   di      S )zDeactivate a staff profile.Fmessagez deactivated.
get_object	is_activesaver   namer'   requestpkprofiles       r(   
deactivatezStaffProfileViewSet.deactivate4   s<     //#!w||nM$BCDDr*   c                     | j                         }d|_        |j                          t        d|j                   di      S )zRe-activate a staff profile.Tr0   z activated.r1   r6   s       r(   activatezStaffProfileViewSet.activate<   s<     //# w||nK$@ABBr*   N)__name__
__module____qualname____doc__r   objectsselect_relatedallquerysetr   IsAuthenticatedr    permission_classesr)   r   r:   r<    r*   r(   r"   r"   (   s|     ##226:>>@H%55w?&
 4&*E +E 4&*C +Cr*   r"   c                       e Zd ZdZej
                  j                         ZeZ	e
j                  egZeeegZg dZg dZddgZd Z eddg	      dd       Z eddg	      dd       Z eddg	      dd       Zy
)TrustAccountViewSetz,
    Trust Accounts management ViewSet.
    )account_typer   associated_entity_type)account_nameaccount_number	bank_namerM   created_datec                 P    |j                  | j                  j                         y N)
created_byr4   r7   r#   r'   
serializers     r(   perform_createz"TrustAccountViewSet.perform_createU       4<<#4#45r*   Tr+   r,   Nc                     | j                         }d|_        t        j                         |_        |j                          t        d|j                   d|j                  d      S )zDeactivate a trust account.Inactive"" deactivated.)r0   deactivated_date)r2   r   r	   nowr]   r4   r   rM   r'   r7   r8   accounts       r(   r:   zTrustAccountViewSet.deactivateX   sU     //###+<<> a(<(<'=^$Lbibzbz{||r*   c                     | j                         }d|_        d|_        |j                          t	        dd|j
                   di      S )zRe-activate a trust account.ActiveNr0   r[   z" activated.)r2   r   r]   r4   r   rM   r_   s       r(   r<   zTrustAccountViewSet.activatea   sH     //#!#' a(<(<'=\$JKLLr*   getc                    | j                         }t        j                  j                  |d      j	                  dd      }g }t        d      }|D ]J  }|j                  dk(  r||j                  z  }n||j                  z  }|j                  |j                  t        |j                        |j                  t        |j                        |j                  |j                  |j                  xs$ |j                  r|j                  j                   nd|j"                  xs$ |j                  r|j                  j$                  nd|j&                  |j(                  xs |j*                  |j,                  r|j,                  j,                  ndt        |      d	       M t/        |j0                  |j2                  |d
      S )zILedger statement: Chronological list of transactions and running balance.F)trust_account
is_deletedtransaction_dateid0DEBIT N)rh   rg   transaction_typeamountpayment_modecommodity_type
donor_namedonor_name_tapaid_topurposereceipt_numberrunning_balance)rM   rK   transactions)r2   r   rB   filterorder_byr   rl   rm   appendrh   strrg   rn   ro   rp   memberr5   rq   name_tarr   rs   purpose_descriptionrt   r   rM   rK   )r'   r7   r8   r`   txnsdatabalancets           r(   ledgerzTrustAccountViewSet.ledgerj   sq    //#!))00!e 1 

(%t
, 	 #, 	A!!W,188#188#KKdd$'(:(:$;$%$6$6ahh- !"#"2"2llQqxx}}b!"!ZQXX5E5EWY9999=(=(=EFEUEU!"2"2"A"A[_#&w< 	( #00#00 
  	r*   r=   )r>   r?   r@   rA   r   rB   rD   rE   r   serializer_classr   rF   r   rG   r   r   r   filter_backendsfilterset_fieldssearch_fieldsordering_fieldsrW   r   r:   r<   r   rH   r*   r(   rJ   rJ   I   s     ##'')H-%557JK*L.IOKCM%~6O6 4&*} +} 4&*M +M 4%)! *!r*   rJ   c                       e Zd ZdZeZej                  egZ	e
eegZddgZddgZddgZdgZd Zd	 Z fd
Z fdZ eddg      dd       Z eddg      dd       Z eddg      dd       Z eddgd      d        Z xZS )AccountHeadViewSetuj   
    Account Heads — both Accountant and Admin can list/create.
    Only Admin can edit/deactivate.
    r3   	head_typer5   description
created_atz-created_atc                 >    t         j                  j                         S r=   )r   rB   rD   r&   s    r(   get_querysetzAccountHeadViewSet.get_queryset   s    ""&&((r*   c                 P    |j                  | j                  j                         y rR   rT   rU   s     r(   rW   z!AccountHeadViewSet.perform_create   rX   r*   c                     |j                   j                  st        ddit        j                        S t        |   |g|i |S Nerrorz"Only admin can edit Account Heads.r   )r#   is_staffr   r   HTTP_403_FORBIDDENsuperupdater'   r7   argskwargs	__class__s       r(   r   zAccountHeadViewSet.update   sJ    ||$$>?00  w~g7777r*   c                     |j                   j                  st        ddit        j                        S t        |   |g|i |S r   )r#   r   r   r   r   r   partial_updater   s       r(   r   z!AccountHeadViewSet.partial_update   sK    ||$$>?00  w%g????r*   Tr+   r,   c                     |j                   j                  st        ddit        j                        S | j                         }d|_        |j                          t        dd|j                   di      S )z(Deactivate an account head (Admin only).r   z(Only admin can deactivate Account Heads.r   Fr0   r[   r\   )	r#   r   r   r   r   r2   r3   r4   r5   r'   r7   r8   heads       r(   r:   zAccountHeadViewSet.deactivate   sk     ||$$DE00   		a		{.$ABCCr*   rc   c           
      2   | j                         }t        j                  j                  |d      }|j                  d      j	                  t        d            d   xs t        d      }|j                  d	      j	                  t        d            d   xs t        d      }|j                  d
v r||z
  }n||z
  }t        |j                  t        |      t        |      t        |      t        |      t        |      |j                         d      S )z4Per-head summary: total debits, credits, net, count.Faccount_headrf   rj   rl   rm   totalr   ri   CREDITAssetExpense)r   total_incometotal_expensetotal_debitstotal_creditsnet_balancetransaction_count)r2   r   rB   rw   	aggregater   r   rK   r   r5   rz   count)r'   r7   r8   r   r~   r   r   r   s           r(   summaryzAccountHeadViewSet.summary   s     !))00% 1 
 {{$ # 

)#h-)
(2 B5<S\ 	 % $ 

)#h-)
(2 B5<S\ 	  44&6K',6K II. .- /{+!%
  	r*   c           	      |    | j                         }t        ||gd|j                  j                  dd       d      S )z
        Export a single Account Head's transactions as .xlsx.
        Supports ?from=YYYY-MM-DD&to=YYYY-MM-DD query params.
        AccountHead_ _z.xlsxfilename)r2   _build_export_responser5   replacer   s       r(   exportzAccountHeadViewSet.export   sB      %dV#DII$5$5c3$?#@F
 	
r*   Fz
export-allr-   r.   url_pathc                     |j                   j                  st        ddit        j                        S t
        j                  j                         }t        ||d      S )z&Export ALL account heads (Admin only).r   zAdmin access required.r   zAll_Account_Heads.xlsxr   )	r#   r   r   r   r   r   rB   rD   r   )r'   r7   headss      r(   
export_allzAccountHeadViewSet.export_all   s[     ||$$2300  ##'')%U%=
 	
r*   r=   )r>   r?   r@   rA   r   r   r   rF   r   rG   r   r   r   r   r   r   r   orderingr   rW   r   r   r   r:   r   r   r   __classcell__r   s   @r(   r   r      s     -%557JK*L.IO#[1]+M|,OH)68@ 4&*
D +
D 4%) *8 4%)	
 *	
 55'LA

 B

r*   r   c                   
   e Zd ZdZdZej                  egZe	e
egZg dZg dZg dZdgZd Zd Zd	 Zd
 Zd Zd Z eddg      d        Z eddgd      d        Z eddgd      d        Z eddgd      d        Zy)AccountTransactionViewSetz
    Accountant: create / edit own / soft-delete own.
    Admin: view all / edit all / soft-delete all.
    Member: read-only access to own donations via my-donations action.
    N)r   rl   rn   )rp   rr   donor_contactrs   )rg   rm   r   -transaction_datec                     | j                   dk(  rt        j                         gS t        j                         t               gS )z
        my-donations is the only action accessible to regular Members.
        All other actions (list, retrieve, create, update, destroy) still
        require IsAccountantOrAdmin.
        my_donations)r   r   rF   r   r&   s    r(   get_permissionsz)AccountTransactionViewSet.get_permissions  s:     ;;.(//122++-/B/DEEr*   c                 6    | j                   dv rt        S t        S )N)r%   )r   r   r   r&   s    r(   r)   z.AccountTransactionViewSet.get_serializer_class  s    ;;+%55++r*   c                 6   t         j                  j                  ddddd      }| j                  j                  j                  d      }|dk(  r | j                  j                  j                  s|j                  d	      }| j                  j                  j                  d
      }| j                  j                  j                  d      }|r|j                  |      }|r|j                  |      }| j                  j                  j                  d      }|r|j                  |      }| j                  j                  j                  d      }|rO|j                  d      D cg c]#  }|j                         s|j                         % }}|j                  |      }| j                  j                  j                  d      }	|	rO|	j                  d      D cg c]#  }|j                         s|j                         % }}|j                  |      }| j                  j                  j                  d      }
|
dk(  r|j                  d      }| j                  j                  j                  d      }|dk(  r|j                  d      }|S c c}w c c}w )Nr   
entered_byr{   rt   re   include_deletedtrueFrf   fromtotransaction_date__gtetransaction_date__lte)trust_account_id
head_types,)account_head__head_type__inaccount_types)account_head__account_type__inis_bankBank)trust_account__account_typeis_cashCash)r   rB   rC   r7   query_paramsrc   r#   r   rw   splitstrip)r'   qsr   	date_fromdate_to
trust_acctr   r   typesr   r   r   s               r(   r   z&AccountTransactionViewSet.get_queryset  s%   ''66L(4Do
 ,,33778IJ6)dll.?.?.H.He,B LL--11&9	,,++//5;B9B \\..22?C
J7B \\..22<@
(2(8(8(=K1QWWYKEKu=B 1155oF(5(;(;C(@N1AGGIQWWYNEN%@B ,,++//	:fv>B ,,++//	:fv>B	' L Os   %J;JJ1Jc                 P    |j                  | j                  j                         y )N)r   rT   rU   s     r(   rW   z(AccountTransactionViewSet.perform_createJ  rX   r*   c           	         | j                         }| j                  j                  }|j                  s|j                  |k7  rddlm}  |d      g }|j                  j                         D ]  \  }}t        ||d      }t        |d      r|j                  }t        |d      r|j                  }t        |      t        |      k7  s[|j                  |t        |      t        |      t        j                         j!                         |j#                         d        |r9t%        |j&                  xs g       }	|	j)                  |       |	|j                  d<   |j+                          y)z(Log changes before saving (audit trail).r   )PermissionDeniedz#You can only edit your own entries.Nr8   fieldoldnewatby
change_log)r2   r7   r#   r   r   rest_framework.exceptionsr   validated_dataitemsgetattrhasattrr8   rz   ry   r	   r^   	isoformatget_usernamelistr   extendr4   )
r'   rV   instancer#   r   changesr   	new_value	old_valuelogs
             r(   perform_updatez(AccountTransactionViewSet.perform_updateM  s0   ??$||   }}!4!4!<B"#HII  * 9 9 ? ? A 	E9%6Iy$'%LL	y$'%LL	9~Y/"y>y>",,.224++-  	  x**0b1CJJw69J%%l3r*   c                     | j                         }|j                  j                  s6|j                  |j                  k7  rt	        ddit
        j                        S d|_        t        |j                  xs g       }|j                  dddt        j                         j                         |j                  j                         d       ||_	        |j                          t	        d	d
it
        j                         S )z#Soft-delete instead of hard-delete.r   z%You can only delete your own entries.r   Trf   FalseTruer   r0   zTransaction soft-deleted.)r2   r#   r   r   r   r   r   rf   r   r   ry   r	   r^   r   r   r4   HTTP_200_OK)r'   r7   r   r   r   r  s         r(   destroyz!AccountTransactionViewSet.destroyp  s    ??$ ||$$)<)<)LAB00 
 #8&&,"-

!,,.**,,,++-
 	 "34%%
 	
r*   Frc   r,   c                    t         j                  j                  d      }|j                  d      j                  t	        d            d   xs t        d      }|j                  d	      j                  t	        d            d   xs t        d      }t        t        |      t        |      t        ||z
        |j                         d
      S )z!Overall summary across all heads.Fr   rj   r   rm   r   r   ri   r   )r   r   r   total_transactions)	r   rB   rw   r   r   r   r   rz   r   )r'   r7   r   r   r   s        r(   r   z!AccountTransactionViewSet.summary  s      ''..%.@yy$ ! 

)c(m)
$S* :-4S\ 	 		% " 

)c(m)
$S* :-4S\ 	 . .}|;<"$((*	
  	r*   zcommodity-summaryr   c                 z   t         j                  j                  d      }|j                  d      j                  d      j	                  t        d            d	   xs t        d
      }|j                  d      j                  d      j	                  t        d            d	   xs t        d
      }|j                  ddd      j	                  t        d            d	   xs t        d
      }|j                  ddd      j	                  t        d            d	   xs t        d
      }|j                  ddd      j	                  t        d            d	   xs t        d
      }|j                  ddd      j	                  t        d            d	   xs t        d
      }|j                  ddd      j	                  t        d            d	   xs t        d
      }	|j                  ddd      j	                  t        d            d	   xs t        d
      }
t        t        |      t        |      t        ||z
        dt        |      t        |      t        ||z
        dt        |      t        |      t        ||z
        dt        |	      t        |
      t        |	|
z
        dd      S )z~
        Natively calculates and summarizes physical weight assets: Gold and Silver,
        alongside fiat currency.
        Fr   r   r   Commodities)rn   rm   r   r   ri   rj   Gold)rn   ro   rl   SilverOther)r   r   r   )fiatgoldsilverother)	r   rB   rw   excluder   r   r   r   rz   )r'   r7   r   fiat_creditsfiat_debitsgold_creditsgold_debitssilver_creditssilver_debitsother_creditsother_debitss              r(   commodity_summaryz+AccountTransactionViewSet.commodity_summary  s     ''..%.@ yy(y;CCQ^C_iipst|p}i~  @G  H  X  LS  TW  LXiii9AA}A]ggnqrzn{g|  ~E  F  V  JQ  RU  JV yymFemynxx  @C  DL  @Mx  N  OV  W  g  [b  cf  [gii]6dkilvv  ~A  BJ  ~Kv  L  MT  U  e  Y`  ad  Ye hiqr||  DG  HP  DQ|  R  SZ  [  k  _f  gj  _k		}Xho	pzz  BE  FN  BOz  P  QX  Y  i  ]d  eh  ]i 		}Wgo	pzz  BE  FN  BOz  P  QX  Y  i  ]d  eh  ]iyymGfmynxx  @C  DL  @Mx  N  OV  W  g  [b  cf  [g!$\!2 #K 0"<+#=> "%\!2 #K 0"<+#=> "%^!4 #M 2">M#AB "%]!3 #L 1"=<#?@!
  	r*   zmember-balancesc                    ddl m} |j                  j                  dd      j	                  d      }g }|D ]  }t
        j                  j                  |dd      j                  t        d	      
      d   xs t        d      }t
        j                  j                  |dd      j                  t        d	      
      d   xs t        d      }|j                  |j                  |j                  |j                  |j                  |j                  t        |      t        |      t        ||z
        d        t!        |      S )z
        Roster of all members showing their Name and their exact running financial balance.
        Balance = Cumulative DEBIT (due/billed) - Cumulative CREDIT (paid).
        r   )MemberT)r3   is_family_headr5   rj   F)r{   rl   rf   rm   r   r   ri   r   )rh   	member_idr5   r|   phoner   r   ru   )members.modelsr   rB   rw   rx   r   r   r   r   ry   rh   r"  r5   r|   r#  rz   r   )r'   r7   r   membersr   mdebitscreditss           r(   member_balancesz)AccountTransactionViewSet.member_balances  s1    	*..''$t'LUUV\] 	A'//667u 7 ic(mi,W6 F9@  )00778 8 ic(mi,W6 F9@  KKdd[[99 #F!$W#&v'7#8	 		& ~r*   zmy-donationsc                 Z   |j                   }	 |j                  }t        j                  j                  d|d      j                  dd      j                  d	      }t        |d
      }|j                  t        d            d   xs t        d      }|j                  d      j!                  t        d      t#        d            j                  d      }t        |j$                  t'        |      t)        |      d      S # t        $ r  t        ddit        j
                        cY S w xY w)zq
        Member-facing endpoint: returns all INCOME transactions linked
        to the logged-in member.
        r   zNo member profile found.r   INCOMEF)rl   r{   rf   r   rt   r   T)manyrm   r
  r   ri   account_head__namerh   )r   r   z-total)	donationslifetime_totalper_head_breakdown)r#   member_profile	Exceptionr   r   HTTP_404_NOT_FOUNDr   rB   rw   rC   rx   r   r   r   r   valuesannotater   r   rz   r   )r'   r7   r#   r{   r   rV   r/  per_heads           r(   r   z&AccountTransactionViewSet.my_donations  s    ||	((F  ''..% / 
 .)9
:88DW;X	 	 2"4@
H6s;Kws|II*+XCMtX=Xh 	 #!.1"&x.
  	+  	4500 	s   D &D*)D*)r>   r?   r@   rA   pagination_classr   rF   r   rG   r   r   r   r   r   r   r   r   r   r)   r   rW   r  r  r   r   r  r)  r   rH   r*   r(   r   r      s    
 %557JK*L.IOKIMBO#$HF,
,\6!F
6 55'* +" 55'4GH, I,\ 55'4EF G< 55'NC! D!r*   r   c                   j     e Zd ZdZeZej                  gZd Z	 fdZ
 eddg      dd       Z xZS )	ReceiptViewSetuo  
    ModelViewSet for receipts + PDF download.

    Queryset scoping rules:
    - Admin (is_staff=True)  → all receipts.
    - Accountant (StaffProfile) → all receipts.
    - Member                  → only receipts whose member
                                 matches the logged-in user's member profile.
    - Anyone else              → empty queryset.
    c                    | j                   j                  }t        j                  j	                  dd      j                  dd      }|j                  r|S 	 |j                  }|j                  dk(  r|j                  r|S 	 |j                  }|j                  |      S # t        $ r Y *w xY w# t        $ r Y |j                         S w xY w)Nr{   rS   rv   transactions__account_head
ACCOUNTANT)r{   )r7   r#   r   rB   rC   prefetch_relatedr   staff_profileroler3   r2  r1  rw   none)r'   r#   base_qsr9   r{   s        r(   r   zReceiptViewSet.get_queryset#  s    ||  //00l


8
 	 ==N	((G|||+0A0A
	((F>>>00  		  	 ||~		s$   (B  B- 	B*)B*-	CCc                    t         |   |       | j                  dv r\|j                  }d}	 |j                  }|j
                  dk(  xr |j                  }|j                  s|s| j                  |d       y y y y # t        $ r Y 0w xY w)N)r%   r   r   r  Fr<  z0Only admins and accountants can modify receipts.)r0   )
r   check_permissionsr   r#   r>  r?  r3   r2  r   permission_denied)r'   r7   r#   is_accountantr9   r   s        r(   rC  z ReceiptViewSet.check_permissionsA  s    !'*;;KK<<D!M,, ' < RARAR MM]&&w8j&k &3M L  s   )A< <	BBTrc   r,   c                    | j                         }|j                  }d}|j                  rd}n*	 |j                  }|j                  dk(  xr |j
                  }|j                  j                  d      dk(  xs | }ddl	m
} |r< ||d      }	t        |	d	
      }
d|j                  j                  dd       d|
d<   |
S |j                  sQddlm}  ||      }	|j                  j                  dd       d}|j                  j#                  | ||	      d       t        |j                  j%                         d	
      }
d|j                  j                  dd       d|
d<   |
S # t        $ r Y w xY w)zDownload receipt PDF.FTr<  typer{   r   )generate_receipt_pdf)member_onlyzapplication/pdfcontent_typez%attachment; filename="member_receipt_/r   z.pdf"Content-Dispositionr   )ContentFilez.pdf)r4   attachment; filename=")r2   r#   r   r>  r?  r3   r2  r   rc   receipt_generatorrH  r   rt   r   pdf_filedjango.core.files.baserN  r4   read)r'   r7   r8   receiptr#   is_staff_or_accountantr9   rI  rH  	pdf_bytesresponserN  r   s                r(   downloadzReceiptViewSet.downloadN  s    //#||!&==%)",,)0)E)['J[J[& ++//78CdMcIc;,W$GI#.H
 88N8N8V8VWZ\_8`7aafg *+ O :,W5I!0088cBC4HH!!(K	,B!N!!#*

 %W%;%;%C%CC%M$NeT 	&' C  s   )E& &	E32E3r=   )r>   r?   r@   rA   r   r   r   rF   rG   r   rC  r   rX  r   r   s   @r(   r9  r9    sG    	 )%556<l 4%)- *-r*   r9  c                    ddl }ddlm}m}m}m}m} | j                  j                  d      }	| j                  j                  d      }
|j                         }|j                  |j                  |j                          |ddd	      } |d
d
d      } |ddd      } | |d       |d       |d       |d            }t        d      }t        d      }|D ]~  }t        j                  j                  |d      j!                  ddd      }|	r|j                  |	      }|
r|j                  |
      }|j                  d      j#                  d      }|j                  d      j#                  d      }|j%                  t'        d            d    xs t        d      }|j%                  t'        d            d    xs t        d      }||z  }||z  }|j(                  dd! }|j+                  | d"#      } |dd$d%	      |j-                  d&d&d'(      _        |j1                  d)        |d*      |j-                  d&d&+      _        g d,}t5        |d&      D ]5  \  }}|j-                  d-||(      }||_        ||_        ||_        ||_        7 t5        |d.      D ]  \  }}t;        |j<                        } d/}!	 |j>                  j@                  }!|jD                  jG                  d0      |jH                  |jJ                  |jL                  |jN                  r|jN                  jP                  nd/|jN                  r|jN                  j(                  nd/tS        |jT                        |jV                  |jX                  |jZ                  |!| g}"t5        |"d&      D ]   \  }}#|j-                  |||#(      }||_        "   |j+                  | d1#      }$ |dd$d%	      |$j-                  d&d&d'(      _        |$j1                  d2        |d*      |$j-                  d&d&+      _        g d3}%t5        |%d&      D ]5  \  }}|$j-                  d-||(      }||_        ||_        ||_        ||_        7 t5        |d.      D ]  \  }}t;        |j<                        } d/}!	 |j>                  j@                  }!|jD                  jG                  d0      |j\                  |j^                  |j`                  |jb                  tS        |jT                        |jV                  |jd                  |!| g
}"t5        |"d&      D ]   \  }}#|$j-                  |||#(      }||_        "   |j+                  d4d5      }& |d6d6d      }' |dd$d%	      |&j-                  d&d&d'(      _        |&j1                  d7        |d*      |&j-                  d&d&+      _         |dd$8      |&j-                  d-d&d9(      _        |&j1                  d:       d/}(|	s|
r5d;|	xs d< d=|
xs d> }(|&j-                  d.d&|((       |&j1                  d?       d@})t5        g dAd&      D ]5  \  }}|&j-                  |)||(      }||_        |'|_        ||_        ||_        7 |)d&z   }*t        d      }+|D ]  }t        j                  j                  |d      }|	r|j                  |	      }|
r|j                  |
      }|j                  d      j%                  t'        d            d    xs t        d      },|j                  d      j%                  t'        d            d    xs t        d      }-|jf                  dBv r|-|,z
  }.n|,|-z
  }.|+|.z  }+||&j-                  |*d&|j(                  (      _        ||&j-                  |*d-|jf                  (      _        ||&j-                  |*d.tS        |,      (      _        ||&j-                  |*dCtS        |-      (      _        ||&j-                  |*d@tS        |.      (      _        |*d&z  }*  |dd8      }/|/|&j-                  |*d&dD(      _        ||&j-                  |*d-d/(      _        |/|&j-                  |*d.tS        |      (      _        |/|&j-                  |*dCtS        |      (      _        |/|&j-                  |*d@tS        |+      (      _        ti        d&dE      D ]  }||&j-                  |*|+      _         |jj                  D ]  }0|0jl                  D ]~  }d}1d}2|D ]O  }to        |dF      r|jp                  }2|jr                  s(tu        |1tw        ty        |jr                                    }1Q |2s^t{        |1dCz   dG      |0j|                  |2   _?          ddHl@mA}3  |3       }4|j                  |4       |4j                  d       t        |4j                         dIJ      }5dK| dL|5dM<   |5S # tB        $ r Y w xY w# tB        $ r Y Nw xY w)Nzo
    Build an .xlsx HttpResponse with Income / Expense / Summary sheets
    for the given account head(s).
    r   N)FontPatternFill	AlignmentBorderSider   r   T   FFFFFF)boldsizecolor4338CAsolid)start_color	end_color	fill_typecenter)
horizontalvertical	wrap_textthin)style)leftrighttopbottomri   Fr   r{   r   rt   r   r   r   r   rg   rj   rm   r
  r      z Credits)title   D97706r   u5   ஸ்ரீ ராமஜெயம் | Sri Ramajeyam)rowcolumnvaluezA1:L1)rj  )rw  rx  )Datez
Donor NamezDonor Name (Tamil)Contactz	Member IDzMember NameAmountPayment ModezPurpose/RemarkszPurpose/Remarks (Tamil)
Receipt No
Entered By      rk   z%Y-%m-%dz DebitszA1:K1)
rz  zPaid TozPaid To (Tamil)zPurpose/DescriptionzPurpose/Description (Tamil)r|  r}  zBill Referencer~  r  Summary)rt  index059669zA1:E1)ra  rb  zAccount Head Report SummaryzA2:E2zFrom: Startu	    — To: PresentzA3:E3   )zAccount HeadzAccount TypezTotal CreditszTotal DebitszNet Balancer      TOTAL   column_letter(   )BytesIOzAapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetrJ  rO  r[   rM  )Fopenpyxlopenpyxl.stylesrZ  r[  r\  r]  r^  r   rc   Workbookactiveremover   r   rB   rw   rC   rx   r   r   r5   create_sheetcellfontmerge_cells	alignment	enumeratefillborder_get_display_namer   rT  rt   r2  rg   strftimerp   rq   r   r{   r"  floatrm   rn   rs   
purpose_tarr   
paid_to_tar}   purpose_description_tabill_referencerK   range
worksheetscolumnsr   r  ry  maxlenrz   mincolumn_dimensionswidthior  r4   seekr   getvalue)6r7   account_headsr   r  rZ  r[  r\  r]  r^  r   r   wbheader_fontheader_fillheader_alignthin_borderoverall_debitsoverall_creditsr   r   income_txnsexpense_txnshead_incomehead_expense	safe_name	ws_incomeincome_headerscolhdrr  row_idxtxnentered_name
receipt_novalsval
ws_expenseexpense_headers
ws_summarysummary_header_filldate_range_str	start_rowrw  overall_net_balancehiher   
total_fontwsmax_len
col_letterr  bufrW  s6                                                         r(   r   r     s
   
 JJ$$((0I""&&t,G				B	yy
		"))Dr:K(hRYZK8tTLt&'9vt&'9K
 S\NclO g*''..% / 

.<1A
B 	 ;B9Biii:CCDVWyy'y:CCDVW!++c(m+<SAQWS\#--H->sCSws|;&,& IIcrN	 OOYKx*@OA	nrx|  DF  NV  oW	1Q.efkg&4=4R	1Q'1
 ".!4 	&HC>>a3>?D#DI#DI)DN%DK	& &k15 	*LGS,S^^<LJ [[77

 $$--j9!!!!(+



$$#&::

2cjj!  D &dA. *S ~~'#S~I)*-	*6 __i[+@_A
osy}  EG  OW  pX
Aa/fglw'5>(5S
Aa(2
 "/15 	&HC??qC?@D#DI#DI)DN%DK	& &lA6 	*LGS,S^^<LJ [[77

 $$--j9''**cjj!  ""D &dA. *S!73cJ)*)	*cg*T y:J%G lp(lJOO!+bOch 7#1:h1OJOO!O$.QURJOO!+HOIN 7#NG!)"6w!7yAUI@VWAa~>w'IXZ[ "S 9SD	'	%!" a-C!#, ''..% / 
 ;B9BYYY1;;c(m;LSQaU\]`UaYYY0::S]:KCP`T[\_T` 44r'Kr'K{*EP
C;BMX
C1B1BCJEP
Cr;BEP
Cr;BNY
C{1CDKq16 4b)J=GJOOAWO5::EJOOARO07  OO!7  
  OO~!6  
  OO':!;  
Q{ B6A
C,3B mm 
N:: 		NCGJ A41!%!3!3J::!'3s4::+?@G	A
 9<Wq["9M$$Z06		N
N 
)CGGCLHHQKXH )?xj&JH"#OG  V  s$   
g-%g=-	g:9g:=	h
	h
c                     	 | j                   j                  S # t        $ r Y nw xY w	 | j                  j                  S # t        $ r Y | j	                         S w xY w)z%Get a human-readable name for a user.)r>  r5   r2  r1  r   )r#   s    r(   r  r  o  sc    !!&&& ""''' s    	$$> 	AA)APIView)settingsc                   "    e Zd ZdZd Zd Zd Zy)SystemSettingsViewzE
    API endpoint to get and set system-level receipt templates.
    c                     | j                   j                  dk(  rt        j                         gS t        j                         t	               gS )NGET)r7   methodr   rF   r   r&   s    r(   r   z"SystemSettingsView.get_permissions  s>    <<%'//122++-/B/DEEr*   c           
      @   t        t        j                        }t        j                  j                  |dd      }d}d}d}t        j                  j                  |      rc	 t        |dd      5 }t        j                  |      }|j                  dd      }|j                  d	d      }|j                  d
d      }d d d        t        j                  j                  |d      }	t        j                  t        j                  j                  |	d            }
|
D cg c]!  }t        j                  j                  |      # }}d|vr|j                  d       d}t        j                  j                  |	|      }t        j                  j                  |      r(	 t        |dd      5 }|j                         }d d d        t!        |||t#        t%        |            |d      S # 1 sw Y   *xY w# t        $ r Y 9w xY wc c}w # 1 sw Y   NxY w# t        $ r Y \w xY w)N
accountingsystem_settings.jsonztax_receipt_template.htmlrk   rutf-8encodingactive_receipt_templatedefault_tax_head_iddefault_seethana_head_idz*.html)r  r  r  	templatestemplate_content)rz   r  BASE_DIRospathjoinexistsopenjsonloadrc   r2  globbasenamery   rS  r   r   set)r'   r7   base_dirsettings_pathactive_templater  r  fr   dir_path
html_filesr  r  active_template_paths                 r(   rc   zSystemSettingsView.get  s   x(()X|=ST5 #% 77>>-(-w? X199Q<D&*hh/HJe&fO*.((3H"*M'/3xx8RTV/W,	X 77<<,7YYrww||Hh?@
2<=QRWW%%a(=	=&i789 !ww||HoF77>>./.gF 0!'(vvx$0
 '6#6(@c)n- 0
  	3X X
   >0 0 s[   !G0 /AG#;G0 &H H 'H8H #G-(G0 0	G=<G=H
H 	HHc                 <   |j                   j                  d      }t        j                  j	                  t        t        j                        d      }|dk(  r|j                   j                  d      }|j                   j                  d      }|r|st        ddit        j                        S t        j                  j                  |      }|j                  d	      s|d	z  }t        j                  j	                  ||      }	 t        |d
d      5 }|j                  |       d d d        t        dd| di      S t        j                  j	                  |d      }	i }
t        j                  j#                  |	      r-	 t        |	dd      5 }t%        j&                  |      }
d d d        |j                   j                  d      }|r~t        j                  j                  |      }t        j                  j#                  t        j                  j	                  ||            st        ddit        j(                        S ||
d<   d|j                   v r(t        |j                   j                  dd            |
d<   d|j                   v r(t        |j                   j                  dd            |
d<   	 t        |	d
d      5 }t%        j*                  |
|d       d d d        t        ddi      S # 1 sw Y   xY w# t        $ r0}t        dt        |      it        j                         cY d }~S d }~ww xY w# 1 sw Y   xY w# t        $ r Y w xY w# 1 sw Y   |xY w# t        $ r0}t        dt        |      it        j                         cY d }~S d }~ww xY w)Nr   r  save_template_contenttemplate_namecontentr   z Missing template_name or contentr   z.htmlwr  r  r0   z
Template "z" saved successfully.r  r  r  zTemplate file does not existr  rk   r  r  )indentz%System settings updated successfully.)r   rc   r  r  r  rz   r  r  r   r   HTTP_400_BAD_REQUESTr  endswithr  writer2  HTTP_500_INTERNAL_SERVER_ERRORr  r  r  r3  dump)r'   r7   r   r  r  r  target_pathr  er  config_datar  s               r(   r+   zSystemSettingsView.post  s   !!(+77<<H$5$5 6E,,#LL,,_=Mll&&y1G *L MV\VqVqrr GG,,];M ))'2('',,x?Ka+sW= %GGG$%jG\,] ^__ GGLL3IJMKww~~m,mS7C 3q&*iil3
 &ll../HIO"$''"2"2?"Cww~~bggll8_&MN#W.L$MV\VoVopp9H56$4589I9IJ_ac9d5e12)W\\9:=gll>N>NOikm>n:o67a-w? 81IIk1Q78,S TUUA% %  a#a& 1&:_:_``a3 3   8 8  a#a& 1&:_:_``as   K= K0%K=  M L9$M 4M" MM" 0K:5K= =	L6%L1+L61L69M>M 	MMMM" "	N+%NNNN)r>   r?   r@   rA   r   rc   r+   rH   r*   r(   r  r    s    F
(T3ar*   r  ):rA   r  decimalr   django.contrib.auth.modelsr   django.db.modelsr   r   r   django.httpr   django.utilsr	   rest_frameworkr
   r   r   rest_framework.decoratorsr   rest_framework.responser   django_filters.rest_frameworkr   rest_framework.filtersr   r   modelsr   r   r   r   r   serializersr   r   r   r   r   r   r   r   r    ModelViewSetr"   rJ   r   r   r9  r   r  rest_framework.viewsr  r  r  django.confr  r  rH   r*   r(   <module>r     s   
   + * * $ ! 8 8 , , = ? X X   6C(// CBC(// CTe
.. e
XN 5 5 NjhX** h^iX
 )  	  fa far*   