
    $1i                        d 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 ddl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mZ dd
l m!Z!m"Z" ddl#m$Z$m%Z%m&Z& ddl'm(Z( ddl)m*Z+m,Z-m.Z/m0Z1m2Z3m4Z5m6Z7m8Z9m:Z:m;Z;m<Z=m>Z?m@ZA ddlBmCZCmDZDmEZEmFZFmGZG ddlHmIZImJZJmKZKmLZLmMZM ddlNmOZPmQZRmSZTmUZVmWZX ddlYmZZZm[Z[ ddl\m]Z]m^Z^ ddl_m`Z`  e       Za ej                  ec      Zdeaj                  deefef   ej                         e	e      ddededefd       Z,eaj                  deefef          e	e      ddededefd       Z@eaj                  deefef          e	        e	        e	e      fded ededefd!       Z.eaj                  d"eefef          e	e      fdedefd#       Zieaj                  d$eefef          e	e       ed%d&d%'       edd(d)'       edd*d+'       ed,d-d.d/d,0      fded1ejd2eef   d3eef   d4ekdefd5       Zleaj                  d6eefef          e	e       edd7d8'      fd9efded:eef   defd;       Z*eaj                  d6eefef          e	e      fd9efd<ededefd=       Z2eaj                  d6eefef          e	e      fd9efdedefd>       Z4eaj                  d?eefef   ej                         e	e      fd9efd@e"dedeefef   fdA       Zoeaj                  d?eefef          e	e       ed-d-dBd-C       ed,d-dDdEd,0       eddFdGg dHI       eddJdK'       eddLdK'       eddMdN'      fd9efdedOekdPekdQeef   dReej   dSeej   dTeef   deefef   fdU       Zpeaj                  dVeefef          e	e      fd9efdWekdedeefef   fdX       Zqeaj                  dVeefef          e	e      fd9efdWekd@erdedeefef   f
dY       Zseaj                  dVeefef          e	e      fd9efdWekdedeefef   fdZ       Zteaj                  d[eefef   ej                         e	e      fd9efd\e%dedeefef   fd]       Zueaj                  d[eefef          e	e       ed-d-dBd-C       ed,d-dDdEd,0       eddJdK'       edd^d_'       edd`da'       eddbdc'      fd9efdedOekdPekdReej   dTeef   ddeef   deeef   deefef   fdf       Zveaj                  dgeefef          e	e      fd9efdhefdedeefef   fdi       Zweaj                  dgeefef          e	e      fd9efdhefd\e&dedeefef   f
dj       Zxeaj                  dgeefef          e	e      fd9efdhefdedeefef   fdk       Zyeaj                  dleefef          e	e      dded9efdefdm       Z<eaj                  dneefef   dodpdqdrdsdtdKdrd-dudvdvdd-d-dwdxdydzd{gd-d-d,ddd|d}iid~ddiddid       eddd'       ed,d-dDdEd,0       eddddC       eddd'       e	e      fd9efd4ekdekdTeef   dedeefef   fd       ZOeaj                  dneefef   ej                  dddddsdtdKdd-dudvdvdd-d-dwdxdydzd{diid~ddiddiddid       eddd'       edd       e	e      fd9efde]dedeefef   fd       ZQeaj                  deefef   dddddsdtdKdd-dudvdvdd-d-dwdxdydzd{diid~ddiddid       eddd'       eddd-'       e	e      fd9efdekdedeefef   fd       ZWeaj                  deefef   dddddsdtdKdd-ddvddd-d-dwdxdydzd{diid~ddiddiddid       eddd'       eddd-'       edd       e	e      fd9efdekde^dedeefef   f
d       ZSeaj                  deefef   dddddsdtdKdddiid~ddiddid       eddd'       eddd-'       e	e      fd9efdekdedeefef   fd       ZUy)z>
Customer router for handling customer-related API endpoints.
    )ListOptionalDictUnionAny)	APIRouterDependsHTTPExceptionstatusQueryPathBody)SessionN)get_session)APIException)CustomerSchemaCustomerListSchema)CustomerCreateRequestSchemaCustomerUpdateRequestSchemaCustomerActionRequestSchemaCustomerBulkActionRequestSchemaCustomerFilterSchemaCustomerPaginationSchema)AddressSchemaAddressCreateRequestSchema)CustomerContactSchema"CustomerContactCreateRequestSchema"CustomerContactUpdateRequestSchema)User)get_customercreate_customerget_customers_listget_customer_by_emailupdate_customerdelete_customeractivate_customerdeactivate_customercheck_customer_id_existscheck_account_literal_existsget_customer_activitiesget_customer_summarybulk_customer_actions)create_customer_addressget_customer_addressesget_customer_addressupdate_customer_addressdelete_customer_address)create_customer_contactget_customer_contactsget_customer_contactupdate_customer_contactdelete_customer_contact)get_customer_notescreate_customer_noteupdate_customer_notedelete_customer_noteget_customer_note)NoteResponseSchemaNoteListResponseSchema)NoteCreateRequestSchemaNoteUpdateRequestSchema)generate_id )response_modelstatus_code)dbrD   customer_inreturnc                    K   t        | |       d{   \  }}|t        t        j                  |      d|t	        |d      r|j                         dS |dS 7 Hw)ac  
    Create new customer.
    
    The system supports two ways to handle account literals:
    1. User-provided: Include 'account_literal' field (15 characters) - system will validate uniqueness
    2. Auto-generated: Leave 'account_literal' empty - system will generate a unique account literal
    
    Use /customers/account-suggestions to get suggested account literals before creation.
    
    Note: All validation (email uniqueness, account literal format, etc.) is handled by Pydantic validators.
    Note: customer_id is for internal use only, account_literal is the public-facing account number.
    )customer_dataNrC   detailT
model_dumpsuccessmessagedata)create_customer_servicer
   r   HTTP_400_BAD_REQUESThasattrrK   )rD   rE   customerrN   s       W/var/www/html/hwPaymentPortal-be-dev/hw-payment-portal-api/src/apps/customers/router.pyr!   r!   ^   sy     & 6bTTHg33
 	
 )0<)H##%  OW  Us   AAA	Az/actions)rB   action_requestc                   K   	 t        | |j                  |j                         d{   }|d   dk(  }|rd|d    d|j                   d}nd	|d    d
|d    d}|||dS 7 :# t        $ r&}t	        |j
                  |j                        d}~wt        $ r8}t        j                  d|        t	        t        j                  d      d}~ww xY ww)a  
    Perform bulk actions on multiple customers.
    
    Limit- Maximum 10 customers per request for performance optimization.
    
    Available actions:
    - activate: Enable customers and restore soft-deleted ones
    - deactivate: Disable active customers  
    - delete: Soft delete customers
    
    For single customers, pass one ID in the ids array.
    Returns detailed success/failure results for each customer.
    )rD   actioncustomer_idsNfailed_countr   zAll success_countz customers were successfully dzBulk action completed: z succeeded, z failedrL   rI   z+Unexpected error in bulk customer actions: z:An unexpected error occurred while processing bulk actions)bulk_customer_actions_servicerW   idsr   r
   rC   rN   	Exceptionloggingerrorr   HTTP_500_INTERNAL_SERVER_ERROR)rD   rU   resultsoverall_successrN   es         rT   r,   r,      s    & 
5!(('++
 
 ".1Q6W_566STbTiTiSjjklG/0H/IV]^lVmUnnuvG '
 	

(  
99
 	
  
CA3GH==O
 	

sD   C%A& A$9A& #C$A& &	C/!BC3CCC
paginationfiltersc           	        K   | j                   dz
  | j                  z  }|j                  dk7  r|j                  nd|_        |j                  dk7  r|j                  nd|_        t	        ||| j                  |d       d{   }d|d   |d   |d   |d	   |d   |d	   z   dz
  |d	   z  |d
   du|d   dud|d
   |d   |d   |d   ddS 7 Kw)z_
    Retrieve customers with filtering and pagination using schema-based query parameters.
       r   NT)rD   rf   limitoffsetpaginaterO   totalpageper_pagenextprevious)rl   rm   rn   total_pageshas_nexthas_previousfirstlast)ro   rp   rt   ru   )rM   rO   metalinks)rm   rn   	is_active	is_vendorget_customers_list_service)re   rf   rD   rj   pagination_results        rT   r"   r"      s#     oo!Z%8%88F .5->->!-C))G-4->->!-C))G 9!!  !&)&w/%f-)*5-g69J:9VVYZZ_pq{_||)&1=-j9E
 &f-)*5&w/%f-	
 s   A>C CACz/account-suggestionsc                   K   	 g }d}d}t        |      dk  rR||k  rMt        d      }t        | |       d{   s||vr|j                  |       |dz  }t        |      dk  r||k  rMt        |      dk  r%t        j                  dt        |       d| d       d	d
t        |       d|ddddddS 7 # t        $ r8}t        j                  d|        t        t        j                  d      d}~ww xY ww)a0  
    Generate four unique 15-character account literal suggestions.
    
    Returns four automatically generated account literals that are:
    - Exactly 15 characters long
    - Follow a consistent pattern
    - Validated against database for uniqueness
    - Used as public-facing account numbers
       r   rh   rS   NzCould only generate z unique suggestions after z	 attemptsTz
Generated z account literal suggestions   z9ACC + 3-char identifier + 6-digit timestamp + 3-char UUIDACCM7X123456ABC)lengthformatexample)suggestionspattern_inforL   z&Error generating account suggestions: z&Failed to generate account suggestionsrI   )lenr@   r)   appendloggerwarningr^   r`   r
   r   ra   )rD   r   max_attemptsattemptsaccount_literalrd   s         rT   get_account_suggestionsr      s0    '
+"x,'>)*5O 6b/JJJ"+5&&7MH +"x,'> {aNN1#k2B1CC]^j]kktuv #C$4#55QR* Y0!
 	
 K.  
=aSAB==;
 	

s?   C=3B9 B71B9 *AB9 6C=7B9 9	C:3C55C::C=z/summaryFzFInclude vendor statistics: true=vendor summary, false=customer summary)descriptionr   z5Start date for summary statistics (YYYY-MM-DD format)z
2024-01-01z3End date for summary statistics (YYYY-MM-DD format)z
2024-12-31
   rh   2   z(Number of top/lowest customers to return)geler   r   ry   	date_fromdate_tori   c                 6  K   	 t        | |       d{   }|S 7 # t        $ r&}t        |j                  |j                        d}~wt
        $ rD}t        j                  d|        t        t        j                  dt        |             d}~ww xY ww)z
    Get customer summary statistics.
    
    Returns summary data including top customers, lowest customers, and most frequent customers.
    Currently returns static data for demonstration purposes.
    NrI   z!Error fetching customer summary: Internal server error: )get_customer_summary_servicer   r
   rC   rN   r^   r   r`   r   ra   str)rD   ry   r   r   ri   summary_datard   s          rT   get_customer_summary_endpointr     s     
9"iHH I 
99
 	
  
8<===,SVH5
 	

s<   B  B 	B!AB?BBBz/{customer_id}z]Comma-separated list of related fields to include: addresses, contacts, merchant, attachmentszaddresses,contactscustomer_idfieldsc                    K   	 t        || |       d{   }ddt        |d      r|j                         dS |dS 7 (# t        $ r&}t	        |j
                  |j                        d}~ww xY ww)z
    Get customer by ID with optional related fields.
    
    By default, no related fields are loaded for better performance.
    Use the 'fields' parameter to specify which relationships to include.
    r   r   NTzCustomer foundrK   rL   rI   )get_customer_servicerR   rK   r   r
   rC   rN   )r   rD   r   rS   api_excs        rT   r    r    7  s     
-bkRXYY'-4X|-LH'')
 	
 S[
 	
 Z  
++??
 	

?   A2A  >#A  A2A  A2A   	A/	!A**A//A2customer_updatec                    K   	 t        || |       d{   }ddt        |d      r|j                         dS |dS 7 (# t        $ r&}t	        |j
                  |j                        d}~ww xY ww)z 
    Update customer by ID.
    )r   rH   NTzCustomer updated successfullyrK   rL   rI   )update_customer_servicerR   rK   r   r
   rC   rN   )r   r   rD   updated_customerr   s        rT   r$   r$   S  s     
!8ds!tt65<=M|5\$//1
 	
 cs
 	
 u  
++??
 	

r   c                 f  K   	 t        || d       d{   }t        ||        d{   }|st        t        j                  d      dd	d
S 7 ;# t        $ rP}|j                  dk(  rt        t        j
                  d      t        |j                  |j                        d}~ww xY w7 w)z.
    Delete (soft delete) customer by ID.
    Nr     Customer not foundrI   )r   zFailed to delete customerTzCustomer deleted successfullyrM   rN   )	r   r   rC   r
   r   HTTP_404_NOT_FOUNDrN   delete_customer_servicerQ   )r   rD   existing_customerrd   rM   s        rT   r%   r%   j  s     
"6r{[_"`` ,BKHHG33.
 	
 2 + a 	
==C"55+  99
 	
	
 IsB   B1A AA B1B/&B1A 	B,AB''B,,B1z/{customer_id}/addressesaddress_datac                   K   	 t        || |       d{   }ddt        |d      r|j                         dS |dS 7 (# t        $ r&}t	        |j
                  |j                        d}~wt        $ rG}t        j                  d|  d|        t	        t        j                  d	t        |             d}~ww xY ww)
z>Create a new address for a customer with use_as_default=False.NTzAddress created successfullyrK   rL   rI   z$Error creating address for customer : r   )r-   rR   rK   r   r
   rC   rN   r^   r   r`   r   ra   r   )r   r   rD   addressrd   s        rT    create_customer_address_endpointr          
/KNN5,3G\,JG&&(
 	
 QX
 	
 O  
99
 	
  
;K=1#NO==,SVH5
 	

G   B?? =#? B?? B?? 	B<!A))B<5AB77B<<B?zPage number for pagination)r   r   r   d   z"Number of items per page (max 100)zFilter by address typebilling)r   shippinglegalmailing)r   r   enumz>Filter by active status: true=active only, false=inactive onlyTz Filter by default address statusz0Search in address lines, city, state, or countryzNew Yorkrm   rn   address_typerx   use_as_defaultsearchc                   K   	 |}|dz
  |z  }	t        || ||	||||       d{   }
dd|
d    d|
d   |
d   |
d	   |
d
   |
d   |
d   |
d   |
d   ddS 7 2# t        $ r&}t        |j                  |j                        d}~wt
        $ rG}t        j                  d|  d|        t        t        j                  dt        |             d}~ww xY ww)zAGet paginated list of customer addresses with optional filtering.rh   )rD   r   ri   rj   r   rx   r   r   NTFound rl   z
 addressesrO   rm   rn   ro   rp   rt   ru   rl   rm   rn   ro   rp   rt   ru   rM   rN   rO   rv   rI   z%Error listing addresses for customer r   r   )r.   r   r
   rC   rN   r^   r   r`   r   ra   r   )r   rD   rm   rn   r   rx   r   r   ri   rj   resultrd   s               rT   list_customer_addressesr     s    '
(h&-#%)	
 	
 w0
;6Nv":.v":.v	
 	
	
0  
99
 	
  
<[MA3OP==,SVH5
 	

E   C A A1A CA 	C"!BCACCCz%/{customer_id}/addresses/{address_id}
address_idc           	        K   	 t        || |       d{   }ddt        |d      r|j                         dS |dS 7 (# t        $ r&}t	        |j
                  |j                        d}~wt        $ rJ}t        j                  d| d|  d	|        t	        t        j                  d
t        |             d}~ww xY ww)z,Get a specific address by ID for a customer.NTzAddress foundrK   rL   rI   zError getting address  for customer r   r   )r/   rR   rK   r   r
   rC   rN   r^   r   r`   r   ra   r   )r   r   rD   r   rd   s        rT   get_customer_address_endpointr          
,RjII&,3G\,JG&&(
 	
 QX
 	
 J  
99
 	
  
-j\}TVWXVYZ[==,SVH5
 	

G   C? =#? C? C? 	B?!A))B?5AB::B??Cc           	        K   	 t        || ||       d{   }ddt        |d      r|j                         dS |dS 7 (# t        $ r&}t	        |j
                  |j                        d}~wt        $ rJ}t        j                  d| d|  d	|        t	        t        j                  d
t        |             d}~ww xY ww)z4Update a customer address with partial or full data.NTzAddress updated successfullyrK   rL   rI   zError updating address r   r   r   )r0   rR   rK   r   r
   rC   rN   r^   r   r`   r   ra   r   )r   r   r   rD   r   rd   s         rT    update_customer_address_endpointr          
/K\ZZ5,3G\,JG&&(
 	
 QX
 	
 [  
99
 	
  
.zl.UWXYWZ[\==,SVH5
 	

L   CA  >#A  CA  CA   	C 	!A**C 6AB;;C  Cc           	      J  K   	 t        || |       d{    dddS 7 	# t        $ r&}t        |j                  |j                        d}~wt
        $ rJ}t        j                  d| d|  d|        t        t        j                  d	t        |             d}~ww xY ww)
z/Soft delete a customer address with validation.NTzAddress deleted successfullyr   rI   zError deleting address r   r   r   )r1   r   r
   rC   rN   r^   r   r`   r   ra   r   )r   r   rD   rd   s       rT    delete_customer_address_endpointr          
%b+zBBB5
 	
 	C
  
99
 	
  
.zl.UWXYWZ[\==,SVH5
 	

=   B#    B#  	B !A

B ABB  B#z/{customer_id}/contactscontact_datac                   K   	 t        || |       d{   }ddt        |d      r|j                         dS |dS 7 (# t        $ r&}t	        |j
                  |j                        d}~wt        $ rG}t        j                  d|  d|        t	        t        j                  d	t        |             d}~ww xY ww)
z$Create a new contact for a customer.NTzContact created successfullyrK   rL   rI   z$Error creating contact for customer r   r   )r2   rR   rK   r   r
   rC   rN   r^   r   r`   r   ra   r   )r   r   rD   contactrd   s        rT    create_customer_contact_endpointr   3  r   r   z9Search across contact name, email, title, or phone numberjohnz+Filter by contact job title (partial match)ManagerzFilter by contact relation typeprimarytitlerelationc                   K   	 |}|dz
  |z  }	t        || ||	||||       d{   }
dd|
d    d|
d   |
d   |
d	   |
d
   |
d   |
d   |
d   |
d   ddS 7 2# t        $ r&}t        |j                  |j                        d}~wt
        $ rG}t        j                  d|  d|        t        t        j                  dt        |             d}~ww xY ww)z@Get paginated list of customer contacts with optional filtering.rh   )rD   r   ri   rj   rx   r   r   r   NTr   rl   z	 contactsrO   rm   rn   ro   rp   rt   ru   r   r   rI   z$Error listing contacts for customer r   r   )r3   r   r
   rC   rN   r^   r   r`   r   ra   r   )r   rD   rm   rn   rx   r   r   r   ri   rj   r   rd   s               rT   list_customer_contactsr   N  s    '
(h&,#	
 	
 w0	:6Nv":.v":.v	
 	
	
0  
99
 	
  
;K=1#NO==,SVH5
 	

r   z$/{customer_id}/contacts/{contact_id}
contact_idc           	        K   	 t        || |       d{   }ddt        |d      r|j                         dS |dS 7 (# t        $ r&}t	        |j
                  |j                        d}~wt        $ rJ}t        j                  d| d|  d	|        t	        t        j                  d
t        |             d}~ww xY ww)z4Get a specific contact by contact_id for a customer.NTzContact foundrK   rL   rI   zError getting contact r   r   r   )r4   rR   rK   r   r
   rC   rN   r^   r   r`   r   ra   r   )r   r   rD   r   rd   s        rT   get_customer_contact_endpointr     r   r   c           	        K   	 t        || ||       d{   }ddt        |d      r|j                         dS |dS 7 (# t        $ r&}t	        |j
                  |j                        d}~wt        $ rJ}t        j                  d| d|  d	|        t	        t        j                  d
t        |             d}~ww xY ww)z4Update a customer contact with partial or full data.NTzContact updated successfullyrK   rL   rI   zError updating contact r   r   r   )r5   rR   rK   r   r
   rC   rN   r^   r   r`   r   ra   r   )r   r   r   rD   r   rd   s         rT    update_customer_contact_endpointr     r   r   c           	      J  K   	 t        || |       d{    dddS 7 	# t        $ r&}t        |j                  |j                        d}~wt
        $ rJ}t        j                  d| d|  d|        t        t        j                  d	t        |             d}~ww xY ww)
z/Soft delete a customer contact with validation.NTzContact deleted successfullyr   rI   zError deleting contact r   r   r   )r6   r   r
   rC   rN   r^   r   r`   r   ra   r   )r   r   rD   rd   s       rT    delete_customer_contact_endpointr     r   r   z/{customer_id}/activitiesc                 <  K   	 t        | |       d{   }|S 7 # t        $ r&}t        |j                  |j                        d}~wt
        $ rG}t        j                  d| d|        t        t        j                  dt        |             d}~ww xY ww)z
    Get customer activities.
    
    Returns a list of activities for the specified customer.
    Currently returns static data for demonstration purposes.
    NrI   z'Error fetching activities for customer r   r   )get_customer_activities_servicer   r
   rC   rN   r^   r   r`   r   ra   r   )rD   r   activities_datard   s       rT   r*   r*     s     
 ?K PP Q 
99
 	
  
>{m2aSQR==,SVH5
 	

s=   B  B 	B!ABABBBz/{customer_id}/noteszGet Customer Notesz8Retrieve paginated list of notes for a specific customerz2Paginated list of customer notes with user detailsNotes retrieved successfullyzapplication/jsonr   z)Customer called regarding payment inquiryz2025-12-02T15:30:00.000ZAdminr   zadmin@example.com)id
first_name	last_nameemail)r   r   
created_at
updated_at
deleted_atcreated_by_id
created_by)rl   rm   rn   ro   rp   )rM   rN   rO   re   )r   contentr   r   Internal server error)   r     )rB   summaryr   response_description	responses.zCustomer ID (customer_id field)ACCKDU1537895E7z&Number of items to skip for paginationz2Search term to filter notes by description contentpaymentrj   c                 r  K   	 t        || |||       d{   }dd|d   |d   |d   |d   |d	   |d
   |d   |d   dddS 7 ,# t        $ r&}t        |j                  |j                        d}~wt
        $ r8}t        j                  d|        t        t        j                  d      d}~ww xY ww)a  
    Get paginated list of notes for a specific customer.
    
    Returns paginated notes associated with the customer, ordered by creation date (most recent first).
    Each note includes full details of the user who created it.
    
    **Features:**
    - Pagination support with configurable page size
    - Search functionality in note descriptions
    - Full user details for note creators
    - Ordered by creation date (newest first)
    
    **Parameters:**
    - **customer_id**: The customer's unique identifier
    - **limit**: Number of notes per page (1-100, default: 10)
    - **offset**: Number of notes to skip (default: 0)
    - **search**: Optional search term to filter notes
    )ri   rj   r   NTr   rO   rl   rm   rn   ro   rp   rt   ru   r   r   )rM   rN   rO   re   rC   rI   z(Unexpected error in get_customer_notes: r   )
get_customer_notes_servicer   r
   rC   rN   r^   r   r`   r   ra   )r   ri   rj   r   rD   r   r   rd   s           rT   r7   r7     s     L
15
 
 56Nv":.v":.v 
 	

$  
++??
 	
  
?sCD==*
 	

sD   B7A A+A B7A 	B4!A00B4<3B//B44B7zCreate Customer Notez)Create a new note for a specific customerz+Note created successfully with full detailsNote created successfullyrL   z&Invalid input data or validation error)     r   r   )rB   rC   r   r   r   r   z7Note creation data with description (1-2000 characters))r   	note_datac                 h  K   	 t        ddddd      }t        || ||       d{   }dd	|j                         d
dS 7 # t        $ r&}t	        |j
                  |j                        d}~wt        $ r8}t        j                  d|        t	        t        j                  d      d}~ww xY ww)a  
    Create a new note for a customer.
    
    Creates a new note associated with the specified customer.
    The note will be attributed to the currently authenticated user.
    
    **Features:**
    - Automatic user attribution to authenticated user
    - Description validation (1-2000 characters)
    - Customer existence validation
    - Returns full note details with user information
    
    **Request Body Example:**
    ```json
    {
        "description": "Customer called regarding payment inquiry and requested status update"
    }
    ```
    
    **Authorization Required:** Valid JWT token (currently uses placeholder user ID)
    rh   temp@example.com	temp_userTempr   r   r   usernamer   r   NTr   r   rM   rN   rO   rC   rI   z*Unexpected error in create_customer_note: r   )r   create_customer_note_servicerK   r   r
   rC   rN   r^   r   r`   r   ra   )r   r   rD   created_by_usernoter   rd   s          rT   r8   r8   X  s     D
 $ 
 2Y
 
 2OO%	
 	

  
++??
 	
  
A!EF==*
 	

sA   B2!A ?A B2A 	B/
!A++B/73B**B//B2z/{customer_id}/notes/{note_id}zGet Customer Notez(Get a specific note by ID for a customerz"Note details with user informationzNote found successfully
Note foundzCustomer or note not foundzNote ID to retrievenote_idc                 F  K   	 t        || |       d{   }dd|j                         ddS 7 # t        $ r&}t        |j                  |j
                        d}~wt        $ r8}t        j                  d|        t        t        j                  d      d}~ww xY ww)	a  
    Get a specific note by ID for a customer.
    
    Returns full details of the specified note, including the user who created it.
    
    **Features:**
    - Full note details with user information
    - Customer and note existence validation
    - Soft-delete awareness (won't return deleted notes)
    
    **Parameters:**
    - **customer_id**: The customer's unique identifier
    - **note_id**: The note's unique ID to retrieve
    NTr
  r   r  rI   z'Unexpected error in get_customer_note: r   )get_customer_note_servicerK   r   r
   rC   rN   r^   r   r`   r   ra   )r   r  rD   r	  r   rd   s         rT   r;   r;     s     n
.r;HH#OO%	
 	
 I  
++??
 	
  
>qcBC==*
 	

s<   B!0 .0 B!0 	B!AB&3BBB!zUpdate Customer Notez&Update an existing note for a customerz+Note updated successfully with full detailsNote updated successfullyzWUpdated note: Customer called regarding payment inquiry and provided additional detailsz2025-12-02T16:15:00.000Z)r   r   r   r   zNote ID to updatez5Note update data with description (1-2000 characters)c                 j  K   	 t        ddddd      }t        || |||       d{   }dd	|j                         d
dS 7 # t        $ r&}t	        |j
                  |j                        d}~wt        $ r8}t        j                  d|        t	        t        j                  d      d}~ww xY ww)a  
    Update an existing note for a customer.
    
    Updates the specified note with new data.
    Only the user who created the note or admin users should be able to update it.
    
    **Features:**
    - Description validation (1-2000 characters)
    - Customer and note existence validation
    - Automatic timestamp update
    - Full note details in response
    
    **Request Body Example:**
    ```json
    {
        "description": "Updated note: Customer called regarding payment inquiry and provided additional details"
    }
    ```
    
    **Authorization Required:** Valid JWT token (currently uses placeholder user ID)
    **Permissions:** Note creator or admin users
    rh   r  r  r  r   r  NTr  r   r  rI   z*Unexpected error in update_customer_note: r   )r   update_customer_note_servicerK   r   r
   rC   rN   r^   r   r`   r   ra   )r   r  r   rD   updated_by_userr	  r   rd   s           rT   r9   r9     s     F
 $ 
 2Wi
 
 2OO%	
 	

  
++??
 	
  
A!EF==*
 	

sC   B3"A A A B3 A 	B0!A,,B083B++B00B3zDelete Customer Notez!Soft delete a note for a customerzNote deleted successfullyzNote ID to deletec                 B  K   	 t        ddddd      }t        || ||       d{   }|S 7 # t        $ r&}t        |j                  |j
                        d}~wt        $ r8}t        j                  d	|        t        t        j                  d
      d}~ww xY ww)a  
    Delete a note for a customer.
    
    Soft deletes the specified note (sets deleted_at timestamp).
    Only the user who created the note or admin users should be able to delete it.
    
    **Features:**
    - Soft delete (preserves data with deleted_at timestamp)
    - Customer and note existence validation
    - Returns success confirmation
    
    **Parameters:**
    - **customer_id**: The customer's unique identifier
    - **note_id**: The note's unique ID to delete
    
    **Authorization Required:** Valid JWT token (currently uses placeholder user ID)
    **Permissions:** Note creator or admin users
    
    **Note:** This is a soft delete operation - the note will be marked as deleted but data is preserved in the database.
    rh   r  r  r  r   r  NrI   z*Unexpected error in delete_customer_note: r   )r   delete_customer_note_servicer   r
   rC   rN   r^   r   r`   r   ra   )r   r  rD   deleted_by_userr   r   rd   s          rT   r:   r:   m  s     d
 $ 
 4Wo
 
 
  
++??
 	
  
A!EF==*
 	

s<   B!. ,. B. 	B!AB$3BBB)z__doc__typingr   r   r   r   r   fastapir   r	   r
   r   r   r   r   sqlalchemy.ormr   r_   src.core.databaser   src.core.exceptionsr   *src.apps.customers.schemas.customer_commonr   r   ,src.apps.customers.schemas.customer_requestsr   r   r   r   r   r   src.apps.base.schemas.commonr   r   +src.apps.customers.schemas.customer_contactr   r   r   src.apps.users.models.userr   src.apps.customers.servicesr    r   r!   rP   r"   rz   r#   get_customer_by_email_servicer$   r   r%   r   r&   activate_customer_servicer'   deactivate_customer_servicer(   r)   r*   r   r+   r   r,   r\   #src.apps.customers.address_servicesr-   r.   r/   r0   r1   #src.apps.customers.contact_servicesr2   r3   r4   r5   r6   src.apps.notes.servicesr7   r   r8   r  r9   r  r:   r  r;   r  "src.apps.notes.schemas.note_commonr<   r=   $src.apps.notes.schemas.note_requestsr>   r?   src.core.functionsr@   router	getLogger__name__r   postr   HTTP_201_CREATEDgetr   boolintr   putdeleter   r   r   dictr   r   r   r   r   r   r        rT   <module>r7     s   4 3 P P P "  ) ,  S  ,   "   
 +				8	$ RS#XF<S<ST +& - 		 U@ ZS#X7 +&2
2
 42
 		2
 82
j BtCH~.+29$+I+&)()!) 	) 		) /)X "4S>B+&3
3
3
 C3
l JtCH~6+&E/w  BG  H$T7n  yE   F"45j  uA  BraB4^hjk


 }
 c]	

 
 	
 7
: T#s(^< +&!$  5T  ^r  s


 SM
 		
 =
6 T#s(^< +&

0
 	
 		
 =
, S#X? +&!!! 	! @!J 'S#XTZTkTkl +&

,
 	
 
#s(^	
 m
4 &tCH~F +&aA+GQRS"s8\fhi"':R\e  mX  #Y %d8x  CG  !H%*4=_im%n!$4fpz{2
2
2
 2
 	2

 3-2
 ~2
 TN2
 SM2
 
#s(^2
 G2
j 3DcNS +&


 	
 
#s(^	
 T
4 3DcNS
 +&	


 
 		

 
#s(^
 T
6 6tCQTH~V +&


 	
 
#s(^	
 W
4 &tCH~SYSjSjk +&

4
 	
 
#s(^	
 l
4 %d38nE +&aA+GQRS"s8\fhi %d8x  CG  !H!$4oy  A 3`jst#D6Wajk2
2
2
 2
 	2

 ~2
 SM2
 C=2
 sm2
 
#s(^2
 F2
j 24S>R +&


 	
 
#s(^	
 S
4 24S>R
 +&	


 5
 		

 
#s(^
 S
6 5d3PS8nU +&


 	
 
#s(^	
 V
2 'S#XG +&

 
 		
 H
8 S> JM :"#'#A '(/Z.H.H.212*+2917-@	/"!" &'$%(*$((,'' %!
D 1245I%  ,\ C-NXijraC5Ycefa-U_`a!$4hr{|+&6
6
6
 6
 SM	6

 	6
 
#s(^6
[,Z6
r S>''";F 7"#'#>"#+V*D*D*.-.&'.5-3)<	+! %
2 EF12459  %N C-NXij)-c?x)y+&;
;
&;
 	;
 
#s(^;
M%L;
| $S>:= 5"#'#/"#+V*D*D*.-.&'.5-3)<	+! %
2 9:457  #J C-NXij)>J+&%
%
%
 	%
 
#s(^	%
I#H%
P $S>"8F 7"#'#>"# ,E*D*D*.-.&'.5-3)<	+! %
2 EF9:459  $L C-NXij)<aH)-c?v)w+&	=
=
=
 '=
 		=
 
#s(^=
K$J=
@ $S>"34 7"#'#> $ %
 9:45  0 C-NXij)<aH+&5
5
5
 	5
 
#s(^5
/.5
r6  