
    1#3iҏ                        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	Z	d dl
mZ ddlmZmZmZmZmZ d d	lmZ d d
lmZ d dlmZ d dlZ ej.                  e      ZdedefdZd Zd Zd Zd Zd Z d Z!d Z"d Z#d Z$d Z%d Z&d Z'ddZ(y)    )transactionIntegrityErrormodels)Responsestatus   )CompanyHistoryNtimezone)CompanyOfficeHoursHolidaySalesTimingCompanyBotSettings)Userdatetime)urlparseurlreturnc                     | s| S t        d| v r| nd|        }|j                  j                         }|j                  d      r|dd }|j	                  d      S )ag  
    Normalize a website URL into a consistent comparable format.

    This function ensures all website URLs are stored and compared
    in a uniform way by removing protocol, 'www', trailing slashes,
    and converting to lowercase.

    Steps performed:
    1. Adds 'http://' if the URL has no scheme (so it can be parsed).
    2. Extracts the domain part (netloc) only.
    3. Removes 'www.' prefix if present.
    4. Converts to lowercase.
    5. Removes any trailing slashes.

    Example:
        >>> normalize_website("https://www.ABC.com/")
        'abc.com'
        >>> normalize_website("abc.com")
        'abc.com'
        >>> normalize_website("http://abc.com:8000/test")
        'abc.com:8000'

    Args:
        url (str): The website URL to normalize.

    Returns:
        str: Normalized domain (e.g. "abc.com") or the original value if empty/None.
    z://zhttp://zwww.   N/)r   netloclower
startswithrstrip)r   parsedr   s      =/var/www/html/dp2/backend_v2.1/server/apps/companies/utils.pynormalize_websiter!      s^    : 
Uc\c?F]]  "F ==    c                 @   ddl }ddlm} 	 t        j                  |       S #  Y nxY w|j                  d|       }|rTt        |j                  d            }t        |j                  d            }ddlm}  |||dk\  r|n|       } ||      S t        j                  S )	z
    Parse timezone string and return a valid timezone
    Handles formats like: '(GMT-09:00) Alaska' or 'US/Pacific'

    Args:
        timezone_string (str): Timezone string from database

    Returns:
        timezone object
    r   N)	timedeltazGMT([+-]\d{2}):(\d{2})r	      r   )hoursminutes)	rer   r$   pytzr   searchintgroupUTC)timezone_stringr(   r$   matchr&   r'   dt_timezoneoffsets           r    parse_timezone_offsetr2   6   s     "}}_-- II/AEEKKN#ekk!n%45A:G8T6"" 88Os   ! %c                    	 t         j                  j                  | d      }	 ddlm} t        |t              r	  |j                  |d	      }t        |j                        }|j                  t        j                  j                  |      }|j                  |      }|j!                         }|j#                         }|j%                  d      j'                         }t(        j                  j+                  |||d      j-                         }	|	rddd|	j.                   ddS 	 t0        j                  j                  ||      }
|
j4                  sddd|j3                          ddS |
j6                  |cxk  r|
j8                  k  r
n ndddddS dddddS # t         j                  $ r
 dddddcY S w xY w# t        $ r1 	  |j                  |d
      }n# t        $ r dddddcY cY S w xY wY w xY w# t0        j                  $ r ddd|j3                          ddcY S w xY w# t:        $ r}dddt        |      dcY d}~S d}~ww xY w)a  
    Check if office is open at a specific datetime (for Maya bot)

    Args:
        company_id (int): Company ID
        check_datetime (datetime or str): Datetime to check
            Can be:
            - datetime object: datetime(2025, 10, 1, 14, 30)
            - string: "2025-10-01 14:30" or "2025-10-01 14:30:00"

    Returns:
        dict: {
            'is_office_hours': bool,   # True if office is open, False if closed
            'is_holiday': bool,        # True if it's a holiday, False if not
            'message': str,            # Simple message
            'error': str               # Error message if any, None otherwise
        }
    T)id	is_activeFCompany not foundzCompany not found or inactive)is_office_hours
is_holidaymessageerrorr   r   z%Y-%m-%d %H:%M:%Sz%Y-%m-%d %H:%MzInvalid datetime formatzMDatetime string must be in format "YYYY-MM-DD HH:MM" or "YYYY-MM-DD HH:MM:SS"N%Acompanystart_date__lteend_date__gter5   z	Holiday: r=   dayzNo office hours configured for zOffice closed on zOffice is openzOutside office hourszAn error occurred)r   objectsgetDoesNotExistr   
isinstancestrstrptime
ValueErrorr2   r   tzinfor)   utclocalize
astimezonedatetimestrftimer   r   filterfirstr9   r   
capitalizeis_open
start_timeend_time	Exception)
company_idcheck_datetimer=   r   company_timezonecheck_time_company
check_datecheck_time_only	check_dayholidayoffice_hourses               r    #check_maya_office_hours_by_datetimera   X   s   (	
//%%t%D[
%nc*!2!2!2>CV!W 11A1AB   (!XX..~>N+667GH',,.
,113&//5;;=	 //((&$	 ) 

 %' 	 #("&w&78	 	&..22 3 L ###(#.y/C/C/E.FG	  ""oN9N9NN#'#+	  $)#1	 m  
$*4	
 	

  	%6X%6%6~GW%XN! +0&+#<!p	  #	Z '' 	#(#<Y=Q=Q=S<TU	 	B  
$*V	
 	

s   !F H) F; CH) &!G8 #H) +(H) H) F87F8;	G5GG5G.)G5+H) -G..G51H) 4G55H) 8+H&#H) %H&&H) )	I2IIIc                     	 t         j                  j                  | d      }|j                  }t	        j
                  |j
                        }t        j                         j                  |      }t        |j                         j                         dz        }d}|j                         }t        j                  j                  ||||d      j                         }|rd}t        j                  j                  |dd      j                         }	|	r3|	j                   |j#                         cxk  xr |	j$                  k  nc }
nd}
t&        j                  j                  |d      j)                  d	      }g }|D ]  }t+        |d	      s|j,                  j.                  s'|j,                  j0                   d
|j,                  j2                   j5                         }|j7                  | d|j8                           |rdj;                  |      nd}|
||r|j<                  nd||j>                  |dS # t         j@                  $ r ddddddcY S t        j@                  $ r ddddddcY S tB        $ r}ddddddcY d}~S d}~ww xY w)z8
    Check if it's sales time based on phone number
    Tphone_numberr5     Fr=   botsr>   r?   r5   hazelr=   botr5   	companiesr5   profile 	 have id , No advisor dataNo holiday today.)r7   r8   holiday_messagetimezone_offsetcompany_nameadvisor_data i)r7   r8   rs   rt   rv   )r7   rt   r8   rs   rv   N)"r   rB   rC   r=   r)   r   nowrL   r+   	utcoffsettotal_secondsrM   r   rP   rQ   r   rT   rN   rU   r   select_relatedhasattrrm   rd   
first_name	last_namestripappendr4   joinr9   namerD   rV   )rd   rj   r=   rY   current_timert   r8   todayr^   sales_timingis_sales_timecompany_usersadvisor_listuseradvisor_namerv   r`   s                    r    check_sales_time_by_phoner      s~   M
 ((,,,RV,W++==)9)9:||~001ABl446DDFMN
!!#//((! ) 
 %' 	 J"**11'wZ^1_eeg(33|7H7H7JclNcNccM!M ++ , 
 .
# 	
 !DtY'DLL,E,E"&,,"9"9!:!DLL<R<R;STZZ\##|nIdggY$GH "
 3?tyy.DU  -$29w?R.#LL(
 	
 ** 
$!!-
 	
 ## 
$!!-
 	
  
$!!-
 	

s7   FH: H: %BH: :JJ3J;JJJc                 (   	 	 t         j                  j                  d      j                  | d      }|j
                  }|j                  sdd|j                   d	dS |j                  d
k7  rdd|j                   ddS t        j                  |j                        }t        j                         }|j                  |      }|j                         }	 t        j                  j                  |d
d      }|j                  |cxk  xr |j                   k  nc }|ddS # t         j                  $ r dd|  ddcY S w xY w# t        j                  $ r dd|j                   dcY S w xY w# t"        $ r}	ddt%        |	       dcY d}	~	S d}	~	ww xY w)an  
    Check if a bot is currently in sales time based on bot phone number

    Args:
        bot_phone_number (str): The bot's phone number to check

    Returns:
        dict: {
            'is_sales_time': bool,        # True if currently in sales time
            'error': str                  # Error message if something went wrong, None otherwise
        }
    r=   Trc   FBot with phone number  not found or inactive)r   r:   Company  is inactiverh   zBot z- does not have sales timing (only hazel does)ri   z,No sales timing configured for hazel bot in NUnexpected error: )r   rB   r{   rC   rD   r=   r5   r   bot_namer)   r   rx   rL   rN   r   rT   rU   rV   rF   )
bot_phone_numberrj   r=   rY   current_time_utccurrent_time_companycurrent_time_onlyr   r   r`   s
             r    check_bot_sales_timer   )  s   <
		$,,;;IFJJ- K C ++  !&#GLL>>  <<7"!&~-Z[   ==)9)9:#<<>/::;KL0557
	&..22 3 L %//3D]H]H]] +
 	
Y ".. 	!&12B1CCYZ 	D '' 	!&G~V 	  
")#a&2
 	

sk   0D  *E- !E-  AE- "E 7(E-  D?<E- >D??E- %E*'E- )E**E- -	F6FFFc                    	 t         j                  j                  d      j                  | d      }|j                  }|j
                  sddddS 	 t        j                  |j                        }t        j                         }|j                  |      }|j                         j                         d	z  }|j                  d
      j                         }d}|j                         }	t         j                  j#                  ||	|	d|      j%                         }
|
rd}	 t&        j                  j                  ||      }|j(                  sd}n;|j+                         }|j,                  |cxk  xr |j.                  k  nc }| xr |}d}t0        j                  j#                  |d      j                  d      }g }|D ]  }t3        |d      s|j4                  j6                  s'|j4                  j8                   d|j4                  j:                   j=                         }|s|j>                  }|j4                  j6                  }|jA                  d| d| d        |r|djC                  |      dz   z  }|jD                  r|d|jD                   dz  }|dz  }|tG        |      |dS # t         j                  $ r	 ddddcY S w xY w# t&        j                  $ r d}Y [w xY w)a  
    Check if bot is currently in working hours based on bot phone number

    Args:
        bot_phone_number (str): Bot phone number

    Returns:
        dict: {
            'is_off_hours': bool,  # false if holiday OR outside working hours, true if NOT holiday AND within working hours
            'timezone_offset': int,  # UTC offset like -7
            'transfer_instructions': str  # Transfer instructions for the company
        }
    r=   Trc   Fr   zCompany is inactive)is_off_hoursrt   transfer_instructionszBot not foundre   r;   )r=   r>   r?   r5   rg   r@   rw   rk   rm   rn   If the user wants to reach  then transfer to ;FIf the user wants to schedule a meeting then transfer the call to BDC ) and say 'I'll transfer you to our BDC'; If the user asks for an advisor who is not in the list, say 'I'm sorry, we don't have an advisor by that name at our company. Would you like to connect with someone else?')$r   rB   r{   rC   r=   r5   rD   r)   r   rx   rL   ry   rz   rO   r   rM   r   rP   rQ   r   rS   rN   rT   rU   r   r|   rm   rd   r}   r~   r   usernamer   r   
bdc_numberr+   )r   rj   r=   rY   r   r   rt   current_dayr8   r   bot_holidayr_   r   r   is_within_hoursr   r   user_instructionsr   r   advisor_phones                        r    get_bot_working_infor   v  s#   
 ((77	BFF) G 
 ++   %#$)>  ! }}W%5%56  ||~+667GH +446DDFMO '//5;;=K J %%'E //(( )  eg  
"**.. / 

 ## L !5 9 9 ;*559JclNcNccO)>=oL  LL'' (  nY  4#(A(A"ll556a8N8N7OPVVXL#}} LL55M$$-l^;Mm_\]^  *;!<s!BB TU\UgUgTh i7 8	
  	v
 %/!6 w ** 
! %4
 	

d ## s%   AJ- A+K -K	K	K%$K%c                 V   	 	 t         j                  j                  d      j                  | d      }|j
                  }|j                  sddd	|j                   d
dS t        j                  |j                        }t        j                         }|j                  |      }|j                         }t        j                  j                  |||d      j                  d      }|j!                         sddddS |D ]Z  }|j"                  j                  |j$                        j!                         s8d|j&                  xs d|j                   dddc S  ddddS # t         j                  $ r ddd|  ddcY S w xY w# t(        $ r}	dddt+        |	       dcY d}	~	S d}	~	ww xY w)a  
    Check if a bot phone number is currently experiencing a holiday.

    Args:
        bot_phone_number (str): The bot's phone number to check

    Returns:
        dict: {
            'is_holiday': bool,           # True if it's a holiday
            'message': str,               # Holiday message if applicable, None otherwise
            'error': str                  # Error message if something went wrong, None otherwise
        }
    r=   Trc   FNr   r   )r8   r9   r:   r   r   r<   rg   r4   zHappy !r   )r   rB   r{   rC   rD   r=   r5   r   r)   r   rx   rL   rM   r   rP   prefetch_relatedexistsrg   r4   r9   rV   rF   )
r   rj   r=   rY   r   r   r   company_holidaysr^   r`   s
             r    check_bot_holiday_by_phoner     s   C

	$,,;;IFJJ- K C ++  ##GLL>>   ==)9)9:#<<>/::;KL$))+ #??11!	 2 

 
6
" 	  &&( $  (G||""cff"-446 #'&JF7<<.2J!  (  
 	
c ".. 	#12B1CCYZ 	n  
)#a&2
 	

sS   0E  +F BF ;9F 5#F F  F =F ?F  F 	F(F#F(#F(c                 0
   | j                   }|j                  st        ddit        j                        S | j
                  j                  dd      st        ddit        j                        S |j                  j                  d      j                  |j                  j                  	      }|j                         st        dd
it        j                        S g }g }|D ]A  }|j                  d|      r|j                  |       '|j                  |j                         C |st        d|dt        j                        S t         j"                  j                  |j                        j%                  d      }|j                         st        ddit        j                        S t'        |      }|rt        d|it        j                        S 	 t)        j*                         5  t         j"                  j                  |      j-                          t.        j"                  j                  |j                        D ci c]  }|j0                  | }	}g }
|D ]L  }t.        j"                  j                  |      D ci c]  }|j0                  | }}|j3                         D ]0  \  }}||	v s|	|   }|j4                  |_        |j7                          2 |D ]  }t         j"                  j9                  ||j                  |j:                  |j<                  |j>                  |j4                        }|j@                  jC                         D cg c]  }|j0                  |v r||j0                     ! }}|r|j@                  jE                  |       |
j                  |        O g }|jG                         }|D ]I  }|j                  tI        ||dddd| d|j                  j                   d|j                                K tH        j"                  jK                  |d       ddd       dtM        |       dtM        |      |jG                         |r|nd|j                  j                  |jG                         d}t        ||st        jN                        S t        jP                        S c c}w c c}w c c}w # 1 sw Y   xY w# tR        $ r3}t        ddtU        |       it        jV                        cY d}~S d}~ww xY w) zOApply current company's holidays to all user's companies with bot relationshipsr:   No active companyr   confirmF*You must confirm to apply to all companiesTr5   r   No other companies foundedit_company!No permission to edit any companyr:   denied_companiesr=   rg   z$No holidays found in current companycompany__in)r=   r   r9   
start_dateend_dater5   bulk_replacer   N	Replaced z holidays from     → r=   
updated_byaction
model_name	object_iddetailsd   
batch_sizezHolidays applied to 
 companiesr9   applied_counttotal_companiesskipped_companiessource_companyitems_countOperation failed: ),r   active_companyr   r   HTTP_400_BAD_REQUESTdatarC   rl   rP   excluder4   r   has_company_permissionr   r   HTTP_403_FORBIDDENr   rB   r   validate_holidaysr   atomicdeleter   r   itemsr5   savecreater9   r   r   rg   allsetcountr
   bulk_createlenHTTP_200_OKHTTP_206_PARTIAL_CONTENTrV   rF   HTTP_500_INTERNAL_SERVER_ERROR)requestr   user_companiesallowed_companiesdeniedr=   current_holidaysvalidation_errorrj   source_botscreated_holidaystarget_botsr   
target_bot
source_botr^   new_holidaymatching_botshistory_logsr   response_datar`   s                         r    apply_holidays_to_all_companiesr   K  s   <<D"56v?Z?Z[[ <<Iu-"NOX^XsXstt ^^**T*:BBdFYFYF\F\B]N  ""<=fFaFabb F!&&~w?$$W-MM',,'	 " 8 &
 ++- 	- --d6I6I-J[[\bc""$"HIRXRmRmnn ))9:"23F<W<WXXJp!OO""/@"AHHJ .55<<TEXEX<YYC c!Y  
  ",  299@@@QQ LL#%Q  
 -8,=,=,?(Hj;.%0%:
/9/C/C
,") -@  0G")//"8"8 '$\\ '#*#5#5!(!1!1")"3"3 #9 #K +2,,*:*:*<%*<J%..+= $J$7$78*< " % %#((,,];$++K8'  0 -H L$**,E,##N##)("'wod>Q>Q>V>V=WW\]d]i]i\jk%  - ""..|.Lu "| .c2C.D-EZP !23-335+1t"1166+113
 f.@.@ttTZTsTsttG,%E "!P  p$6s1vh"?@InInoopsp   S +ASR>,SSS7B S$S
;B6S1A7S )S >SSS 	T"(T
TTc           	      
   d}d}	 t         j                  j                  | d      }|j                  }t        j                  |j                        }t        j                         }|j                  |      }t        j                  d       t        j                  d|        t        j                  d|        t        j                  d|        |j                         j                         dz  }|j                  d      j                         }d}|j!                         }	t        j                  d|	        t"        j                  j%                  ||||d      j'                         }
t        j                  d|
        |
rd}	 t(        j                  j                  ||      }t        j                  d|        |j*                  sd}n|j-                         }|j.                  |cxk  xr |j0                  k  nc }t        j                  d|j2                          t        j                  d|j4                          t        j                  d|        t        j                  d|j.                          t        j                  d|j0                          t        j                  d|        t        j                  d|        | xr |}d}t6        j                  j%                  |d      j9                  d      }g }|D ]  }t;        |d      s|j<                  j>                  s'|j<                  j@                   d |j<                  jB                   jE                         }|s|jF                  }|j<                  j>                  }|jI                  d!| d"| d#        |r|d jK                  |      d z   z  }|jL                  r|d$|jL                   d%z  }|d&z  }g }|D ]  }t;        |d      s|j<                  j>                  s'|j<                  j@                   d |j<                  jB                   jE                         }|jI                  | d'|j2                           d(jK                  |      }|j4                  ||
r|
jN                  nd|tQ        |      |r|s||d*S d)|d*S # t        j
                  $ r ddddddd	d
cY S w xY w# t(        j
                  $ r d}Y w xY w)+ab  
    Check if company is currently in working hours based on phone number

    Args:
        phone_number (str): Company phone number

    Returns:
        dict: {
            'is_office_hours': bool,  # false if holiday OR outside working hours, true if NOT holiday AND within working hours
            'is_holiday': bool,  # true if today is a holiday, false otherwise
            'holiday_message': str,  # Holiday message if applicable, None otherwise
            'timezone_offset': int,  # UTC offset like -7
            'transfer_instructions': str  # Transfer instructions for the company
        }
    NTrc   zno company configuresFrr   r   r6   rq   )ru   r7   r8   rs   rt   r   rv   zN================================= COMPANY INFO ===============================zCurrent time UTC: zCurrent company time: zCompany timezone: re   r;   zToday date in timezone: rf   z
Holiday : r@   zOffice hours: zcompany id: zcompany name: zcurrent day: zoffice_hours.start_time: zoffice_hours.end_time: zcurrent_time_only: zis_within_hours: rw   rk   rm   rn   r   r   r   r   r   r   ro   rp   z`Cannot transfer calls in off hours or holidays. Please record a message for the advisor instead.)ru   r7   rs   r8   rt   r   rv   ))r   rB   rC   r=   r   rD   r)   r   rx   rL   loggerinfory   rz   rO   r   rM   r   rP   rQ   r   rS   rN   rT   rU   r4   r   r   r{   r|   rm   rd   r}   r~   r   r   r   r   r   r9   r+   )rd   companyBotSettingsr=   rY   r   r   rt   r   r8   r   r^   r_   r7   r   r   r   r   r   r   r   r   r   rv   s                          r    get_company_working_infor     s     G
/77;;ae;f$,, }}W%5%56  ||~+667GH
KK`a
KK$%5$678
KK()=(>?@
KK$%5$678 +446DDFMO '//5;;=K J %%'E
KK*5'23oo$$,* %  eg  KK*WI&' 
 "**.. / 

 	n\N34###O !5 9 9 ;*559JclNcNccOKK,wzzl34KK.78KK-}56KK3L4K4K3LMNKK1,2G2G1HIJKK-.?-@ABKK+O+<=> #-n@O  LL'' (  nY  4#(A(A"ll556a8N8N7OPVVXL#}} LL55M$$-l^;Mm_\]^  *;!<s!BB TU\UgUgTh i7 8	
  	v L4#(A(A"ll556a8N8N7OPVVXL<.	$'' CD 
 99\*L  *.57??;N /:IR\!6$  cE$ {  	
3$2 %8-
 	
	
V ##   s$   -S ES( S%$S%(T Tc                 L    t         j                  j                  | |||||      S )z&Helper function to log company changesr   )r
   rB   r   )r=   r   r   r   r   r   s         r    log_company_changer   `  s2    !!(( )  r"   c                 6   | j                  t        j                  d      t        j                  d      z        }|j                         ry| D ]G  }|j                  s|j
                  s|j                  |j
                  kD  s7d|j                   dc S  y)zValidate holidays dataT)start_date__isnull)end_date__isnullz:Invalid holidays: some holidays are missing start/end datezInvalid holiday "z%": start date must be before end dateN)rP   r   Qr   r   r   r   )holidaysinvalid_holidaysr^   s      r    r   r   l  s    D)FHHd,KK  K '"2"2w7I7IGL\L\7\&w||n4YZZ  r"   c                     | j                  d      j                  t        j                  d      t        j                  d      z        }|j                         ryy)zValidate office hours dataT)rS   start_time__isnullend_time__isnullz?Invalid office hours: some open days are missing start/end timeNrP   r   r  r   )r_   invalid_hourss     r    validate_office_hoursr  |  sU     '' ( fD)FHHd,KK 
 Pr"   c                     | j                  t        j                  d      t        j                  d      z        }|j                         ryy)zValidate sales timings dataTr  r  z>Invalid sales timings: some timings are missing start/end timeNr	  )sales_timingsinvalid_timingss     r    validate_sales_timingsr    s@    #**D)FHHd,KKO Or"   c                 	   | j                   }|j                  st        ddit        j                        S | j
                  j                  dd      st        ddit        j                        S |j                  j                  d      j                  |j                  j                  	      }|j                         st        dd
it        j                        S g }g }|D ]A  }|j                  d|      r|j                  |       '|j                  |j                         C |st        d|dt        j                        S |j                   j                  |j                        }	|	j                         s/t        dd|j#                          dit        j                        S |r' ||	      }
|
rt        d|
it        j                        S 	 t%        j&                         5  |j                   j                  |      j)                          g }|D ]  }|	D ]  } |d)d|i|j*                  j,                  D ci c]M  }|j                  dk7  r<|j                  dk7  r-|j.                  s!|j                  t1        ||j                        O c}}|j                  |         |j                   j3                  |d      }g }|	j5                         }|D ]Z  }|j                  t7        ||d|dd| d|j#                          d|j                  j                   d|j                                \ t6        j                   j3                  |d       ddd       | dt9        |       dt9        |      |j5                         |r|nd|j                  j                  |	j5                         d }t        ||st        j:                        S t        j<                        S c c}w # 1 sw Y   xY w# t>        $ r}tA        |      }d!|v r4t        dd"|j#                          d#it        j                        cY d}~S d$|v r"t        dd%it        j                        cY d}~S t        dd&| it        j                        cY d}~S d}~wtB        $ r  t        dd'it        j                        cY S tD        $ r3}t        dd(tA        |       it        jF                        cY d}~S d}~ww xY w)*a}  
    Generic utility to apply current company's data to all user's companies

    Args:
        request: Django request object
        model_class: The model class (OfficeHours, SalesTiming, etc.)
        model_name: String name for logging (e.g., 'OfficeHours', 'SalesTiming')
        validation_func: Optional custom validation function

    Returns:
        Response object
    r:   r   r   r   Fr   Tr   r   r   r   r   r   r   zNo z found in current companyr   r=   r4   i  r   r   Nr   rn   z from r   r   r   z applied to r   r   zUNIQUE constraint failedz
Duplicate z found. Please try again.zFOREIGN KEY constraint failedzInvalid company referencezData constraint violation: zPermission deniedr    )$r   r   r   r   r   r   rC   rl   rP   r   r4   r   r   r   r   r   rB   r   r   r   r   _metafieldsauto_createdgetattrr   r   r
   r   r   r   r   rF   PermissionErrorrV   r   )r   model_classr   validation_funcr   r   r   r   r=   current_datar   new_recordsitemfield
new_recordcreated_recordsr   r   r   r`   	error_msgs                        r    apply_to_all_companies_bulkr     s    <<D"56v?Z?Z[[ <<Iu-"NOX^XsXstt ^^**T*:BBdFYFYF\F\B]N  ""<=fFaFabb F!&&~w?$$W-MM',,'	 " 8 &
 ++- 	- &&--d6I6I-JL C
(8(8(:';;T"UV%::< 	< *<8W&67@[@[\\;p!&&3D&ELLN K,(D!, " '"NYN_N_NfNf iNfU#jjD0UZZ95LUZUgUg !::wtUZZ'@@Nf i"J
  &&z2 ) - *11==kVY=ZO L &&(E,##N##))"'wa
0@0@0B/C6$J]J]JbJbIcchipiuiuhvw%  - ""..|.LA "H %\#6G2H1IT !23-335+1t"1166'--/
 f.@.@ttTZTsTsttCi "!\  vF	%2W
:3C3C3E2FF_&`a#)#>#>@ @,	9W&AB6KfKfggW(CI;&OPY_YtYtuu Z"56v?X?XYY p$6s1vh"?@InInoops   O9 )AO->AO(C	O-A9O9 O9 (O--O62O9 9	S6=R?S6 R%S6+R
S6)S6;S6(S1+S61S6)N))	django.dbr   r   r   rest_framework.responser   rest_frameworkr   r
   r)   django.utilsr   r   r   r   r   r   apps.core.modelsr   r   urllib.parser   logging	getLogger__name__r   rF   r!   r2   ra   r   r   r   r   r   r   r   r   r  r  r   r  r"   r    <module>r*     s    9 9 , ! "  ! R R !  ! 			8	$$3 $3 $LDz
zQ
hJ
Z}@R
jspl\~	 	qpr"   