
    k)i                         d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	 de
fdZdee
   defd	Zdd
edefdZ	 	 	 	 dde	dededee
   dededefdZdde	dede
fdZy)z8
Utility functions specific to payment requests module.
    N)Optional)select)Sessionreturnc                    | syt        | d      r| j                  r| j                  S t        | dd      xs d}t        | dd      xs d}|r|r| d| j                         S |r|j                         S |r|j                         S t        | d      r| j                  r| j                  S t        | d      r| j
                  r| j
                  S y)	z
    Get the full name of a user from a user object.
    
    Args:
        user_obj: User object with first_name, last_name, or full_name attributes
        
    Returns:
        Full name string or fallback identifier
    zUnknown User	full_name
first_name 	last_name usernameemail)hasattrr   getattrstripr   r   )user_objr	   r   s      g/var/www/html/hwPaymentPortal-be-dev/hw-payment-portal-api/src/apps/payment_requests/utils/functions.pyget_full_namer      s      x%(*<*<!!! <4:J+r28bIiQyk*0022	!!	   x$):):   	7	#~~    user_agent_stringc                 `   | s	dddddddS | j                         d}dv rd}ndv rd}nd	v rd
}ndv rd}ndv rd}d}dv rd}n#dv rd}ndv rd}ndv rd}ndv sdv sdv rd}t        fddD              }t        fddD              }|xs | }d}|rd }n|rd!}||||||dS )"z
    Extract device details from user agent string.
    
    Args:
        user_agent_string: HTTP User-Agent header string
        
    Returns:
        Dictionary containing device details
    UnknownFT)browserosdevice	is_mobile	is_tablet
is_desktopchromeChromefirefoxFirefoxsafariSafariedgeEdgeoperaOperawindowsWindowsmacmacOSlinuxLinuxandroidAndroidiosiphoneipadiOSc              3   &   K   | ]  }|v  
 y wN .0keyword
user_agents     r   	<genexpr>z%get_device_details.<locals>.<genexpr>c         gGz)    )mobiler/   r2   ipod
blackberryzwindows phonec              3   &   K   | ]  }|v  
 y wr6   r7   r8   s     r   r<   z%get_device_details.<locals>.<genexpr>g   r=   r>   )tabletr3   kindlesilkplaybookDesktopMobileTablet)lowerany)r   r   os_namer   r   r   device_typer;   s          @r   get_device_detailsrN   2   sJ     
 	
 #((*J G:	j	 	Z		:		J	 GJ	*		J		j	 	*	J 6&J:N   :  I   :  I  ,9-JK	   r   decimalsc                 `    t        | d|z  z  dz         d|z  z  }|dz  dk(  rt        |      }|S )z
    This function rounds a number half up. Eg. 18.5 will round to 19
    
    Args:
        number: Number to round
        decimals: Number of decimal places
        
    Returns:
        float: Rounded number
    
   g      ?   r   )int)numberrO   rounded_values      r   round_half_uprV   }   sB     "h,/#56"h,GMqAM*r   dbpayment_request_idamount
invoice_idtipshipping_amountc                 d   ddl m} ddlm} t	        j
                  t              }	 t        |      j                  |j                  |k(        }	| j                  |	      }
|
j                         }|s|j                  d| d       |xs dS |xs |j                  }||j                  xs dz  }||z  }||z  }t        |      j                  |j                  |k(        }	| j                  |	      }
|
j!                         j#                         }|D ]  }|j$                  dk(  r1|j&                  r||j                  dz  z  }n|j                  }||z  }C|j$                  d	k(  r1|j&                  r||j                  dz  z  }n|j                  }||z  }|j$                  d
k(  s||j                  z  } |j(                  r&|j(                  dkD  r||j(                  dz  z  }||z  }t+        |d      }t-        |d      S # t.        $ r'}|j1                  d| d|        |xs dcY d}~S d}~ww xY w)ac  
    Calculate final amount including adjustments, tips, and fees
    
    Args:
        db: Database session
        payment_request_id: Payment request ID
        amount: Base amount
        invoice_id: Optional invoice ID
        tip: Tip amount
        shipping_amount: Shipping amount
        
    Returns:
        float: Final calculated amount
    r   PaymentRequest)PaymentRequestAdjustmentszPayment request z
 not foundg        discountd   feelate_fee   z3Error calculating final amount for payment request z: N)0src.apps.payment_requests.models.payment_requestr_   <src.apps.payment_requests.models.payment_request_adjustmentsr`   logging	getLogger__name__r   whereidexecutescalar_one_or_nonewarningrY   shipping_feerX   scalarsalladjustment_typeis_percentagetax_percentmaxrV   	Exceptionerror)rW   rX   rY   rZ   r[   r\   r_   r`   loggerstmtresultpayment_requestfinal_amountadjustments
adjustmentdiscount_amount
fee_amount
tax_amountes                      r   get_final_amountr      sI   , Pfx(F8 n%++N,=,=AS,STD! 335NN-.@-ALM=S  7!7!7 	44;;' 	 /066%88<NN
 D!nn&**,% 	2J))Z7++&2j6G6G#6M&NO&0&7&7O/++u4++!-1B1BS1H!IJ!+!2!2J
*++z9
 1 11	2" &&?+F+F+J%)D)Ds)JKJJ&L <-\1-- JK]J^^`ab`cde}s,   A$G? DG? $AG? ?	H/H*$H/*H/lengthc                    ddl m} ddlm} d}t	        |      D ]  }dj                  t        j                  t        j                  t        j                  z   |            }t        |      j                  |j                  |k(        }| j                  |      }|j                         }	|	r|c S   ||      j!                         S )z
    Generate unique payment request literal
    
    Args:
        db: Database session
        length: Length of the literal
        
    Returns:
        str: Unique payment request literal
    r   r^   )generate_secure_idrb   r
   )k)r   )rf   r_   src.apps.base.utils.functionsr   rangejoinrandomchoicesstringascii_uppercasedigitsr   rk   payment_request_literalrm   rn   upper)
rW   r   r_   r   max_attempts_literalrz   r{   existings
             r   'generate_unique_payment_request_literalr      s     P@L<  
''&..)?)?&--)OSYZ[ n%++N,R,RV],]^D!,,.N
 V,2244r   )r   )r   Nr   r   )	   )__doc__rh   r   r   typingr   
sqlalchemyr   sqlalchemy.ormr   strr   dictrN   rS   floatrV   r   r   r7   r   r   <module>r      s         ""s "JH(3- HD HVC  (  $SSS S 	S
 
S S Sl5 5 5S 5r   