
    /i                    j   d dl Z d dlZd dlZd dlZd dl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mZmZ d dlmZ d d	lm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 dl#m$Z$ d dl%Z&d dl% d dl'Z&d dl' d dl(m)Z)m*Z* d dl+m,Z, d dl-Z&d dl+m.Z.  G d de&j^                  j`                        Z1 G d de&j^                  j`                        Z2dZ3e4jk                  d      Z6i Z7 G d d      Z8d Z9d Z:de;fdZ< G d de=      Z> e?d d!"      Z@ G d# d!e>$      ZA G d% d&eA      ZB G d' d(eA      ZC G d) d*eC      ZD G d+ d,eC      ZE G d- d.eB      ZFe G d/ d0             ZG G d1 d2      ZHej
                   G d3 d4             ZIej
                   G d5 d6eI             ZJ G d7 d8      ZKy)9    N)	dataclass)OrderedDictdefaultdict
namedtuple)Mapping)deepcopy)	lru_cache)IterableListDictOptional)
MethodType)nullcontext)	LockError)aliased)ProgrammingError)translit)*)imutable_deep_copymutable_deep_copy)cmfutil)
cmf_exportc                       e Zd ZdZy)CmfOrmFieldsSpecErroruC   Недопустимые правила загрузки полейN__name__
__module____qualname____doc__     ./cmf/models/base_model.pyr   r       s    Mr!   r   c                       e Zd ZdZy)CmfOrmNotLoadedErroru"   Объект не загруженNr   r    r!   r"   r$   r$   $   s    ,r!   r$   defaultz(?<!^)(?=[A-Z])c                       e Zd ZdZy)
_NamespacezNamespace classNr   r    r!   r"   r'   r'   .   s    r!   r'   c                     |j                         D ]:  \  }}t        |t              r t        | j	                  |i       |      | |<   6|| |<   < | S )zupdate nested dicts)items
isinstancer   _dict_mergeget)dukvs       r"   r+   r+   2   sO    	 1a!quuQ|Q/AaDAaD	
 Hr!   c                 J    t         j                  d|       j                         S )N_)_camel_to_snake_regexsublowerss    r"   camel2snaker8   <   s     $$S!,2244r!   r7   c                 P    dj                  d | j                  d      D              S )N c              3   <   K   | ]  }|j                           y wN)
capitalize).0r4   s     r"   	<genexpr>zsnake2pascal.<locals>.<genexpr>A   s     <3>>#<s   r2   )joinsplitr6   s    r"   snake2pascalrB   @   s    77<qwws|<<<r!   c                   ^     e Zd ZdZ fdZd Zd Zed        Zed        Z	ed        Z
 xZS )BaseModelMetau,   
    Метаданные модели.
    c           
         i }t        |      D ]h  }t        |t              s|j                  j	                         D ]8  \  }}t        |t        |g      |d   |d    d| |j                  d      ||<   : j t        |j	                               D ]  \  }}	t        |	t              rji }
|d   |
d<   |d   dz   |z   |
d<   |	j                  |
d<   |
j                  |	j                         t        |t        |	j                  g      |
      ||<   ||= t        |	t              s|	||<   ||=  ||d<   t        | =  | |||      S )u%   преобразуем Field в classr   r   .)r   r   captionrG   fields)reversedr*   rD   rH   r)   typetuplerG   list	FieldDataupdatekwargsbaseCmfTypeMetasuper__new__)clsnamebases	namespacerH   base_cls
field_name	field_clsr/   r0   new_type_namespace	__class__s              r"   rS   zBaseModelMeta.__new__I   sk    ! 
	H(M2-5__-B-B-D )J	)-"yk**3L*A/8/H.I:,,W'0'8'8*F:&
	 *+ 	!DAq!Y'%'"3<\3J"<05>~5NQT5TWX5X">201		"9-"))!((3 E166(O5GHq	aLA{+q	aL	! %	(wsD%;;r!   c                 X    | j                   j                  |      x}r|S t        ||       r<   )rH   r,   AttributeErrorselfitemrZ   s      r"   __getattr__zBaseModelMeta.__getattr__j   s/    --9- T4((r!   c                    t        | j                        | _        | j                  | _        g | _        i | _        di i| _        | j                  st        | t              rzd}|D ])  }t        | |      rt        d| d| j                          d}|D ]C  }t        j                  |t                      t        |   }t        | |      }||v r||   }| ||<   E | j                   j#                         D ]z  \  }}	| |	_        | j                   d|	j                   |	_        |	j                  | j                  d   |<   |	j                  sV| j                  j)                  |	j                         | t+        |       D ][  }
|
j-                  d      r|
| j.                  v r$t        | |
      }t1        |t2              rAt5        |      rM|| j                  |
<   ] y )NrH   )ui_name	ui_modulecode_prefixu   Заполните поле     в классе )rd   rf   rF   r2   )r8   r   	tablename
class_nameprimary_key__dp__ui_metaabstract
issubclass	CmfEntityhasattr
ValueError_unique_fields_cache
setdefaultdictgetattrrH   r)   instance_classclass_full_nameappenddir
startswithui_meta_skipr*   propertycallable)rT   argsrO   rH   field_unique_field_cachevalue_cached_clsrY   rZ   r/   r0   s               r"   __init__zBaseModelMeta.__init__t   s   #CLL1
n||
3	 :<F nsE*$'CE7J[\_\j\j[k%lmmn
 1F 1$//tv>&:5&A#U+//"5e"<K .1#E*1 &)ZZ%5%5%7 	;!J	'*I$+.>>*:!I<P<P;Q(RI%090A0ACKK!*-$$&&y'9'9:	; S 	A||C C$$$QA!X&{CKKN	r!   c                     ddl m} | j                  r| j                  d   nt        }| j                  j                  |      }|s |||       }|| j                  |<   |S )u9   Доступ к датапровайдеру моделиr   )DataProvider)data_sourcemodel)cmf.data_providers.baser   data_sourcesDEFAULT_DATASOURCErk   r,   )rT   r   r   dp_s       r"   dpzBaseModelMeta.dp   sV     	9-0-=-=c&&q)CUjjnn[);cBC&)CJJ{#
r!   c                 L    | j                   j                  j                  |       S r<   )r   data_driverdp_modelrT   s    r"   r   zBaseModelMeta.dp_model   s    vv!!**3//r!   c                 ,    t        | j                        S )u!   метаданные модели)r8   r   r   s    r"   	snakenamezBaseModelMeta.snakename   s     3<<((r!   )r   r   r   r   rS   rb   r   r|   r   r   r   __classcell__r\   s   @r"   rD   rD   D   sU    <B)1f 	 	 0 0 ) )r!   rD   BM	BaseModel)boundc                      e Zd ZU 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ZdZeed<   dZdZdZeed<   dZdZeed	<   dZeed
<   dZeed<   dZeed<   dZeed<   dZ eed<   g dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*g Z+dZ,e-dd       Z.e-d        Z/ddZ0d Z1d Z2d Z3ddZ4d Z5d Z6d Z7e8d        Z9e-d        Z:ddZ;ddZ<ddZ=d  Z>d! Z?e-d"ed#efd$       Z@e-dd%       ZAe-d&        ZBe-dd'       ZCe-d(        ZDd) ZEe-d*        ZFe-dd+       ZGdd,ZHe-dd-       ZIe-dd.eJfd/       ZKe-d.eJfd0       ZLe-dd.efd1       ZMe-d2eJfd3       ZNdd4ZOePd5        ZQdd6ZRe- eSd78      d.eTfd9              ZUe-d.eJfd:       ZVe-dd;       ZWe-dd<d=eXeY   d#eYfd>       ZZe-dd<d=eXeY   d#eYfd?       Z[e-dddd@dA       Z\e-d=eXeY   fdB       Z]e-dC        Z^e-dD        Z_e-dddEd=eXeY   d#e`eY   fdF       Ze-dddEd=eXeY   d#e`fdG       Zae-dH        Zbe-dddddIdJ       Zce-dK        Zde-dd<dL       Zee-ddMdN       Zfe-ddO       Zge-	 	 	 	 ddPeJdQedRefdS       Zhe-dT        Zie-dU        ZjddWZkdX ZldY Zmd#efdZZnd[ Zod\ Zpd] Zqd^ Zrd_ Zsddd`daZtdb Zudc ZvdddZwde ZxddfZydVddgdhZzdi Z{dj Z|ePddk       Z}dl Z~ddmZddnZdo ZddpZdddddqdrZddsdtZeP eduddv      dw               Zdx Zdy Zdz Zdd{Zdd|Zdd}Zd~ Ze-ddddd       Ze-d        Ze-d        Ze-d        Ze-g dd       Ze-d        ZdddZe-dddd       Zd ZePd        ZddZddZe-dd       Zd Zy)r   NTu   ОбъектFr    info_audit_fieldsr%   acl_typeacl_allow_createacl_static_user_write_fieldsacl_static_owner_write_fieldsacl_static_self_write_fieldsacl_static_public_fields	api_allow)countcreatedeleteexport2filefield_options_listr,   sgetrL   slistubql2bqlrN   upsertget_ui_full_pathget_metarestore_deferred)$menu_tree_parent_idmenu_tree_ordernomenu_tree_node_is_branchrl   r{   rh   rH   r   rm   r   r   r   valuesvalues_dictrj   db_nameis_recursion_savedisable_simpler   acl_default_user_policyr   r   r   r   r   essential_child_modelsdisable_auditr   api_methodsr   r   c           
      R    | j                   }t        j                  d||||||d|S )N)ri   field_namesbqlformat_fileinclude_archivedorder_byr    )ri   r   r   )rT   r   r   r   r   r   rO   ri   s           r"   r   zBaseModel.export2file,  s>    ^^
%% 02=*-2=7G/70 )/0 	0r!   c              #      K   ddl m} t        |      j                         D ]$  }t	        |t
              st        ||       s!| & y w)Nr   models)cmf.includer   varsr   r*   rJ   rn   )rT   r   r   s      r"   iter_subclasseszBaseModel.iter_subclasses7  s=     &&\((* 	E%&:eS+A	s   3A
A
A
c                    |s| j                   |   }|s|j                  } |       }| |_        || j                  |<   |st        j                  t        j                        }t        |t              rD|j                  s|j                  r,|j                         |_        |j                         |_        n%t        |t              r'|j                  s|j                  r||_        ||_        nt        |j                   t"              r?|j                   j%                         |_        |j                   j%                         |_        nt        |j                   t&        t(        f      r5t+        |j                         |_        t+        |j                         |_        n@|j-                  |j                         |_        |j-                  |j                         |_        d|_        |S NT)rH   ri   instance__dict__datetimenowtimezoneutcr*   CmfDateauto_nowauto_now_adddate_value_oldCmfDateTimer%   r   __func__rL   rt   copycast	orm_dirty)r`   rY   rZ   emptyr   r   s         r"   
init_fieldzBaseModel.init_field?  sF   J/I"--J$)j!,,x||,C%)u~~ASAS"xxz XXZ
E;/U^^uGYGY" 
EMM:6$}}557"]]335
EMMD$<8#EMM2!%--0
$zz%--8"ZZ6
"EOr!   c                 >   | j                   j                  |      x}ru| j                  rUt        | j                  |      rt	        | j                  |      S |j
                  st        | j                   d| d| |      | j                  ||d      S t        ||       )NrF   u&    для тонкого объекта.Tr   )
rH   r,   simple_objectrp   ru   virtualCmfOrmImplicitLazyLoadri   r   r^   r_   s      r"   rb   zBaseModel.__getattr__]  s    --9-!!4--t4"4#5#5t<< ((0DOO3DAdVKq1rtxz~??4$???T4((r!   c                    | j                   j                  |      }|r| j                  r(t        j                  j                  d|  d| d|       t        |t        j                   j                        r&t        d| j                  j                   d| d      | j                  j                  |d      x}du r| j                  ||d	      }|j                  | |       y t        j                  | ||       y )
NERROR: Object z is readonly, try set =zField rF   z! is a backref hence it's readonly.Tr   )rH   r,   readonlycmf
base_errorCmfOrmReadonlyModifyErrorrn   
CmfBackrefNotImplementedErrorr\   r   r   r   setobject__setattr__)r`   r/   r0   rZ   r   s        r"   r   zBaseModel.__setattr__h  s    KKOOA&	}}nn>>PTvUklmknnopqor?stt)SZZ%:%:;)F4>>3J3J2K1QCOp*qrr**1c22s:9DAIIdAtQ*r!   c                     d| _         y)u   
        Помечаем что обьект уже создан в бд
        Эту опцию нельзя использовать в бизнес логике
        TN)_BaseModel__exists_in_dbr`   s    r"   mark_exists_in_dbzBaseModel.mark_exists_in_dbu  s    
 #r!   c                 >   d| _         d| _        d| _        || _        | j                  r,d| _         d}|r!t        j
                  j                  d| |      | j                          |sv|j                  d| j                                dD ]  }||v rt        t        dd       ||<    | j                  j                         D ]  \  }}| j                  |||        d| _        d| _        d| _        d | _        |j                         D ]  \  }}t'        | ||        y )NTFuh   Нелья передавать поля для инициализации вместе с simple_objectid)
cmf_author	cmf_ownercmf_modified_bycurrent_personr   )is_newr   is_ellipsis_idobjr   r   r   CmfOrmError	wrap_savers   gen_idru   grH   r)   r   r   
is_changedr   _save_data_donesetattr)r`   r   r   rO   ir/   r0   s          r"   r   zBaseModel.__init__|  s3    # "'*DKEnn00~  AE  GMN N 	dDKKM2C ?;#A'7>q	?
 ))+ 311E23 !&# LLN 	 DAqD!Q	 r!   c                 @    | j                   j                         }|d= |S )Nsave)r   r   )r`   r-   s     r"   __getstate__zBaseModel.__getstate__  s     MM fIr!   c                 2    || _         | j                          y r<   )r   r   )r`   states     r"   __setstate__zBaseModel.__setstate__  s    r!   c                 ,    t        | j                        S r<   )hashr   r   s    r"   __hash__zBaseModel.__hash__  s    DGG}r!   c                 ,    t        |       j                  S r<   )rJ   r   r   s    r"   r   zBaseModel.dp  s    Dz}}r!   c                     t        |      t        k(  s|j                  }n|}|j                  d      d   }t	        t
        j                  j                        |   S )N:r   )rJ   strr   rA   r   r   includer   )rT   r   tuuidri   s       r"   get_model_by_idzBaseModel.get_model_by_id  sH    Bx3HHEE[[%a(
CKK&&'
33r!   c                 \   |du rC| j                   D cg c]-  }|| j                  v s| j                  |   j                  s,|/ c}S |du rC| j                   D cg c]-  }|| j                  v s| j                  |   j                  s,|/ c}S t	        | j                         S c c}w c c}w )uP   
            Ключи инициализированных полей
        T)rH   r   r   
is_definedrL   r`   r  r   r/   s       r"   keyszBaseModel.keys  s     #{{a!a4==.@T]]STEUE`E`Aaa4#{{a!a4==.@T]]STEUE`E`Aaa$$	 bas"   B$B$B$B).B)B)c                 f    | j                  ||      D cg c]  }|t        | |      f c}S c c}w )uo   
            пары ключ:значение для инициализированных полей
        r  r   r  ru   r  s       r"   r)   zBaseModel.items  s2     04yyJ[ey/fg!GD!$%gggs   .c                 b    | j                  ||      D cg c]  }t        | |       c}S c c}w )ug   
            возвращает списком инициализированные поля
        r  r  r  s       r"   r   zBaseModel.values  s-     +/))zV`)*abQa bbbs   ,c                 L    	 t        | |      S # t        $ r}t        |d }~ww xY wr<   )ru   r^   KeyError)r`   keyes      r"   __getitem__zBaseModel.__getitem__  s,    	"4%% 	"!	"s    	##c                 N    	 t        | ||      S # t        $ r}t        |d }~ww xY wr<   )r   r^   r  )r`   r  r   r  s       r"   __setitem__zBaseModel.__setitem__  s.    	"4e,, 	"!	"s    	$$ubqlreturnc                 \    t         j                  ||       }t        j                  |d      S )NF)ensure_ascii)UbqlConverterr   jsondumps)rT   r  r   s      r"   r   zBaseModel.ubql2bql  s'    $$T3/zz#Ez22r!   c                 .   ddl m} g d}	|s|rt        j                  ||	dd      }n`|rT|rRt        j                  |      }
|
s |dd       y t        j
                  |
      }t        j                  |||	dd      }n
 |dd       |s
 |d	d       |S )
Nr   	cmf_alert)ui_view_formparentprojectTrH   include_deletedinclude_dummyz+DEV: FATAL get_ui_full_path class_name=Noneabortz3DEV: FATAL get_ui_full_path ui_name=None, code=NoneuC   Объект не найден или возможно удален)r   r&  r   get_obj_by_idget_class_name_by_ui_nameget_model_by_nameget_obj_by_code)rT   r   rd   codere   	parent_idrupobjr&  rH   ri   r   s               r"   _get_ui_full_path_objzBaseModel._get_ui_full_path_obj  s    )6++BvtcghT$>>wG
!KSWX11*=--dE&Z^nrsOW[\_hlm
r!   c                     t         j                   G d d             t         j                   G fdd             } |t        t        |j                              }|S )Nc                       e Zd Zy)5BaseModel.get_automation_ui_form.<locals>.UiFormFieldNr   r   r   r    r!   r"   UiFormFieldr:    s     r!   r<  c                   6     e Zd ZU eed<   fdZ fdZ xZS )0BaseModel.get_automation_ui_form.<locals>.UiForm_formc                 \            }t        | ||       |D ]  }t        ||||           y r<   )r   )r`   rY   rO   ui_form_fieldoptr<  s        r"   r   z;BaseModel.get_automation_ui_form.<locals>.UiForm.init_field	  s5     +j-8! =CM3s<=r!   c                    t        |   |i | d| _        || _        | j                  j                  j                         D ]5  \  }}i }t        |d      r|j                  |d<    | j                  |fi | 7 y )NTchoices)	rR   r   r?  r   rH   r)   rp   rD  r   )r`   r   r~   rO   ui_field_name
orig_fieldoptionsr\   s          r"   r   z9BaseModel.get_automation_ui_form.<locals>.UiForm.__init__  s|     $1&1!
"
151B1B1H1H1J >-M: Gz95-7-?-?	*#DOOM=W=	>r!   )r   r   r   bool__annotations__r   r   r   )r\   r<  s   @r"   UiFormr>    s    K=	> 	>r!   rJ  r   )dataclassesr   ru   r   ri   )rT   r6  rJ  ui_formr<  s       @r"   get_automation_ui_formz BaseModel.get_automation_ui_form  s[    				 	 
	 
			> 	> 
	>& wvs~~>?r!   c                 b   ddl m} dg}	|s| j                  |||||d|      }|j                  dk(  r(|j	                  d|d	      s) |d
|d|d|d       n	 |j                  g d       |j                  r)t        j                  |j                        j                  n|j                  }
t        }|j                  j                  r|j                  }n|}|r|}
d}|dk(  rd}d|j                  v r|j                  n|j                  j                         }d}|j                   r*t        j"                  |j                   j$                  d      }d|
 d|j&                   d| d| d|j(                   d|j                   | d| }|S # t        $ r  |d
|d|d|d       Y =w xY w)Nr   r%  r'     )r   rd   r3  re   r4  r5  r6  
CmfProjectzPPP-PR-BROWSEF)r6  raise_error$   Объект не найден id =  ui_name =  code = Tr-  )r   rU   r3  r4  )check_fieldsr:   z&rup=0-/z/?parent_id=z&vf=z&code=z	&ui_name=#)r   r&  r7  ri   check_project_role_access_acl_check_readCmfPermissionErrorr4  r   r  re   is_not_nullrH   r'  rd   r5   rU   translit_stripr   r   r3  )rT   r   rd   r3  re   r4  r5  r6  r&  rH   tmp_ui_moduletranslit_nametmp_parent_idrup_txtr'  translit_name_for_urlurls                    r"   r   zBaseModel.get_ui_full_path  s   ) !++r7Ybnw}~  EH+  IC >>\) 00cW\0]AB7,G<yQUPYZbfgh##1T#U
 MPMM//>HH_b_l_l==$$MMM%M %M!8G+9SZZ+Gs''S[[M^M^M` "88$+$:$:388>>3$O!-#&&m_DV\]`]e]e\f#++wiq1F0GI
1 & hAB7,G<yQUPYZbfgghs   F F.-F.c                     ddl m}  | j                  |i |}|j                  dvr |dt        dt
        dt        d        | j                  |i |d	|iS )
Nr   r%  )rQ  CmfDocument	CmfFolderCmfTaskrS  rT  rU  Tr-  r6  )r   r&  r7  ri   r   rd   r3  r   )rT   r~   rO   r&  r6  s        r"   public_get_ui_full_pathz!BaseModel.public_get_ui_full_pathI  sk    )'c''88>> "
 
 =wl|9TIV^bc#s##T=V===r!   c                      y r<   r    r`   r~   rO   s      r"   public_nonezBaseModel.public_noneY  s    r!   c                      y r<   r    rk  s      r"   public_none_classmethodz!BaseModel.public_none_classmethod]  s     r!   c                    d }|s|S t        |      } ||      rwt        |t        t        f      r |D cg c]  } |j                  di | c}S t        t        |      t        j                  j                        r |j                  di |S |S t        |t        t        f      r|S t        t        |      t        j                  j                        r|j                         S |S c c}w )u   
        Конвертация в дикты с последующей серилизацией
        :param relation_load_only:
        :param relation_load:
        :param obj:
        :param filter_fields:
        :return:
        c                 0   t        | t        t        f      rRt        |       dkD  rDt	        t        | d         t        j                  j                        st        | d   t              ryt	        t        |       t        j                  j                        ryy)Nr   TF)
r*   rL   rK   lenrn   rJ   r   r   r   
CmfRelBaser6  s    r"   is_model_objz&BaseModel.asdict.<locals>.is_model_objm  sn    #e}-#c(Q,JtTWXYTZ|]`]g]g]q]qDrGQRUVWRXZdGeDIszz';';<r!   rH   r    )rt   r*   rL   rK   get_values_dictrn   rJ   r   r   r   rH   CmfTypeasdict)r`   r6  rH   rt  paramsr   s         r"   rx  zBaseModel.asdictb  s    	 JV$#e}-=@A)))3F3AADIszz';';<*s**4V44
 
	 dE]+JS	3::#5#56::<
 Bs   C*c           	         t               }dd} |        ||r| j                  |      }| j                  d      D ]  \  }}t        |xr |j	                  |      xs |      }|r||vr0t        |t        j                  j                  t        j                  j                  f      r*|j                  D cg c]  } |j                  d	i | }	}nYt        |t        j                  j                        r)|j                  r |j                  j                  d	i |}	n|j                  }	|	du rd}	|	||<    | j                  |d<   |S c c}w )
uy   
        Функция превращает instance в dict для дальнейшей серилизации
        c                     	 dt         vrt               t         _        dt         j                  vr| t         j                  d<   y t         j                  dxx   | z  cc<   y # t        $ r
}Y d }~y d }~ww xY w)Nprofiler_data	obj_count)r   rt   r|  	Exception)nr  s     r"   inc_obj_countz0BaseModel.get_values_dict.<locals>.inc_obj_count  s]    "!+&*fAO !//1/0,,1,  s   A 	A2-A2NTr  full_fields_load.ri   )rP  r    )r   r  r)   rt   r,   r*   r   rH   
CmfM2MBaseCmfBackrefBaser   rv  CmfRelationBaser"  ri   )
r`   rH   r  rr  rY   	field_valry  r6  field_values
             r"   rv  zBaseModel.get_values_dict  sA   
 M
	2 	##'#8#8#@ %)ZZ4Z%@ 	(!J	+;+`@P@T@TU_@`+tdtuFJ6F$F 

 5 5szz7P7PQ IRX2s22<V<XXIszz'A'ABy=ioo==GG'nnc!"'AjM'	(, //, Ys   9Ec                 b    | j                   j                         }fd}t        ||      }|S )Nc                 F    | j                   k(  ry| j                  dk(  ryy)NTr   F)visibleri   )fr  s    r"   filter_visiblez-BaseModel.meta_fields.<locals>.filter_visible  s$    99'<<4'r!   )rH   r   filter)rT   r  rH   r  s    `  r"   meta_fieldszBaseModel.meta_fields  s5     ""$ NF3Fr!   rH   c           
      
   t        t              }t        t              }g }d|v rd}t        t              }	|smi |	d<   |rft        | t              ri |	d<   i |	d<   i |	d<   t        | t
              r7i |	d<   i |	d<   i |	d	<   i |	d
<   i |	d<   i |	d<   i |	d<   i |	d<   i |	d<   i |	d<   i |	d<   |dk(  rd}t        |j                               D ]  \  }
}|
j                  d      rTd}|t        |
      k  r!|
|dz       dk7  rn|dz  }|t        |
      k  r!|
d|  }||||f<   t        ||   |      ||<   ||
= k|
j                  d      rt        d|
 d      |
j                  d      s||
= |
dd }
|j                  |
       |st        d|
||       | j                  j!                         D ]  }|j"                  dk(  r/|r-|r|j$                  dk(  r|j'                  |j$                  i        t        |t(        t*        f      rz|j                         D ]f  \  }}|j"                  dk7  s|s|j$                  j                  |      s4|d k\  s:|j'                  |j$                  i       }t-        |||d f          h t        |t.              r|j                         D ]w  \  }}|j"                  dk7  s|s|j$                  j                  |      s4|d!k\  s:|j'                  |j$                  i       }t-        |||d f          t-        |||d!f          y n|j                         D ]U  \  }}|j"                  dk7  s|s|j$                  j                  |      s4|dk\  s:|j'                  |j$                  i        W  |D ]
  }
|
|v s||
=  |	j                         D ]#  \  }
}|j'                  |
i       }t-        ||       % t        |j                               D ]G  \  }}|di ik(  s| j                  j1                  |      }|s,t        |t.              s=||= i ||d"z   <   I |j                         D ]  \  }
}| j                  j1                  |
      }|s$t        |t2              s5|j5                         }|st
        g}i }|D ]/  }t7        |      }|j9                  |||
||#       t-        ||       1 |j;                          t-        ||        fd$ |      }|d%kD  rXt<        j>                  jA                  d&| d'tB        jD                   d(tB        jF                   d)tB        jH                   d*       yy)+u  
        Разворачиваем мета-правила
        - вначале *, **, ***, включая <prefix>*, ... - пока маски только для префиксов
        - затем -field_name
        - затем +fild_name - deprecated
        --Fr   r4  
project_idcmf_owner_idrU   r3  workflow_idcache_cluster_idperm_effective_acl_idperm_inherit_acl_idperm_parent_idperm_parent_owner_id%perm_security_level_allowed_ids_cachesl_owner_locksystemr(  Tr   r   rP  N+u   Синтаксис +field u)    устарел, используй fieldrW  u=   У "-" не может быть вложенных полейalwayslogic_prefixlazy      _id)fields_is_lazyrelation_field_nameauto_fieldshack_parent_noalwaysc                 b    d}| j                         D ]  \  }}|dz  }|s| |      z  } |S )Nr   rP  )r)   )_BaseModel__fieldscr/   r0   _BaseModel__field_counts       r"   __field_countz4BaseModel._fields_load_expand.<locals>.__field_countV  sD    A ( *1Qq))A* Hr!     u_   DEV: WARNING. В запросе используется слишком много полей: uC   . Возможно, где-то используется ** method=z args=z kwargs=)
debug_only)%r   intrt   rn   CmfModelro   rL   r)   endswithrq  maxrz   CmfDeprecatedErrorrx   r   rH   r   	load_moderi   rs   r  r  r+   r  r,   rr  related_modelsr   _fields_load_expandclearr   r  r&  r   
api_methodapi_args
api_kwargs)rT   rH   r  r  r  r  fields_prefixesasterisk_specsminus_fieldsplus_fieldsrY   
field_speccntprefixr   asterisk_cntplus_field_specfnamefspecr  related_model_listfield_spec_newrelated_modelfield_spec_subfield_countr  s                            @r"   r  zBaseModel._fields_load_expand  s    &c*$T*6>K!$' "Kc8,/1K,02K- 35K/c9-*,K'*,K'13K.68K 23;=K 789;K 5646K 01:<K 67KMK GH35K0,.K)(*#'  '+6<<>&: 	Q"J
""3'C
O+!CE(+s21HC C
O+ $EcT* 1;}-*-of.Es*K':&&&s+(+Ej\Qz){||&&s+J''^
##J//0oq{  ~H  JP  Q  Q3	QD ZZ&&( 	@E(*{DX\a\l\lp~\~!!%"2"2B7%*n!=> -<,A,A,C M(FL61V % 0 0 ; ;F CXYHY%+%6%6u7G7G%L
#J{0KLM E?3,;,A,A,C M(FL61V % 0 0 ; ;F CXYHY%+%6%6u7G7G%L
#J{0KL#J{0KLM -<,A,A,C @(FL61V % 0 0 ; ;F CXYHY))%*:*:B?@1	@< ' 	'JV#:&	'
 ,7+<+<+> 	5'J**:r:J
O4	5 !0 	/LE5r
"JJNN5)A7u,.F55=)	/ '-lln 	8"J
JJNN:.EE:6 &+%9%9%;")*3&!#%7 @M &.j%9N!55nUc  zD  R]  tH5  I?@   "J7#	8(	 $F+ KK!!  %D  EP  DQ Q,,-LL>

|8TUT`T`Sa#cos " u r!   c                 6   t        |j                               D ]T  \  }}|j                  d      \  }}}||k7  s!|j                  |i       j                  |i       j	                  |       ||= V |j                         D ]  }|s| j                  |        y)u   
        Структурируем плоские имена полей.
        Например: {field.sub_field...: {}} => {field: {sub_field: {...}}}
        rF   N)rL   r)   	partitionrs   rN   r   _fields_split)rT   rH   full_field_namer  rY   r2   sub_field_names          r"   r  zBaseModel._fields_splitf  s     ,0+? 	,'OZ,;,E,Ec,J)J>_,!!*b1<<^RPWWXbc?+		, !--/ 	.J!!*-	.r!   c                 D   ddl }|j                         }|rg }nt        j                  }|xs |D ci c]  }|i  }}| j                  |       |s| j	                  ||       |j                         |z
  }	|	dkD  rt
        j                  d| d|	dd|         |S c c}w )	u  
        Преобразуем список правил загрузки полей, во вложенную структуру,
         которая содержит имена полей для каждого уровня.

        fixme Правильно ли?
        Структура будет у всех вложенных объектов одна. Первый объект разворачивает свои мета команды, другие используют.
        Так быстрее, но могут быть проблемы со * в generic полях, т.к. они должны разворачиваться по-разному.

        :param fields_is_lazy: признак, что список ленивых полей
        :param fields: Список правил загрузки полей.
        :type fields: list

        :return: Структура загружаемых полей.
        :rtype: dict
        r   N)r  g?z!!! full_fields_load(z): duration z.3fz too long! Model: )timeconfigORM_DEFAULT_FIELDSr  r  r   debug)
rT   rH   r  group_byr  start_tsdefault_fields
field_ruletree_fieldsdurations
             r"   r  zBaseModel.full_fields_loadw  s    " 	99;N#66N8>8P.Q*z2~QQ+& ##K#O99;)c>GG+F8<~M_`c_def Rs   
Br  c                    g }| j                   j                         D ]0  }|j                  |v s|j                  |j	                                2 |r| j                  |      }t        ||       |j                         D ]y  \  }}|j                  |      }|s| j                   j                  |      }|s8t        |t              sI|j                         }|st        g}|D ]  }	|	j                  |        { y)uF   Рекурсивно добавим _id поля, если нужно.N)rH   r   ri   extendget_required_fieldsr  r+   r)   r,   rn   rr  r  ro   _enrich_load_plan)
rT   r  required_fieldsr   required_fflrY   r  	field_fflr  r  s
             r"   r  zBaseModel._enrich_load_plan  s     ZZ&&( 	DE#33&&u'@'@'BC	D //@L(,7&6&<&<&> 	?"J
(,,Z8IJJNN:.EE:6%*%9%9%;")*3&%7 ?M!33I>?	?r!   c                 F     | j                   | j                  |      fi |S r<   )_load_fields_build_load_plan)r`   rH   forcerO   s       r"   load_fieldszBaseModel.load_fields  s%     t  !6!6v!>I&IIr!   c                     | sy t        j                  |       } |d      }t        |       } | |j                  _        | |j                  _        |j                          d|_        d|_        |S )NTr   F)	r   r  r
  r   r   r   r   r   r   )r   rT   r6  s      r"   make_ellipsis_idobjzBaseModel.make_ellipsis_idobj  s`    %%b)oW
 $
r!   c                 F   ddl m} | j                  st        d| j                          yt        |      }dt        dt        ffd | |      ry| j                  st        d       y| j                  rHt        |      | j                     j                  | j                  d	||||j                  d
d	            }n6t        |      | j                     j                  | j                  d	|||      }|fdt        dt        dt        ffd | |       d| _        | S )u   
        Прогрузим поля по правилам fields
        Вложенные объекты уже могут быть прогруженны, важно догрузить только то, чего не хватает.
        r   r   uB   SKIP!!! попытка _load_fields при not __exists_in_db. id=Nr   fflc           	         d}| j                         D ]  }||v s| |   }|j                  du s2t        |t              r%|j                  r|j                  j                  rd}Pt        |t              r*|j
                  sm |j
                  ||         r||= d}t        |t        t        f      r-d}|j
                  D ]  } |t        ||               rd}  t        |t              sJ  |S )u   
            Проверим всё ли загружено рекурсивно. Уберём из ffl, что грузить не требуется.
            Вернём True, если всё загружено
            T.FN)
r  r   r*   r  r   r   r  r  r   rr  )r   r  loadedrY   r   list_loadedrel_instance	strip_ffls          r"   r  z)BaseModel._load_fields.<locals>.strip_ffl  s    
 F&mmo A
$$Z0EzzS(Z-OTYT^T^chcmcmcc!& !%9 ;;(c*oF$'
O).#EJ+GH&* -2KK &L#,\8C
O;T#U). %	& $.eZ#@@@-A0 Mr!   uL   fSKIP2!!! попытка _load_fields при not __exists_in_db id={self.id}Tver_resolve_head)include_deleted_oncer  r+  r,  r  )r  r  r+  r,  dst_instancesrc_instancec           
      (   t        |j                               t        |j                  d            z
  }|t        |j                               z  }|rt        d|       |j                  d      D ]  }||   }| |   }|j                  r|j                  durrt	        |t
              rb|j                  j                  rL|j                  |j                  k7  r"|j                  |j                  |i              n|j                  |_        |j                  du r|j                  |_        |j                  du s2t	        |t
              r|j                  r|j                  j                  rpt	        |j                  t        t        f      rt        |j                        |_        n|j                  |_        t	        |t              r|j!                          n	 it	        |t
              r|j"                  r'|s|j                  |j                  |i              |rJ|j                  |j                  k(  r1 
|j                  |j                  |j                  |i              |s|j                  |j                  |i              t	        |t        t$        f      r|j                  D ci c]  }|j                  j                  | }}|j                  D ]  }	|	j                  j                  |v rJ 
|	||	j                  j                     |j                  |i              ||	j                  j                  = e|j"                  sr|	j                  |j                  |i               t	        |t&              sJ  yc c}w )un   Если поле изменилось, то доводим новое значение до кондиции.Tr  ue   DEV: merge_fields поля запросили для загрузки, но не загружены: .)r  N)r   r  printr   r*   r  r   r   r  r,   r   r   rL   rt   r   r  apply_changesr   r  rr  )r  r  r  missing_fieldsrY   	src_field	dst_fieldsrc_isrc_instancesdst_imerge_fieldss             r"   r  z,BaseModel._load_fields.<locals>.merge_fields  s   
 !_s<3D3DPT3D3U/VVN+c,2C2C2E.FFN}  @N  O*//4/@ 9A
(4	(4	##	(8(8(C
S\^mHns|  tD  tD  tV  tV ||y||3 "..swwz2/FG ,5??	(##s*'0I$ >>S(Z	?-SXaXfXfktkyky  lL  lL!)"2"2T4LA)-i.>.>)?	)2)9)9	!)Z8!//1 i9 ++$%22377:r3JK$IOO)K( )$'GGJ$;= '%22377:r3JK	J+GHHQ$XuUXX^^U%:$XM$X!* 	L 88>>]:( %}UXX^^'D$'GGJ$;= !.ehhnn =(33 % 2 2377:r3J K	L  *)Z@@@s9AZ %Ys   6NF)r   r   r   r  r   r   r   rt   cmf_verr   ri   _getr,   r   )	r`   r  r+  r,  rO   r   new_instancer  r  s	          @@r"   r  zBaseModel._load_fields  s<   
 	'""VW[W^W^V_`a,-=>		 	 	@ T+, ""`a ||#F|DOO<AAGG$IYkz"/&**M_aeBf  B  h
  $F|DOO<AAGG$IYkz"/  B  1 -B	A'B	A7@B	AB	AF 	T<(!&r!     )maxsizec                 d    | j                  |      xs i }| j                  |       t        |      S r<   )r  r  r   )rT   rH   r  s      r"   _build_load_plan_for_tuplez$BaseModel._build_load_plan_for_tupleh  s5     //7=2./!"233r!   c                 >    t        |      }| j                  |       |S r<   )r   r  rT   rH   s     r"   _build_load_plan_for_dictz#BaseModel._build_load_plan_for_dicto  s    "6*f%r!   c                     t        |t              r| j                  |      S | j                  t	        t        |xs g                   S )u7   Готовим и возвращаем full_fields_load)r*   rt   r  r  rK   sortedr  s     r"   r  zBaseModel._build_load_planv  s>     fd#008811%v|8L2MNNr!   ru  rT   c                   d}|r!|D ]  }d|v s| j                  |      sd} n |r | j                  |d|i|}|r|d   S y| j                  r|sg }d|vr|j                  d       | j	                  |      } | j
                  |d|i|S )	x   
        fields - список мета-правил для указания какие поля грузить
        F__TrH   r   Ncmf_ver_head2cur_idr  )_allowed_field_funcsrL   r  rx   r  r   )rT   rH   r~   rO   aggregate_selectrY   resr  s           r"   r,   zBaseModel.get~  s    
 !$ 
:%//
;+/(	
 #((D::6:C1v ;;$F234//7sxxK0@KFKKr!   c                D   | j                   r|sg }d|vr|j                  d       | j                  |      }|j                         D ]C  }t	        | |d      }|st	        |dd      s!t	        |dd      s/ | j
                  |d|i|c S   | j                  ||dd|S )	r  r  Nr   Fvirtual_cache_timeliferH   simple)r  mapper)r  rx   r  r  ru   r,   r   )rT   rH   r~   rO   r  rY   r   s          r"   r   zBaseModel.sget  s     ;;$F234//7 +//1 	?JCT2Eui/GEC[]a4bsww>V>v>>	? sxx0@\U[\\r!   )r  r  r  c                H   d| j                   v r%|j                  d      s|s|j                  dd       |ru|D ]p  }t        | |d      }t        |dd      st        j
                  s|j                  t        _        Dt        t        j
                  |j                        t        _        r  | j                  j                  |d|i|}| j                  rg|re|rct        |j                        j                  | j                   d      }	|	r0dd	|j                  g|d
<    | j                  j                  dd|i|}|sd
|v rt        |d
         dk(  r|d
   d   dk(  r|d
   d   }
t!        |
t"              r|
j$                  }
|
r{d|
v rw| t&        j(                  k(  rdt+        t&        d      rTt&        j,                  j/                  |
dg      }|r0dd	|j0                  g|d
<    | j                  j                  |d|i|}|s d|v r|j3                  d      }
t!        |
t"              r|
j$                  }
|
d|
v r| t&        j(                  k(  rft+        t&        d      rVt&        j,                  j/                  |
dg      }|r0dd	|j0                  g|d
<    | j                  j                  |d|i|}|S | j                  dk(  r	 |S |s[|
j5                  d      d   }|j7                         r7t        |      dkD  r)ddd| g|d
<    | j                  j                  |d|i|}|S )u  
        Прогружаем поля которые не знает как прогрузить драйвер базы
        например м2м поля, виртуальные поля.

        full_fields_load - иерархия полученная из fields

        Т.к. по show definition люди придут за гайдом по использованию filter именно сюда, дублирую доку
        https://bcrm.carbonsoft.ru/project/Document/DOC-000282
        cmf_deletedr+  FNr  r  z:Hr   r   r  r  r   r3  r  rW  CmfTaskCodeHistorytask_id)r3  rH   LIKEz%-r    )rH   r,   rs   ru   r   jscache_timelifer  minr   r  r
  r   rz   ri   r  rq  r*   rw  r   r   rh  rp   r  r   r  poprA   isdigit)rT   r  r  r  r~   rO   rY   r   instis_linkr3  task_code_historycode_numbers                r"   r   zBaseModel._get  s*    CJJ&vzz:K/LUimU3. c
Z65":DA---2-I-I*-01C1CUEaEa-b*c svvzz@$4@8>@ ;;4$4$''l--0@.CDG$(#t/G/G#Hx !svvzzN3CNvN
 F*s6(3C/D/IfU]N^_`NaekNk(#A&D$(zzt&..(WV=Q-R(.(A(A(F(FDZcYd(F(e%(,0#7H7P7P+Qx()svvzz4]BR]V\]&(::f%D$(zz
 C4K &..(WV=Q-R(.(A(A(F(FDZcYd(F(e%(,0#7H7P7P+Qx()svvzz4]BR]V\]  ^^';;   &*jjob&9&..0S5E5I06"[M@R/SF8,#-366::t#aFV#aZ`#aDr!   c                     t               }|s|S |D ]8  }d|v s|j                  d      \  }}||vrg ||<   ||   j                  |       : |S )Nr  )rt   rA   rx   )rT   rH   resultrY   funcs        r"   _parse_aggregate_fieldsz!BaseModel._parse_aggregate_fields  sf    M  	0Jz!#-#3#3D#9 jv~#%F4Lt##J/	0 r!   c                 >    g d}|j                  d      \  }}||v ryy)N)sumavgr   r  r  r  TF)rA   )rT   rY   allowed_funcsr&  s       r"   r  zBaseModel._allowed_field_funcs
  s*    =%++D1j= r!   c                    t         j                  j                  d      s!t        j                  t        j
                  k(  ry d|v r|j                  d      \  }}d }|j                  d      rt        | |j                  d      d       }|st        | |d       }|r/|j                  s"J d|j                   d|j                   d       y y )	NFrR  r  r   r  u%   Группировка по полю (u   ) запрещена)r   CmfAccessListcheck_admin_moder   r   system_personrA   r  ru   rstripTEXKOM_group_by_allowri   rG   )rT   rY   	func_namer   s       r"   _check_group_by_aclzBaseModel._check_group_by_acl  s    00U0CqGWGW[\[j[jGj:$.$4$4T$:!Izt$C!2!25!94@ECT2E..  O2WX]XhXhWiijkpkxkxjy  zN  1O  O. r!   )rH   r  c                d   |}|s#|r!|D ]  }d|v s| j                  |      sd} n |rad|vr|j                  d       |r|D ]  }||vs|j                  |        |D ]  }| j                  |        | j                  |      }|d= n| j	                  |      } | j
                  ||||d|S )r  r  Tr  r   )r  r  r  )r  rx   r5  r  r  _list)rT   rH   r  r~   rO   r  rY   r  s           r"   rL   zBaseModel.list!  s    
 $F$ 
:%//
;+/(	
 6!d#"* 2J!/j12 % 4
''
34"33F; &"33F;syy$1AHgw  C  |B  C  	Cr!   c                   |}|s#|r!|D ]  }d|v s| j                  |      sd} n |rad|vr|j                  d       |r|D ]  }||vs|j                  |        |D ]  }| j                  |        | j                  |      }|d= n| j	                  |      }|j                         D ]C  }t        | |d      }|st        |dd      s!t        |dd      s/ | j                  |d	|i|c S   | j                  ||||d
d|S )r  r  Tr  r   Nr   Fr  rH   r  )r  r  r  r  )	r  rx   r5  r  r  r  ru   rL   r7  )	rT   rH   r  r~   rO   r  rY   r  r   s	            r"   r   zBaseModel.slist>  s\    $F$ 
:%//
;+/(	
 6!d#"* 2J!/j12 % 4
''
34"33F; &"33F;*//1 	@JCT2Eui/GEC[]a4bsxx?f???	@ syy$1AHgw  AI  T  MS  T  	Tr!   c                    t        | d      r#|j                  d      s|j                  dd       t        | d      r4|j                  d      s#|j                  d      s|j                  dd       t        | d      r#|j                  d      s|j                  dd       t        | d      rA|j                  d	      s0| j                  xs g }|j                  d	|j	                                |S )
Nr  r+  Fcmf_archivedr   is_dummyr,  orderingr   )rp   r,   rs   r<  r   )rT   _kwargsorder_fieldss      r"   _default_kwargszBaseModel._default_kwargse  s    3&w{{;L/M}e43'<N0OX_XcXcduXv~u53
#GKK,Hz51 3
#GKK
,C<<-2Lz<+<+<+>?r!   )r  r  include_veronly_ver_headc                   | j                  |      }|ru|D ]p  }t        | |d      }t        |dd      st        j                  s|j                  t        _        Dt        t        j                  |j                        t        _        r |sg }| j                  r|s|s|r|g dgng d}|r|r|g dgng d} | j                  j                  |||d|}	|	S )   
        Т.к. по show definition люди придут за гайдом по использованию filter именно сюда, дублирую доку
        https://bcrm.carbonsoft.ru/project/Document/DOC-000282
        Nr  )cmf_ver_curr   T)cmf_ver_head2cur!=N)r  r  )	r?  ru   r   r  r  r  r  r   rL   )
rT   r  r  r@  rA  r~   rO   rY   r   	inst_lists
             r"   r7  zBaseModel._listt  s     $$V,. c
Z65":DA---2-I-I*-01C1CUEaEa-b*c F;;}AG&"<=MgGM&"BCSsCFFKK8HQWb[ab	r!   c                 8    t         | j                  |i |      S r<   )rH  r   rT   r~   rO   s      r"   existszBaseModel.exists  s     ICIIt.v.//r!   c                P    | j                  ddg      } | j                  |d|i|S )r  r  r   r  )r  _count)rT   rH   r~   rO   r  s        r"   r   zBaseModel.count  s5    
 //t=szz4M2BMfMMr!   r  c                d    | j                  |      } | j                  j                  |d|i|}|S )rC  r  )r?  r   r   )rT   r  r~   rO   rets        r"   rL  zBaseModel._count  s8     $$V,cffllDN3CNvN
r!   c                 (     | j                   |fi |S )u  
        Метод-обёртка field_options_list для вызова с подстрокой поиска, чтобы избежать кеширования на фронте.
        Сейчас фильтрация идёт на фронте, строка поиска не передаётся. Вероятно этот метод никогда не понадобится.
        )r   )rT   r  searchrO   s       r"   field_options_searchzBaseModel.field_options_search  s     &s%%&9DVDDr!   models_filtersall_optionsrP  c                 
   | j                   j                  |      }|st        d| d|  | |      |sg }|r|xr |j                  d      }|r|dd|gg}g }|rd|d<   t        |t        j                   j
                        r|xs t        |dd      }|r|D cg c]  }t        t        |       }}n|j                         }|s'd	d
g}t        j                  j                  d| d       d}|r;t               }|j                         D ]  \  }}t        |||        t        |      }d}d}|rgt        j                  j                  ||ddg      }|rA|j                   r5t"        j%                  |j                   j&                        }|j(                  }|j+                  d      rst        j,                  j                  | j.                  |ddg      }|rC|A|j                   r5t"        j%                  |j                   j&                        }|j(                  }||j                   }|j(                  }|r0|.t0        j3                  d| j.                   d| d|d|d       g S d	}|D ]  } |r|}!nV|xs i j                  | j.                        }!|!| j4                  xs g }!|r|!|g}!|r|!|g}!|st7        | d      r|!dg dg dgg}!|rt9        j:                  |      }"t=        |      dk  r1ddd| dgddd | dgdd|" dgddd |" dgd!d| dgd!dd | dgg}#ndddd| dgddd|" dgd!dd| dgg}#| j.                  d"k(  r&|d#k(  r!dd$dd| dgd$dd|" dggg}$d|#d%|$d&d'd(d)gggg}#| j.                  d*k(  r.|
r,d+|
v s t?        tA        jB                  d, |
            rd|#d+d-|#gg}#| j.                  d.k(  r|d/k(  r~d|#d0dd| dgd1dd| dgd2d| dgd3d| dgd4dd| dgd5dd| dgd6dd| dgd7dd| dgd8dd| dgd9dd| dgd:d| dgd;dd| dgd<d| dgd=d| dgd>d| dgd?dd| dgg}#| j.                  d*k(  rIt=        |      dk  r%d|#dd@d| dgd@dd | dgdAd| dgdAdd | dggg}#nd|#dd@dd| dgdAdd| dggg}#| j.                  dBk(  rd|#ddCdD|gdEdd| dggg}#|!|#g}! | jD                  dJ|!|dF|}%tG        |d	   |z
  d	      }&tI        |dG   |d	   z
  t=        |      z
  |%      }'|&|&|'z   g}(||%z  }|(d	   |%kD  r|jK                   | jL                  dJ|
|!|(|	|dH|       t=        |      |dG   |d	   z
  k\  s |S  |S t        dI| d|  ||       c c}w )Ku  
        Метод для получения списка значений для выбора во фронтенде
        :param relation_field_name:
        :param object_id: в некоторых случаях для фильтрации передаётся id объекта - параметра фильтра, но он портит кеш
        :param object_fields: в некоторых случаях для фильтрации передаётся поля объекта - параметры фильтра
        :param all_options: Все возможные значения, используется в т.ч. для фильтрации на фронте.
        :param slice: диапазон значений для пагинации. !! Есть риск зацикливания, если бэк не будет поддерживать.
        :param search: строка поиска для фильтрации значений. no_cache? обсудить.
        :param kwargs:
        :return:
        u   Не нашел поле rg   r4  r   Tinclude_systemfield_options_list_limitNr   d   zfield_options_list u0    без slice, показали первые 100)SELFoptions_list_bqloptions_list_bql_exclusive)r(  rU   rH   cf_)cmf_model_namerU   rH   z%sz.field_options_list(z): require_field_filter=z and field_filter=z is None, return []
cmf_hiddenOR)r]  r   F)r]  r   Nr  rU   ILIKE%z% r3  rh  parent_taskzparent_task.nameANDr  INz	task.epicztask.subproject	CmfPersonrolesc                 $    | j                  d      S )Nzroles.)rz   )r  s    r"   <lambda>z.BaseModel.field_options_list.<locals>.<lambda>g  s    Q\\(=S r!   EXISTSCmfAssetassetszlocation.name	asset_tagserial_number	po_numberinvoice_numberlease_contractmaintenance_contractownership_typedevice_type
os_versionimeiphone_number	ip_adressdomain_namemarkcodeinv_noemaillogin
CmfCompanyinn==
legal_name)r  filter_contextrP  )rH   r  slicer   r  u)   Некорректный тип поля r    )'rH   r,   rq   rn   r   rr  ru   r   r  r  r&  r'   r)   r   rt   CmfCustFieldConfFieldrY  r"  loadsr   rZ  rz   CmfCustFieldri   loggingwarningdefault_options_filterrp   r   ninja_reversrq  anybuiltinsr  r   r  r  r  rL   ))rT   r  	object_idobject_fieldsmodels_listcust_field_conf_idrR  r  require_field_filterr   rH   r  filter_by_projectrS  rP  include_hiddenrO   r   r4  resultsrV  
model_namer  r  
obj_fieldsr/   r0   field_filterfield_filter_exclusivecust_field_conf_field
cust_fieldprocessed_countmmodel_filter
alt_searchsearch_filterby_parent_task_namemodel_countmodel_startmodel_lengthmodel_slices)                                            r"   r   zBaseModel.field_options_list  s   $ 

2389L8MM^_b^cdfik~F%H-*;*;K*HI ;Y"?@'+F#$eSZZ223'2'fgeE_ae6f$'Ph!i*'&*"=!i!i!&!5!5!7C%%(;<O;P  QA  'B  C!N'\
+113 .FQJ1-.!%:!6  L%)" " )/(D(D(H(H-4G.0LM )I )O% ),=='+zz2G2X2X2^2^'_1F1a1a.
 #--e4#0044#&>>8K.0LM 5 O
 #+
0K0K'+zz*2M2M2S2S'T1;1V1V.
 #$55).)I)I&#(< ~~&&:;N:O P.,..AL?BUWX 	  O# J)#/L %3$8b#=#=all#KL#+'('?'?'E2(4f'=#(4l'C)wq,/G(4t=WYr6s't ")!5!5f!=J6{Q)-$g&|<$gF81~>$g*Q/?@$gJ<q/AB$g&|<$gF81~>) *.$g6(!}=$g:,a/@A$g6(!}=) ||y05HM5Y/3/AfXQ-H/Aj\:KL6 /+
 !)"!4"0$FW8X!Y) 3"#v-"8??3SU[#\] !)$h>)@
 ||z16IX6U ),g6(!}E('Qvha=A,g&|D('fXQ<@-w!F81F-w!F81F3W&mL-w!F81F*Gq]C)7axqMB#Wl;+W&mD('fXQ<@*Gxq\B'VHA,?%w!F81>%)* ||{2v;? $ -!%%,g&|$D%,gF81~$F%,g&|$D%,gF81~$F	!"	-M !% -!%%,g6(!}$E%,g6(!}$E!"-M |||3 )!!&f 5!-w!F81 F) %1-#@L%aggc\.c\bc!%(_"<a@"58eAh#6W#E{S*K,,FG;.q>K/AFF A%l+X`'5A9?AB w<58eAh#66 [JZ  HO`ad`efhmorssG "js   U6c                 2   | j                  |d         }t        ||      }|D ]r  }t        t        j                  j
                        |d   j                  d      d      j                  |d         }|j                  |       |j                  d       t y )Nr   r	  r   rP  depth)	r,   ru   r   r   r  r   rA   rx   r   )rT   leftr  
right_listr6  r   ra   item_objs           r"   m2m_add_valueszBaseModel.m2m_add_values  s    ggd4j!01 	 DCKK../T
0@0@0Ea0HIMMT
H LL"JJQJ	 r!   c                 4    | j                    dt                S )Nr	  )ri   uuid1r   s    r"   r   zBaseModel.gen_id  s    ..!57),,r!   r   c                     |dkD  s| j                   syd| _         | j                  d      D ]  }|j                  |dz           y)ub   
            сброс состояния объекта после сохранения
        rP  NFTr  r  )r   r   flush)r`   r  r0   s      r"   r  zBaseModel.flush  sG     19DOO- 	%AGG%!)G$	%r!   c           	         | j                  d      D cg c]\  }t        | |      j                  du s@t        t        | |      j                  d      r"t        | |      j                  j                  r|^ }}|D cg c]  }t        t        | |      t              r|! }}|D cg c]	  }|dvs| }}|r| j                  |       y y c c}w c c}w c c}w )NTr   .r   )cmf_viewed_atcmf_viewed_bycmf_viewed_by_idcmf_version)r  ru   r   rp   r   r*   r  r  )r`   r/   rH   s      r"   _load_changed_fieldszBaseModel._load_changed_fields  s     "YY$Y7 x74;K;P;PTW;WgdA.335HIgVZ\]N^NcNcNuNu  x x#VJwtQ7G,T!VV $vq0u'u!vvV$ xV ws   A!C<CC&	C0Cc                      y r<   r    r`   r=  s     r"   before_save_hookzBaseModel.before_save_hook      r!   c           
          | j                   sg S | j                   D cg c]  }t        t        | |d      dd      du r|  c}S c c}w )u   Возвращает не изменённые поля из info_audit_fields (поля уже подгружены в save_preload_fields).Nr   F)r   ru   )r`   rY   s     r"   _load_info_audit_fieldsz!BaseModel._load_info_audit_fields  sQ    %%I)-)?)?
%wtZ6eLPUU 
 	
 
s   #Ac                      y r<   r    r  s     r"   before_save_data_hookzBaseModel.before_save_data_hook  r  r!   c                     g }| j                         D cg c]  }|s|	 }}t        t        j                  ||z               S c c}w r<   )r  rL   rt   fromkeys)r`   base_fieldsr  audit_fieldss       r"   save_preload_fieldszBaseModel.save_preload_fields  sF     #'#?#?#AGaQGGDMM+"<=>> Hs
   AAc                    t        j                  dd      }dd l}|j                         }| j                         }|r| j	                  |        |        |j                         |z
  dkD  rt
        j                  d|  d|        y y )NzBaseModel.save_prepare   r   rP  zPROF save_prepare z	 fields: )r   make_prof_pointr  r  r  r   r  )r`   
prof_pointr  prof_str  s        r"   save_preparezBaseModel.save_prepare  s}    ,,-EsK
))+"6680199; 1$GG(i8K7LMN %r!   c                      y r<   r    r   s    r"   check_edit_permzBaseModel.check_edit_perm  r  r!   c                      y r<   r    r   s    r"   check_delete_permzBaseModel.check_delete_perm  r  r!   )	only_dataemitc                   | j                         D ]  }|j                  durt        j                  t        j
                        }t        |t              r!|j                  r|j                         |_
        t        |t              r|j                  r||_
        | j                  st        |t              r!|j                  r|j                         |_
        t        |t              s|j                  s||_
         t        t        dd       }|rd| j                   v r| j"                  j                  du r|| _        | j                  r7d| j                   v r)| j&                  j                  du r|j(                  | _        | j                  r7d| j                   v r)| j,                  j                  du r|j(                  | _         | j0                  |d|i|S )N.r   r   r   r   r  )r   r   r   r   r   r   r*   r   r   r   r   r   r   r   ru   r   rH   cmf_modified_by_idr   r   r   cmf_author_idr   r  
_save_data)r`   r  r  r~   rO   r   r   r   s           r"   _save_importzBaseModel._save_import"  sh    [[] 	&E||3&,,x||,C%)enn!hhj%-%..!{{eW-%2D2D"%((*EKe[1e6H6H"%EK	& !$4d; DKK/D4K4K4R4RVY4Y'5${{|t{{:t?U?UY\?\%3%6%6"{{{dkk9dnn>S>SWZ>Z$2$5$5!t:4:6::r!   c                      ddd fd
}|S )NF)r  save_importc                 	   j                   r#t        j                  j                  d d      t	              }|t
        j                  v rO| r j                  dd| i|S t        j                  ddj                  t        j                                      S 	 t
        j                  j                  |       d_        j                  d      D ]n  }|   j                   rt#        |   j$                  t        j&                  j(                        sE|   j*                  |   j,                  k7  sed|   _        p t
        j.                  rd} t
        j.                  s| s|rdt
        _         t1              j                  g|dt
        j.                  i|}| rQdt
        _        |j3                  d	d      rVt5        t6              rFj                   r:t
        j9                  d
       j;                          t
        j9                  d       t5        t<              rtt?        d      rj@                  s\t?        d      rjB                  sDjD                  rjG                  d       njG                          t
        j9                  d       t5        tH        jJ                        rjM                          t5        t6              r jO                  ddjP                          |radt
        _        jS                          jD                  rd_*        jW                          d_"        n t1              j                  g|ddd| jS                          t
        jX                  dk7  rRt5        t6              r2jD                  sjZ                  j                   rj]                          j_                           j`                  di | d_1         t1              jd                  g|d| i| jb                  stg        d      d_"        t5        tH        jJ                        rjM                          t
        j                  ji                  |       d_        jk                          S # t
        j                  ji                  |       d_        w xY w)Nr   z is readonly, try save()r  z(BaseModel.save(): skip recursion save %s
Tr  Fr  
emit startemit endr;  is_templateinsertinitiator_actionzproject_notify endz_save_with_flush1 name=celery	debug_msg)r  
invalidatez@BaseModel.save_with_flush(): _save_data do not run during save()r    )6r   r   r   r   r   r   current_save_objectsr  r  infor@   	tracebackformat_stackaddr   r  r   rn   r\   rH   CmfJsonr   r   save_only_data_hackrJ   r,   r*   ro   r  r  r  rp   r;  r  r   project_notifyr   rQ  invalidate_cachemark_full_searchrU   r  import_originalr  disable_permissionsr(  _calc_projectr  r  r   r   r   remover  )r  r  r~   rO   self_idr/   r  r`   s          r"   save_with_flushz5BaseModel.save_flush_wrapper.<locals>.save_with_flush>  s   }}nn>>PTvUm?noo
 hG!000 +4??IYI&IIGS\SiSiSkIlmu/&&**73)-& d3 2AAw)) %d1g&7&79K9KL Aw~~a5-1Q*2 (( %I((I,0A)-T
--deTeQEZEZe^deA 05- "::fd3
48SX\XgXgGGL1 IIKGGJ/%dH5)0z)Bt}})0})E$JZJZ#{{ $ 3 3X 3 N $ 3 3 5GG$89 &dF,=,=> 113%dI6 11LcdhdmdmcnJo1p"05-))+;;37D0))+&+& *DJ))$bbRWb[ab %%',,4 &dI6DKK4;;KaKa !..0,,.)D))3F3+0D(#DJOODO4O9OO//)*lnrss
 #(DK!$(9(9:--/&&--g6).&JJLK &&--g6).&s   BR ;L%R (S r    )r`   r  r  s   `  r"   save_flush_wrapperzBaseModel.save_flush_wrapper=  s    -2 I	T r!   c                 D    | j                  | j                        | _        y r<   )r  r   r   s    r"   r   zBaseModel.wrap_save  s    ++DII6	r!   c                 L    | j                   j                  dd|i|}| j                  d      D ]  }|j                  dv r|j                  dk(  r"|j                  j	                  d      r.|j                  dk(  s|j                  dk(  s|j                  d	k(  sk|j                  j                  d
      rt        |t        j                  j                        s$t        |t        j                  j                        rt        ||j                  |j                          |S )Nr3  Tr  )r3  r   cmf_created_atr   r   r  r  perm_perm_encryptperm_encrypt_helpperm_policyr  r    )r   r   r   ri   rz   r  r*   r   rH   r   r  r   r   )r`   r3  rO   r  r   s        r"   clonezBaseModel.clone  s    dggmm000[[D[1 	8E#hh?2**73$$6''+>>''=8((/%!6!67:eSZZMfMf;gC))5;;7!	8" 
r!   c                      y)u4   
        Вычисляем кеш поля
        Nr    r   s    r"   _update_cache_fieldszBaseModel._update_cache_fields  s     	r!   c                      | j                   dddi|}|r+t        |       t        j                  vr| j	                          |S )u'   Метод вместо save(only_data)r  Tr    )r  r   r   r  r  )r`   r  r  rO   r6  s        r"   	save_datazBaseModel.save_data  s>     doo777RXQ%;%;;JJL
r!   )r  r  c                    d|f fd	}ddl }|j                         } j                           j                  r j                  nd}	  j                  s;d _         t	               j
                  j                   g|i   |||       nC j                           |||        t	               j
                  j                   g|i   j$                  dk(  sst'         dd      sf j)                  d      D ]Q  }|j*                  s|j-                         }|t         j.                  vs3t         j.                  j1                  |       S |j                         |z
  }|dkD  rGt3        d|dd j$                   d j4                   dd j6                  v xr  j                   d	       d _         S # t        $ rA}	ddl
m}
  |
d	| d
 j                   dd       t        j                  |	       Y d}	~	/d}	~	wt        $ r0}	ddl
m}
 t         j#                  |	        |
dd       Y d}	~	fd}	~	ww xY w)u)  
            Финальное низкоуровневое сохранение в базу
            Умышленно не разделяем save() на update() и create(), т.к.
            обычно в бизнес-логике очень много общего кода.
        Fc                    d}d}||k  r҉j                  d      D ]  }t        |t        j                  j                        re|scd}j
                  r+t        j                  j                  j                  d       n*t        j                  j                  j                  d       dv r|j                  || d   d       |j                  || d	        y y )
NrP  FTr  r   rN   notify)r  r  r   invalidate_done)r  r  r  )
r   r*   r   rH   r  r   app	CMF_CACHEr  r   )r  r  	max_depthr  r   rO   r`   s        r"   check_relationsz-BaseModel._save_data.<locals>.check_relations  s    I#O y ![[D[9 [E!%)>)>?
  /.2O#{{ # 1 1 < <T8 L # 1 1 < <T8 L6)

)FS[L\nr
s

)UY
Z![ !r!   r   Nu   объектаT)r  r  r%  u   Код  uS    уже существует. Укажите уникальное значение.r-  uA   Нарушение ограничения целостности.CmfOrmColumnHistoryr;  r  rP  z&!!! --- _save_data::duration too long .1f sec, r.  , r3  ))r  _acl_check_writeverbose_namer   rJ   r   r   r  rN   CmfOrmUniqueErrorr   r&  r3  r  	exceptionCmfOrmIntegrityErrorr   r  ri   ru   r   column_historyhistorydeffered_history_columnsrx   r  r   rH   r   )r`   r  r  r~   rO   r  r  startr  r  r&  r   field_historyr  s   `   `         r"   r  zBaseModel._save_data  s$    ',5 	[0 			
 	,0,=,=t((CS	h&&&*#$T
$$T;D;F;)5A ))+)5A %T
$$T;D;F; "77jZ^@_5 I''$)MMOM$A,F,FF2299-H	I
 99;&a<8# GOO$AdggYb&DKK2G1VTYY0WWXZ[  $5 ! 	!- ~Qtyyk  :M  N  VZ  [a  # 	h-GGAJ Ybfgg	hs%   B
F? ?	I 6HI %H;;I c                 .   | j                         D ]  }|j                  durt        j                  r#t        j                  t        j                        }t        |t              r!|j                  r|j                         |_        t        |t              r|j                  r||_        | j                  s|j                  durt        |t              r!|j                  r|j                         |_        t        |t              s|j                  s||_         t!        t        dd      }|rd| j"                  v r?t        j                  r(t        j                  r| j$                  j                  du r|| _        | j                  r-d| j"                  v r| j(                  j                  du r|| _        | j                  r-d| j"                  v r| j*                  j                  du r|| _         | j,                  di |  | j.                  |i |S )uA   
        Супер общая бизнес логика
        .r   Nr   r   r   r    )r   r   r   import_moder   r   r   r   r*   r   r   r   r   r   r   r   ru   rH   r  r   r   r   r  r  )r`   r~   rO   r   r   r   s         r"   r   zBaseModel.saveA  s   
 [[] 	&E||3&1==,,x||,C%)enn!hhj%-%..!{{<<s*eW-%2D2D"%((*EKe[1e6H6H"%EK	&  !$4d; DKK/}}$:Q:Q:X:X\_:_+9D({{|t{{:t?U?UY\?\"0{{{dkk9dnn>S>SWZ>Z!/""",V,t///r!   c                 Z    | j                          | j                  j                          | S r<   )r   r   commitr   s    r"   _test_save_commitzBaseModel._test_save_commitb  s    		r!   c                     t        d      )uw   
        Формируем кеш словарь связи объектов по parent_id и tree_parent_id
        
Deprecated)r~  r   r   r   r  r   r/  CmfAccessRule
CmfCommentr  r   r   ru   sysinternr4  r  r   tree_parent_id)r+  rU  r,  rO   r%  skip_modelsr   obj_datas           r"   _build_relation_cachezBaseModel._build_relation_cacheg  s     %%r!   c                 ^   t        j                         }t        j                  j                  | j
                  k(  r|j                          d}|j                  | j                  v rd|d<   	 t        j                  d|         |j                  dddi| 	 t        j                  j                  | j
                  k(  r |j                  |  y y # t        $ r t        j                         } w xY w# t        j                  j                  | j
                  k(  r |j                  |  w w xY w)NNNNTskip_owner_checku-   Удаляем дочерний обьект r  r    )r   disable_aclr   r   r   r  	__enter__ri   r   r  r   r~  r  exc_info__exit__r`   r6  rO   r(  r*  s        r"   _delete_child_objectzBaseModel._delete_child_object  s    ))+$"3"33!!##
 >>T888)-F%&	0GGCC5IJCJJ,T,V,
 ""d&7&77$$$h/ 8	  	||~H	 ""d&7&77$$$h/ 8s   ,,C C00C3 39D,c           	         |xs |}|xs |}|xs |} | j                   d||||d|}t               }| j                  j                  h}|rLt               }	|D ]8  }
|
|v s||
   D ])  }||v r|j	                  |       |	j	                  |       + : |	}|rLt
        j                  j                  j                  j                  dgdd|gddd      D ]  } | j                  |f||||d|  |D ]J  }t
        j                  j                  j                  |dg|      x}s3 | j                  |f||||d| L y )	Nr+  TEXKOM_db_deleterU  r,  r   r4  rc  T)rH   r  TECHCOM_nocacherU  r+  )rH   r+  r    )r$  r   r   r   r  r   r  r   r  rL   r-  r   r/  )r`   r0  r+  rU  r,  rO   relation_cachechildren_id_setlevel
next_levelr4  child_idcommentchilds                 r"   %_depricated_children_recursion_deletez/BaseModel._depricated_children_recursion_delete  s   *=o);^(9M333 3+>N_m'3+13 %J" 1	.$29$= 1#6$'++H5"x0	11 E  {{))4499uk4%I[_#T : ; 	lG &D%%g laq5CS`ldjl	l ( 	pH++99(C5bq9rrur)))% pcs9GWdphnp	pr!   c                    	 xs xs xs dfd	d fdddt         dt         f	 f	d  j                  j                  f        	 j                  j                  g      } |       y )Nid_listc           	      
   t               }t        j                  j                  j                  t        j                  j                  j
                  t        j                  j                  j                  f}t        j                         D ]  }g }||v r
t        |d      r|j                  dd| g       t        |d      r(|r|j                  dd       |j                  dd| g       |sa|j                  g dd|      D ]y  }t        |dd       r.|j                  t        j                   |j"                               t        |dd       sL|j                  t        j                   |j"                               {  |S )	Nr4  rc  r!  r   r^  r  r   r4  r!  T)rH   r1  r+  rU  r  r,  )r   r   r  r   r/  r  r  r  r   rp   rx   r  r   ru   r  r  r   r   )	r;  new_id_listr"  r   _filterr#  r+  r,  rU  s	         r"   list_children_idsz?BaseModel._children_recursion_delete.<locals>.list_children_ids  sR   %K KK&&44KK&&44KK&&11K "113 AK'5+.NNKw#?@5"23q.NN$4dG#DE %3^pt<K\jsz:G !, !I AH xd;#

8;;(?@x)94@#

8;;(?@AA& r!   c           	          t         j                  j                  j                  j	                  dgdd| gddd      D ]  } j
                  |fd  y )Nr   r4  rc  T)rH   r  r1  rU  r+  r,  r/  )r   r  r   r  rL   r-  )r;  r7  r0  r+  r,  rU  rO   r`   s     r"   delete_commentsz=BaseModel._children_recursion_delete.<locals>.delete_comments  s}    ;;--88==u#T73 $# $+ >   *))$3%5#1"/ r!   id_setc           	      d  	 |
t               } |       }|r+t        j                  dt        |       d        ||        |        | D ]P  }||vst        j
                  j                  j                  |dg      x}s9 j                  |f	d
 R |j                  |        y )Nu   Удаляем u    обьектовr   r*  )r+  r,  r0  rU  )
r   r   r  rq  r   r  r   r/  r-  union)r;  rC  r>  r6  r8  r0  rB  r+  r,  rU  rO   level_deleter@  r`   s        r"   rF  z:BaseModel._children_recursion_delete.<locals>.level_delete  s    ~+G4K/#k*:);;LMN[&1G$ $ C6) # 3 3 A A(TWSXjy  JW A  !X  Xu  X111%  Chu  IY  jx  C  |B  C	C LL!r!   )r;  r
   r<   )r   r   r   )
r`   r0  r+  rU  r,  rO   children_idsrB  rF  r@  s
   `````` @@@r"   _children_recursion_deletez$BaseModel._children_recursion_delete  sz    *=o);^(9M	<	 	&	"# 	"s 	" 	"( 	()($''--9\"r!   c                     | j                   D ]I  }t        j                  |      }|j                  dgdd| gd      D ]  } | j                  |fddi|  K y )Nr   r(  r   T)rH   r  r1  r'  )r   r   r1  rL   r-  )r`   rO   essential_child_model_nameessential_child_modelr7  s        r"   _essential_children_deletez$BaseModel._essential_children_delete
	  sw    *.*E*E 	T&$+$=$=>X$Y!055cUHVY[_K`rv5w T *))'SDSFST	Tr!   c                     |ri S g S )u(   Получим всех потомковr    )r`   group_by_modelsr=  s      r"   list_childrenzBaseModel.list_children	  s    $r,",r!   )	recursiver  r0  r   c                "   | j                  dg       | j                  dvrh|s|r.|j                  dd      xr ||d<    | j                  dd|i| n6|s$| j	                  d      x}rt        d	|  d
|      | j                          t        | t              r9| j                  r-|s+d| _
        |j                  dd        | j                  |i |S | j                          g }| j                  D ]E  }	t        | j                  |	   t         j                  j"                        s5|j%                  |	       G |rO| j                  |dd       |D ]6  }	t'        | |	      st)        | |	g        t'        | |	      j                          8 t+        | d      r@| j,                  r4t.        j0                  j3                  | j4                  j6                  d        t9        |       j:                  j<                  | g|i |}
| j?                          |
S )Nr   ru  r  	CmfNotifyCmfAttachmentr   Fr0  T)	skip_subsu   Нельзя удалить u1   , на него ссылаются потомкиr  )r+  r,  full_searchr   r    ) r  ri   r,   rH  rO  CmfOrmHasReferenceErrorrL  r*   r  logical_deleter  rs   r   r  rH   rn   r   r  rx   ru   r   rp   rV  r   CmfFullSearch_text_search_sql_delete_partnor   r   rJ   r   r   r  )r`   rP  r  r0  r   r~   rO   children
m2m_fieldsrY   r  s              r"   r   zBaseModel.delete	  s   & ??"NN, $*::h#>#I6x ///\AQ\U[\D,>,>,>,N N N-0LTF  SD  /E  GO  P  P //1dH%$*=*=FV#Dk40499d-f--
++ 	.J$++j13::3H3HI!!*-	. ZTR( 5
4,D*b1D*-2245 4'D,<,<  ??qQ"d4jmm""49$9&9


r!   rP  c                    d| _         d| _        |j                  dd        | j                  |i |}| j                  dvr&|r | j
                  di | |S | j                          |S )uy   
        Восстановление из корзины логически удаленного объекта
        Fr  TrR  r    )r  tree_node_is_branchrs   r   ri   _children_recursion_restore_essential_children_restore)r`   rP  r~   rO   r  s        r"   restorezBaseModel.restoreE	  sx     ! $) +t,dii((??"NN000:6: 
 002
r!   u0   Восстановление из корзины)descriptionshow_bg_progressbar	only_oncec                     t         j                  d|         t        j                  | d      } |j                  |i |}|j
                  S )u   
        Восстановление из корзины логически удаленного объекта через джобу
        zStart restore obj T)r+  )r   r  r   r/  rb  r   )obj_idr~   rO   r6  r  s        r"   r   zBaseModel.restore_deferredY	  sH     	
$VH-.##FDAckk4*6*vvr!   c                      y r<   r    r   s    r"   tree_child_restore_hookz!BaseModel.tree_child_restore_hooke	  r  r!   c                 ,   | j                   D ]  }t        j                  |      }|dk(  r7|j                  dgdd| gg dgddd      D ]  } | j                  |fi |  T|j                  dgdd| gddd      D ]  } | j                  |fi |   y)	u   
        Восстановление дочерних объектов которые являются неотьемлемой частью объекта
        Вложения, комментарии и т.д.
        r  r   r(  r   )tree_parentr~  NT)rH   r  r1  r+  r,  N)r   r   r1  rL   _restore_child_object)r`   rO   rJ  rK  r6  s        r"   ra  z%BaseModel._essential_children_restoreh	  s     +/*E*E 
	>&$+$=$=>X$Y!)\9055cUXWZ\`Lab}K~  QUFJZ^ 6 ` >C.D..s=f=> 155cUHVY[_K`rvHL\` 6 b >C.D..s=f=>
	>r!   c                    t        j                         }t        j                  j                  | j
                  k(  r|j                          d}	  |j                  di | 	 t        j                  j                  | j
                  k(  r |j                  |  yy# t        $ r t        j                         } w xY w# t        j                  j                  | j
                  k(  r |j                  |  w w xY w)uP   
        Восстановление дочернего объекта
        r&  Nr    )r   r(  r   r   r   r  r)  rb  r~  r  r*  r+  r,  s        r"   rl  zBaseModel._restore_child_objectz	  s     ))+$"3"33!!##	0CKK!&!
 ""d&7&77$$$h/ 8	  	||~H	 ""d&7&77$$$h/ 8s   B B99B< <9C5c           	         t               }| j                  j                  h}t        j                  j
                  j                  t        j                  j
                  j                  t        j                  j
                  j                  f}|rt               }t        j                         D ]  }||v rd}t        |d      rddt        |      g}t        |d      r"|rd|ddt        |      gg}nddt        |      g}|sU|j                  g ddd|d|      D ]>  }	t        |	j                        }
|
|v r|j                  |
       |j                  |
       @  |}|rt         j#                  d	       t        j                  j
                  j                  j                  d
dgddd|gdd| ggdgdd      D ]  } | j$                  |fi |  t         j#                  d       |D ]F  }
t        j                  j&                  j)                  |
d
gdd      x}s4 | j$                  |fi | H t         j#                  d       y)ul   
        Рекурсивно восстанавливаем все дочерние объекты
        Nr4  rc  r!  r^  r=  T)rH   r1  r+  rU  r,  r  z%_children_recursion_restore end levelr   r(  r   r  )rH   r  r   r1  r+  z3_children_recursion_restore end restore CmfCommentsr*  z7_children_recursion_restore end restore children_id_set)r   r   r   r   r  r   r/  r  r  r  r   rp   rL   r   r
  r  r   r  rl  r   r/  )r`   rU  rO   r3  r4  r"  r5  r   r  r#  r6  r7  r8  s                r"   r`  z%BaseModel._children_recursion_restore	  sK    % KK,,KK,,KK))
 J!113 -K'#5+.$/tE{#CL5"23#(,l=MtUYZ_U`<a'b(8$U'L# %3^pt<@Q_os3? !, !A -H  #8;;/H?2 #''1NN8,--, E1 2 	
79 {{))4499X{D/BXsTXDYZ*+ $d	 : < 	:G
 'D&&w9&9	: 	
EG' 	<H++99(C5bfvz9{{u{***5;F;	< 	
IKr!   c                 V   t         j                  ry | j                  dk(  ry | j                  dk(  rft         j                  t         j                  k7  rEt
        j                  j                  d| j                  | d       t        d| j                         t        | t              xr | j                  j                  }t        | t              xr | j                   j                  }| j"                  rKt        | t              xr8 | j$                  r| j&                  j(                  n| j&                  j                  }n(t        | t              xr | j&                  j                  }| j                  }| j                  dk(  rQt         j                  t         j                  k(  ry 	 t
        j*                  j-                  d| j                          y | j                  d	k(  rd
}| j/                  d      D ]  \  }}	|	j0                  dk7  s|dk7  sd} n d}
t3        t5        |       d      rVt5        |       j6                  rA| j/                  d      D ],  \  }}	|	j0                  r|t5        |       j6                  vs+d
}
. |sy t         j                  st         j8                  ry t         j                  t         j                  k(  ry t
        j*                  j-                  dd
      ry t
        j:                  j=                  g dd      }| j                  dk(  re| j$                  xr& |j                  j>                  t         j@                  v }| j$                   xr! |t         jB                  j                  k(  xr |
}n| j$                  xr& |j                  j>                  t         j@                  v }| j$                   xrI |t         jB                  j                  k(  xr* |j                  j>                  t         j@                  v xr |
}|s|rKt3        | d      r>| jD                  r2tG        | | jD                        jI                         jK                          y t
        j                  j                  d|| d       | j$                  rt        d      t        d| j                   d|       	 t        | tL        j
                  j                        xr | jN                  j                  }tQ               }|rtQ        |      }| j/                  d      D ]n  \  }}||v r|jS                  |       |j0                  r(t
        j*                  jU                  d||||| j                  j>                  || | j$                  |
       p |ra|D ][  }| |   }|j0                  rt
        j*                  jU                  d||||| j                  j>                  || | j$                  |
       ] y y # t        $ r*}t
        j                  j                  d|| d       |d }~ww xY w# t        $ r{}|jV                  d| j                   fz   |_+        tY        jZ                         5  t
        j                  j                  d| j                  | d        # 1 sw Y   nxY wY d }~y d }~ww xY w)Nno_aclr  rN   failoperater\  r(  result_statusuO   Отказано в модификации системного объекта adminmessageproject_adminFTr  r  r   r:   r-  )r3  r~  ProjectAdmins)r  cache_inmemoryCmfPersonGroupacl_self_parent_link_depricatedu   Отказано в создании объекта. Разрешено только Администраторам системы и членам группы Создатели проектовu:   Отказано в модификации объекта u   . Разрешено только Администраторам системы или Администратору проекта и Владельцу объекта write)
access_levelinitial_acl_keyobject_modelobject_owner_idobject_fieldr  object_parent_idobject_instancer   perm_security_level_allowed_ids).r   r  r   r   r1  r   CmfAuditaudit_eventri   r\  r   r*   ro   r  oldr  r4  r   r   r  newr/  r0  r)   rp  rp   rJ   r   acl_admin_moder{  r,   r   current_person__member_ofcurrent_userr|  ru   loadr  r   r  r   r  check_accessr~   r   r(  )r`   force_check_fieldsr  obj_parent_idobj_owner_idri   r  
need_checkchanged_field_namechanged_fieldowner_write_fields_allowproject_admins_groupaccept_creationaccept_editr  force_check_fields_setrY   r   s                     r"   r  zBaseModel._acl_check_write	  s6     ==H$==H$)9)9Q__)LOO''aeu{'|$'vw{w~w~v  &A  B  B$T95X$:T:T:X:X"42It~~7I7I   %dH5 Q)-!!%%$:K:K:O:O  &dH5O$:K:K:O:OL__
==G#1??2$$55  AP  QU  QX  QX  PY  ?Z5  [ ==O+ J59ZZ4Z5P 1"M ''4/4FJ[4[!%J (,$tDz#BCT
HpHp9=t9T 95&$++ )d1Y1YY380	9 $$(8(81??2##44RU4K#)#8#8#<#<Dctx#<#y 
 "22"&++"n2F2I2I2O2OSTSnSn2n"&++op,!..BSBS2SpXp"&++"n2F2I2I2O2OSTSnSn2n"&++o |,!..BSBS2S |"6"9"9"?"?1C^C^"^|c{ + 4!BCHlHlD$"F"FGLLN__aOO''\`6< ( >{{( ,[ ] ] )+efjfmfmen oO P\  O]*^ _ _%	4>tSZZEYEY4Z  5N_c  `J  `J  `N  `N1%(U"!),-?)@&%)ZZ4Z%@ 	o!
E!77*11*=<<$$11!(/!+\Xb"ggmmm]a;;Hm	 2 o	o &"8 sJ ,E|| ((55%,o%/\f"&''---ae#{{Lq	 6 s	s &a & ++HZ`dtz+{B " 	VV![\`\c\c[dehhAF$$& ++HT__eiy+  A  	sC   $-W. 4D8X$ .	X!7%XX!$	Z(-6Z##/ZZ	Z##Z(c                    | j                   dk(  s| j                   dk(  ryt        | t              xr | j                  j                  }t        | t
              xr | j                  }t        | t        j                  j                        xr | j                  j                  }| j                  }	 | j                  d      D ]  \  }}	|	j                  r|rFt        j                  j                  d|||| j                   j                  || j"                  |      }
nFt        j                  j                  d|||| j                   j                  || | j"                  |	      }
d|
vst$         y# t$        $ rX}|j&                  d	| j                    fz   |_        |s-t        j(                  j+                  d| j                  | d
       |d}~ww xY w)u  
        check_fields - если контретные филды проверить, передать явно список
        Дефолт - загруженные (is_defined) поля
        TEXKOM_skip_failread_audit - используем, когда не нужно аудировать отказ в чтении.
            Прямой отказ при открытии объекта мы аудировать должны, а вот если объект отфильтровали в list или поиске - нет
        TEXKOM_ppp_project_simplecheck - игнорирование объектных разрешающих правил в проектных правах PPP-PR-BROWSE
            TODO1: после рефакторинга этих правил по аналогии с perm_security_level_allowed_ids_cache - уничтожить флаг
            для некоторых мест (например, поиск) ради скорости игнорируем, что не отобразятся доступные объекты в закрытых проектах
                (где пользователю проект недоступен, но есть доступ через поля объекта)
        rp  public_readNTr  read)r~  r  r  r  r  r  r   r  )	r~  r  r  r  r  r  r  r   r  u0   Отказано в чтении объекта rq  rr  )r   r*   ro   r  r   r  r4  r   r   r  r  ri   r)   rp  r/  r  r   r   r\  r~   r  r  )r`   rV  TEXKOM_skip_failread_auditTEXKOM_ppp_project_simplecheckr  r  r  ri   rY   r   rulesr  s               r"   r[  zBaseModel._acl_check_readN
  s    ==H$(F$T95Z$:T:T:Z:Z"42Et~~0:4AUAU0V  1J[_  \F  \F  \J  \J-__
'	%)ZZ4Z%@ -!
E<<1"00==%+_%/j"&''---#{{8] > E #00==%+_%/j"&''---(,T[[8] > E &,,+-B " 	VV!QRVRYRYQZ[^^AF-++F4??cgw}+~G	s    /B7E/ 'E/ /	G8AGGc                      y r<   r    r   s    r"   _check_sl_owner_lockzBaseModel._check_sl_owner_lock
  s    r!   )rH   save_kwargsr  c                     | |i |}|si }|j                  d|      |d<    |j                  di | |r| j                  |j                  |      S |S )Nr  ru  r    )r,   r   r   )rT   rH   r  r  r~   rO   r   s          r"   r   zBaseModel.create
  s^    ''K#.??;	#JK $$778;;v766r!   c                     | j                   S r<   )rl   r   s    r"   r   zBaseModel.get_meta
  s    {{r!   c                 
   | j                   t        j                  vrg }| j                         D ]  }|j                  r|j
                  d   j                         D ci c]  \  }}|j                  d      r|| }}}|s|j                  s`|j                  |j                   |j                  |j                  |d        |t        j                  | j                   <   t        j                  | j                      S c c}}w )NrH   r[  )ri   ui_group_fieldsrM  rH   )ri   APPall_models_metar   rm   rl   r)   rz   rM  rx   r  )rT   _argsr=  r%  modelClsrY   
field_metacustom_fields_metas           r"   r  zBaseModel.all_models_meta
  s     >>!4!44F//1 $$IQIYIYZbIcIiIiIk&/Ez:!,,U3 
*&" & &)9)9MM&.&9&9+3+C+C#+#3#3"4	#  39C/""3>>22&s   C?c                     t        | d      r#|j                  d      s|j                  dd       t        | d      r#|j                  d      s|j                  dd        | j                  j                  | g|i |S Nr  r+  Fr;  r,  )rp   r,   rs   r   bulk_deleterI  s      r"   r  zBaseModel.bulk_delete
  n    3&vzz:K/LmU33
#FJJ,Gj%0!svv!!#7777r!   )r   c                z    |D ]  }| j                         |d<     | j                  j                  | g|d|i|S )Nr   r   )r   r   bulk_insert)rT   r   r~   rO   r0   s        r"   r  zBaseModel.bulk_insert
  sF     	#AjjlAdG	#!svv!!#FFVFvFFr!   c                     t        | d      r#|j                  d      s|j                  dd       t        | d      r#|j                  d      s|j                  dd        | j                  j                  | g|i |S r  )rp   r,   rs   r   bulk_updaterI  s      r"   r  zBaseModel.bulk_update
  r  r!   )r  c                ,   | j                   s_t        j                  | j                         t	        | d      rt        j                  | j
                         t        j                  d       | j                  j                         D ]  }||vrt        | |      }t        |t        j                  j                  t        j                  j                  f      rSt        |t              r6|j                   s|j"                  dk7  r|d d |vrt%        | |d d ||          t%        | |||           |si }|j'                  dd       |d= t        j                  d       | j)                          t        j                  d        | j*                  di |S )	Nr3  zupdate cache_obj_lock_get endr   r  zupdate setattrs endzupdate _check_sl_owner_lock endr    )TEXKOM_no_cacher   cache_obj_lock_getr   rp   r3  r   r  rH   r  ru   r*   r   r   CmfGenericBackrefCmfTUUIDforeign_keyri   r   r,   r  r   )r`   r  r  rO   rY   	field_objs         r"   rN   zBaseModel.update
  sY   ##&&tww/tV$**4995GG34 ++**, 	:J'j1I)cjj&;&;SZZ=Y=Y%Z[)X.I4I4IYMaMaeiMi "#2&0D*Sb/6*3EFD*fZ&89	:  K??;-9K(	%&!!#	12tyy';''r!   )r  r  c                    i  fd          j                   di ddd}|s         g}t        |      dkD  r't        j                  j	                  d| d d        |d	   j
                  dd
|i| |d	   S )u  
        update or insert: Создаём новый объект или изменяем уже существубщий.
        fixme т.к. фильтр работает по _id, а присваивание по релейшен, то используем filter только для поиска,
          а в kwargs нужно дублировать поля ключа. Пример: upsert(filter=[person_id, =, '...'], person={id: '...'}, ...)
        :param filter: фильтр по ключевому значению, используется для поиска объекта.
         Только простой фильтр на равенство: [field, ==, value] или [[field1, ==, value1], [field2, ==, value2]]
        :param save_kwargs: параметры вызова .save
        :param kwargs: поля которые нужно изменить: {field: value, ...}
        :return:
        c                    | rt        | d   t              r| D ]
  } |        yt        |       dk7  s| d   dvr't        j                  j                  d|  d d       | d   j                  vr+t        j                  j                  d	| d    d d
d       | d   | d   <   yt        j                  j                  d|  d d       y)u   Соберём в key_values значения полей из фильтра, и проверим, что фильтр простой.r   r  rP  )r   r~  ud   Фильтр для upsert должен быть простой: [field, =, value], передан: r
  Tr-  u8   В фильтре upsert неизвестно поле: u6   , допустимый фильтр: [field, =, value]r  u2   Указан пустой фильтр в upsert: N)r*   rL   rq  r   r  r&  rH   )
sub_filtersub_sub_filtercheck_simple_filterrT   r  
key_valuess     r"   r  z-BaseModel.upsert.<locals>.check_simple_filter  s   jmT2*4 <+N;< :!+z!}K/O--00:|2fXGNR . T "!}CJJ6--VWabcWdVeeghngo pT U\` . b 1;1Jz!}-%%(Z[eZffhiohp&qy}%~r!   T)r   r  )
for_updater  rP  u9   Ключ в фильтре upsert не уникален: r
  r-  r   r  r    )rL   rq  r   r  r&  rN   )rT   r  r  r  rO   obj_listr  r  s   ``    @@r"   r   zBaseModel.upsert
  s     
	* 	F#388HjHTHwHx=1KK!!$]^f]ggijpiq"rz~!={=f={r!   c                    t        | d      rt        | d      r| j                  j                  sE| j                  j                  s/t	        |       j
                   d| j                  j                   dS t	        |       j
                   d| j                  j                   d| j                  j                   dS t	        |       j
                   d| j                  r| j                  j                   dS | j                   dS )NrU   r3  r.  r  : )	rp   rU   r  r3  rJ   r   r   r   r   r   s    r"   __repr__zBaseModel.__repr__#  s    4 WT6%:99''		0D0Dt*--.a/?qAA4j))*!DII,<,<+=R		@P@P?QQRSSt*%%&aASAS(:(:(=(='aabccY]Y`Y`'aabccr!   c                 b   t        | t              r#| D cg c]  }t        j                  |       c}S t        | t              r`d| v r\| d   }t
        j                  |      }| j                         D ci c]  \  }}|t        j                  |       }}} |di |ddiS | S c c}w c c}}w )Nr   r   Tr    )r*   rL   r   	from_jsonrt   r  get_cls_by_tuuid_strr)   )r"  r   r  rT   r/   r0   rH   s          r"   r  zBaseModel.from_json,  s    dD!489qI''*99dD!ddlt*C//4C<@JJLIDAqa,,Q//IFI,,t,, :
 Js   B&5 B+c                 n    |sg }i }| j                  d      D ]  \  }}||vr|j                  ||<    |S )NTr  )r)   r"  )r`   rH   rN  	fieldnamer   s        r"   to_jsonzBaseModel.to_json9  sM    F $

d
 ; 	(Iu&"ZZC	N	(
 
r!   c                 ~    |dk(  rt        j                  |       S |dk(  rt        j                  |       S t               )Nrt   r"  )r   
dumps_dict
dumps_jsonNotImplemented)r`   rJ   s     r"   r#  zBaseModel.dumpsG  s;    6>%%d++V^%%d++r!   c                    t               }|r| j                  |v r|S |r"t        di | j                  t               i|}nt               || j                  <   | j                  dg      }| j                  j                  |      D ]  }| j                  ||       |j                         }| j                  j                         D ]Y  \  }}t        |t        t        f      r||v r||= |j                  |      r~t        |t        t        f      rh|r|j                  |v r\|j                  |v rk|j                  | j                  k(  rt!        t"              |j                     }|j%                  |      }|j                  |      st        |t&        t(        f      s|j"                  st+        d| d       |j"                  D ]S  }	|r|	|v r
|	|v r|	| j                  k(  r|	t!        t"              vr1t!        t"              |	   }|j%                  |      }U \ || j                     j-                  |        |S )uT  
        Дампим все обьекты класса и ссылки в dict для последующей серилизации
        :param upper_res: предыдущий дамп для исключения повторений и правильной последовательности
        :return: словарь
        r   r  u   WARNING: поле u    без modelsr    )r   r   rL   r  r   _load_extra_fieldsrv  rH   r)   rn   r  r  r,   CmfRelationCmfM2Mr   r   r   dump_data_dictCmfGenericRelationCmfGenericM2Mr  rx   )
rT   	upper_resr  r  ra   	item_dictrY   rZ   fk_modelr  s
             r"   r  zBaseModel.dump_data_dictN  s    m2Dtv 6D)DC $C//6FFKK1AKB )	0D""4)9:,,.I),)9)9); #;%
Ii/>)JK!Y.%j1==,IU[G\1] Y__	%A  #-  #,,6 #F|IOO<H"11#6C]]:.:iJ\JWJY 4Z$++ 2:,nMN &/&6&6 ;
$y)@$%,$%5$%T&\9$#'<
#;&55c:;/#;H $$Y/S)	0T 
r!   c                     t        |t              r| j                  |j                  k(  S t        |t              r0|j                  j                  ry| j                  |j                  k(  S yNF)r*   r   r   r  is_null)r`   others     r"   __eq__zBaseModel.__eq__  sO    eY'77ehh&&e_-xx77ehh&&r!   )NNcsvFNNNF)FNNN)NNNNNrP  Nr<   )NNTFr&  r  FF)NNNNNNNNNNFFNF)r   r   )FNF)FFFFTFNFF)r"  )r   r   r   r   rm   fields_orderr<  r  verbose_name_pluralr   r  rM  r  r  r   customsmart_notifyr   rL   rI  rz  r   r   r
  r   r   rH  r   r   r   r   r   r   r   r  enable_edit_permenable_delete_permrh   rH   rj   r   r   iconcache_cluster_fieldsr{   classmethodr   r   r   rb   r   r   r   r   r  r  r|   r   r  r  r)   r   r  r  r   r7  rN  r   ri  rl  rn  rx  rv  r  rt   r  r  r  r  r  staticmethodr  r  r	   rK   r  r  r  Typer   r,   r   r   r'  r  r5  r   r   r?  r7  rJ  r   rL  rQ  r   r  r   r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r   r  r$  r-  r9  rH  rL  rO  r   rb  cmf_deferred_jobr   ri  ra  rl  r`  r  r[  r  r   r   r  r  r  r  rN   r   r  r  r  r#  r  r  r    r!   r"   r   r      sV   LHLH!LMOGO!FL"t"N
 H Hc'!d!(, #,)-!3-(, #,$(c(It
K( G  IFKND L< 0 0  <	)+## J
   4 4	%hc"" 33 33 3 3  & % %N ( (T > >      D.`   ^u ^u ^u@ .4 . .  "d " "H ? ? ?4J  K~ s4 4  4
 t   O O )- Lb LB L L8 *. ]$r( ]R ] ]. *.U]a G GR 
T"X 
 
   O O *. C$r( CDQSH C C8 +/$ $T48 $TT $T $TL   +/%_d  4 0 0 !% N N ,0   E E osKOFKHM	H H 	H 03	H HT     - -
%%$
 

?
O2 -1u ;6KZ7* '(5 Ob0B
  20."pHL#\T- ',55Y] ,\ (- ( "Tjnz~ @ >$0">L@AF<| "&DE     3 3* 8 8 ') G G
 8 8 *. '(R #'T ) )Vd 
 
 : :xr!   )	metaclassc                       e Zd ZdZ	 dZdZdZej                  g dz   Z e	e
dddddd      Z e	ed	dddd
gdd      Z e	eddddd
gdd      Zej                   j                  ej                   j"                  dddd      Z e	eddddd
gdd      Z e	eddddd
gdd      Z e	eddddd      Z e	edddddddd	      Z e	edddddddd	      Z e	eddddddd      Z e	edddddd       Z e	ed!ddddd"#      Zed$e fd%       Z!d4d&Z"e#d5d'       Z$e# fd(       Z%e#d5 fd)	       Z&d* Z'd6d+Z( fd,Z)d- Z*d. Z+ fd/Z,d7d0Z-d1 Z.d8d2Z/d3 Z0 xZ1S )9r  us   Базовый класс, содержит стандартные поля для типовых объектов.T)r  F)all_relation_persons
get_ownersget_project_name)   Идентификатор объекта3   Автоматически генерируетсяrG   r7  nullablerj   r   r  u
   Авторrd  CmfPersonWidget)rG   r  linkabler   r   fullsearch_indexwidgetu   Владелец)rG   r  r   r  r   r  r   u   Родительro   )rG   
base_modelr  r  u'   Последний изменивший)rG   r  r   r  r   autorp  u$   DEPRICATED. Кто захватил r  )rG   r  r   indexr   r  rp  u#   DEPRICATED. Дата захвата)rG   r  r   r  rp  u   Дата создания)rG   r  r   r  r   r  r  r  u   Дата изменения)rG   r  r   r  r   r  r  rp  u   Дата просмотра)r  rG   r   r  r   r  rp  u   Удален)rG   r  r   r%   r  r  u   Номер версии
CmfVersion)rG   r  r   r  rp  r   r  c                 ,    t        |       j                  S r<   )rJ   r   r   s    r"   r   zCmfModel.db_name!  s    Dz!!!r!   c                    g d}|r$dD ]  }|D ]  }|j                  | d|         ! | j                  |       t               }| j                  r6|| j                  j                  |k(  r|j                  | j                         t        | dg       D ]%  }||j                  |k(  s|j                  |       ' t        |      S )N)r   cmf_owner_assistantszcmf_owner.user_localzcmf_owner_assistants.user_local)r   r  rF   ru  r  )rx   r  r   r   
user_localr  ru   rL   )	r`   rH   r  rO   self_fieldsperson_field_namer  r%  owners	            r"   r  zCmfModel.all_relation_persons%  s    v%H C! CA&&*;)<AaS'ABCC 	,>>!T^^%>%>*%L

4>>*T#92> 	"E!U%5%5%C

5!	" F|r!   c                    g }g }|r&|D ]   }|j                  | j                  |          " n| j                  j                         D ]  }t        |t        j                  j
                        r(|j                  dv r7|j                  j                  d      r+|j                  dk7  r|j                  j                  d      s}|j                  s|j                  |        |D ]z  }|j                  |j                  |j                  |j                  |j                  xr |j                  | j                  | j                  |j                  |j                   d       | |S )N)r   r3  r  r  r  
cmf_importr  import_raw_jsonr  ext_idr[  )rG   rY   field_qualnamerequiredr  r  r   r  )rx   rH   r   rn   r   r   ri   r  rz   r  rG   r   r  r  r  r   r  )rT   fields_namer%  rH   rY   r   s         r"   import_shop_fieldszCmfModel.import_shop_fields5  sA   ) 6
cjj456 **, %eSZZ%:%:;## (\ \$$--e4((H4!,,77>}}e$%  
	EMM ==#.."'"4"4!NN<u}} # 0 0,,"'"6"6	 	
	 r!   c                    t        |j                               j                         D ]  \  }}|j                  d      st        | |j	                  d      d         s7|s:d|vs?t        t        j                  j                        |j	                  d      d      j                  |      ||j	                  d      d   <    t        | ,  |i |S )Nr  r   z:Classr	  )r   )rt   r)   r  rp   rA   r   r   r  r   r,   rR   r   )rT   r~   rO   r/   r0   r\   s        r"   r   zCmfModel.createY  s    (..0 	DAq

5!gc1775>!3D&E(!+ -11C1C,DGGCLO-##) qwwu~a()	 w~t.v..r!   c                     |g }|dv rc|dk(  r^|j                  dd       rL|d   j                  dd       dk(  r4|j                  dd       r"d|vri |d<   dg i|d<   t        |   |fd	|i|S t        |   |fd	|i|S )
N)r   r   r  r   r  parent_logic_prefixzproject.servicedeskrP  rR  rd  r  )r,   rR   r   )rT   r  r  rO   r\   s       r"   r   zCmfModel.field_options_listf  s    >F"UU
 #k1JJ5?+//0EtLPee::h-'v535/00;R/@F+, 756IcRXc\bccw)*=WfWPVWWr!   c                     | j                   j                  s| j                  sy t        t        j	                  t
        j                        j                  d      d d       | _         y )Nz%Y%m%d%H%M%S%fr  )r  r   r  r   r   r   r   strftimer   s    r"   _increment_versionzCmfModel._increment_versionz  sI    &&doox||HLL9BBCSTUXVXYZr!   c                      y r<   r    )r`   r  s     r"   r  zCmfModel.project_notify  r  r!   c                     | j                          t        | d      r| j                  s/| j                  r| j	                  d       n| j	                          t        |   |i |S )Nr  r  r  )r  rp   r  r   r  rR   r   r`   r~   rO   r\   s      r"   r   zCmfModel.save  sY    !m,1A1A{{##X#>##%w|T,V,,r!   c                 J   t         j                  g}| j                  }d }| j                  j                  r| j                  j                  }|s|S |j
                  j                  d      rd}t        j                  |      }nOd}| j                  }| j                  j                  r| j                  j                  }|r|j                  ddg       |s|S |s<|j                  j                  r&|j                  |j                  j                         n|j                  |j                         t        |d      rh|sD|j                  j                  r.|j                  j                  D ]  }|j                  |        |S |j                  D ]  }|j                  |        |S )NCmfProject:TFr  r   )r   r1  r4  r   r  r   rz   r  get_cache_projectperm_parentr  r   rx   rp   r  )r`   r%  r  r   
is_projectr  s         r"   get_parent_ownerszCmfModel.get_parent_owners  se   //">>$$..,,KM **=9J//?KJ**K~~(("nn00'')?(MNM k33>>MM+//334MM+//0; 67+"B"B"M"M(==AA )EMM%()
  )== )EMM%()r!   c                 `   | j                  g d       t        j                  g}| j                  j                  r&|j                  | j                  j                         n|j                  | j                         t        | d      re| j                  j                  r-| j                  j                  D ]  }|j                  |        n"| j                  D ]  }|j                  |        | j                  r|j                  | j                                |D cg c]  }|s|	 c}S c c}w )u   
        Все владельцы обьекта
        fixme метод используется для проверки прав доступа, но не для всех владельцев сейчас реализован доступ.
        )r   r  r(  r  )r  r   r1  r   r   rx   r  rp   r  r(  r  r"  )r`   r~   rO   ownersr  s        r"   r  zCmfModel.get_owners  s    
 	HI//" >>$$MM$..,,-MM$..)4/0((33!66:: )EMM%() "66 )EMM%();;MM$0023#)3%U333s   D+$D+c                     | j                   s7| j                  j                  r!t        j                  | j                         v ry t        |   di |S )Nr    )r   r   r   r   r   r"  rR   r  )r`   rO   r\   s     r"   r  zCmfModel._acl_check_write  sC    {{t~~884#9#9#;;w'1&11r!   c           	      h   | j                   sy t        j                  ry | j                  sI| j                  ry d}| j                  d      D ]Y  }|j                  | j                         vs |j                  j                  d      r<|j                  j                  d      rXd}[ |r| j                         }t        j                  |vrt        t        j                        t        |D cg c]  }|j                   c}      z  sjd|  ddj                  t        |      D cg c]  }|j                   j"                   c}       d	}|r||z  }t$        j&                  j)                  |
       y | j                  r3t*        j-                  | j                        }|j/                  d|        y |st               }| j                  d      D ]r  }|j                  | j                         vs |j                  j                  d      r<|j                  j                  d      rX|j1                  |j                         t d|v rCt*        j-                  | j                        }|j/                  d|        |j3                  d       d|v sd|v rt*        j-                  | j                        }| j4                  j6                  rV| j                  j8                  r@| j                  j8                  | j                  j:                  k7  r|j/                  d|        | j<                  j6                  s| j4                  j6                  r | j                  r|j/                  d| d       d|v r|j3                  d       d|v r|j3                  d       d|v r|j3                  d       d|v rCt*        j-                  | j                        }|j/                  d|        |j3                  d       |r3t*        j-                  | j                        }|j/                  d|        y y c c}w c c}w )NFTr  cache_r  u   Это действие над v    разрешено только владельцам объекта и владельцам его родителя: r
  4    или Администратору системы.rv  zPPP-OBJ-CREATErs  ordernozPPP-OBJ-TREE-ORDERr(  r)  zPPP-OBJ-MOVE)r6  use_new_projectrk  zPPP-OBJ-TREEMOVEzPPP-OBJ-EDIT)r  r   r  r  r   r   ri   project_perm_allow_fieldsrz   r  r  r   r   r  r   r@   rU   r   r   r/  r0  r  r  rZ  r  r  r)  r   r  r  r(  )	r`   changed_fields_to_checkadditional_error_msgr  r   
all_ownersomsgr)  s	            r"   r  zCmfModel.check_edit_perm  s   $$  {{J5 &((0N0N0PP % 0 0 ; ;H E % 0 0 9 9% @!%J& !__.
##:5q::;cQ[B\A144B\>]] ?v F""&))3z?,SaQVV\\,S"T!U TV 0#77C,,==c=J;;++DOO<G--.>D-I '&)e#5 B((0N0N0PP % 0 0 ; ;H E % 0 0 9 9% @+//0@0@AB //++DOO<G--.B-M#**95 ..)?V2V++DOO<G||&&4??+>+>4??CVCVZ^ZiZiZmZmCm11.d1K&&$,,*A*At112B^b1c22'..x833'..y9 77'..}= 33++DOO<G--.@d-K#**=9"++DOO<G--n$-G #m C],Ss   .P*
&P/c           	      p   | j                   sy t        j                  ry t        | d      r| j                  s| j                         }t        j                  |vrt        t        j                        t        |D cg c]  }|j                   c}      z  sdd| j                   ddj                  |D cg c]  }|j                  j                   c}       d}t        j                  j!                  |       y t"        j%                  | j                        }|j'                  d|        y c c}w c c}w )	Nr)  u   Удаление r(  r
  r)  rv  zPPP-OBJ-DELETErs  )r  r   r  rp   r  r  r   r   r  r   r3  r@   rU   r   r   r/  r0  r  r  rZ  )r`   r/  r0  r1  r)  s        r"   r  zCmfModel.check_delete_perm%  s    &&  tY't*Jz11667#Z>Xqtt>X:YY-dii[ 9"iiz(J!(JKLPRC ((99#9F''8))*:)E ?Y(Js   :D.
3D3c                    |ri ng }t         j                         D ]  }d}t        |j                  t        j
                  j                        r%| j                  |j                  j                  v r(d}n%| j                  |j                  j                  k(  rd}|st        |t              rxt        |j                  t        j
                  j                        r%| j                  |j                  j                  v r(d}n%| j                  |j                  j                  k(  rd}|sdd| g}|r|j                  | j                  v r-|r|j                  dv r?t        |t              rd|dd| gg}|r'|j                  |      x}so|||j                  <   |j                  |j                  |ddg	              |S )
ur  
        Получим всех потомков
        Пока только parent and tree_parent
        Может логику через модель надо определять, т.к. связи разные могут быть...
        Поддержка soft_link? Связи, которые надо разрывать при удалении.
        FTr(  r   )r/  r^  rk  r  r  rH   )r  r   rn   r(  r   rH   r  ri   r   r   ro   rk  r   r   r  rL   )	r`   rN  rU  r=  r%  r   linkedfilter_r  s	            r"   rO  zCmfModel.list_children:  s    'B--/ $	\E F%,,

(E(EF??ell&9&99!F??ell&8&88!Fj	:e//1N1NO%*;*;*B*BB!%%*;*;*A*AA!%d+GU--1L1LLU--1DD%+=#t*DE"'++W+"==;=/:F5++, ejjPX@YjZ[I$	\J r!   c                     | j                   r_t        j                  | j                         dk(  r<| j                  j	                         xr  | j                  j
                  j                  S yy)u   
        Хак для доступ к имени проекта для опубликованных документов.
        rQ  N)r4  r   get_class_name_by_idr(  r  rU   r   r  s     r"   r  zCmfModel.get_project_namej  sQ     >>g::4>>JlZ;;##%@$++*:*:*@*@@ [>r!   r   r<   )rN   r  )TF)2r   r   r   r   rX  r   r   r   r   Fieldr  r   r  r   r   r   rH   CmfSubclassedGenericRelationr(  r   cmf_locked_byr   cmf_locked_atCmfCreateDateTimer  cmf_modified_atr  CmfBoolr  	CmfBigIntr  r|   r
  r   r  r  r  r   r   r  r  r   r"  r  r  r  r  rO  r  r   r   s   @r"   r  r    s   }$ N*I'' +
 
K 
;E
B } 	J $6u} I ZZ

//"  F 9}	O 6}	M BE\`hmvz|M+
N -
O -	M K 4edZ_hl  vBCK " " "  ! !F 
/ 
/ X X&[
-%N402OHbF*.`Ar!   r  c            	       ^    e Zd ZdZdZ eedddddd      Z eedd      Z	 eedd      Z
y	)
BaseM2MModelTFr  r  r  u%   Родительская запись)rG   r  u   Корневая записьN)r   r   r   rp  r   r:  CmfM2MTUUIDr   r  r4  root_idr    r!   r"   rC  rC  r  sL    FI	;E
B h(OW[\IH&ETRGr!   rC  c                   N     e Zd ZdZ G d de      Z fdZeddd       Z xZ	S )CmfGM2MModelu2   Базовый класс для GM2M Связейc                       e Zd ZdZdZy)CmfGM2MModel.description   Описание связиTNr   r   r   rG   r  r    r!   r"   rc  rI        /r!   rc  c                     t        |   |i | d|v r#t        |d   d      r|d   j                  | _        d|v r%t        |d   d      r|d   j                  | _        y y y Nr  rU   rightrR   r   rp   rU   left_name_cacheright_name_cacher  s      r"   r   zCmfGM2MModel.__init__  l    $)&)Vv ?#)&>#6#6D f&!A$*7O$8$8D! "Br!   T)r  c                t   g }| j                   }|j                  }|rN| j                  j                         D ].  }|j	                  |      }|j	                  t        |            }	|j	                  |       }
t        |	      }|j                  |      }|j                  |
|
j                  |j                  k(        }|j                  ||
j                  |j                  k(        }|j                  |
j                  dk(        }|j                  |j                  |j                  j                  k(        }|j                         }|j!                         }|j#                  |       1 |S | j$                  j                         D ].  }|j	                  |       }
|j	                  |      }	|j	                  t        |            }t        |      }|j                  |	      }|j                  |
|
j                  |	j                  k(        }|j                  ||
j                  |j                  k(        }|j                  |
j                  dk(        }|j                  |j                  |j                  j                  k(        }|j                         }|j!                         }|j#                  |       1 |S )u*  
        Получаем список обьектов через связанную таблицу с проверкой существования обьектов по обе стороны
        TODO TODO1 перенести в драйвер и прожать по full_fields_load
        N)r   r   rO  r  r   rJ   r   query_deprecatedr@   right_idr   left_idr  r4  r   order_queryallr  r  )rT   r6  r  r  r  r   dd	model_clsdp_right_modeldp_left_modeldp_m2m_modeldp_left_model_aliasedr  dp_right_model_aliaseds                 r"   select_relatedzCmfGM2MModel.select_related  sI    VV^^ YY557 $	!#Y!7 "DI 6!{{3/(/(>%)).9hh|\-B-BnFWFW-WXhh) ((,A,D,DDF jj!7!74!?@jj!6!9!9SVV\\!IJoo'ggis#$@  !XX446 $	!{{3/ "I 6!#T#Y!7)0)@&))-8hh|\-A-A]EUEU-UVhh* ))-C-F-FFH jj!7!74!?@jj!7!:!:cffll!JKoo'ggis#$ r!   
r   r   r   r   
CmfStr4096rc  r   r  ra  r   r   s   @r"   rG  rG    s.    <j 9 .2 ) )r!   rG  c                   J     e Zd ZdZ G d de      Z fdZedd       Z xZ	S )CmfM2MModelu1   Базовый класс для M2M Связейc                       e Zd ZdZdZy)CmfM2MModel.descriptionrJ  TNrK  r    r!   r"   rc  rg    rL  r!   rc  c                     t        |   |i | d|v r#t        |d   d      r|d   j                  | _        d|v r%t        |d   d      r|d   j                  | _        y y y rN  rP  r  s      r"   r   zCmfM2MModel.__init__  rS  r!   c                 @   | j                   }|j                  }d}t        t              | j                  j
                     }|j                  t        |      j                  k(  rd}t        t              | j                  j
                     }|j                  |      }|j                  |      }	|j                  |       }
|dk(  r|j                  |	      }|j                  |
|
j                  |	j                  k(        }|j                  ||
j                  |j                  k(        }|j                  |j                  |j                  j                   k(        }|j#                         }n|j                  |      }|j                  |
|
j                  |j                  k(        }|j                  |	|
j                  |	j                  k(        }|j                  |	j                  |j                  j                   k(        }|j#                         }|j%                         }|S )NrO  r  )r   r   r   r   r  r   r   rJ   rO  r   rU  r@   rV  r   rW  r  r   rX  rY  )rT   r6  r  r   rZ  r@   left_cls	right_clsr]  r\  r^  r  s               r"   ra  zCmfM2MModel.select_related  s   VV^^</S	 2 22DL1	H-Y/{{3'6>%%n5C((<)>)>.BSBS)STC((=,*>*>-BRBR*RSC**]--=>C//#C%%m4C((<)=)=AQAQ)QRC((><+@+@NDUDU+UVC**^..#&&,,>?C//#Cggi
r!   r  rb  r   s   @r"   re  re    s+    ;j 9  r!   re  c                   
    e Zd ZU dZdZeed<   dZdZdZ	g dZ
dZdZdZej                  d      Zej$                  dz   Zd	Zej(                  g d
z   Z ee      Z ee      Z eeddddd      Z eeddd      Z eeddgdd      Z eeddgdd      Z  eeddgdd      Z! ee"dddgdddd	      Z# eed dd!d	d"      Z$e%jL                  j+                  e%jL                  jN                  d#d	d$      Z( ee)d%d	d&      Z* eed'ddd(      Z+ ee,d)d	d*d+dd	,      Z-e%jL                  j+                  e%jL                  j4                  dd-d.      Z.e%jL                  j+                  e%jL                  jD                  d/dd	g 0      Z/e%jL                  j+                  e%jL                  j<                  d1d2dd	g 3      Z0e%jL                  j+                  e%jL                  j4                  d4dd	d5      Z1e%jL                  j+                  e%jL                  j4                  d6ddd	7      Z2e%jL                  j+                  e%jL                  j4                  d8dd	d5      Z3e%jL                  j+                  e%jL                  jh                  d9d dd:      Z5e%jL                  j+                  e%jL                  jl                  d;d<d	d	d	=      Z7e%jL                  j+                  e%jL                  j4                  d>d?      Z8d	Z9g Z:d@gZ;e%jL                  j+                  e%jL                  jx                  dAd	dd	dBC      Z=e%jL                  j+                  e%jL                  j|                  dDdEdFdGdHddIJ      Z?e@dKefdL       ZAeBd	ddMdN       ZCe@ fdO       ZDe@ddPeEf fdQ       ZFe@dR        ZGddSedTefdUZHe@dV        ZIdW ZJdX ZKddYZL fdZZMe@d[        ZNe@d\        ZOe@dd]       ZPe@dd^       ZQe@d_        ZRe@dd`       ZSe@dda       ZTe@ddb       ZUe@ddc       ZVe@ddd       ZWe@dde       ZXdf ZYdg ZZe[dh        Z\di Z]dj Z^dk Z_dl Z`dm Zadn Zbdo Zcdp ZddqeEfdrZeddsZfdBdtdqegfduZhdv Zidw Zjddx fdy
ZkddzZld{ Zmd| Zn fd}Zod~ ZpeB eqd	dd      ddKefd              ZrddesfdZtd ZudBd	d fd
ZvddZweB eqd	d	dKgd      d               ZxddZyd Zze@d        Z{e@dddddd       Z|d Z}d Z~d Zd Zd Zd Zd fd	ZdqefdZdedqdfdZdd fd
Zd Ze@d        ZeBdeEfd       ZeBd        ZddZe@d        Zd Ze%jL                  j+                  e%jL                  j4                  ddd      Ze%jL                  j+                  e%jL                  j4                  ddd      Ze%jL                  j+                  e%jL                  jl                  dd	dd      Ze%jL                  j+                  e%jL                  j4                  d	dd.      Ze%jL                  j+                  e%jL                  jh                  dd	d d      Ze%jL                  j+                  e%jL                  j&                  d	ddd!      Ze%jL                  j+                  e%jL                  j&                  d	dd!d      Ze%jL                  j+                  e%jL                  j&                  d	dd      Ze%jL                  j+                  e%jL                  jN                  dd      Ze%jL                  j+                  e%jL                  j4                  dddd      Ze%jL                  j+                  e%jL                  j2                  dd	      Zd Ze@dd       Ze@dd       Zd Zd Zd ZddZd ZdÄ ZdĄ ZddńZeB eqd	d	g dƢǫ      	 	 ddȄ              ZdɄ Zdʄ Zd˄ Z fd̄Zd̈́ Zd΄ Ze@ddededesfd҄       ZeB eqdd	ԫ      	 ddededededesf
dׄ              Z xZS )ro   u   CmfEntity - базовый класс для типичных моделей подлежащих автоматизации на преприятии.

    Пример: Task, Invoice, SalesOrder, Bill

    class Task(CmfEntity): pass
    Nacl_parent_fieldr  F))r3  rU   textr:  r  r4  logic_type.codeactivity.codezcmf_owner.loginzcmf_owner.emailzcmf_author.loginzcmf_author.emailzcmf_modified_by.loginzcmf_modified_by.emailr  r  r?  r!  zcomments.textzcomments.log_levelzcomments.cmf_author_idzcomments.cmf_created_atresult_textzresponsible.loginzresponsible.emailzexecutors.loginzexecutors.emailzspectators.loginzspectators.emailcache_status_typez	tags.namero  rp  r]  r  r  full_search_typezparent.full_search_typeparent.nameztree_parent.namecompanyz^DEL[0-9]+[ _])delete_prefix_patternT)custom_field_synclock	lock_pingmark_clickedmark_viewed
move_above
move_belowmove_up	move_downmove_middlerb  rP  unlockux_check_permattach_listu   Системный объектu   Нельзя удалять)rG   r7  r  r%   r  u
   Текстu   Текст сущностиu!   Добавить описание)rG   r7  placeholderu   Задачи сущностиrh  r(  )rG   r   backrefr  u#   Документы сущностиrf  u'   Комментарии сущностиr  r  	CmfImportCmfProjectImportu   Импортированimport_objects)r  r   rG   r  r  r  u,   Исходная версия импортаr  )rG   r  r  rp  r%   u&   Сырые данные импорта)rG   r  r  u"   Ид внешней системы)rG   r   r  u   Объект в архиве)rG   r  r%   r  u   Избранный дляCmfPersonVar	favorites)rG   rO  r   r  r  rp  u3   В избранное всем участникам)r%   rG   r  u!   Родительская нода)rG   r  r   r   u   Ветви дереваrk  )rG   r  r  r   r   u(   Есть вложенные узлы old)rG   r  r   r%   u$   Есть вложенные узлы)rG   r%   r  r   u)   Не отображать в деревеu-   DEPRICATED. Корневой Родитель)rG   r  r  r  u   ПроектrQ  )rG   r   r  r  r  u>   Редактирование только владельцем)rG   r%   r*  u   Сортировкаr   )rG   r  r  r  r%   u,   Метод индексации поискаu!   Полная индексацияu%   Только наименованиеu'   Индексация отключена)0_full_index1_name	9_disabler  )rG   rD  r  r%   rg  c                     t         r<   )r   )rT   rg  s     r"   process_dirty_attachzCmfEntity.process_dirty_attach  s    !!r!   )r  rH   c                 z   g }|sg }t        j                  | dg      }|rat        j                  j	                  dddt        |j                  D cg c]  }|j                  j                   c}      gdd|gg|      }|S t        j                  j                  ddd|j                  gdd|gg|      }|S c c}w )Ncommentsru  r^  r(  rc  r   r5  )
r   r/  r   rT  r   r   r  r   r   rL   )rg  r  rH   r~   rO   r  r6  r7  s           r"   r  zCmfEntity.attach_list  s    F##FJ<@&&,,THdCqtq}q}P~fmQXQ[Q[QaQaP~L  <A  DL  NQ  SV  CW  5X  ag,  hC 
 &&++D8T3<<:X[cehjmZn3ox~+C
 Qs   B8c                     t         |   |      }|j                  d   j                         D ]  \  }} |j                  |fi |  |S )N	ui_fields)rR   rN  ui_form_jsonr)   r   )rT   r6  rM  rE  ui_field_datar\   s        r"   rN  z CmfEntity.get_automation_ui_form  sT    '05,/,<,<[,I,O,O,Q 	?(M=G}>>	?r!   cust_field_confc                 f   |rW|j                  dd       r|d   dv r|dd|d   gg}t        t              |d      j                  |      }|dk(  r|g dg}nJ|}nG|j	                  d	      r6t        j
                  j                  |dg
      }|j                  dv r|g dg}t        | $  ||fi |S )Nfield_custom_type)choice_multichoice_cascade_multir  r   r   r4  r   )r  r   Nr[  rU   rH   )
r,   r   r   r   rz   r  r   r  rR   r   )	rT   r  r  r  rO   filter_with_confcount_with_confr  r\   s	           r"   r   zCmfEntity.field_options_list  s    ""#6=/ReBf  kS  CS$*-A3XlHm,n#o "&v,w/G"H"N"NVf"N"g"a'$&GHF .F ++E2,,117JTgSh1iJ++/WW "CDw)*=vPPPr!   c                     | j                   }|s
t               }d|d<   d|d<   d |d<   |j                  dt                     |d<   |S )Nr%   r3  rU   r  r  )rM  rt   r,   )rT   r~   rO   r  s       r"   _build_ui_formzCmfEntity._build_ui_form  sR    {{6L(V(V"U$0$4$4[$&$I[!r!   rU   r3  c                    | j                  dg       | j                  || j                        }|D ]%  }t        ||      s|dk7  st	        ||||          ' ||_        | j                  |      }|j                  d       d|_        |S )u/   
        Копируем обьект
        z**)r3  r)  r   Tr  )	r  r  r)  rp   r   rU   _post_copy_hookr   r   )r`   rU   r3  r~   rO   obj_copyr  s          r"   r   zCmfEntity.copy  s     	$  ::4:>  	4Cx%#+#vc{3	4 ''1%r!   c                     |j                          |j                          |j                          |j                          |j	                          |S r<   )_calc_perm_parent_calc_perm_inherit_acl_id_calc_perm_has_acl_calc_perm_acl_calc_perm_effective_acl)rT   r  s     r"   r  zCmfEntity._post_copy_hook  sC    ""$**,##%!))+r!   c                     | j                   r%t        j                  j                  | dg|i | y t        j                  j                  | dg|i | y )Ncreatedupdated)r   r   CmfEventdo_eventrk  s      r"   _do_event_savezCmfEntity._do_event_save  sE    ;;OO$$T9FtFvFOO$$T9FtFvFr!   c                 L    t        j                  j                  | dg|i | y )Ndeleted)r   r  r  rk  s      r"   _do_event_deletedzCmfEntity._do_event_deleted
  s       yB4B6Br!   c                    t               }|dkD  rt        d| dd       |j                  d      sy|dk(  r:| j                  g d	       | j                  r|j                  | j                         |d
k(  rH| j                  g d       | j                  j                         r|j                  | j                         |dk(  rt        j                  gS |dk(  r|j                  | j                                |dk(  r#|j                  | j                  ddg             g }|D ]  }|j                  j                  j                  d      r;|j                  | j                  |j                  j                  |dz   |             c|j                   rpt#        |d      r|j$                  r|j                  |        |S )u?  
        Получение значение по шаблонным объектам.

        Возвращает список (в том числе пустой), если передан шаблонный объект
            или None, если объект не является шаблонным
        
   un   Зацикливание рекурсии в раскрытии var-пользователя: extract_var_obj(r  Tr-  zvar:Nz	var:owner)r   zcmf_owner.cmf_deletedzcmf_owner.does_not_workz
var:author)r   zcmf_author.cmf_deletedzcmf_author.does_not_workzvar:current_userzvar:followerszvar:all_related_usersr  does_not_workru  rP  )	recursionall_nested_persons)rL   r&  rz   r  r   rx   r   r  r   r  r  get_all_followersr  r3  r   extract_var_objr  rp   r  )r`   obj_coder  r  	var_usersres_var_usersvar_users          r"   r  zCmfEntity.extract_var_obj  s    F	r>  G  HP  GQ  QR  S  [_  `""6*{"^_~~  0|#ab##%  1))NN##&T3356..T66}o>^6_` ! 		+H}}""--f5$$T%9%9(--:M:MYbcdYdM_ &: &a b##x1h6L6L  *		+ r!   c                    | j                          | j                          | j                          | j                          | j	                          | j                          | j                          | j                          | j                          | j                          t        | ,  |i |}| j                  dd| j                          |S )u   
        Функция сохранения при импорте, чтобы ускорить исключив лишние логики и защиты
        Fz_save_import1 name=r  )r  r  r  r  r  _calc_tree_parentr  
_calc_code_calc_orderno_check_tree_node_is_branchrR   r  r  rU   )r`   r~   rO   r  r\   s       r"   r  zCmfEntity._save_import9  s     	 &&(!%%' '')g"D3F3U8KDII;6WX
r!   c                 :    | j                   xr d| j                   v S )N-orderno)r<  r   s    r"   _is_orderno_descending_sortz%CmfEntity._is_orderno_descending_sortM  s    ||:
cll ::r!   c                     | j                   s| j                   S | j                   D cg c]  }|j                  d      r|dd  nd|  c}S c c}w )NrW  rP  )r<  rz   )rT   rY   s     r"   _revers_orderingzCmfEntity._revers_orderingQ  sZ     ||<< "ll, )33C8JqrN*>NN, 	, ,s   "Ac                    |j                  d      s|j                  d      sy |st        j                  j                  }|s!t	        j
                  |      }|j                  }t	        j                  |      t        j                  urt        j                  d| d       y t        j                         }||_        d|_        ||_        ||_        ||_        ||_        d|_        |j%                          y )NCmfDocument:CmfTask:zproject_id "z-" is not a valid CmfProject obj_id, aborting;clickF)rz   r   r   r   r   r/  r4  r  r   rQ  r  CmfSearchStatrg  actionsearch_query	person_idr  
aggregatedr   )rT   r  rg  r  r  r4  r6  stats           r"   rz  zCmfEntity.mark_clickedZ  s    !!.1V5F5Fz5R((++I''/CJ"":.f6G6GGGGmJ</]^_##%(""$		r!   c                    |s|sy |s|r|D ]  }| j                  ||        |r| j                  ||      }|s|g}|D ]  }|j                  d      s#|j                  d      s|j                  d      s8t        j                  |dgdd      }|st        j                  d| d	       n|s@|j                  d      r#|j                  r#|j                  j                  }n|j                  }|s|st        j                  |      t        j                  urt        j                  d
| d       |s|j                  }|s+|j                  d      r|j                  j                         }t        j                         }	||	_        d|	_        ||	_        ||	_        ||	_        ||	_        d|	_        |	j)                           y )N)rg  r  r  r  zCmfAttachment:r(  Tr*  zobj is None for obj_id "z", skipping;zinvalid project_id "z+": it is not a CmfProject obj_id, skipping;rf  viewF)mark_viewed_objrz   r   r/  r   r  r(  r4  r  r   rQ  cur_workflow_version_idr  CmfStatrg  r  r  r  
history_idr  r   )
rT   rg  obj_id_listr  r  r  r4  rO   r6  r  s
             r"   r{  zCmfEntity.mark_viewedu  s    k+" E##3)#DE ++FI>I!(K! )	F  0F4E4Ej4QU[UfUfgwUx++FH:W[kopGG7x}MN!(()9:::),)=)=J%(]]
!!**:6f>O>OOGG3J<?klm  #I!f&7&7&F!$!<!<!A!A!CJ~~'$$!*",",!*"'		S)	r!   c                    |st         j                  j                  }|t         j                  j                  k7  rXt         j                  t         j                  k7  r!t        j
                  j                  dd       t        j                  |      }nt         j                  }t        j                  d|j                   d| d      5  |j                  d      rQt        j                  j                  |j                  |d	      s%t        j                  ||
      j                          d d d        |S # 1 sw Y   |S xY w)NzKDEV: FATAL self.id != g.current_person.id and self.id != g.system_person.idTr-  zCmfEntity.mark_viewed:r	     timeout)r  r  zCmfComment:)r  rg  r  )personr6  )r   r   r   r1  r   r  r&  r   r/  CmfLockrz   r   CmfPersonViewr,   r   )rT   rg  r  r  s       r"   r  zCmfEntity.mark_viewed_obj  s   ((++I((+++1??2%%emq & s**95F%%F__5fii[&JTVW 	G  !LM & 4 4 8 8699U[hl 8 m$$F$?DDF	G 		G s   	A#D66E c                 "   | j                   s$t        j                  j                  d|  d       y dg| j                   z   }| j	                  ||      }|j                         g}|r|j                  |       d}| j                  dg||ddg      }t        |      dk\  r#t        j                  j                  d|  d	       |D ]H  }|j                  |k  r||_	        |j                  d
       |dz  }1t        |j                        dz   }J y )Nu"   DEV: Переиндексация uW   .orderno не выполнена, так как не указан orderno_partition_by.r*  ru  r  r   )r   r  rH   rA   u   Переиндексация ug   .orderno выполнена частично, так как объектов слишком много.Tr  )orderno_partition_byr   r  r&  r,   _orderno_filterrx   rL   rq  r*  r   r  )	rT   rg  r  rH   r6  orderno_filtercur_ordernofix_obj_listfix_objs	            r"   _orderno_reindexzCmfEntity._orderno_reindex  s!   ''KK!!$Fse  Lc  #d  es777ggfVg,--/0!!&)xx)^TZcdeibjxk|$KK!!$A#  Gn  #o  p# 	:G,"-t,t#!'//2T9	:r!   c           	         || j                         }g d| j                  z   }| j                  ||      }| j                  ||      }	|	j                  rL|j	                  d      r|	j                  j                  d|	       n|	j                  j                  d|	       |	j                         g}
|r|
j                  |       |sO| j                  |
dd|j                  gg	      d
kD  r+| j                  ||	        | j                  d||||dd|S |
j                  d|rdnd|j                  g       | j                  |rdndg|
|      }|rt        |j                  |j                  z
  dz        }|s`t        t        |j                  |j                  z
              d
k  r2| j                  ||	        | j                  d||||dd|S |rd}nd}|j                  |z
  |	_	        |	j                  d       |	j                  S )N)r)  r*  r(  ru  r  PPP-TSK-ORDERrs  PPP-OBJ-ORDERr*  r   r4  rP  T)rg  	before_idr  reversreindex><r  r   r  rH   r  r  r  r    )r  r  r,   r)  rz   rZ  r  rx   r   r*  r  r|  r  absr   )rT   rg  r  r  r  r  r=  rH   beforer6  r  	prev_itemdeltas                r"   r|  zCmfEntity.move_above  s   >446F1C4L4LL62ggfVg, ;;  ,55o35O55o35O--/0!!&)399^ifnn=],^9_bcc   7!3>>|9V\blp|t{||y#S&..QRGG6iz%JSajpGq	)*;*;;q@AEs3v~~	8I8I'I#JKqP$$VF$;%s~~  AVyQW`fpt  Ax  A  Annu,4 {{r!   c           	         || j                         }ddg| j                  z   }| j                  ||      }|j                  rL|j	                  d      r|j                  j                  d|       n|j                  j                  d|       | j                  ||      }	|j                         g}
|r|
j                  |       |sO| j                  |
dd|	j                  gg	      d
kD  r+| j                  ||	        | j                  d||||dd|S |
j                  d|rdnd|	j                  g       | j                  |rdndg|
|      }|rt        |j                  |	j                  z
  dz        }|s`t        t        |j                  |	j                  z
              d
k  r2| j                  ||	        | j                  d||||dd|S |rd}nd}|	j                  |z   |_	        |j                  d       |j                  S )Nr)  r*  ru  r  r  rs  r  r   r4  rP  T)rg  after_idr  r  r  r  r  r  r  r  r  r  r  r    )r  r  r,   r)  rz   rZ  r  rx   r   r*  r  r}  r  r  r   )rT   rg  r  r  r  r  r=  rH   r6  afterr  	next_itemr  s                r"   r}  zCmfEntity.move_below  s   >446FY'#*B*BBggfVg, ;;  ,55o35O55o35O0--/0!!&)399^iemm=\,]9^abb   7!3>>z(6Z`jnzryzzy#S%--PQGGFj	%JSajpGq	**U]]:a?@Es3y'8'85=='H#IJaO$$VF$;%s~~~Vhv^dnr~v}~~mme+4 {{r!   c                     | j                  ddg|      }|j                  |k(  ry | j                  ||j                  |      S )Nr  r   )rH   r  rg  r  r  )r,   r   r|  )rT   rg  r  r  s       r"   r~  zCmfEntity.move_up+  s@    tV<99~~Vvyy~PPr!   c                     | j                  | j                         ddg|      }|j                  |k(  ry | j                  ||j                  |      S )Nr  r   )r   rH   r  )rg  r  r  )r,   r  r   r}  )rT   rg  r  r  s       r"   r  zCmfEntity.move_down3  sL    !5!5!7tU[\88v~~Vehhv~NNr!   c                     | j                  |      }|dz  }| j                  ddg|||dz   g      }t        |      sy |d   }|j                  |k(  ry | j	                  ||j                  |      S )	Nr4  r  r  r   rP  rH   r  r  r   r  )r   rL   rq  r   r|  )rT   rg  r  
count_objs	half_objsbefore_listr  s          r"   r  zCmfEntity.move_middle;  s{    YYfY-
!O	hhtTl6)U^abUbIchd;Q99~~Vvyy~PPr!   c                     g dg}| j                   rig }|j                  |       | j                  | j                          | j                   D ],  }t        | |      }|j                  |d|j                  g       . |S )N)r*  rF  Nr   )r  rx   r  ru   r   )r`   r  partition_filterrY   r   s        r"   r  zCmfEntity._orderno_filterJ  s    12$$!!!"23T667"77 	H
j1 !''S%++(FG	H r!   c                    | j                   r| j                  rJt        j                  d| j                   d| j
                   d| j                    d| j                          y t        j                  d| j                   d| j
                   dt        | dd               | j                         }t        j                         5  | j                  dgg |	      j                  }d d d        r|d
z   | _        y d
| _        y # 1 sw Y   xY w)Nu   _calc_orderno: SKIP для r	  z is_new=z	 orderno=u   _calc_orderno: CALC для z partition=r  max__orderno)rH   r   r  r  )r   r*  r   r  ri   r   ru   r  r   r(  r,   r  )r`   r  max_ordernos      r"   r  zCmfEntity._calc_orderno\  s   {{dllGG1$//1B!DGG9HUYU`U`Taajkokwkwjxyz	-doo->ayT[\`bxz~T  TA  B  	C%%'  " 	((&' #  l	 	 &-DLDL	 	s    DD
c                 R    | j                    d| j                   d| j                   S )Nz/?obj=r	  )re   rd   r3  r   s    r"   hrefzCmfEntity.hrefv  s&    ..!~QtyykBBr!   c                      y r<   r    r   s    r"   r  zCmfEntity._calc_tree_parentz  r  r!   c                 H    | j                   s| j                         | _         y y r<   )r3  gen_coder   s    r"   r  zCmfEntity._calc_code}  s    yyDI r!   c                    t        | d      r| j                  s| j                          t        j                         5  dd l}|j                         }| j                         dz   | j                         z   }d}d}| j                  dd|gdd| j                  ggd	d	
      rl|dz  }| j                          d| j                          }||k  sJ d| d| j                   d       | j                  dd|gdd| j                  ggd	d	
      rl|j                         |z
  }|dkD  rGt        d|dd| j                   d| j                   dd| j                  v xr | j                   d	       |cd d d        S # 1 sw Y   y xY w)Nr)  r   rW  '  r3  r   r   rF  T)r  r+  r,  rP  u8   Превышен лимит поиска кода limit=z model=uA   , возможно надо отключить def gen_code: passz$!!! --- gen_code::duration too long r  r	  r.  r
  r  )rp   r  r  r   r(  r  get_code_prefixnext_code_numberr   r   ri   r  rH   r3  )r`   r  r  r3  limitr   r  s          r"   r  zCmfEntity.gen_code  s   4#DOO   " 	IIKE'')C/$2G2G2IIDEA))VS$$7$dgg9N#Oaeuy)zQ..0143H3H3J2KL5y e$\]b\ccjkokzkzj{ |d #e ey ))VS$$7$dgg9N#Oaeuy)z yy{U*H!|:8C. I($''"f6K5ZQUQZQZ4[[\^_ #	 	 	s   CE6A E66E?c                     | j                   S r<   )rf   r   s    r"   r  zCmfEntity.get_code_prefix  s    r!   c                     d}| j                  g ddgdd      }|r't        |j                  j                  d      d         }|S )Nr   )r3  
SIMILAR TOz[A-Z]+-[0-9]+\Z-cmf_created_atT)r  r   r+  r,  rW  r  )r   r  r3  rA   )r`   
max_numberlasts      r"    _get_current_code_number_from_dbz*CmfEntity._get_current_code_number_from_db  sM    
yy IUfTg$(  >TYY__S1"56Jr!   c                    t         j                  }d| j                   }| j                   d}|j                  j	                  |d      }|j                          	 |j                  |      r|j                  |      }n%| j                         dz   }|j                  ||       	 |j                          |d
S # t        j                  j                  $ r?}t        j                  d| d|j                   d|j                           Y d	}~|d
S d	}~ww xY w# 	 |j                          w # t        j                  j                  $ r<}t        j                  d| d|j                   d|j                           Y d	}~w d	}~ww xY wxY w)uN    Высчитывает следующий номер для кода
        znext_code_number-z.lock   r  rP  zlock release error z, lock_name z
, timeout N06)r  REDIS_DBri   redisrx  acquirerJ  incrr  r   release
exceptionsr   r   r  rU   r  )r`   redis_dbr  lock_keyrx  r  r  s          r"   r  zCmfEntity.next_code_number  sg    <<!$//!23oo&e,~~""8R"8
	bs##+==#5 #'#H#H#JQ#N S"23b #2&' ##-- b-aSTYYKzRVR^R^Q_`aa"2&'bb##-- b-aSTYYKzRVR^R^Q_`aabsO   AD &B: :D2DDFD,+F,F	2F ;F FFc                      y r<   r    r   s    r"   gen_namezCmfEntity.gen_name  s    r!   c                      | |   j                   S r<   )	log_level)r`   rY   r~   rO   s       r"   _get_field_log_levelzCmfEntity._get_field_log_level  s     J)))r!   r  c           	          | j                   si S i }| j                         D ]1  }t        | |d      }|	 |j                  |j                        ||<   3 |S # t
        $ r t        t        |dd            ||<   Y Zw xY w)ui   Формирует audit_data для info_audit_fields, пропуская изменённые поля.Nr   r:   )r   r  ru   _format_for_html_diffr   r~  r
  )r`   
audit_datarY   r  s       r"   _build_info_audit_dataz CmfEntity._build_info_audit_data  s    %%I
668 	NJj$7I N)2)H)H)Y
:&	N   N),WY-L)M
:&Ns   A"A<;A<c                    | j                   ry |sy i }g }| j                  d      D ]%  \  }}|dv r|j                  d      r|j                  d      r0t	        |t
        j                  j                        r|j                  sZa|j                  du r#t        j                  d|j                   d       |j                  dur|j                  |j                  k(  r| j                  |      }|d	k  r|j!                         }|s|||<   |j#                         }|s|d
k(  r|j                  }|s|j%                  | d|        ( | j'                         }	|	j                         D ]  \  }}
|j)                  ||
        |sy d}| j*                  rd}| j,                  }| j.                  dk(  r| j0                  r| j0                  dd }|st3        | d      r| j4                  }t7        || j.                  t        j8                  | t;        |      t;        | j4                        |dj=                  |      d	      }t?        j@                  jB                  di | |S )NTr  )
r  cache_fieldsr   r?  r  viewslikesstatus_closed_atstatus_modified_atstatus_in_progress_endr  r'  .u&   DEV: INFO. Возможно, поле uI    не попало в аудит, т.к. его old не загруженrn  r  rN   r   r  r      r3  z<br>F)	rs  r\  r   r(  parent_nameparent_coder*  html_diff_dataignore_transactionr    )"r   r)   r  rz   r*   r   rH   r  _changesr   r   r  rw   r   r  r'  
audit_diff	html_diffrx   r+  rs   r   rU   ri   rn  rp   r3  rt   r   r
  r@   r   r  r  )r`   auditr*  r;  rY   r  r&  _audit_diff
_html_diffinfo_audit_datar  rs  tmp_namer=  s                 r"   _system_auditzCmfEntity._system_audit  sV   
	%)ZZ4Z%@ "	@!J	 b b ""5)$$X. )SZZ%:%:; ))>>S(GG@AZAZ@[  \e  fg>>,IMM1Q11*=IB#..0K%0Jz"",,.J*"6&__
  J<r*!>?E"	@J 557'6'<'<'> 	;#J!!*k:	; ;;G99??l*tyyyy3'HGD&1yyH??''HDII!!;;y1$

 	##.g.r!   )r  c                    t               S r<   )r   )r`   r  r~   rO   s       r"   r  zCmfEntity.get_all_followers%  s	    ur!   c                 F    t        j                  j                  dd| i| y )Nr6  r    )r   rS  place_notifyr`   rO   s     r"   _place_notifyzCmfEntity._place_notify(  s    %%9$9&9r!   c                 x   | j                   j                  r| j                  j                          | j	                  ddg      }|D ]p  }|j
                  j                          |j
                  D ]E  }| j                   r| j                  j                  |       +| j                  j                  |       G r y y )NT
person_var)inherit_executorsrH   )is_favoriter   favorite_forr  r  rH  rx   r  )r`   	executorsexecutorrH  s       r"   _calc_executors_favoritesz#CmfEntity._calc_executors_favorites,  s    &&""$11DR^Q_1`I% =##((*"*"5"5 =J''))00<))00<	== 'r!   r   c                    t        |   |d|i| |s0| j                  s#| j                  s| j	                         | _        y y y y )Nr   )rR   r   r   r3  r  )r`   r   r~   rO   r\   s       r"   r   zCmfEntity.__init__8  sE    $6e6v6T//99 MMO	  0ur!   c                 f   | j                   s^| j                  rR| j                  j                  d      r7| j                  g d       | j                  | _        |s| j                          y | j                   r1| j                   | j                  k(  ry | j                  j                  sy | j                  r| j                  s	 | j                  r<| j                  j                   j                  s| j                  j                  dg       | j                  r| j                  j                   }n| j                  dk(  r| j                  }nd }| j                   |k7  rY|rV| j
                  j                          t        j                  j                  |ddg      | _        |s| j                          y y y y )Nr  )zparent.task_code_prefixz&parent.task_code_use_logic_type_prefixzlogic_type.obj_code_prefixr  rQ  r  ui_form_scheme)r   rH   )r  r4  rz   r  r(  r)  r  r   r  ri   r   r  r   rQ  r,   )r`   skip_project_perms_checkr  s      r"   r  zCmfEntity._calc_project@  sK    4>>dnn6O6OP]6^ < =  ;;DL+$$&??$..0;;))>>$++ ;;t{{55@@KK##\N3;;//J__,JJ??j(ZLL!,,00JXhGi0jDL+$$& , .8(r!   c                    | j                   ry t        j                  t        j                  k(  ry d}| j	                         }| j                  d      D ]K  }|j                  |vs|j                  j                  d      r.|j                  j                  d      rJd}M |sy | j                  }| j                  j                  r,| j                  j                  r| j                  j                  }| j                  }| j                  j                  r| j                  j                  }|s| j                  r| j                  j                  j                  d      sa| j                  ddg       | j                   rB| j                   j                  r,| j                   j                  }| j                   j                  }| j                  d	v rV| j                  d
dg       | j"                  j                  sy | j"                  j                  }| j"                  j                  }| j                  dk(  rV| j                  ddg       | j$                  j                  sy | j$                  j                  }| j$                  j                  }| j                  j                  ry| j                  rmt        j&                  j(                  | j                  k7  rFt+        j,                  |dg      }t.        j0                  j3                  d|j4                   d       |sy t        j&                  j(                  |k7  rGt+        j,                  |dg      }t.        j0                  j3                  d|j4                   d       y y )NFTr  r'  r  r  parent.sl_owner_lockzparent.cmf_owner_id)	CmfStatusCmfTransCmfTransValidCmfTransActionCmfTransFilterzworkflow.cmf_ownerzworkflow.sl_owner_lockCmfSchemeWfRulezscheme_wf.cmf_ownerzscheme_wf.sl_owner_lockrU   ru  u   Этот реквизит может устанавливать только владелец объекта. Свяжитесь с r-  ul   Владелец запретил изменять настройки объекта. Свяжитесь с )r   r   r   r1  r,  r   ri   rz   r  r  r   r  r  r4  r   r  r(  workflow	scheme_wfr  r   r   r/  r   r  r&  rU   )r`   r  r,  r   r  r  r   s          r"   r  zCmfEntity._check_sl_owner_lockj  s   ;; q.
$($B$B$D![[D[1 	"E$$,EE!,,77A!,,55e<!
	"  ((''D,=,=,A,A,,00L**(( ..22M~~dnn&:&:&E&Em&T  "8:O!PQ;;4;;#<#<#';;#;#;L$(KK$=$=M ?? T T24LMN==..==55L MM77M ??//35NOP>>//>>66L NN88M ((T-?-?ANNDUDUY]YjYjDj--lF8LIKK!!  %i  js  jx  jx  iy  #z  BF!  G>>,--lF8LIKK!!  %Q  R[  R`  R`  Qa  #b  jn!  o -r!   c                     dgS )NrK  r    r   s    r"   r,  z#CmfEntity.project_perm_allow_fields  s     
 	
r!   c                 *    t         |          g dz   S )N)r  r*  zparent.project_idr  r  rT  )rR   r  )r`   r\   s    r"   r  zCmfEntity.save_preload_fields  s"     w*, 0Y Y 	Yr!   c                     ddl m} | j                  j                  r| j                  j                  ry || j                  j
                        | _        y)u   
        Защита от инжектов которые могут написать пользователи системы которые не всегда являются сотрудниками
        :return:
        r   )markup_html_cleanN)cmf.util.cmf_clean_textr`  rn  r   r  r   )r`   r`  s     r"   _clean_textzCmfEntity._clean_text  s7    
 	>yy##tyy'8'8%diioo6	r!   u6   Обновление дочерних объектов)re  rc  rd  c           	         t        j                  |       }t        j                  | ddg      }|st        j	                  d|        y g }|j
                  D ]J  }t        j                  |      }|j                  |j                  dd| gdd|j                  gg             L t        |      D ]F  \  }}|j                  |_	        t        j                         5  |j                          d d d        |sGH y # 1 sw Y   xY w)	Nr   r)  ru  zGessential_update_project_job(%s): obj not found. May be it was deleted.r(  r   rF  r4  )r   r  r/  r  r  r   r1  r  rL   r)  	enumerater(  r   )	rg  update_bg_progressbar	obj_modelr6  sub_objsr  r   nnsub_objs	            r"   essential_update_project_jobz&CmfEntity.essential_update_project_job  s     ++F3	 ##FD)3DEOOegmn#:: 	^J--j9EOO

Hc6#:Yckk<Z"[
\^	^ 'x0 	MR!kkGO$$&  % 	 s   C88D	force_fgc                    t         j                  }	 |st        j                  j	                         rdt         _        t         j                  r(| j                  | j                  j                  d       n/ddlm	}  || j
                  | j                  j                  g       |t         _        y # |t         _        w xY w)NTF)re  r   schedule_deferred_job)r~   )
r   '_essential_update_project_job__force_fgr   CmfDeferredJobis_jobrj  r   r   r   rn  )r`   rk  *old_essential_update_project_job__force_fgrn  s       r"   _essential_update_project_jobz'CmfEntity._essential_update_project_job  s    565^5^2	c600779 =A98811$''--W\1]=%d&G&Gtww}}o^8bA58bA5s   BB0 0B=c                    | j                   j                  sy | j                  ddg       | j                   j                  r`| j                   j                  sJd| j                   _        t        j                         5  | j                   j                  d       d d d        | j                   j                  r&| j                   j                  j                  |        y y # 1 sw Y   FxY w)Ntree_parent.tree_node_is_branchtree_parent.log_levelTr  )
rk  r   r  r]  r_  r   r(  r   r  tree_child_deleter   s    r"   r  z$CmfEntity._check_tree_node_is_branch  s    **;=TUV''0@0@0T0T37D0$$& 6  %%%56   2248  6 6s   <CC'r  r  c                   | j                          | j                  rf| j                  sZ| j                  j                  s| j
                  j                  r.t        j                  j                  d| j                   d       | j                          | j
                  s| j                         | _        | j                          | j                          | j                          | j                          | j!                          | j                  r<|r:t"        j%                  d       | j'                          t"        j%                  d       | j)                          | j+                          | j-                          | j/                          | j1                          t"        j2                  rd| _        n| j4                  rd| _        t7        | p  |||d|}| j;                          | j                  sv| j<                  j                  r`t>        j%                  d| | j<                  j@                  | j<                         | jC                  tE        | tF        jH                        	       | jK                  |jM                  d
d              | jN                  |i | | jQ                  d| j
                          |S )NuN   Запрещено редактировать системный объект Tr-  r  r  Frx  zGCmfEntity.save(): Need update essential models for %s: parent: %s -> %s)rk  r<  )r<  z_save1 name=r  ))rb  r  r   r3  r   rU   r   r  r&  r   rN  r$  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  rR   r   _acl_spread_inheritancer)  r  r  rs  r*   r   rh  rA  r,   r  r  )r`   r  r  r~   rO   r  r\   s         r"   r   zCmfEntity.save  s   ;;t{{ yy##tyy';';%%(vw{w~w~v  'A  IM%  N&&(yyDI'')  	??tGGL!IIKGGJ 	 &&(!%%'==#'D !!#(D glDDCFC$$& {{t||66MM#$($,,*:*:DLL ..
48X.Y 	GT!:;T,V,,tyyk(BC
 
r!   r:   c                 `   | j                   sy t        j                  d| j                  j                   d|        | j
                  s0t        j                  d| j                  j                   d|        y t        j                  j                  | j                  j                  ||       y )Nz1mark_full_search run CmfFullSearch.mark_dirty id=z celery=zDmark_full_search self.name is None SKIP CmfFullSearch.mark_dirty id=)
fast_indexr  )	rV  r   r  r   r   rU   r   rY  
mark_dirty)r`   r  r  s      r"   r  zCmfEntity.mark_full_searchH  s     	
CDGGMM?RZ[aZbcdyyGGZ[_[b[b[h[hZiiqrxqyz{''&T]'^r!      )
system_jobre  only_once_argspriorityc                    t         j                  d|         t        j                  j	                         rt         j                  d       y t        j
                  |       }|j                  | |j                  dd      }|st        j                  j                  | g d      }|s+d|  }t         j                  |t        j                         y d	|j                   d
|j                   d|j                   d|j                   }t         j                  |t        j                         t        j                  j!                  |        y |j#                          t         j                  d|         y )NzStart celery_full_search_index uJ   Не индексируем поскольку запущен импортTr*  )r   obj_namedirty_atis_dirty)rg  rH   u   celery_full_search_index: Не индексируем поскольку объект не найден или удален в бд (включая запись CmfFullSearch) obj_id:)r4  u   celery_full_search_index: Не индексируем поскольку объект не найден или удален в бд id:z
 obj_name:z
 dirty_at:z
 is_dirty:zEnd celery_full_search_index )r   r  r   enable_import_modeimport_is_runningr  r,   full_search_preload_fieldsr   rY  r  ERRORr   r  r  r  '_text_search_sql_delete_obj_with_childsfull_search_index)rg  r~   rO   r   r6  
search_rawerr_strs          r"   celery_full_search_indexz"CmfEntity.celery_full_search_indexU  sC    	
1&:;%%779GG`a''/iiu'G'GY]mqir--11Hr1sJNNTXWw}}5$--
:3F3F2GzR\ReReQf g  * 3 346G GGG7==G1  HHP	/x89r!   c           	      
   dd l }dd l}ddlm} t        j
                  j                  t        j                  d| j                  j                  d      d   t        | j                              } |d| j                  j                  d      d   t        | j                        d t        | j                        dz    t        | j                              }t        j
                  j                  |      rV |t        j                  |      }|j                         s/|j                  j!                  d       |j#                  ||       n#|j%                  ||       |j'                  |       | d}t        j
                  j                  |      r|j#                  ||j                         t(        j*                  j-                  d	d
| gg d      D ]s  }	|	j.                  j0                  }
|	j2                  j0                  }|	j4                  j0                  }d |	_        |	j7                          |
|	j.                  k7  r| j8                  j;                          | j8                  j0                  j=                  |
|	j.                  j0                        | _        | j8                  j0                  j=                  |j>                  jA                  |
      |	j.                  j0                        | _        | j8                  j0                  j=                  |j>                  jC                  |
      |	j.                  j0                        | _        | j8                  j0                  j=                  ||	j2                  j0                        | _        | j8                  j0                  j=                  |j>                  jA                  |      |	j.                  j0                        | _        | j8                  j0                  j=                  |j>                  jC                  |      |	j.                  j0                        | _        | j8                  j0                  j=                  ||	j4                  j0                        | _        | j8                  j0                  j=                  |j>                  jA                  |      |	j.                  j0                        | _        | j8                  j0                  j=                  |j>                  jC                  |      |	j.                  j0                        | _        | jD                  sb| j7                  d       v |r |t        j                  |      }t        |      S )Nr   )Pathr6  r	  r  T)exist_okz.metar(  r~  )rd  url_preview_imgurl_previewr5  r  )#shutilurllibpathlibr  ospathr@   r  
UPLOAD_DIRr   rA   r
  rq  ri   rJ  r(  mkdirmover   rmtreer   rT  rL   rd  r   r  r  r   rn  r  replaceparsequote
quote_plusr   )r`   absoluter  r  r  old_pathr  new_pathold_meta_pathattachold_urlold_url_preview_imgold_url_previews                r"   get_files_dirzCmfEntity.get_files_dirn  s    77<< 1 15$''--:LQ:OQTUYU\U\Q]^E477==-a0TWW>Ws4???SVW?W1XZ]^b^e^eZfg77>>(#F--t4H??$%%t%4Hh/Hh/h''j.Mww~~m,M8??; ..33Hd4;P  ZC3  D . ****&,&<&<&B&B#"("4"4":":!
fjj(IINN$ $		 7 7AQAQ RDI $		 7 78J8J78SU[U_U_UeUe fDI $		 7 78O8OPW8XZ`ZdZdZjZj kDI $		 7 78KVMcMcMiMi jDI $		 7 78J8JK^8_agakakaqaq rDI $		 7 78O8OPc8dflfpfpfvfv wDI $		 7 7I[I[IaIa bDI $		 7 78J8J?8[]c]g]g]m]m nDI $		 7 78O8OP_8`bhblblbrbr sDI??III-+.. ))40D4yr!   c                    ddl m} 	 | j                  dk7  rt        j                  ry ddlm} t        j                  d      }|si }i t        _        |j                  | j                  j                        }|i }| j                  j                  |d<   t        j                  xr$ t        j                  j                  j                  |d<   d |d<   d |d	<   d |d
<   | j                  |d<   g |d<   g |d<   g |d<   g |d<   t        | d      r/| j                  j                  r| j                  j                  |d<   t        | d	      r/| j                  j                  r| j                  j                  |d	<   t        | d
      r/| j                   j                  r| j                   j                  |d
<   |d   j#                  d       |j                  d      xs g }| j$                  r| j'                  d      D ]  \  }}|dv rt)        | |      }|j*                  durI|j,                  |j                  k(  r0t        j/                  d| j                   d|j                          ot1        |t2        j4                  j6                        rt1        |t2        j4                  j8                        r:|j:                  D ]*  ^}	}
}|j#                  |
j                  j                         , nt1        |j                  t<              s<|j                  0|j#                  |j                  j                  j                         nPt1        |j                  t<              r6|j                  D ]'  }|j#                  |j                  j                         ) |j*                  du r"t        j/                  d|j>                          |j*                  durt1        |t2        j4                  j6                        rt1        |j,                  t<              s<|j,                  0|j#                  |j,                  j                  j                         nPt1        |j,                  t<              r6|j,                  D ]'  }|j#                  |j                  j                         ) |d   j#                  |        |d   jA                  |       d}	| jB                  rd}	| jD                  j                  r| jD                  dk(  rd}	|d   j#                  |	       t=        tG        |d               |d<   t=        tG        |d               |d<   t=        tG        |d               |d<   t=        tG        |d               |d<   dt        v rt        jH                  |d<   nd|d<   dt        v rt        jJ                  |d<   nd|d<   |t        j                  | j                  j                  <   y )Nr   )r   r  cmf_emit_event	emit_listr   event_current_personr4  r  placeri   relation_personschanged_fieldschanged_relationsr  __DEFERRED_all_relation_personsTr  )r?  r   r  r  r=  r<  .zemit: FIXME is changed bug rF   uR   DEV: INFO Могла не прийти инвалидация для old-поля rN   r  r  jsurlr:   session_tab_id)&collectionsr   ri   r   r  r   r  r,   r  r   r   r   rp   r4  r  r  r  rx   r   r)   ru   r   r  r  r*   r   rH   rr  r  r9  rL   rw   r  r   r  r   r  r  )r`   r   r  r  bodyr  r/   r0   r   r  r6  r2   r   s                r"   r  zCmfEntity.emit  s   +	 ??k)amm. EE+&	IAK}}TWW]]+<DDJ+,+;+;+Y@P@P@S@S@Y@YD'( $D $D DM!%D')D#$%'D!"(*D$%DN4$)B)B $ 4 4D4$)B)B $ 4 4D4 TZZ%:%: JJ,,DM 	 ''(IJ HH%89?R??zzTz2 1! G G a( ::S(UYY!''-AGG9$//9J!EL\L\K]^_eSZZ%:%:;!%)>)>? 05~~ COFC!-44SVV\\BC'T:u{{?V)001E1EF#EKK6!& AA-44QTTZZ@A ::$GGpqv  rG  rG  qH  I  J::S(Zszz?T?T-U%eii6599;P)001C1CD#EIIt4!& AA-44QTTZZ@A%&--a0?1@ 	 !(():;;;F&&4+;+;t+CFXf%c4>23X!%c$/?*@&A!B$(T2E-F)G$H !#'D1C,D(E#F a<GGDMDMq %&%5%5D!"%'D!"%)DGGMM"r!   c           
      N   g }|j                         j                  d      }|D ]Q  }t        |      dk\  r0|j                  dj	                  |d t        |      dz
                A|j                  |       S dj	                  dj                  |      j                  d            S )Nr  r  z{}%r  z%{}%r`  )striprA   rq  rx   formatr@   )rT   querystemmed_query_wordswordsws        r"   _get_stemmed_queryzCmfEntity._get_stemmed_query  s     ##C( 	.A1v|#**5<<+3q6A:+GH#**1-		.
 }}chh':;BB3GHHr!   )r  rH   r  r  c                   | j                  |      }|j                  d      }ddd|gg}	d|v r+|j                  d      D ]  }
|	j                  |
d|g        nOdD ]  }
|	j                  |
d|g        t        j                  || j
                        r|	j                  d	d|g       |r|	|g}	|r|	j                  d	d
|g       | j                  ||	|      }|S )N)r  r4  r^  r3  r~  fields_filterr_  )rU   rn  r3  r   rF  r  )r  r,   rx   r   is_tuuidri   rL   )rT   r  rH   r  r  r~   rO   stemmed_queryr4  r?  r  r  s               r"   rP  zCmfEntity.search  s    ..U.;JJ{+	T5!
 f$ZZ0 <7M:;< . <7M:;< s~~6dE23'GNND$	23hhfWEhB
r!   c                 n    | j                   st        d      t        j                  | j                         S )NK   Блокировка объектов без id не реализована)r   rq   r   ry  r   s    r"   ry  zCmfEntity.lock_ping'  s*    wwjll  ))r!   c                 n    | j                   st        d      t        j                  | j                         S )ut   
        Из редиса заберём структуру, где есть данные
        :return:
        r  )r   rq   r   	lock_infor   s    r"   r  zCmfEntity.lock_info,  s,    
 wwjll  ))r!   c                     	 | j                   st        d      | j                          | j                  dk(  r| j	                  d|        t        j                  | j                   d      S )u`   
        Захват объекта на редактирование
        :return:
        r  rQ  zPPP-PR-ADMINrs  i  )r   rq   r  ri   rZ  r   rx  r   s    r"   rx  zCmfEntity.lock6  s\    
	wwjll
 ??l***>t*D||DGGW--r!   c                 n    | j                   st        d      t        j                  | j                         S )u>   
        Снятие захвата
        :return:
        r  )r   rq   r   r  r   s    r"   r  zCmfEntity.unlockI  s*    
 wwjll~~dgg&&r!   c                 x    | j                  dg       d| _        | j                          | j                  d      S )Nr:  Tr  r  r:  rA  r   rk  s      r"   archivezCmfEntity.archiveR  s8    .)* yy4y((r!   c                 x    | j                  dg       d| _        | j                          | j                  d      S )Nr:  FTr  r  rk  s      r"   archive_restorezCmfEntity.archive_restoreX  s8    .)*!yy4y((r!   c           
         | j                          | j                  g d       | j                  ry|swt        | d      r=t        j
                  j                  d| j                   d| j                   dd       n.t        j
                  j                  d| j                   d       |s| j                          |s| j                         }| j                  |       t        j                  | j                        t        j                  u rt         j"                  j$                  szt        | d      rnt        | d	      rb| j                  dd	g
       | j&                  rB| j&                  j(                  | _        | d| j&                   | _        | j&                  | _        | j.                  r| j.                  j1                  |        | j2                  s| j4                  s| j                  }| j6                  dk(  r5| j8                  j;                          | j8                  r| j8                  dd }| j=                         }t        j>                  jA                  d| j6                  t         jB                  | tE        |      tE        | jF                  jH                        d|       |s | jJ                  di | | jM                  d       t        t        d      r#|s!t        jN                  jQ                  | dd       tS        	|   d||d|}t        t        d      r#|s!t        jN                  jQ                  | dd       |s| jW                  d| j                          |S )N)r  r   r)  r  rk  rv  ru  rU   u<   Нельзя удалять системный объект  (r  Tr-  r{  rz  ru  r2   r  r   r4  r   F)rs  r\  r   r(  r5  r6  r8  r*  r  CmfAutomationCrudTriggerbefore_save)r  r0  
after_savezdelete1 name=rz  r    ),r  r  r  rp   r   r  r&  rU   r   r  generate_delete_prefixapply_delete_prefixr   r  r   rd  r   global_settingslogin_reuse_lockr{  r   deleted_loginrz  rk  rw  r  r   ri   rn  r  r+  r  r  r   r
  r3  r  r  r  r  	crud_hookrR   r   r  )
r`   r  r'  r0  rO   r  r@  r*  r  r\   s
            r"   r   zCmfEntity.delete_  s    
 	 ;;utV$%%(deienendooqrvryryqzz{&|  EI%  J%%(deieleldm&nvz%{""$  002F$$V,
 ''0F4D4DD%%66$(WT7-C  '(: ;::)-)9)9D&$*81TZZL!9DJ!%DJ ..t4%%99??l2IINN$yy#'99Qs#3!88:
++$#'?? // #H #DIIMM 2',) , 	 (*D**4V4:656?O++55dHmTgnV5;KVvV656?O++55dHlS!!mDII;,G!H
r!   c                 N    dt         j                         j                  d       S )u9   Префикс для удалённых объектовDEL%Y%m%d%H%M%S)r   r   r  r   s    r"   r  z CmfEntity.generate_delete_prefix  s!    X\\^,,^<=>>r!   r  c                    | j                   j                  s| j                   j                          | j                  rt        j                  d| j                  j                        sh| j                   s[| d| j                   d| j                  j                   | _        | d| j                   d| j                  j                   | _        yyyy)ua   Добавляет префикс удаления к коду и названию объектаz[A-Z]+-\d{4,}\Zr2   Nr  )	r  r  r  r3  rematchr   
max_lengthrU   )r`   r  s     r"   r  zCmfEntity.apply_delete_prefix  s    **!!#IIbhh'9499??KTXTdTd!(!DII;/0E1E1EFDI!(!DII;/0E1E1EFDI UeKIr!   r]  c          
         | j                  g d       | j                  j                  rUt        j                  | j                  ddddg      }|r.|j
                  r| j                  | _        n|j                          | j                  rnt        j                  | j                  | j                  j                        r:t        j                  | j                  d| j                  j                        | _	        | j                  rnt        j                  | j                  | j                  j                        r:t        j                  | j                  d| j                  j                        | _        t!        | d      rXt!        | d      rL| j                  g d	
       | j"                  r,| j$                  j                  | _        | j"                  | _        | j(                  s| j                  }| j*                  dk(  r5| j,                  j/                          | j,                  r| j,                  dd }t0        j2                  j5                  d| j*                  t6        j8                  | t;        |      t;        | j                  j<                        d       t1        j>                  j@                  | dg|i | tC        |   |d|i|S )N)r!  r(  r)  Tr  r_  )r+  r,  rH   r:   r{  rz  )r{  rz  r  ru  r  r   r4  rb  F)rs  r\  r   r(  r5  r6  r8  restoredrP  )#r  r!  r]  r   r/  r  r)  rk  ri  rU   r  r  rv  r   r4   r3  rp   r{  r  rz  r   ri   rn  r  r   r  r  r   r   r
  r  r  r  rR   rb  )r`   rP  r~   rO   rk  r@  r\   s         r"   rb  zCmfEntity.restore  s   @A**!//0C0CUYim8EG\7]_K**'+||D$77999$"<"<diiooNt992tyyODI99$"<"<diiooNt992tyyODI4!gdG&<$GHzz!//55
!ZZ
!!yyH,.		 99#yy3/HOO''!#++M		.#( (  OO$$T:GGGwD	DVDDr!   c                 `   | j                   j                         sy| j                  j                         D ]4  }|j	                  dd| j
                  gdd|j
                  gg      }|s4 y d| _         t        j                         5  | j                  d	       ddd       y# 1 sw Y   yxY w)
u    Убирает метку дерева у объекта при удалении узлов, при перемещении узлов Nr!  r~  r   rF  r4  FTr  )	r_  r  
tree_nodesr  r   r   r   r(  r   )r`   r8  r   r6  s       r"   rw  zCmfEntity.tree_child_delete  s    '',,.__335 	E**&6dgg%FtUZU]U]H^$_*`C	
 $)   " 	&III%	& 	& 	&s   B$$B-c                 0    t        j                  | fi | y)u   
        Синхронизируем настройки полей с фронта
        TODO: мб чекать права, т.к. можно заспамить систему
        N)CmfCustomClassrw  )rT   rO   s     r"   rw  zCmfEntity.custom_field_sync  s     	((77r!   datac                 ,    t         j                  |       S u   
        !!! Здесь для совместимости, т.к. вызывается из импорта, патчей, и мб ручных скриптов.
        )r  custom_fields_gen_metar  r=  s     r"   r  z CmfEntity.custom_fields_gen_meta  s    
 44T::r!   c                 ,    t         j                  |       S r  )r  reload_model_handlerr  s     r"   custom_field_sync_update_modelsz)CmfEntity.custom_field_sync_update_models  s    
 22488r!   c                     ddl m} |j                  dk(  r& |d| j                   | j	                                y  |d| j                   | j	                                y )Nr   r  ztask-comment-)event_personszaudit-task-comment-)cmf.appr  r&  r   r  )r`   r7  r~   rO   r  s        r"   _comment_save_hookzCmfEntity._comment_save_hook  sR     	+!]477)4DD]D]D_`0	:$JcJcJefr!   c                      y)uE    Базовый шаблон почтовых уведомлений zmail_notification.htmlr    r   s    r"   +get_default_mail_notification_template_namez5CmfEntity.get_default_mail_notification_template_name  s     (r!   c           	           j                   j                         D cg c]  \  }}|j                  s| }}} j                   j                  |z           j
                  dk(  r@ j                  s4t        j                  j                   j                  j                         y j
                  dk(  rO j                  j                  d      r4t        j                  j                   j                  j                         y j
                  dk(  rt        j                   j                  j                  j
                        j                   sy j                  j                  j
                  dk7  rVt"        j%                   j                   d       t        j                  j                   j                  j                         yd|vrzd}t'         j(                  d d	
      dd D ]T  }|j*                  dk(  s|dt        j                  j-                  t/        |j0                  xs d      dd       dd z   z  }V ||d<   d|vrb j2                  sVt"        j%                   j                   d       t        j                  j                   j                  j                         y j
                  |d<    j4                  |d<    j6                  r2 j8                  j;                         j                  j                  |d<   n j                  j                  |d<   |j=                  d j>                  j                         |j=                  d j2                  j                          j@                  r|d   |d<   |j=                  d jB                  j                         |j=                  d jD                  j                         |j=                  d jF                         |j=                  d j                  j                         |j=                  d jH                  xr   jH                  j2                  j                  xs d       |j=                  d jJ                  xr   jJ                  j2                  j                  xs d       |j=                  d jL                  xr   jL                  j2                  j                  xs d       |j=                  d jN                  j                         tQ         d      r&|j=                  d  jR                  j                         |j=                  d! jT                  j                         |j=                  d" jV                  j                          fd#} |       }|r||d$<   nd|d$<    fd%}	 |	       |d&<    fd'}
t        jX                  j[                  d(d)t[         |
             gd*g+      }g }|D ]4  }|j\                  s|j_                  |j\                  j                         6 |rd,ja                  |      |d-<   d7fd.	d}d}d}d/ j                   v rD jb                  r jb                  j2                  nd} jb                  j                  j                  }d} j                  r%   j                  j                  |||0      \  }}}d1 j                   v r; jR                  r/td        jg                   jR                        }|r|j2                  nd}d|vr9t        j                  j-                  t/         j0                  xs d            |d<   ||d2<   ||d3<   ||d4<    jh                  j                  |d5<    j2                   d,|xs d d,|xs d d,| jk                         |d6<    j
                  dk(  r0 j                  j                  j
                  dk(  r j                  j                  j;                           j                  j                  s4t        j                  j                   j                  j                         yt        j                   j                  j                  j                  j
                        j                   s4t        j                  j                   j                  j                         y j                  j                  j                  |d<   t        j                  jl                  d8i | yc c}}w )9u   
        Медленный метод для вызова из celery или из массовых индексаций
        rT  Nz
CmfPerson:r  u3    Объект с model full_search=False mark_cleancomments_textr:   c                     | j                   S r<   )r  )r  s    r"   rg  z-CmfEntity.full_search_index.<locals>.<lambda>L  s    q?O?O r!   T)r  reverser  r   r  r  i   rU   ud    Объект без имени в поиск добавлять бессмысленно mark_cleanr  model_verbose_namerg  r  rn  obj_archivedobj_deletedobj_hrefr  obj_owner_nameobj_author_nameobj_modified_by_nameobj_tree_parent_idr  obj_project_idobj_created_atobj_modified_atc                  J   i } d }d j                   j                         D ]  \  }}|j                  s|dk(  rt        |      }|j                  r3t        |t        j                   j                        r-t        j                  j                  t        |            d d }nKt        |t        j                   j                        r ||j                        }nt        |t        j                   j                        r ||j                        }nt        |t        j                   j                        r |j                        }nt        |t        j                   j                         rdj#                  fd|D              }nft        |t        j                   j$                  t        j                   j&                  f      r|j(                  j+                  |d      }nt        |      }|r|j-                         st        |      | |j.                  <    | S )Nc                 h    t         j                  | j                     }| d| j                  d       S )Nr  z%Y-%m-%d)r   	RU_MONTHSmonthr  )r   
month_names     r"   _format_datezVCmfEntity.full_search_index.<locals>.get_obj_addon_fields_2_dict.<locals>._format_datex  s1    $..u{{;
$Qu~~j'A&BCCr!   c                    | syt        | j                  xs d      j                         }t        | j                  xs d      j                         }d}t	        | d      r/| j
                  r#t        | j
                        j                         }d}t	        | d      r/| j                  r#t        | j                        j                         }| }|r||k7  r|d| z  }|r||k7  r||k7  r|d| z  }|r||k7  r||k7  r||k7  r|d| z  }|S )Nr:   r{  rz  r  )r
  rU   r5   r3  rp   r{  rz  )r   rU   r3  r{  rz  r  s         r"   _format_relzUCmfEntity.full_search_index.<locals>.get_obj_addon_fields_2_dict.<locals>._format_rel|  s   5::+,2245::+,2245'*u{{,224E5'*u{{,224EDDLQtf:%CUd]u}Qug;&CUe^%4-Qug;&C
r!   tagsi  r  c              3   .   K   | ]  } |        y wr<   r    )r>   r   r  s     r"   r?   zSCmfEntity.full_search_index.<locals>.get_obj_addon_fields_2_dict.<locals>.<genexpr>  s     +NqKN+Ns   r:   )rH   r)   r  ru   r  r*   r   	CmfMarkupr   rY  
strip_htmlr
  r   r   r   r  r  r@   	CmfChoiceCmfChoiceIntrD  r,   r  rG   )r%  r
  r  r   	obj_fieldresult_valuer  r`   s         @r"   get_obj_addon_fields_2_dictz@CmfEntity.full_search_index.<locals>.get_obj_addon_fields_2_dictv  s   FD. %)KK$5$5$7 ": 	5--& #D)4	$$i)=)=> $*#7#7#B#B3y>#RSXTX#YL	3::+A+AB#/	#@L	3::+=+=>#/	#@L	3::+E+EF#.y#?L	3::+@+@A#&88+NI+N#NL	CJJ,@,@#**BYBY+Z[#(==#4#4Y#CL#&y>L#<+=+=+? ),L(9u}}%E":H Mr!   obj_addon_fields_dictc                     g } | j                  j                  j                  j                  j                  d       j                  r\j                  j                  rF| j                  j                  j                  j                  j
                  j                  d       j                  rj                  j                  rj
                  j                  r-j                  j                  j
                  j                  k7  rF| j                  j                  j                  j                  j                  j                  d       dj                  v r~j                  rrt        j                  j                        }|r|j                  nd}|rA|j                  k7  r2| j                  |j                  j                  j                  d       t        j                  |       S )N)rU   r   r)  r:   )rx   rU   r   r   rk  r!  r(  r4  rH   r  r  r  r"  r#  )r  r)  project_namer`   s      r"   obj_breadcrumbsz4CmfEntity.full_search_index.<locals>.obj_breadcrumbs  sb   CJJ		tww}}EFD$4$4$9$9

D$4$4$9$9$?$?tGZGZG`G`ab{{t{{//9L9L9R9RVZVdVdVjVjnr  oB  oB  oH  oH  WH

DKK$4$4$:$:$..BVBVWXDKK'DOO//@/6w||B  Gt{{$:JJ(:(:$//BWBWXY::c?"r!   r  c                     t               } | j                  j                  j                         dj                  v r1j
                  r%| j                  j
                  j                         | j                  j                  j                         | j                  j                  j                         dj                  v r]j                  rQj                  D ]B  }t        |t        j                        s| j                  |j                  j                         D dj                  v r]j                  rQj                  D ]B  }t        |t        j                        s| j                  |j                  j                         D dj                  v rEj                  r9j                  d d D ]'  }| j                  |j                  j                         ) | j                  d        | S )Nresponsible_idrL  
spectatorsr  2   )r   r  r  r   rH   r  r  r  rL  r*   r   rd  r   r  r  discard)related_personra   r7  r`   s      r"   fill_obj_related_personsz=CmfEntity.full_search_index.<locals>.fill_obj_related_persons  s~    UNt006674;;.43F3F""4#6#6#<#<=t66<<=t11778dkk)dnn NN :D!$(8(89&**477==9: t{{*t OO :D!$(8(89&**477==9:
 T[[(T]]#}}Sb1 DG"&&w'<'<'B'BCD
 ""4(!!r!   r   rc  r{  r5  r  obj_related_person_loginsc                 &   t        |      j                  d      r|||fS t        j                  |g ddd      }|st	        d|  d|        |||fS d| j
                  v rR|sPd|j
                  v rB|j                  r6|j                  j                  }|j                  j                  j                  }t        |t        j                        s|j                  r|d|j                  z   z  }|j                  r | |j                  ||	      S |||fS )
NzCmfUWorkList:)r(  r4  rt  zcompany.name
company_idT)rH   r+  r   u'   ERROR! CmfFullSearch у объекта u2    указан несуществующий parent=ru  r  )company_nametmp_breadcrumbs)r
  rz   r   r/  r  rH   ru  rU   r   r   r*   r   rQ  r(  r4  )r6  r4  r$  r#  r%  _tmp_parentobj_tmp_breadcrumbs_fieldss         r"   r'  z?CmfEntity.full_search_index.<locals>.obj_tmp_breadcrumbs_fields  s6   9~((9 "<@@!//	  CG  Y]  pt  uK?uDv  xA  wB  C  D!<@@CJJ&|	[M_M_@_dodwdw*2277(003399
k6+<+<=###s[-=-='==O!!1#{7L7L[g  zI  J  J|_<<r!   ru  )r6  r4  r$  r#  r%  r)  r  r$  obj_company_idrs  text_prefix)NNNNr    )7rH   r)   r  r  r  ri   r(  r   rY  
mark_cleanr   r   r4  rz   r   r1  rV  r   r  r
  r  r&  r  r
  rn  rU   r  r  cmf_ver_headr  rs   r3  r  r:  r  r  r   r   r   r!  rp   r  r  r?  rd  rL   r{  rx   r@   ru  r  r  rs  r  index_object)r`   rO   r/   r0   addon_fieldsr  r7  r  r  r  r   r  releated_person_loginspr#  r$  r  r%  r)  r'  s   `                  @r"   r  zCmfEntity.full_search_index%  sI    '+kk&7&7&9PdaQ=O=OPP 	88<GH ??o-dkk  ++DGGMM:??o-$..2K2KL2Y  ++DGGMM:??o---dkk.?.?.J.JKWW!!,,<477)#VWX$$//>&(
 M!$--5OY]^_b`bc t$$)!TF,@,@,K,KCPWP\P\Pb`bLcdjejLk,lmrnr,s%ssMt '4F?#		GGtwwi   D  E  F  ++DGGMM:#|'+'8'8#$<<#00557::@@F8#ww}}F8*diioo6&$))//2#F^F6N.$*;*;*A*AB-)9)9)?)?@*dii0/4>>+?+?@*DNN,Xt~~?R?R?X?X,`\`a+T__-[AUAUA[A[-c_cd0$2F2F2j4K_K_KdKdKjKj2rnrs.0C0C0I0IJ 4&.0E0EF*D,?,?,E,EF+T-A-A-G-GHA	F !< = !.CF*+.2F*+	#, %4$5 !	"@ ##$%=%? @A9 $ 
 "$ 	=Aww&--aggmm<	= "25((;Q2RF./	=. 
#044<<,,$L..J>>8R....)% /95Jo #++DOO<G+27<<L#11<<Sb=QRF6N!-~!-~#- %)%:%:%@%@!" $(99+Q|/Ar.B!LDVTVCWWXYhXi j p p r} ??o-$++2C2C2N2NR^2^KK##%;;%%$$//>,,T[[-?-?-E-E-P-PQ]]$$//>&*kk&;&;&A&AF?#))3F3W	 Qs
   c=c=u8   Разрешить публичный доступ DELME)r  rG   r%   u-   Задать права для объектаr/  u<   Список для проверки прав доступа)r   r   r  rG   u!   Наследовать праваu#   Наследуем права от )r  r   r  rG   u*   Кеш Владельца Родителя)r   r  rG   r  u;   Наследуемый список прав доступа)r   rG   r  r  u;   Эффективный список прав доступа)r   r  rG   u   Кеш неразвернутых записей Уровней безопасности, которым разрешен доступ)rG   r  u   Шифрованныйu5   Для просмотра требуется ключ)r%   r  rG   r7  u7   Подсказка к паролю шифрования)rG   r  c                 *    | j                  g d       y )N)perm_has_aclz
perm_acl.*zperm_acl.cmf_ownerz!perm_acl.object_ownerperm_inheritr   r  r  r   )r  r   s    r"   _load_perm_fieldszCmfEntity._load_perm_fields  s     2 	3r!   c                    t        j                  |      }	 |r|gnd}|dk(  r|j                  |       n|j                  |       t	        |t
        j                        r|j                  ddg       |dk(  rnt        j                  |j                  k(  r(|j                  j                  d|j                         y|j                  j                  d	|j                         	 y|d
k(  rlt        j                  |j                  k(  r(|j                  j                  d|j                         y|j                  j                  d|j                         y# t        $ r Y yw xY w)u   
        Метод чисто для вызова с фронта для красоты
        perm = create|update|read|delete
        Nr  r  r)  r(  rN   PPP-COM-EDIT-OWNrs  PPP-COM-EDIT-ALLr   PPP-COM-DELETE-OWNPPP-COM-DELETE-ALLFT)r   r/  r[  r  r*   r   r  r  r   r  r   r)  rZ  r(  r\  )rT   rg  rY   permr6  rH   s         r"   OLD_ux_check_permzCmfEntity.OLD_ux_check_perm  sG    ##F+	%/j\TFv~##F+$$$? #v001H 568#~~6==>PVYV`V`=a   ==>PVYV`V`=a  X%~~6==>RX[XbXb=c  ==>RX[XbXb=c  " 		s%   B&E >'E 'A	E 1'E 	E%$E%c                 N   ddl m} |r&t        j                  |ddg      }|j                  }n'| j
                  dk7  rt        j                  |dg      }	 |r|gnd }|dk(  r|j                  |       nY|dv r|j                  |	       nB|d
v rn=|dk(  r+|j                  sy|j                  j                  d|       n |d| d       	 | t        j                  u rG|dk(  r{|j                  rt        j                  |j                  k(  r(|j                  j                  d|j                         y|j                  j                  d|j                         	 y|dk(  r{|j                  rt        j                  |j                  k(  r(|j                  j                  d|j                         y|j                  j                  d|j                         	 y|dk(  r,|j                  r|j                  j                  d|       	 y|dk(  r	 y |d| d       	 y| t        j                   u rj|dk(  rt        j                  j"                  st        j$                  st        j&                  st        j                  j)                  d      snt        d      | t        j*                  u rQ|dk(  r|j                  j                  d|       y|dk(  r)|j                  r|j                  j                  d|       y# t        $ r Y yw xY w# t        $ r Y yw xY w) Nr   r%  r)  zparent.projectru  rQ  r  )rN   r   r4  )r   publiczview-workflowFzPPP-PR-VIEW-WORKFLOWrs  u/   Недопустимый параметр perm=Tr-  rN   r5  r6  r   r7  r8  r   zPPP-COM-ADDProjectCreators)
group_codeuP   У пользователя нет прав на созднаие проектаr<  PPP-DOC-SHAREzPPP-DOC-EDIT)r  r&  r   r/  r(  ri   r[  r  r)  rZ  r\  r   r  r   r  r   rQ  is_adminr  r  in_person_grouprf  )rT   r6  rY   r9  r(  r&  rH   s          r"   r  zCmfEntity.ux_check_perm  s    	&''Y@P4QRCZZF^^|+**69+FF	%/j\TFv~##F+--$$$?--({{ 556LRU5VKD6RZ^_'	f'''8#{{>>S]]:KKAABTZ]ZdZdAeH E  KKAABTZ]ZdZdAeD C X%{{>>S]]:KKAABV\_\f\fAg< 9  KKAABV\_\f\fAg8 7 X%~~@@TZ@[2 1 V^. +  OPTvV^bc* ) )))8#>>22A<Q<QUVUeUe#$>>#A#AM^#A#_&8  :L  'M  !M***8#KK99/s9S  X%{{==nRU=V ] " 		V " 		s^   AL	 #+L	 A)L 9'L "AL 9'L "/L L L )B0L .L 		LL	L$#L$c                    | j                   s-| j                  j                  s| j                  j                  sy | j	                          d }| j                  r| j                  }|| _        y | j                  r| j                  }|| _        y r<   )r   rk  r   r(  r2  r   )r`   r   s     r"   r  zCmfEntity._calc_perm_parent   so    t//::dkk>T>T **K ' [[++K&r!   c                 .   | j                   j                  sy | j                          | j                   rT| j                   j                  ddg       | j                   j                  | _        | j                   j                  | _        y d | _        d | _        y )Nr  r  )r   r   r2  r  r  r  r  r  r   s    r"   r  z#CmfEntity._calc_perm_inherit_acl_id,  s{    ** ((*A>)RS'+'7'7'M'MD$(,(8(8(E(ED%'+D$(,D%r!   c                      y r<   r    r   s    r"   r  zCmfEntity._calc_perm_has_acl9  s    r!   c                    | j                   j                  s?| j                  j                  s)| j                  j                  s|s| j	                         syd}| j
                  r| j                  dk(  r| j                  j                  r| j                  j                  rut        j                  | j
                        }|j                  d|        d}t        j                  j                  t        j                   j"                  j$                         | j
                  r^| j                  dk(  rO| j                  j                  r9| j&                  j)                          | j&                  j                  d|        d}| j+                          | j                   rt| j,                  sht        j!                  |       | _        | j.                  sAt        j                  j                  t        j                   j"                  j$                         | j,                  rS| j                    | j,                  _        | j                  | j,                  _        | j                  | j,                  _        | j4                  r| j                  nd| j,                  _        |rVt8        j:                  j<                  j?                         5  | j,                  j@                  jC                          ddd       n$| j,                  j@                  jC                          t8        j:                  j<                  j?                         5  | j,                  jE                          | jG                          ddd       yy# 1 sw Y   fxY w# 1 sw Y   yxY w)	u   TODO2 записать: нужно разобраться с ролевой моделью на правила АЦЛ:
        - кто может менять правила АЦЛ у объекта проектного/нет
        - - нужно ли проектное право на это
        - кто имеет право редактирвоать другие опции объекта, связанные с правами

        Args:
            force (bool, optional): _description_. Defaults to False.
        NFrf  r?  rs  TzPPP-DOC-TREEMOVE)r(  )$r1  r   r  r   _acl_subjects_is_changedr  ri   perm_policy_anonymousperm_policy_guestr  r  rZ  r   deferred_force_show_progressbarr  r   r/  proccess_chanded_acl_jobrU   r)  r  r2  perm_aclr   disabledobject_ownerperm_inheritinherit_acl_idr   r  r   r(  r   r   clear_auto_acl_acl_scaffold)r`   r  can_skip_aclr)  s       r"   r  zCmfEntity._calc_perm_acl<  s    !!,,++66>>,,002??t=$B\B\BgBglp  mC  mC  mN  mN++DOO<G--o4-HL--11&2F2F2_2_2d2de??t=$BZBZBeBeLLLL223E42PL T]]"000=DM;;1155f6J6J6c6c6h6hi== *.):):%:DMM"&*nnDMM#)-DMM&GKGXGX4+C+C^bDMM([[((446 /MM'',,./ / ##((*$$002 %,,.""$% % / /
% %s    %M/:+M;/M8;Nc                      y r<   r    r   s    r"   rQ  zCmfEntity._acl_scaffoldo  s    r!   c                    | j                          | j                          | j                  r| j                  j                  g d       d| j                  _        | j                  j
                  D ];  }|j                  dk(  r|j                          #d|_        |j                  d       = | j                  j                  j                          | j                  d       y )N)policyrL  zrules.disabledzrules.sys_typeTr  r  )
r  r2  rK  r  rL  r  sys_typer   r   r   )r`   r=  rules      r"   r(  zCmfEntity.disable_aclr  s     	 ==MM%%&`a%)DMM"++ .==F*KKM$(DMIII-. MM$$&		D	!r!   c                 r   | j                   j                  sC| j                  j                  s-| j                  j                  s| j                  j                  sy | j                  g d       d }| j                   r| j                  j                  }|| _        y | j                  r| j                  }|| _        y )N)r1  perm_acl_idrN  r  r  )r1  r   rN  rK  r  r  r   r  )r`   r  s     r"   r  z"CmfEntity._calc_perm_effective_acl  s    !!,,$$//==++++66k	m $$(MM$4$4! &;" $($<$<!%:"r!   c                    ddl }| j                  ry| j                  j                  s| j                  j                  syt
        j                  d       ddlm} d}|r|D cg c]  }|j                   }} |t        j                  j                  | j                  || j                  j                  | j                  j                  d       yc c}w )u  
        При изменении эффективного ACL, нужно обновить все объекты и ACL, кто от нас наследуется.
        Наследование:
          child.perm_parent(рекурсивно) -> self, sub_child.perm_parent -> child
          child.perm_inherit_acl_id = self.perm_effective_acl_id
          child.perm_acl.inherit_acl_id = child.perm_inherit_acl_id if child.inherit
          if child.perm_effective_acl_id.is_change:
              do_recursion

        Операция может быть очень тяжёлой, нужно запускать как можно реже.
        !!! Потенциально можем изменять большое количество объектов, высок риск деадлоков.
         Можно разбить на небольшие транзакции, но тогда нужны дополнительные средства обеспечения
         целостности конфигурации. Может глобальный acl_lock в редисе.

        Возможна супер оптимизация, если все связи по perm_parent_id вынести в одну таблицу(модель).
          Тогда их можно получить одним рекурсивным запросом.

        TODO: force=True всё пересчитать без оптимизаций.
        r   NuG   _acl_spread_inheritance: запускаем _acl_spread_inheritance_jobrm  )rg  spread_model_namescmf_owner_is_changedperm_effective_acl_is_changedrO   )r  r   r  r   r  r   r  r   rn  ri   r   rQ  _acl_spread_inheritance_jobr   )r`   spread_modelsr   rn  r[  r  s         r"   r{  z!CmfEntity._acl_spread_inheritance  s    ( 	 ;;**559J9J9U9U	YZ5!8E!F1!,,!F!Ff//KK,0GG8J:>:K:K:V:VCGC]C]ChCh	& 	! "Gs   "C)rg  r\  r]  )re  r  r  c           	      
   d }|r"|D cg c]  }t        j                  |       }}t        j                  | ddg      }t        j	                  d       |r+t        j	                  d|        |}|t
        j                         }|D ]  }t        j                  j                  j                  j                         j                  d|j                  z  |j                  j                  |j                   j                  d      }	t#        |	      }	t$        j&                  j(                  j+                  |j,                  |	D 
ch c]  }
|
d   	 c}
       t        j	                  d	t/        t#        |	                     t        j	                  d
       |rg }g }|j                   j                  g}|r{d}|d | }||d  }|}|t
        j                         }|D ]  }t        j                  j                  j                  j                         j                  d|j                  z  |j0                  j                  |d      }	t#        |	      }	d}t$        j&                  j(                  j+                  |j,                  |	D 
ch c]  }
|
d   	 c}
       |	D ][  }|dz  }|d   |v rt        j	                  d|d    d       ,t        j2                  |d         dk(  rH|j5                  |d          ]  ||z   }t        j	                  dt/        |       dt/        |              |r{t        j	                  dt/        |              t        j	                  d       |rd}|d | }||d  }|}|t
        j                         }|D ]d  }t        j                  j                  j                  j                         j                  d|j                  z  |j0                  j                  |d      }	t$        j&                  j(                  j+                  |j,                  |	D 
ch c]  }
|
d   	 c}
       t        j                  j                  j                  j                         j                  d|j                  z  |j0                  j                  |d      }	t#        |	      }	t$        j&                  j(                  j+                  |j,                  |	D 
ch c]  }
|
d   	 c}
       g t        j	                  dt/        |       dt/        |              |rt        j	                  d       t        j	                  d       t        j	                  d       y c c}w c c}
w c c}
w c c}
w c c}
w )Nr  r  ru  uz   _acl_spread_inheritance: Шаг 1. Если изменился owner_id, апдейтим его всем потомкамuR   _acl_spread_inheritance: Обновляем perm_parent_owner_id потомкам ai  
                    UPDATE %s SET perm_parent_owner_id = :new_owner_id
                    WHERE
                    (
                        perm_parent_owner_id != :new_owner_id
                        OR perm_parent_owner_id is null
                    )
                    AND perm_parent_id = :parent_id
                    RETURNING id
                )new_owner_idr4  r   z+_acl_spread_inheritance: ... update count: ud   _acl_spread_inheritance: Шаг 2. Рекурсивное обновление perm_effective_acl_idr  a  
                        UPDATE %s SET
                            perm_inherit_acl_id = :perm_effective_acl_id,
                            perm_effective_acl_id = :perm_effective_acl_id
                        WHERE perm_parent_id = ANY(:parent_id_list)
                        AND perm_inherit = 't'
                        AND (perm_has_acl = 'f' or perm_has_acl is null)
                        RETURNING id
                    )r  parent_id_listr   rP  u'   _acl_spread_inheritance: Ошибка! u!    уже был обработанr  u6   _acl_spread_inheritance: Уже обработано: u   , к обработке: u:   _acl_spread_inheritance: Всего обработано: u   _acl_spread_inheritance: Шаг 2.1. Рекурсивное обновление child.perm_acl.inherit_acl_id детям с ACLa  
                                            UPDATE cmf_access_list SET
                                                inherit_acl_id = :perm_effective_acl_id
                                            WHERE
                                            (
                                                inherit_acl_id != :perm_effective_acl_id
                                                OR inherit_acl_id is null
                                            )
                                            AND id in (
                                                SELECT perm_acl_id FROM %s WHERE
                                                perm_parent_id = ANY(:parent_id_list)
                                                AND perm_inherit = 't'
                                                AND (perm_acl_id is not null or perm_acl_id != '')
                                            )
                                            RETURNING id
                                        a  
                                            UPDATE %s SET
                                                perm_inherit_acl_id = :perm_effective_acl_id
                                            WHERE perm_parent_id = ANY(:parent_id_list)
                                            AND (
                                                perm_inherit_acl_id != :perm_effective_acl_id
                                                OR perm_inherit_acl_id is null
                                                )
                                            AND perm_inherit = 't'
                                            AND perm_has_acl = 't'
                                            RETURNING id
                                            z_acl_spread_inheritance: DoneuH   _acl_spread_inheritance: Шаг 3. Перезагружаем кеш ACL)r   r1  r/  r   r  ro   r   r   rd  r   _ddSessionexecuterh   r  r   r   rL   r   r  r  invalidate_idsri   rq  r  r9  rx   )rg  r[  r\  r]  r`  r  r6  _spread_modelschild_modelr  row	processedcur_stage_parent_id_listnew_stage_parent_id_listbatch_count	upd_countr  cur_parent_batchs                     r"   r_  z%CmfEntity._acl_spread_inheritance_job  sw    CUVaW66q9VMV ##FND[3\]	  M  	NGGhilhmno*N%!*!:!:!<- X&&))--557?? 	A "++	A, %($4$4$:$:!$. 3i!!001G1G_bIcX[#d)IcdEc$s)nEUVW!X$ 	
vw(I')$(+~$*#+CL[+Q(+CKL+Q(!.!)%.%>%>%@N#1 AK !**--1199;CC E &//E0 251J1J1P1P*B2C s)C !IGG%%44[5K5KcfMg\_cRViMgh  A!Q	T7i/GG&MaPTgYVw$xy$"77$@LP$077$@A+A< &(@@	PQTU^Q_P``yz}  W  {X  zY  Z  [M +N GGPQTU^Q_P`abGG  W  X##,\k#: %kl3	!.!)%.%>%>%@N#1 'iK **--1199;CC E, /:.C.CED  251J1J1P1P*:FC& GG%%44[5K5KcfMg\_cRViMgh **--1199;CC E0 3>2G2GEH 251J1J1P1P*:JC s)CGG%%44[5K5KcfMg\_cRViMghO'iP PQTUeQfPg  hA  BE  FO  BP  AQ  R  S_ ` GG34	Z[ 	
/0U W4 JdH NhV Nh$ Nhs   U,U1U6/U;%V c                 x    | j                   j                  ryt        | d      r| j                  j                  ryy)NTr  F)r   r   rp   r  r   s    r"   rF  z"CmfEntity._acl_subjects_is_changed[  s1    >>$$4/0T5N5N5Y5Yr!   c                     g }| j                   r|j                  | j                          t        | d      r<| j                  j	                          | j                  D ]  }|j                  |        |S )Nr  )r   rx   rp   r  r  )r`   r%  r  s      r"   _acl_subjects_list_level_writez(CmfEntity._acl_subjects_list_level_writec  sa    >>MM$..)4/0%%**,22 %e$%r!   c                     g S r<   r    r   s    r"   _acl_subjects_list_level_readz'CmfEntity._acl_subjects_list_level_readn  s    	r!   c                    | j                   r9| j                  r,| j                  j                  }|j                  j	                  | j                         }|r|j
                  s|j                  j                  r| j                  r| j                  s|j                  g d       | j                  xs |j                  }| j                  xs |j                  }t        j                  j                  d|j                  j                  |j                  ||j                  |j                   j                  |j                  |d	       t#        | H  di |S )N)r  r  r  r}  F)	r~  r  r  r  r  r  r  r  r   r    )rm  r(  r   rH   r,   rp  r  r  r  r  r  r  r   r/  r  ri   r   rR   r  )r`   rO   r(  parent_fieldr  r  r\   s         r"   r  zCmfEntity._acl_check_writer  s     T[[[[&&F!==,,T-B-BCL L$7$733>>doo]a]v]v&&'^_!__A0A0A
#88OF<O<O$$11!(&:V:V:\:\!'!2!2L!-!8!8$iioo
@P@Pbh  2 " w'1&11r!   c                     t        t        d      r2d}| j                  rd}t        j                  j	                  | |d       y y )Nr  rN   r   r  )rp   r   r   r  r  )r`   r=  crud_actions      r"   r  zCmfEntity.before_save_hook  s;    656"K{{&++55dKW	 7r!   c                     t        t        d      r0t        j                  j                  | | j                  rdndd       y y )Nr  r   rN   r  )rp   r   r  r  r   rE  s     r"   r  zCmfEntity.before_save_data_hook  s4    656++55dHYacop 7r!   	operation	subgroupsdisable_users_notifyc           	          ddl m} ddlm}  |d        || j                  | j
                  ||t        j                  j                  j                  |d       y )Nr   r%  rm  up   Обработка может занять несколько минут, ожидайте оповещения.)cls_namer{  r|  notify_person_idr}  r^  )
r  r&  r   rn  _group_changes_jobri   r   r   r   r   )rT   r{  r|  r}  r&  rn  s         r"   group_changeszCmfEntity.group_changes  sR    %5  E  	F""NN&&$%$4$4$7$7$=$=(<		
r!   u#   Массовое изменение)rc  rd  r  r  c           
         dd l }d }d }t        j                  t        j                  t        j                  t        j
                  t        j                  t        j                  d}| |j                         v r||    }	n%t        j                  j                  |
dd       y d}
d	}g }|rt        j                         n	t               5  |D ]  }d
}|	j                  dd|d   gd      } ||j                  di             \  }}d }|rt!        |j                               }|dk(  r|d|vr|j#                  d       t%        d|j'                  ||z              D ]  }|	j!                  dd|d   g||z  ||z  |z   g|d      D ]  }	 |dk(  r6|j)                         D ]  \  }}t+        |||        |j-                          n|dk(  rD|j)                         D ]   \  }}t/        ||      j#                  |       " |j-                          nR|dk(  r|j1                          n<|dk(  r|j3                          n&|dk(  r! |j4                  dd|j6                   di| |j8                  j;                           " |dk(  s|stC        tD              }|j                         }|	j!                  dd|d   g|d      }|D ];  }|D ]4  }t/        ||      }||jF                  }|s!||   jI                  |       6 = |j)                         D ]D  \  }}t/        |	|      jJ                  }tL        jO                  |dt!        |      ||   dg|       F  	 d d d        |rd}
ddjQ                  |       }t        j                  j                  ||
|dd       y #  |j8                  j=                          |j#                   ||             t>        jA                  d|        Y kxY w# 1 sw Y   xY w) Nr   c                     i i }}| j                         D ]>  \  }}d|v r+|j                  dd      \  }}||j                  |i       |<   5d|vs:|||<   @ ||fS )NrF   rP  )r)   rA   rs   )changesdirectrelatedr   valr  r4   s          r"   _split_changesz4CmfEntity._group_changes_job.<locals>._split_changes  ss     "GF%mmo (
s%<"'++c1"5KFC:=G&&vr237%$'F5M( 7?"r!   c                    | j                   dk(  rHd| j                  j                   d| j                  j                   d| j                  j                   dS d| j                   d| j                   d| j                   dS )NCmfGanttTaskz	<a href="u   ">Гант-задача r  z)</a>z">)ri   taskr  rU   r3  rs  s    r"   _get_fail_messagez7CmfEntity._group_changes_job.<locals>._get_fail_message  sq    ~~/"388==/1I#((--XZ[^[c[c[h[hZiinoosxxj388*BsxxjFFr!   )rh  r  CmfTestcaseCmfTestcaseRunCmfTestcaseRunHistoryCmfTestplanTestcaseTrP  )r  rU   r1  force_notify_current_personr  uL   Успешное завершение массового изменения.uO   Массовое изменение закончилось без ошибок.rW  r   rc  r;  )r  r   r  r   rU   )r  r  rH   r   rN   rx   r   r  u    Копияu)   Не удалось обработать )r  rH   r   )r;  r  )r  r{  r|  r  u8   Ошибки при массовом изменения.uA   Обнаружены ошибки при изменении:</br>z</br>r    ))mathr   rh  r  r  r  r  r  r  rS  rD  r   disable_notifyr   r   r,   rL   rx   rangeceilr)   r   r   ru   r   r  r   rU   r   r  rollbackr  r  r   r   r   r  r   ro   r  r@   )r  r{  r|  r  r}  r  r  r  r  rT   notify_name
notify_msgerror_hrefssubgroupstepr  direct_changesrelated_changesrH   r   r6  r  r   rel_id_listsrel_prefixesobjsr  rel_objrel_ididsrel_model_names                                  r"   r  zCmfEntity._group_changes_job  s@    		#	G
 #)..'-':':&,&8&8)/)>)>060L0L.4.H.H {''))h'C))' ,0 *  df
)=W##%;= A	% @iidHY4G'H[_i`2@iY[A\2]/!!."5"5"78F&)!/"MM&1q$))C$J"78 aA"xxdHY<O/P784xTD6Q7=AE  (  G aa(H48F8L8L8N !C$4Iu$+CE$B!C #
!*h!68F8L8L8N !J$4Iu$+C$;$B$B5$I!J #
!*h!6 #

!*i!7 #!*f!4 ( Y
+.F Y. YFFMMO'aa4 (_#.s#3L#2#7#7#9L88D$8K+LUatx8yD# A&2 AF&-c6&:G& (%,ZZF% ,V 4 8 8 @AA (4'9'9'; 
)0f)=)C)C!44%3&.+/9+:6+B( ' .> 5 
m@A	F TK\]d]i]iju]v\wxJ%%#(, 	& 	
EaFFOO-'../@/EF#--0YZ]Y^._`OA	 A	s;   CO7C0N&=
O7	O7A O7.A2O7&AO41O77P r  r<   )r   Fr&  )NNNNNNr  r  r  )Tr:   )FFF)NrN   )NNrN   Nr  )r   r   r   r   rm  r
  rI  custom_fields_base_maxcustom_fields_maxrV  r  menu_tree_parent_idmenu_tree_ordernor   r  compilerv  r  r{   r   r   r:  CmfNamerU   CmfCoder3  r@  r  r  rn  r  tasks	documentsr  r  r  r  r   rH   r  r  CmfStrr  r:  r  rK  rJ  rk  r  has_tree_nodesr_  tree_hiddenr;  root_parentr  r)  r  r  r  r<  CmfIntr*  r  rs  r  r  r  r  rN  rt   r   r  r   r  r  r  r  r  r  r  rz  r{  r  r  r|  r}  r~  r  r  r  r  r|   r  r  r  r  r  r  r  r$  r'  r+  rA  r   r  rF  rN  r   r  r  r,  r  rb  r  rj  rH  rs  r  r   r  r  r  r  r  rP  ry  r  rx  r  r  r  r   r  r  rb  rw  rw  r  r  r  r  r  perm_publicr1  rK  rN  r   r  r  r  r  r  r  	CmfStr256r  r2  r:  r  r  r  r  r  rQ  r(  r  r{  r_  rF  rs  ru  r  r  r  rL   r  r  r   r   s   @r"   ro   ro     st    !c   K" #JJ'89((+EELI&& *
 
K$ >D>D1-F -7	D /{E 5I 9~H )v{TfFg9CS]bjnpJG-[ejv~  HL  V[  \Ojj&&

8	 ' O 4	F .L +L **""

E	 # K **""

%%3UT # K !!

$$)=%Z^ " J ZZ%%

$NX]hlv{ & }N****

$JTYchsw + y**""

$OY^imw| # ~K **""

//9h  vA  KP  X] # ^K jj

  G JJ$$

P % M L
 {Hjj

#9u_cmn  pG zz''

>?=B	
  (  "# " " *.t 	 	   QSW Q Q(   # &  GC*X( ; ; , ,  4 9 9v  " : :, & &P % %N Q Q O O Q Q$ 4 C C(0 (.* JX 23  :
= %* ,('TAoH
Y	7 2j  AF  GS  G :cd c"9" !" ?B_ xj[\]: ^ :.+Zc*L I I !#DT  4*
*.&'))N`? ?G# G$ G (- *EX& 8 8 ;T ; ; 9 9g( ( (
q4z	 **""3::#5#5u  OI  SX"  YK ::##CJJ$6$6O~  IN#  OL zz
zz_tUM   OH
 ::##

D2U_d $ fL **""

//Ze5 # 7K ::++

dECo  |D , E ****

d4qE + +  JJ,,
zzT5B - A -0JJ,<,<

 Y -= -) ::##

E5(2i $ kL 

((

I ) 3 % %N O Od
'-1%f"&;"'!R  Gh i?C^cW1i W1r	2>Xq 
S 
D 
PT 
 
 "G]ab =Ax
x
"%x
26x
x
59x
 c x
r!   ro   c                      e Zd ZU dZeed<   dZeed<   dZeed<   dZe	e   ed<   dZ
eed<   dZeed<   dZeed<   dZeed	<   dZeed
<   dZee   ed<   dZee   ed<   dZeed<   dZeed<   dZe	e   ed<   dZeed<   dZe	e   ed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZ eed<   dZ!eed<   dZ"eed<   dZ#e	e   ed<   dZ$e	e   ed<   dZ%e	e   ed <   d!Z&e'ed"<   e(d'd#efd$       Z)d'd%Z*d& Z+y)(CmfCustomFieldNri   
field_typeui_group_name	ui_groupsrl   rG   r  r  db_typedb_column_namedb_table_namer   r   r   rD  disabled_choicesFdb_need_create_choice_tabledb_choice_table_namer%   rO  r  r  r7  Tr  r   r  options_list_paramsoptions_list_show_columnsoptions_list_search_columnsr   custom_table_no
field_dictc                 X   t        |      }i }d }i }|j                         D ]a  \  }}|dk(  r3t        |t              r#|D ci c]  }t        j                  |      | }}|| j                  v r|||<   |dvr|||<   |dk(  s`|}c  | dd|xs |i|}	|	j                  |       |	S c c}w )NrD  )r  r  r  rl   r  r  r  r  rl   r    )r   r)   r*   rL   r  caption_to_name__dataclass_fields___calc_db_choice_table_name)
rT   r  r   rl   ui_meta_nativerO   r/   r0   choicer  s
             r"   	from_dictzCmfCustomField.from_dictJ  s    j)
$$& 
	#DAqI~*Q"5RST^33F;VCTTC,,,q	 U U 
I~!"
	# >.3G>v>&&u-
 Us   B'c                 Z   |d}dj                  | j                  j                  d      D cg c]  }|j                          c}      }|j                   | | }t	        |      dkD  r;t
        j                  j                  ddt	        |j                        z
   dd	       |S c c}w )
NChr:   r2   @   u8   Имя поля не должно быть больше    u    символовTr-  )r@   ri   rA   r=   rq  r   r  r&  )r`   r   suffixr/  r  s        r"   gen_db_choice_table_namez'CmfCustomField.gen_db_choice_table_name_  s    >F!ww@U@UVY@Z'[1'[\"'"2"2!34H3I&R#$r)KK!!$\]dehiniyiyez]z\{  |M  #N  VZ!  [## (\s   B(c                    t        | dd       }|sy |dk(  s|dk(  rRd| _        |dk(  rdnd }| j                  ||      | _        | j                  | _        | j                  | j
                  d<   y || j                  |      k(  r|| _        y y )Nr   CUSTOM_CHOICE_MODELCUSTOM_CHOICE_MODEL_EXTTExt)ru   r  r  r  r   rl   )r`   r   	rel_modelr  s       r"   r  z)CmfCustomField._calc_db_choice_table_namei  s    D'40	-->W1W/3D,'+DDU$F(,(E(EeV(TD%22DJ$(JJDLL!$77>> )2D% ?r!   r<   ),r   r   r   ri   r
  rI  r  r  r  r   rl   rt   rG   r  rH  r  r  r  r   r  r   r   r   rD  r  r  r  r%   rO  r  r  r7  r  r   r  r  r  r  r  r  r  r  r  r  r    r!   r"   r  r  )  sx   JJM3ItCyGTGSFD!d!GS$(NHSM(#'M8C='FCE3FDIGT"&d3i&(-- $#$GSE4D$KGSGTHdHd%)c)+/tCy/-1c1OS4  ($2r!   r  c                   (   e Zd ZdZedd       Ze ed      defd              Z	ed        Z
e ed      d	               Zd
ee   fdZdee   fdZd Zd Zd ZddZededefd       Zedefd       Zedefd       Zd Zd Zed        Zy)r  u6   Вся логика кастом полей здесьc                     t        |j                  t        j                         j	                  d      ||      }t        d|       y)u  
        Полная синхронизация кастом полей модели в кластере после изменения их настроек
        - event CmfCustomClass:custom_field_sync -> custom_fields_gen_meta()
        - custom_fields_gen_meta()
            - per host lock and read custom field config
            - check_meta_version
            - save_changes()
                - patch db fixme !!! commit/rollback
                - save custom/modules/fields/MODEL_NAME.py
            - apply_changes()
                - do autogen
                - event CmfCustomClass:reload_model -> reload_model_handler()

        - reload_model_handler()
            - load and patch custom model
            - cler APP caches
            - !!! CMF_CACHE.flush_db() fixme !!! per process, drop locks...
            - models.RelationCache.build_fields_cache() fixme !!! per process

        r  )r  meta_versionr  r+   CmfCustomClass:custom_field_syncN)rt   ri   r   r   r  cmf_emit_server_event)rT   r[  r  r+  r=  r  s         r"   rw  z CmfCustomClass.custom_field_sync  s>    ,  ++!00@_np 	@$Gr!   r  )channelr  c           
      T   ddl m} ddl}t        j                  t
        j                        dz  dz  }|j                         }t        j                  d| d       |j                  j                  d| dd	d	
      }|5  t        j                  d       |j                         r5|j                         | d   k(  rt        j                  d       	 ddd       y|j                  | d          t               }t!        t"              | d      }t%        |      }	dd|j&                  gg}
| d   s;|
j)                  ddd|	j*                  D cg c]  }|j&                   c}gg dg       t"        j,                  j/                  |
g dd      D ]c  }|j0                  s(|j3                         ||j4                  j6                  <   nd|	_        |j:                  sKd|_        |j=                  d       e |s|	j8                  rg }|j?                         D ](  }|j)                  t@        jC                  ||             * t        j                  d|        |	jE                  |       t        j                  d       |j                  j                  dd	d	
      5  t        j                  d        |	jG                          ddd       t        j                  d!       |	jI                          ddd       t        j                  d"       yc c}w # 1 sw Y   QxY w# 1 sw Y   0xY w)#u   Метод обновляет файлы с метой на всем кластере

        Args:
            data (dict): _description_
        r   )r  Ntmpcustom_meta_versionuJ   custom_fields_gen_meta берем блокировку per instance lock::z)::cmf__base_model__custom_fields_gen_metazlock::i  )r  blocking_timeoutu<   custom_fields_gen_meta Блокировка полученаr  z-CmfCustomClass:custom_field_sync: already genr  r[  r\  r~  r  r^  rU   NOT IN)dirtyr~  T)r   r(  r   T)r  rH   r+  Fr  rK  z(custom_fields_gen_meta run merge_fields uu   custom_fields_gen_meta берем блокировку global lock::cmf__base_model__custom_fields_gen_meta_run_alterz7lock::cmf__base_model__custom_fields_gen_meta_run_alteruN   custom_fields_gen_meta блокировка получена. run save_changesz$custom_fields_gen_meta apply_changeszcustom_fields_gen_meta done)%r  r  socketr  r  r  PROJECT_DIRgethostnamer   r  r  rx  rJ  	read_text
write_textrt   r   r   r  ri   rx   custom_fieldsr  rL   r  r   rU   r   r   r  r   r   r  r  r  save_changesr  )r  r=  r  r  meta_ver_pathhostname
redis_lockr  rT   custom_classr?  r  r  r  custom_field_datas                  r"   r  z%CmfCustomClass.custom_fields_gen_meta  s    	%V%7%785@CXX
 %%'	\]e\f  gP  Q  	R^^((6(;d)eos  GK(  L
 ,	-GGRS##%-*A*A*CtNG[*[GH,	- ,	- $$T.%9:Iv,tL12C)C8L($?@G=Xl>X>X'Y'YZ) + ,
 %1166"7$( 7  4

 "--7A7J7J7LIjoo334 /3L+##',J$OOdO34 L33 ")2)9)9); a%!(()A)ABS[^)A)_`a B=/RS))-8  P  Q^^((+bmq  EI(  J 0GGlm --/0 >?**,Y,	-Z 	
-.= (Z20 0Q,	- ,	-sF   ALA0LLA:LCL&L-LLL	LL'c                 &   t               }t        j                  j                  dg      D ]c  }|j                  |vs|j                  |j                          | t        j                  |j                              }|j                  d       e y )Nr\  ru  T)only_reload)	r   r   r  r   r\  r  r   r1  reload_model)rT   processed_modelscustom_fieldcustom_models       r"   reload_modelszCmfCustomClass.reload_models  s    5"//55>N=O5P 	<L**2BB $$\%@%@A"7#<#<\=X=X#YZ))d);		<r!   CmfCustomClass:reload_modelc                 n   dd l }t        j                  d|j                          d|         t        j                  d| d           t	        t        j                  | d               }t        j                  d       |j                          t        j                  d|j                                 y )	Nr   z7======================= reload_model_handler START PID=z data=uH   reload_model_handler: создаем CmfCustomClass для модели r\  r  uA   reload_model_handler: вызываем reload_models_and_fields()z5======================= reload_model_handler END PID=)r  r   r  getpidr  r   r1  r  )r  r=  r  r  s       r"   r  z#CmfCustomClass.reload_model_handler  s     		I"))+V\]a\bcd	Z[_`p[qZrst%0I0I$O_J`0ab	ST!!#	G		}UVr!   r[  c                    || _         d | _        g | _        d | _        d | _        g | _        d | _        | j                         | _        | j                  j                  d      | _
        d| _        | j                   j                  j                  j                  | j                   j                        D ci c]  }|d   j                  d      r|d   | c}| _        | j                  j!                         }| j                   j                  j                  j#                  | j                         }| j                  j%                  |       |j%                  |       t'        t(              }| j                   j*                  j-                         D cg c]   }|j.                  j                  d      s|" c}D ]  }|j1                  |j.                        }d }	d }
d }t3        |t4        t6        f      rst9        t:              j1                  |j<                  j1                  d            }|r| j                   j                  j                  j?                  |      retA               }nZt3        |tB              r'|j.                   d}	|	|v r|jE                  |	      nd }n#|j.                  }	|	|v r|jE                  |	      nd }t:        jF                  j1                  |j.                  dg      }|s8tH        jK                  |jM                         |	      }|| j                  jO                  |       |d
| _         | j                  D ci c]  }|j.                  | c}| _        y c c}w c c}w c c}w )Nz.bkFrU   r[  r   r  r   r  rK  T)(r[  current_fieldsr  
db_columnsr   add_to_db_fieldscustom_fields_index_get_model_file_pathmodel_file_pathwith_suffixmodel_bk_pathr   r   inspect_table_columnsrh   rz   r   inspect_ext_columnsrN   r   rL   rH   r   ri   r,   rn   r  r  r   r   rl   	has_tablert   r  r  r  r  r  r   rx   )r`   r[  columnr  ext_colsfields_ui_groupsr0   rZ   r  r  _db_table_namedb_field_info	cmf_modelr  
field_datas                  r"   r   zCmfCustomClass.__init__  s   ">B=?59*.68HL 7;7P7P7R595I5I5U5UV[5\
 ..++77MMdnnNfNfg
f~((/ 6NF"

 __))+
 >>$$00DDT^^Tx((# 't, &*^^%:%:%A%A%Cfq||G^G^_dGe!f 	'I(,,Y-A-ABI!N!N M)nj%AB L,,Y->->-B-B7-KL	!2!2!>!>!H!H!S$(FMI7$-$8$8#9!=BPT^B^
~ >dh!*!5!5BPT^B^
~ >dh,,00i6J6JTWSX0YJ'11*2E2E2Gy1YJ (""))*5"&3	'6 Y]XjXj#k*J$9$9:$E#k W
  g6 $ls   3!M) M.1M.M3rH   c                    | j                   D ci c]  }|j                  | }}|D ]=  }|j                  |j                        }|s$| j                   j                  |       d| _        |}|j                  | j
                  j                  vrX|j                  | j                  vs|j                  dz   | j                  vs| j                  j                  |       d| _        | j
                  j                  |j                     }t        |d      r |j                  |j                  k7  rd| _        t        |d      s|j                  |j                  k7  s7d| _        @ yc c}w )u  
        Получим список новых полей, которые надо создать.
        Соберём новые группы на основе системного значения и списка полей.
        Поля удалять нельзя, т.к. данные могут быть бесценны. TODO удалять, если данных нет.
        Tr  rD  r  N)r  ri   r,   rx   r   r[  rH   r  r  rp   rD  r  )r`   rH   r0  
cur_fieldsr  r  r   s          r"   r  zCmfCustomClass.merge_fields)  s2    04/A/AB!allAoB
B  	+J%>>**?*?@L""))*5"&)&&dnn.C.CC**$//AlF]F]^cFckokzkzFz))00>&*DO--l.E.EF5),1E1E1V&*DO5"45,:W:W[`[q[q:q&*DO#	+ Cs   E)c           	         | j                   j                  j                  }|j                  | j                   |      ry| j                   j                  }|j                  | j                   |       |j                         }	 | d}	 |j                  d| d| d| d       |j                          |j#                          |j                         }	 t        j                  d|        |j                  d| d| d| d       |j                          t        j                  d| d       |j                  d| d       |j                  d| d| d| d       |j                          t        j                  d| d       	 |j#                          y# t        $ re}|j                          t        |j                  d      r3|j                  j                  d	k(  rt        j                  d
| d       n Y d}~Qd}~ww xY w# t         $ r |j                           w xY w# |j#                          w xY w# t         $ r* |j                          t        j%                  d|         w xY w# |j#                          w xY w)uj   Создание extension-таблицы с двухфазным заполнением строками.)r  ext_noN_id_fkeyzALTER TABLE z ADD CONSTRAINT z FOREIGN KEY (id) REFERENCES z(id) ON DELETE CASCADEpgcode42710z_ensure_ext_table(): FK u5    уже существует — пропускаемuJ   _ensure_ext_table(): фаза 1 — массовое заполнение zINSERT INTO z (id) SELECT id FROM z# t WHERE NOT EXISTS (SELECT 1 FROM z e WHERE e.id = t.id)uR   _ensure_ext_table(): фаза 2 — финальная синхронизация u    с локомzLOCK TABLE z IN SHARE MODEz_ensure_ext_table(): u%    создана и заполненаuF   _ensure_ext_table(): Ошибка заполнения таблицы )r[  r   r   r  rh   add_custom_ext_modelre  rf  r  SAProgrammingErrorr  rp   origr  r  r  r~  closer  )r`   ext_table_namer  r   
base_tabler7   constraint_namer  s           r"   _ensure_ext_tablez CmfCustomClass._ensure_ext_tableC  s   nn''33  4>>& I^^--
 	((@ !	!/ 09O		">"2 3&&5%6 733=,>TV
 
 GGI !	 LLefteuvwII~. /"", .33A2BBWY
 HHJ LLmn|m}  ~L  M  NIIJ<~>?II~. /"", .33A2BBWY
 HHJLL00@@efg GGIS & 

1668,'1ILL#;O;L  MB  "C  D D	  	JJL	 GGI2  	JJL fgufvwx	
 GGIsV   H +F B5H? 	H	$AH>H H		H H''H* *H<?3I22I5 5Jc                    | j                   D ]e  }t        t        j                  |j                        }t        |t              r
t               |j                  r|j                  rt        |t              r:| j                  j                  j                  j                  |j                         nt        |t              r| j                  j                  j                  j                  |j                         |j                    d}t        j                  j"                  }| j                  j                  j                  j%                  | j                  j&                  ||       _| j                  j                  j                  j)                  |j                         | j                  j                    |j                   }| j                  j                  j                  j+                  |       t        |t,              r| j                  j&                   d|j                    }| j                  j                    |j                   j/                          }| j                  j                  j                  j+                  |       t        |t0              r*|j                    d}t        j                  j"                  }n|j                   }| j                  j&                  }|j2                  dkD  rE|j2                  d}| j                  j&                   d| }| j5                  ||j2                         | j                  j                  j                  j%                  |||       h | j7                          y)uP   Создадим поля в базе и сохраним файл модели.r  r2   r   02d_extN)r  ru   r   rH   r  rn   r  r  r  r  	CmfM2MExtr[  r   r   add_custom_choice_model_extCmfRelationExtri   r  add_custom_columnrh   add_custom_choice_modeladd_custom_m2m_modelr  r=   r  r  r  _write_custom_model_file)r`   r  r  column_namer  
table_nametarget_tableext_nns           r"   r  zCmfCustomClass.save_changes  s   // $	cJ Z-B-BCJ*n5$&&0099!*i8))55QQR\RqRqr#J?))55QQR\RqRqr)3)>)>(?s&C%(ZZ%8%8
))55GGH`H`bmoyz ))55MMjNmNmn$(NN$=$=#>z?^?^>_!`JNN%%11FFzRJ
3 $ 8 89:;P;P:QR
 $ 9 9::;P;P;[;[;]:^_
!!--BB:NJ8!+!6!6 7s; ZZ00
(33>>33L))A-&66s;"&..":":!;4xH&&|Z5O5OPNN));;L+WabI$	cR 	%%'r!   c                    ddl m} 	 d }	 t        j                  d        |        t        j                  s  |d	d
| j                  j                   i       y y # t        j
                  $ r t        j                  d       | j                  rU| j                  j                         r;t        j                  d       | j                  j                  | j                         nW| j                  rJ| j                  j                         r0t        j                  d       | j                  j                          n t        j                  d        |         w xY w)Nr   )r  c                  8   t        j                  t        j                         } dD ]C  }| dz  |z  }|j	                         st
        j                  d|        |j                          E t
        j                  d       t        j                  g dd       y )N)z__autogen_models.pyz__autogen_models_tmp.pyz__autogen_models.tsr  u6   CmfCustomClass.apply_changes: удаляем мету uF   CmfCustomClass.apply_changes: генерируем новую мету)z/usr/bin/envpython3z	manage.pyautogenT)check)
r  r  r  r  rJ  r   r  unlink
subprocessrun)project_pathautogen_filenameautogen_file_paths      r"   applyz+CmfCustomClass.apply_changes.<locals>.apply  s    "<<6+=+=*>@L$k / $0$67G$G!$++-GGTUfTghi%,,.	/ GG\]NNNVZ[r!   uX   CmfCustomClass.apply_changes: пытаемся перегенерировать метуuG   Ошибка применения новой кастом модели.u=   Есть backup file попробуем откатиться.uA   Попробуем откатиться удалив custom file.u]   CmfCustomClass.apply_changes: Повторный запуск apply() после откатаr  r\  )r   r  r   r  r1  SubprocessErrorr  r  r  rJ  r  renamer  r0  r  r[  ri   )r`   r  r6  s      r"   r  zCmfCustomClass.apply_changes  s	   5Y
	\ 	GGnoG }}!"?BRTXTbTbTmTmAno  )) 	gh!!d&8&8&?&?&A\]""))$*>*>?%%$*>*>*E*E*G`a$$++-GGstG	s   A C>Ec           	         ddl m} ddlm} ddl}ddlm} t        j                  d|j                                 t        | j                        j                  t        j                   dd      j                  dd	      dd
 }t        j                  t        j!                  |             d}t        j                  d|        t        j"                  j%                  |t        |            }t        j"                  j'                  |      }	|	t(        j*                  |<   |j,                  j/                  |	       t        j                  d       t        j                  d       t0        j2                  j4                  j6                  D ]  }
t9        |	|
      }t;        t0              |
   }g }g }|j<                  D ]O  }|j?                  d      s||j<                  vr|jA                  |       |j<                  |   |j<                  |<   Q  ||j<                        D ]A  }|j?                  d      s||j<                  vs$|jA                  |       |j<                  |= C i }t0        j2                  jC                  dd|
ggddg      D ]3  }|jD                  jF                  xs d||jH                  jF                  <   5 |j<                  jK                         D ].  \  }}|j?                  d      s|jM                  |d      |_"        0 |jN                  |_'        |jP                  |_(        t        j                  d|
 d| d|         t;        |	      D ]  }
|
j?                  | jR                  jT                   d      s?|
j?                  | jR                  jT                   | jR                  jT                   d      sjtW        t0        |
t9        |	|
              t        j                  d       i tX        _-        i tX        _.        | jR                  j^                  j`                  jb                  jM                  | jR                  jT                        r?| jR                  j^                  j`                  jb                  | jR                  jT                  = | jR                  j^                  j`                  jd                  jg                          | jR                  j^                  j`                  }| jR                  jh                  }||jj                  jl                  v r|jj                  jl                  |   }to        | jR                  j<                  jq                               }tC        |jr                  jt                        D ch c]7  }|jH                  j?                  d      r|jH                  |vr|jH                  9 }}|rv|D ](  }|jr                  jv                  jy                  |d       * |jr                  jt                  D cg c]  }|jH                  |vr| c}|jr                  jt                  dd |st        jz                  st        j                  d       |j}                          t        j                  d       t0        j~                  j                          t        j                  d|j                                 yyyc c}w c c}w )u   
        без перезагрузки обновляем в памяти модели и поля, добавляя кастомные
        r   )r  )r   N)models_orig_pathui   CmfCustomClass.reload_model: НАЧАЛО - перезагружаем мету в инстансе, PID=rX  r:   rF   r  custom_modelsuP   CmfCustomClass.reload_model: загружаем модуль custom_models из uW   CmfCustomClass.reload_model: модуль custom_models успешно загруженu   CmfCustomClass.reload_model: начинаем обновление кастомных полей для всех моделейr[  r\  r~  rU   r  r5  z#CmfCustomClass.reload_model: model=z
 cf_added=z cf_removed=Cfu[   CmfCustomClass.reload_model: сбрасываем кеш меты для фронтендаuE   CmfCustomClass.reload_model: сбрасываем CMF_CACHE.flushdb()ul   CmfCustomClass.reload_model: пересчитываем кеш полей RelationCache.build_fields_cache()uj   CmfCustomClass.reload_model: ЗАВЕРШЕНО - мета успешно перезагружена, PID=)Ar  r  r   r  cmf.make_modelsr:  r   r  r  r
  r  r  r  r  	importlibreloadimport_moduleutilspec_from_file_locationmodule_from_specr  modulesloaderexec_moduler   r  r\  rD  ru   r   rH   rz   rx   rL   r  r   rU   r)   r,   rl   r  r[  ri   r   r  r  cache_cust_field_config_schemer   r   models_registrycached_queriesr  rh   db_metatablesr   r  _columns_all_columns_datar  r  flushdbRelationCachebuild_fields_cache)r`   r  r  r   r  r:  module_pathmodule_namespecr;  r  r  r[  addedremovedrY   r  cfrZ   r   rh   sa_tableactual_field_namescolstale_namesrU   s                             r"   r  zCmfCustomClass.reload_model  s'    	&4	{|~  }F  }F  }H  |I  J  	K$../776;M;M:Na8PRTU]]^acfghkikl00=> &	bcsbtuv~~55k3GWCXY!77=#0K .	ij 	
  R  	S --<<DD 	nJ"=*=LVZ0IEG*11 S
((/!)9)99Z03?3F3Fz3RI$$Z0	S
 #9#3#34 5
((/JlFYFY4YNN:.!((4	5 "$))..)4<= 12 /  R 574F4F4L4L4QPQ"277==1	R *3)9)9)?)?)A V%
I((/0B0F0FzST0UI-V
 !- 4 4I(4(D(DI%GG9*ZPUwVbcjbklm=	nD }- 	PJ$$(A(A'B"%EF*J_J_cgcqcqc|c|b}  C  M  M  X  X  ~Y  Y[  a\  K]
GM:,NO	P 	
mn -/* >>((88<<T^^=V=VW!!--==dnn>W>WX 	%%44::< nn''33NN,,	++222"**11)<H!$T^^%:%:%?%?%A!B$():):)G)G$H 88&&u-#((BT2T K  ' <D%%++//d;< $,#4#4#A#A5xx{2 5!!..q1
 1== GG[\ GG  C  D  335GG  A  BD  BK  BK  BM  AN  O  P $1{5s   
<[[rG   r  c                 @   |s!t         j                  j                  dd       | j                  |      }t	        d      D ]4  }d| }|s|j                  d      r|d| z  }|| j                  vs2|c S  t         j                  j                  d| d	| d
d       y )NuM   У настраиваемого поля не указано названиеTr-  rW  r[  r  r2   u#   Такое имя уже есть: r.  r  )r   r  r&  r  r  r  r  )r  rG   	name_baserh  rY   s        r"   calc_field_namezCmfCustomClass.calc_field_nameD  s    KK!!"qy}!~ 009	* 	"Byk*JY''."h&
!8!88!!	" 	 CI;aPWyXYZbfgr!   c                 R    t        | dd      }dj                  d |D              }|S )NruT)language_coderI   r:   c              3   `   K   | ]&  }|j                         r|j                         nd  ( yw)r2   N)isalnumr5   )r>   r  s     r"   r?   z1CmfCustomClass.caption_to_name.<locals>.<genexpr>U  s#     HaQYY[	c9Hs   ,.)r   r@   )rG   rU   s     r"   r  zCmfCustomClass.caption_to_nameR  s)    tdCwwH4HIr!   rZ   c                     | j                   D ]5  }t        |dd       }t        |t              s!|j	                  d      s3|c S  y )Nri   Cmf)__mro__ru   r*   r
  rz   )rZ   rX   base_class_names      r"   _field_type_namezCmfCustomClass._field_type_nameX  sD     ")) 	'H%hdCO/3/O4N4Nu4U&&	'r!   c                    t         j                  d| j                          t        j	                  t        j                  t        j                  j                  t        j                  d      g            }d |j                  d<   |j                  d      }| j                  j                  D ]  }|j                  j!                  d      r n d}| j                  j#                         r%| j                  j%                  | j&                         | j&                  j)                  |j+                  | |	             | j&                  j%                  | j                         y)
u^   Дампим кастомные поля в файл используя шаблон и jinja2uP   _write_custom_model_file: Пишем новую кастомную модель zcmf/templates)rE  c                 h    t        | t              r!dj                  | j                  dd            S | S )Nz'''{}'''z'''z""")r*   r
  r  r  )xs    r"   rg  z9CmfCustomClass._write_custom_model_file.<locals>.<lambda>f  s.    ]ghikn]oz/@/@5RWAX/Y uv r!   r  zcmf_model.tmpltcustom.N)r  r  )r   r  r  jinja2EnvironmentFileSystemLoaderr  r  r@   r  r  filtersget_templater[  	__bases__r   rz   rJ  r8  r  r  render)r`   	jinja_envtemplater  s       r"   r&  z'CmfCustomClass._write_custom_model_file`  s   	bcgcwcwbxyz&&**BGGLL9K9K_,]+^_ ' a	 &w	'"))*;<..22 	J((33I>	 J&&(  ''(:(:;%%hooTjo&YZ!!$"6"67r!   c                    t        j                  t        j                   d| j                  j
                   d      }| j                  j                  D ]  }|j                  j                  d      rXdj                  |j                  j                  d      dd       }t        j                  t        j                   d| d      } nYdj                  |j                  j                  d      dd       }t        j                  t        j                   d| d      } n |j                  d	d	
       |dz  }|j                         s)|j                  d      5  	 ddd       t        d|        t        j!                  d      }dj                  |j#                  | j                  j$                        D cg c]  }|j'                          c}      }|| dz  S # 1 sw Y   xY wc c}w )uY   Возвращает путь к файлу где будут кастомные поляz/custom/modules/z/fieldsrl  rX  rF   Nr3  z/custom/T)parentsr  z__init__.pyr  u   Создан z[A-Z][a-z0-9]+r2   z.py)r  r  r  r  r[  re   rr  r   rz   r@   rA   r  rJ  openr  r  r  findallri   r5   )r`   fields_dir_pathrT   postfixpkg_init_file_pathname_word_rewordmodel_filenames           r"   r   z#CmfCustomClass._get_model_file_pathu  s   !,,&*<*<)==MdnnNfNfMggn'op>>++ 		C~~((3((3>>#7#7#<Sb#AB"),,&2D2D1EQwiw/W"X ((3>>#7#7#<Sb#AB"),,&2D2D1EXgYV]/^"_		 	dT:,]:!((*#((- M"4!567zz"23L<P<PQUQ_Q_QjQj<k"lD4::<"lm.!1555 
 #ms   G!;G-!G*c                    i }t         j                  j                  ddg      D ]=  }|j                  |vrg ||j                  <   ||j                     j	                  |       ? |j                         D ]z  \  }}t        j                  |      } | |      }|D ]B  }t        j                  |j                         |      }|j                  j	                  |       D |j                          | y )NTr   )r  rH   r  rK  )r   r  rL   r\  rx   r)   r   r1  r  r  r   r  r&  )	rT   fields_to_model_namer  r  r  r[  
custom_clsr'  r  s	            r"   write_custom_fields_from_dbz*CmfCustomClass.write_custom_fields_from_db  s    !"//44dC54Q 	SL**2FFDF$\%@%@A !<!<=DD\R		S *>)C)C)E 	2%J11*=Iy1J, <+55k6J6J6LT]5^
((//
;< //1	2r!   Nr  r  )r   r   r   r   r  rw  r  on_server_eventrt   r  r  r  r  ro   r   r   r  r  r  r  r  r  r
  r^  r  rQ   rh  r&  r   r  r    r!   r"   r  r  }  s5   @H H4 ?@=/T =/ A =/~ < < :;W < W8l$y/ 8lt+4#7 +4?B+(Z%pNjPX hs hs h h   
 'K ' '8*60 2 2r!   r  c                   ~    e Zd ZU dZeed<   dZeed<   dZeed<   dZeed<   dZ	eed<   dZ
eed<   dZeed<   dZeed	<   y)
CmfUiFullPathNr   re   r4  rd   r3  sharelink_hashvfrU   )r   r   r   r   r
  rI  re   r4  rd   r3  r  r  rU   r    r!   r"   r  r    sT    BN IsIsGS D#NCBND#r!   r  c                       e Zd ZU dZeed<   dZeed<   dZeed<    e	j                  e      Zeed<   dZeed<   d	Zeed
<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   y)CmfUiMenuNodeNr!  r6  Fr_  )default_factoryr  r*  T
allow_movechildren_countr  rV  only_archivedr:  )r   r   r   r!  r
  rI  r6  r_  rH  rL  r   rL   r  r*  r  r  r  r  rV  r  r:  r    r!   r"   r  r    s    
 NCK %%({((>J>GSJNCFDHcM4L$r!   r  c                       e Zd Z G d de      Zed        Zed        Zede	fd       Z
ed        Zede	defd	       Zed
        Zed        Zy)r!  c                       e Zd Zy)UbqlConverter.UBQLParseErrorNr;  r    r!   r"   UBQLParseErrorr    s    r!   r  c                    dd l }d|vrnt        ||      s!| j                  d|j                   d|       t	        ||      }t        |t        j                  j                        sy |j                         S t               }|j                  d      d   }d}|j                  t        j                  j                  j                         t        j                   g      D ]a  }t        ||      sd}t	        ||      }t        |t        j                  j                        sC|j#                  |j                                c |s| j                  d|       t%        |      S )	Nr   rF   u   У модели u    не найдено поле r  FTu0   Не найдено поле у моделей: )	itertoolsrp   r  ri   ru   rn   r   rH   rr  r  r   rA   chainr   ro   r   r  rN   rL   )rT   r   
field_pathr  r   r  right_field_namefound_field_flags           r"   _get_field_model_listz#UbqlConverter._get_field_model_list  sA    j 5*-((+;E<L<L;MMklvkw)xyyE:.EeSZZ%:%:;''))e%++C04 __SZZ%9%9%I%I%KfNaNaMbc 	?Eu./#' '78eSZZ%:%:;&&u';';'=>	?  $$'WXhWi%jkkK  r!   c                    t         j                  t         j                  t         j                  t         j                  t         j
                  t         j                  t         j                  t         j                  t         j                  t         j                  t         j                  t         j                  t         j                  t         j                  t         j                  t         j                   fD ]3  }||vr|j#                  |      }|s|j$                  j&                  c S  |D ].  }|j#                  |      }|s|j$                  j&                  c S  |S )N)r3  )r   rh  CmfListrQ  rf  rU  rd  r{  
CmfOrgUnitCmfRoleCmfWorkflowCmfTagCmfRelationOptionCmfLogicTyperg  r|  CmfActivityr,   r   r   )rT   r3  
model_listr   r6  s        r"   _convert_code_to_uuidz#UbqlConverter._convert_code_to_uuid  s     nnfnnf6G6GI[I[&&(8(8&:O:OQWQbQbnnf&8&8&--IaIa))6+;+;V=N=NPVPbPbd 	$E J&)))&Cvv||#	$   	$E)))&Cvv||#	$
 r!   r  c                    d}d}d}d}|D ]:  }d|vrt         j                  d|z   dz   d|z   dz   | t         j                        } < | j                         } | d   d	k7  rd	|  d
} | D ]  }|r9||z  }||k(  r.|dd j	                         |v r|j	                         }||z  }d}d}?|dk(  rd}|dv r|j                         r||z  }`|}|}e|dv r|j                         }|s/|dk(  r|d   d
k7  r|d   dvr|d	k(  r|r|d   d
k(  r|dz  }||z  }|d   dv r||z  }||z  }d}|dv s|dv r||z  }||z  }d}|j	                         |v r|j	                         }|d|z   dz   z  }||z  }d}	||z  } |S )uU   
        Расстановка кавычек в UBQL без кавычек
        r:   )rc  r  r  zNOT LIKEr_  z	NOT ILIKEr  zNOT SIMILAR TOrh  z
NOT EXISTSr^  rb  r  z([^"'])z\1"z"\2)flagsr   []rP  r  ,)"')r  r  r  )r  r  )g.current_userg.now()g.date())TrueFalseNoner  )r  r4   Ir  upper)r  r  	cur_tokencur_string_symbolorm_operatorsoperr  s          r"   
quote_ubqlzUbqlConverter.quote_ubql
  s3   
 	k " 	kD$66.4/-?$QWAWY]egeiei6jD	k
 zz|7c>tfA;D A	A Q	)) !2,,.-?$-OO$5	9$C "I(*%Cx J??$NI %&!	O#%OO-	 CxCGsNs2wj7P !CxCCGsNs
1HCQ<:-9$C1HC "I II$(AA9$C1HC "I??$5 ) 1IsY,,q	NICA	D 
r!   c                     ddgddgddgddgd	d
gddgddgddgddgddgddgddgddgddgddgddgddgd d!gd"d#gd$d#gg} t        d%       | D ]  \  }}t        j                  |      }t        d&       t        |       t        d'       t        |       ||k7  r!t        d(       t        |       t        d)       t                t                 y )*Nu     [  OR  , ["alarm_date", <, g.now()  ], [name, like,    "Вася Пупкин    "], [parent.agile_story_points, ==, "None"], [cf_val, ==, True], [executors, IN, [n.krat@carbonsoft.ru, v.sdf@gmail.com]]]u   ["OR",["alarm_date","<",g.now(),],["name","LIKE","Вася Пупкин    "],["parent.agile_story_points","==","None"],["cf_val","==",True],["executors","IN",["n.krat@carbonsoft.ru","v.sdf@gmail.com"]]]z[]]][][][]][]]z[]]],[],[],[]],[]]z[name, =, "[qwe, =, 'test']"]z["name","=","[qwe, =, 'test']"]z[name, =, Valsya Poopkin's]z["name","=","Valsya Poopkin's"]u   [name, like, Вася]u   ["name","LIKE","Вася"]zname, =, "vasya"z["name","=","vasya"]z[name = "vasya"]z[name     =       "vasya"]z'    [    name    =   " ilike  "   ]    z["name","="," ilike  ",]z*[[ name = "ilike" ],[name = "ilike" ]]    z-[["name","=","ILIKE",],["name","=","ILIKE",]]uM   [OR, ["alarm_date", <, g.now()], [name, like, "Вася Пупкин    "]]  uM   ["OR",["alarm_date","<",g.now()],["name","LIKE","Вася Пупкин    "]]uC   ["alarm_date", <, g.now()][name, like, "Вася Пупкин    "]uF   ["alarm_date","<",g.now()],["name","LIKE","Вася Пупкин    "]u   [responsible.name like %Вася%] [epic IN [EPC-1624993444 EPC-1624993246 EPC-1624993221 EPC-1624993102 EPC-1624986171 EPC-16249628604 EPC-16249628009 EPC-16249627823]]u   ["responsible.name","LIKE","%Вася%"],["epic","IN",["EPC-1624993444","EPC-1624993246","EPC-1624993221","EPC-1624993102","EPC-1624986171","EPC-16249628604","EPC-16249628009","EPC-16249627823"]]zname like """qwe"s"""z["name","LIKE","""qwe""s""""]u   name "like" %Вася%u   ["name","LIKE","%Вася%"]z+cache_status_type NOT IN ['CLOSED', 'OPEN']z0["cache_status_type","NOT IN",['CLOSED','OPEN']]z-cache_status_type "NOT in" ['CLOSED', 'OPEN']z-cache_status_type 'NOT IN' ['CLOSED', 'OPEN']z0["cache_status_type",'NOT IN',['CLOSED','OPEN']]u,   name "like" %Вася% name2 like %Петя%u<   [["name","LIKE","%Вася%"],["name2","LIKE","%Петя%"]]u-   name "like" %Вася%, name2 like %Петя%%   Тесты конвертера UBQL:UBQL: RES:    Должно быть:   ОШИБКА!!!)r  r!  r  )
test_casesr  ubql_convertedr  s       r"   test_quote_ubqlzUbqlConverter.test_quote_ubqle  s    d b
 !$
 65 25
 -0 '* '*
 1*
 >.
 AC dc
 Z\ @ Z ,3 -2 BF
 DF
 DF CR
 DRc

H 	56&0 	"T>**40C(O$K'N#Jn$./n%'(GG	r!   r  c                     t         j                  |      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }t        j                  |      } fd	d
t
        dt
        ffd	  |      } |      }|S #  j                  $ r=}t        j                  j                  d|j                  d    d       d }Y d }~|S d }~ww xY w)Nr  z'__G_CURRENT_USER'r  z	'__G_NOW'r  z
'__G_DATE'z$self.z	'__SELF.'c                    t        | t              rt        |       } t        | t              s| S d}t        |       dkD  rkt        | d   t              rX| d   j                         dv rd}t        | d   t              r.| d   j                         dk(  r| d   j                         dk(  rd}t        |       d	k(  rt        | d   t              r| d   d
vr|s| }| d   }j                  |      }|r| d   }|s|S t        |t              r| d   dk(  r-g }|D ]  }|j                   |              | d   | d   |g}|S g }|D ]<  }d| d   v r|j                  |       |j                  j                  ||             > | d   | d   |g}|S d|vr| d   | d   j                  ||      g}|S |S g }	| D ]  }
|	j                   |
              |	S )NFr  r   zorder byr   TrP  orderbyr  )r^  rb  rh  r	  )	r*   rK   rL   rq  r
  r5   r  rx   r  )r  skip_orderbyblqrY   r  r  exists_filter_val
tuuid_valsr   r   _recursive_ubql_processrT   r   s              r"   r  z7UbqlConverter.ubql2bql.<locals>._recursive_ubql_process  s   $&Dz dD) L 4y1}DGS!97==?&>>#'Ld1gs+Q70JtTUw}}bfOf#'L 4yA~*T!Wc":47mC[dp!!W
 66ujI
q'C"
!#t,7h.,.M(+ T - 4 45LT5R ST#'7DG]"CC J *,J(+ c#&$q'>$.$5$5d$;$.$5$5c6O6OPTV`6a$b	c
 $(7DGZ"@C J C#AwQ1J1J3PZ1[\J
C 7

21567 Jr!   r  r  c                    t        | t              rt        |       } t        | t              s| S t        |       dkD  r[t        | d   t              rH| d   j                         dk(  r2t        | d   t              r| d   j                         dk(  r	dg| dd z   } t        |       dk\  r=t        | d   t              r*| d   j                         dv rfd	 | dd       }dd
|gS g }| D ]  }|j                   |              |S )u  
            Вычленяем из ubql конструкции сортировки.
            Order by на выражение только один
            ["order by", "=", "-cmf_created_at"]
            ["order_by", "=", "name", "cmf_created_at"]
            ["order by", ["-cmf_created_at", "name"]]
            ["order", "by", "-cmf_created_at", "name"]
            ASC DESK - не поддерживаем! Специально уходим от SQL-формата
            r  r   r  rP  r  r   Nr  c                     g }| D ]O  }t        |t              r|j                   |             +|dk(  r1|j                  |j	                                Q |S )Nr   )r*   rL   r  rx   r5   )
field_list_resrY   rec_parse_order_bys      r"   r  zTUbqlConverter.ubql2bql.<locals>._recursive_ubql_order_by.<locals>.rec_parse_order_by:  sZ    D&0 <
%j$7 KK(::(FG'3.$ KK
(8(8(:;<  Kr!   r   )r*   rK   rL   rq  r
  r5   rx   )r  r   r   r   r  _recursive_ubql_order_bys       @r"   r  z8UbqlConverter.ubql2bql.<locals>._recursive_ubql_order_by"  s    $&Dz dD) 4y1}DGS!9d1gmmoQX>X"47C0T!W]]_5L"|d12h.4yA~*T!Wc":tAw}}Rj?j
  .d12h7"C22C 8

3A678 Jr!   u&   Ошибка обработки UBQL: r   u   . UBQL отключен)r!  r  r  astliteral_evalrL   r  r   r  r&  r~   )rT   r  r   filter_ubql
filter_bqlr  r  r  s   ` `   @@r"   r   zUbqlConverter.ubql2bql  s    ''- ||,0BD||I4||J*6||H	3&&t,6	p,	$ ,	4 ,	\	0=J1*=J
 	 !! 	KK!!$J166RS9+Ul"mnJ		s   B# #C/22C**C/c                 >   dg ddg dg dgggdg ddg dg dgggdg ddg d	g dgggd
g ddg dg dgggdg ddg dddddgggggdd gdg ddg dddddgggggdg ddddddggddddgggggdg dgdg dgdg dgg}t        d       |D ]  \  }}| j                  |t        j                        }t        d        t        |       t        d!       t        |       ||k7  r!t        d"       t        |       t        d#       t                t                 y )$NzZ[['name', '=', 'test'], ['OR', ['parent', '=', 'evateam'], ['parent.name', '=', 'test2']]])rU   r   testr^  )r(  r   /CmfProject:6597795c-95ce-11ea-9023-6f4fdd48682b)rt  r   test2zh[['name', '=', 'test'], ['OR', ['parent.parent.parent', '=', 'evateam'], ['parent.name', '=', 'test2']]])zparent.parent.parentr   r  zf[['name', '=', 'test'], ['OR', ['parent.parent.name', '=', 'evateam'], ['parent.name', '=', 'test2']]])zparent.parent.namer   evateamzS[['name', '=', 'test'], ['OR', ['parent', '=', 'evateam'], ['name', '=', 'test2']]])rU   r   r  z^[['name', '=', 'test'], ['OR', ['parent', '=', 'evateam'], ['name', '=', ['test2', 'test3']]]]rU   r   r  test3za[['name', '=', 'test'], ['OR', ['bad_field', '=', 'evateam'], ['name', '=', ['test2', 'test3']]]]zb[['name', '=', 'test'], ['OR', ['parent', '=', 'RANDOM CODE'], ['name', '=', ['test2', 'test3']]]])r(  r   zRANDOM CODEzn[['name', '=', 'test'], ['OR', ['parent', 'IN', ['evateam', 'activecrm']], ['name', '=', ['test2', 'test3']]]]r(  rc  r  z/CmfProject:8e97dfe2-7113-11eb-b9c1-7571d63a6e0dz!['cmf_modified_at', '<', g.now()])r?  r  __G_NOWz"['cmf_modified_at', '=', g.date()])r?  r   __G_DATEz(['cmf_modified_by', '=', g.current_user])r   r   __G_CURRENT_USERr  r  r  r  r  r  r   r   rh  rT   r  r  r   r  s        r"   test_ubql2bqlzUbqlConverter.test_ubql2bqlY  s    q&/q  tQ  )R  S &/  B_  )`  a }&/UWt(uv j&/q  tJ  )K  L u&/qtz|  CJ  LS  BT  tU  )V  W x y&/MPVX[^egn]oOp(qr E&$Ar  uf  Ag  0h  kq  sv  y@  BI  xJ  jK  )L  M 83 94 ?<?#

J 	56% 	KT3,,tV^^4C(O$K'N#Jcz./c
'( GG	r!   c                 |   ddddgggdddddgggdddddgggd	ddddgggg}t        d
       |D ]  \  }}| j                  |t        j                        }t        d       t        |       t        d       t        |       ||k7  r!t        d       t        |       t        d       t                t                 y )Nz$["order by", "=", "-cmf_created_at"]r   r   r  z+["order_by", "=", "name", "cmf_created_at"]rU   r  z)["order by", ["-cmf_created_at", "name"]]z*["order", "by", "-cmf_created_at", "name"]u.   Тесты конвертера UBQL order by:r  r  r  r  r  r  s        r"   test_ubql2bql_oreder_byz%UbqlConverter.test_ubql2bql_oreder_by  s     ;S#4"56 BS6+;"<= @S#4f"=> AS#4f"=>

" 	>?% 	KT3,,tV^^4C(O$K'N#Jcz./c
'(GG	r!   N)r   r   r   r~  r  r  r  r  r  r
  r  r  rL   r   r  r  r    r!   r"   r!  r!    s      ! !:  . X X Xt t tn yC y4 y yv 5 5n  r!   r!  )Lr  rL  r  r  r  r   r  r   r   r   collections.abcr   r   r   	functoolsr	   typingr
   r   r   r   typesr   
contextlibr   r  redis.exceptionsr  r1  r   sqlalchemy.ormr   sqlalchemy.excr   r  transliterater   
cmf.fieldsr   r   cmf.util.immutablesr   r   cmf.utilr   cmf.base_errorr   r   r   r   r$   r   r  r  r3   rr   r'   r+   r8   r
  rB   rJ   rD   TypeVarr   r   r  rC  rG  re  ro   r  r  r  r  r!  r    r!   r"   <module>r     s      
  ! < < #   1 1  " 
   & " A "     E   NCNN66 N-3>>55 -  

#56   5=C =v)D v)r T%R+- R+jVZAy ZAzS9 S$8< 8v', 'T}(
 }(
@R P2 P2 P2fa2 a2J   2 M  &` `r!   