
    n^j,                         d Z ddlZddlmZ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ededefdZddededefdZ G d de      Z G d de      Z G d de      Zd Z G d de      Zy)uv  
revenue/models.py
=================
Models for Module 4 — Income & Revenue Management.

Hierarchy:
  RevenueHead → RevenueSubHead → RevenueItem
                                      ↓
                              RevenueRecord  (actual transaction)

Revenue codes follow the same auto-generation pattern as budget:
  Head: INV  SubHead: INV-LAB  Item: INV-LAB-001
    N)GroupUser)modelsreverse_lazy)format_html)gettext_lazy)
Department)
BudgetItem)HorillaModelnamemax_lenreturnc                     t        j                  dd|       j                         }|syt        |      dkD  r)dj	                  d |D              j                         d | n|d   d | j                         }|xs dS )Nz[^a-zA-Z0-9\s] X   c              3   &   K   | ]	  }|d      yw)r   N ).0ws     2/var/www/python-projects/worksol/revenue/models.py	<genexpr>z%_make_abbreviation.<locals>.<genexpr>%   s     'A1Q4's   r   )resubsplitlenjoinupper)r   r   wordsabbrs       r   _make_abbreviationr"   !   sw    FF$b$/557E=@Z!^277'''--/9QVWXQYZb[bQcQiQiQkD;3    basefieldc                 .   | d}} |j                   j                  di ||i}|r|j                  |      }|j                         rN|  | }|dz  } |j                   j                  di ||i}|r|j                  |      }|j                         rN|S )N   pkr   r   )objectsfilterexcludeexists)r$   model_classr%   instance_pkcodecounterqss          r   _unique_coder3   )   s    !'D	#			#	#	4udm	4BZZ;Z'
))+y!1'[  ''85$-8{+B ))+ Kr#   c            
       r    e Zd ZdZ ej
                  dd ed            Z ej
                  ddd ed      	      Z ej                  d ed
            Z
 ej                  eej                  dd ed       ed            Z G d d      Z fdZd Zd Zd Zd Zd Zd Z ed      e_         xZS )RevenueHeadzL
    Top-level revenue category (e.g. 'Investigation', 'Consultation').
       Tz	Head Name)
max_lengthuniqueverbose_name   FRevenue Coder7   r8   editabler9   Descriptionblankr9   zAllowed Recorder GroupzXOnly members of this group can record revenue under this head. Leave blank to allow all.)	on_deletenullr@   r9   	help_textc                   2    e Zd Z ed      Z ed      ZdgZy)RevenueHead.MetaRevenue HeadzRevenue Headsr   N__name__
__module____qualname___r9   verbose_name_pluralorderingr   r#   r   MetarE   M   s    (08r#   rN   c                     | j                   s6t        | j                        }t        |t        | j
                        | _         t        |   |i | y )Nr/   )r0   r"   r   r3   r5   r)   supersave)selfargskwargsr$   	__class__s       r   rR   zRevenueHead.saveR   s=    yy%dii0D$T;DGGLDId%f%r#   c                 :    d| j                    d| j                   S N[z] r0   r   rS   s    r   __str__zRevenueHead.__str__X       499+R		{++r#   c                     t        d      S )Nzrevenue-head-listr   r[   s    r   get_absolute_urlzRevenueHead.get_absolute_url_       /00r#   c                 4    t        dd| j                  i      S )Nzrevenue-head-editr)   rU   r   r)   r[   s    r   get_update_urlzRevenueHead.get_update_urlb       /twwHHr#   c                 4    t        dd| j                  i      S )Nzrevenue-head-deleter)   rb   rc   r[   s    r   get_delete_urlzRevenueHead.get_delete_urle       14/JJr#   c                     | j                   S Nr(   r[   s    r   get_delete_instancezRevenueHead.get_delete_instanceh       wwr#   c                 n    | j                   j                  d      j                         }t        d|      S NT)	is_active8<span class="badge oh-badge oh-badge--primary">{}</span>)	sub_headsr+   countr   rS   rr   s     r   sub_head_countzRevenueHead.sub_head_countk   s1    %%%5;;=UW\]]r#   z	Sub-Heads)rH   rI   rJ   __doc__r   	CharFieldrK   r   r0   	TextFielddescription
ForeignKeyr   SET_NULLallowed_recorder_grouprN   rR   r\   r_   rd   rg   rk   rt   short_description__classcell__rV   s   @r   r5   r5   <   s     6s4anUD6r$UVWeUfgD"&""Am<LMK.V..///0no 
&,1IK^ ()~N$$r#   r5   c                   `    e Zd ZdZ ej
                  eej                  d ed            Z	 ej                  d ed            Z ej                  dd	d
 ed            Z ej                  d	 ed            Z G d d      Z fdZd Zd Zd Zd Zd Zd Z ed      e_         xZS )RevenueSubHeadzI
    Second-level revenue category (e.g. 'Laboratory', 'Radiology').
    rq   rF   rA   related_namer9   r6   zSub-Head Namer7   r9      TFr;   r<   r>   r?   c                   >    e Zd Z ed      Z ed      ZddgZddggZy)RevenueSubHead.MetaRevenue Sub-HeadzRevenue Sub-Heads
head__namer   headNrH   rI   rJ   rK   r9   rL   rM   unique_togetherr   r#   r   rN   r      s0    +, 34 &)"F+,r#   rN   c                     | j                   sQt        | j                        }| j                  j                    d| }t	        |t
        | j                        | _         t        |    |i | y )N-rP   )	r0   r"   r   r   r3   r   r)   rQ   rR   )rS   rT   rU   r!   r$   rV   s        r   rR   zRevenueSubHead.save   sV    yy%dii0Diinn%Qtf-D$T>twwODId%f%r#   c                 :    d| j                    d| j                   S rX   rZ   r[   s    r   r\   zRevenueSubHead.__str__   r]   r#   c                     t        d      S )Nzrevenue-sub-head-listr   r[   s    r   r_   zRevenueSubHead.get_absolute_url   s    344r#   c                 4    t        dd| j                  i      S )Nzrevenue-sub-head-editr)   rb   rc   r[   s    r   rd   zRevenueSubHead.get_update_url       3T477OLLr#   c                 4    t        dd| j                  i      S )Nzrevenue-sub-head-deleter)   rb   rc   r[   s    r   rg   zRevenueSubHead.get_delete_url   s    5tTWWoNNr#   c                     | j                   S rj   r(   r[   s    r   rk   z"RevenueSubHead.get_delete_instance   rl   r#   c                 n    | j                   j                  d      j                         }t        d|      S rn   )itemsr+   rr   r   rs   s     r   
item_countzRevenueSubHead.item_count   s1    

!!D!1779UW\]]r#   Items)rH   rI   rJ   ru   r   ry   r5   CASCADErK   r   rv   r   r0   rw   rx   rN   rR   r\   r_   rd   rg   rk   r   r|   r}   r~   s   @r   r   r   w   s     6.. ~&	D 6s?9KLD6r$UVWeUfgD"&""Am<LMK- -&,5MO^ $%W:J  r#   r   c                       e Zd ZdZ ej
                  eej                  d ed            Z	 ej                  d ed            Z ej                  dd	d
 ed            Z ej                  d	 ed            Z ej
                  eej                   d	d	d ed       ed            Z G d d      Z fdZd Zd Zd Zd Zd Zd Z ed      e_         xZS )RevenueItemz
    Leaf-level revenue line item (e.g. 'MCS', 'Pregnancy Scan').
    Optionally maps to a BudgetItem for budget-vs-actual analysis.
    r   r   r   r6   z	Item Namer   (   TFr;   r<   r>   r?   revenue_itemszLinked Budget ItemzQOptional. Links this revenue item to a budget item for budget-vs-actual analysis.)rA   rB   r@   r   r9   rC   c                   >    e Zd Z ed      Z ed      Zg dZddggZy)RevenueItem.MetaRevenue ItemzRevenue Items)sub_head__head__namesub_head__namer   sub_headr   Nr   r   r#   r   rN   r      s)    (0E&/0r#   rN   c                    | j                   st        j                  j                  | j                  | j                  j                         j                  d      j                         }|r*	 t        |j                   j                  dd      d         }nd}| j                  j                    d|dz   d| _         t        | ,  |i | y # t        $ r d}Y Aw xY w)N)r   code__startswithr0   r   r   r   03d)r0   r   r*   r+   r   order_bylastintrsplit
ValueErrorrQ   rR   )rS   rT   rU   r   last_seqrV   s        r   rR   zRevenueItem.save   s    yy##**!]]T]]=O=O +  &!  !"499#3#3C#;B#?@H ==--.a1S/ABDId%f% " ! H!s   -(C CCc                 :    d| j                    d| j                   S rX   rZ   r[   s    r   r\   zRevenueItem.__str__   r]   r#   c                     t        d      S )Nzrevenue-item-listr   r[   s    r   r_   zRevenueItem.get_absolute_url   r`   r#   c                 4    t        dd| j                  i      S )Nzrevenue-item-editr)   rb   rc   r[   s    r   rd   zRevenueItem.get_update_url   re   r#   c                 4    t        dd| j                  i      S )Nzrevenue-item-deleter)   rb   rc   r[   s    r   rg   zRevenueItem.get_delete_url   rh   r#   c                     | j                   S rj   r(   r[   s    r   rk   zRevenueItem.get_delete_instance   rl   r#   c                 N    | j                   j                         }t        d|      S )Nrp   )recordsrr   r   rs   s     r   record_countzRevenueItem.record_count   s#    ""$UW\]]r#   Records)rH   rI   rJ   ru   r   ry   r   r   rK   r   rv   r   r0   rw   rx   r   rz   budget_itemrN   rR   r\   r_   rd   rg   rk   r   r|   r}   r~   s   @r   r   r      s    
 !v  ..)*	H 6s;HD6r$UVWeUfgD"&""Am<LMK#&##//$+,ghK1 1&&,1IK^ &'y\L""r#   r   c                  ^   ddl m}  | j                         j                  }d| d}t        j
                  j                  |      j                  d      j                         }d}|r+	 t        |j                  j                  d      d         dz   }| |d	S # t        t        f$ r Y w xY w)
z(Auto-generate reference: REV-YYYY-NNNNNNr   )datezREV-r   )reference_number__startswithreference_numberr   r   06d)datetimer   todayyearRevenueRecordr*   r+   r   r   r   r   r   r   
IndexError)r   r   prefixr   seqs        r   _generate_rev_referencer     s    ::<DD6^F$$&$I	$	%	 	
 C	d++11#6r:;a?C Xc#Y J' 		s   )*B B,+B,c            
       2    e Zd ZdZ ej
                  ddd ed            Z ej                  e	ej                  d ed      	      Z ej                  eej                  dd ed
            Z ej                  dd ed            Z ej"                   ed            Z ej&                  d ed            Z ej                  eej                  ddd ed            Z G d d      Z fdZd Zd Zd Zd Zd Zd Z ed      e_         xZ S ) r   zG
    An actual revenue transaction recorded against a RevenueItem.
    r   TFzReference No.r<   r   r   r   r
   )rA   rB   r@   r9      r'   u   Amount (₦))
max_digitsdecimal_placesr9   zTransaction Date)r9   r>   r?   revenue_records_recordedzRecorded By)rA   rB   r=   r   r9   c                   4    e Zd Z ed      Z ed      ZddgZy)RevenueRecord.MetazRevenue RecordzRevenue Recordsz-transaction_datez-created_atNrG   r   r#   r   rN   r   9  s#    )* 12'7r#   rN   c                 Z    | j                   st               | _         t        |   |i | y rj   )r   r   rQ   rR   )rS   rT   rU   rV   s      r   rR   zRevenueRecord.save>  s(    $$$;$=D!d%f%r#   c                 j    | j                    d| j                  dd| j                  j                   dS )Nu    — ₦z,.2fz ())r   amountitemr0   r[   s    r   r\   zRevenueRecord.__str__C  s3    ''(T0B"TYY^^DTTUVVr#   c                     t        d      S )Nzrevenue-record-listr   r[   s    r   r_   zRevenueRecord.get_absolute_urlJ  s    122r#   c                 4    t        dd| j                  i      S )Nzrevenue-record-editr)   rb   rc   r[   s    r   rd   zRevenueRecord.get_update_urlM  rh   r#   c                 4    t        dd| j                  i      S )Nzrevenue-record-deleter)   rb   rc   r[   s    r   rg   zRevenueRecord.get_delete_urlP  r   r#   c                     | j                   S rj   r(   r[   s    r   rk   z!RevenueRecord.get_delete_instanceS  rl   r#   c                 .    t        d| j                        S )Nu
   ₦{:,.2f})r   r   r[   s    r   amount_displayzRevenueRecord.amount_displayV  s    <55r#   )!rH   rI   rJ   ru   r   rv   rK   r   ry   r   PROTECTr   r
   rz   
departmentDecimalFieldr   	DateFieldtransaction_daterw   rx   r   recorded_byrN   rR   r\   r_   rd   rg   rk   r   r|   r}   r~   s   @r   r   r     sB    (v''dU?AS 6..~&	D #""//|_J !V  aa6GF (v''Q7I5JK"&""Am<LMK#&##///}%K8 8
&
W3KM6 ()'8N$$r#   r   )   )r0   N)ru   r   django.contrib.auth.modelsr   r   	django.dbr   django.urlsr   django.utils.htmlr   django.utils.translationr	   rK   base.modelsr
   budget.modelsr   horilla.modelsr   strr   r"   r3   r5   r   r   r   r   r   r#   r   <module>r      s    
 2  $ ) 6 " $ 'S 3 s s  SV &36, 36v3.\ 3.vI2, I2b &C9L C9r#   