
    oiy                    ^   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"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#jX                  jZ                        Z. G d de#jX                  jZ                        Z/dZ0e1je                  d      Z3i Z4 G d d      Z5d Z6d Z7de8fdZ9 G d de:      Z; e<dd !      Z= G d" d e;#      Z> G d$ d%e>      Z? G d& d'e>      Z@ G d( d)e@      ZA G d* d+e@      ZB G d, d-e?      ZCe G d. d/             ZD G d0 d1      ZEej
                   G d2 d3             ZFej
                   G d4 d5eF             ZG G d6 d7      ZHy)8    N)	dataclass)OrderedDictdefaultdict
namedtuple)Mapping)deepcopy)	lru_cache)IterableListDictOptional)
MethodType)nullcontext)	LockError)aliased)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*   1   sO    	 1a!quuQ|Q/AaDAaD	
 Hr    c                 J    t         j                  d|       j                         S )N_)_camel_to_snake_regexsublowerss    r!   camel2snaker7   ;   s     $$S!,2244r    r6   c                 P    dj                  d | j                  d      D              S )N c              3   <   K   | ]  }|j                           y wN)
capitalize).0r3   s     r!   	<genexpr>zsnake2pascal.<locals>.<genexpr>@   s     <3>>#<s   r1   )joinsplitr5   s    r!   snake2pascalrA   ?   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   captionrF   fields)reversedr)   rC   rG   r(   typetuplerF   list	FieldDataupdatekwargsbaseCmfTypeMetasuper__new__)clsnamebases	namespacerG   base_cls
field_name	field_clsr.   r/   new_type_namespace	__class__s              r!   rR   zBaseModelMeta.__new__H   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;   )rG   r+   AttributeErrorselfitemrY   s      r!   __getattr__zBaseModelMeta.__getattr__i   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 )NrG   )ui_name	ui_modulecode_prefixu   Заполните поле     в классе )rc   re   rE   r1   )r7   r   	tablename
class_nameprimary_key__dp__ui_metaabstract
issubclass	CmfEntityhasattr
ValueError_unique_fields_cache
setdefaultdictgetattrrG   r(   instance_classclass_full_nameappenddir
startswithui_meta_skipr)   propertycallable)rS   argsrN   rG   field_unique_field_cachevalue_cached_clsrX   rY   r.   r/   s               r!   __init__zBaseModelMeta.__init__s   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_DATASOURCErj   r+   )rS   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rS   s    r!   r   zBaseModelMeta.dp_model   s    vv!!**3//r    c                 ,    t        | j                        S )u!   метаданные модели)r7   r   r   s    r!   	snakenamezBaseModelMeta.snakename   s     3<<((r    )r   r   r   r   rR   ra   r   r{   r   r   r   __classcell__r[   s   @r!   rC   rC   C   sU    <B)1f 	 	 0 0 ) )r    rC   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d/       ZLe-dd-efd0       ZMe-d1eJfd2       ZNdd3ZOePd4        ZQdd5ZRe- eSd67      d-eTfd8              ZUe-d-eJfd9       ZVe-dd:       ZWe-dd;d<eXeY   d"eYfd=       ZZe-dd;d<eXeY   d"eYfd>       Z[e-dddd?d@       Z\e-d<eXeY   fdA       Z]e-dB        Z^e-dC        Z_e-dddDd<eXeY   d"e`eY   fdE       Ze-dddDd<eXeY   d"e`fdF       Zae-dG        Zbe-dddddHdI       Zce-dJ        Zde-dd;dK       Zee-ddLdM       Zfe-ddN       Zge-	 	 	 	 ddOeJdPedQefdR       Zhe-dS        Zie-dT        ZjddVZkdW ZldX Zmd"efdYZndZ Zod[ Zpd\ Zqd] Zrd^ Zsddd_d`Ztda Zudb ZvddcZwdd ZxddeZydUddfdgZzdh Z{di Z|ePddj       Z}dk Z~ddlZddmZdn ZddoZdddddpdqZddrdsZeP edtddu      dv               Zdw Zdx Zdy Zddz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   NTFr   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+   sgetrK   slistubql2bqlrM   upsertget_ui_full_pathget_metarestore_deferred)$menu_tree_parent_idmenu_tree_ordernomenu_tree_node_is_branchrk   rz   rg   rG   r   rl   r   r   r   valuesvalues_dictri   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)rh   field_namesbqlformat_fileinclude_archivedorder_byr   )rh   r   r   )rS   r   r   r   r   r   rN   rh   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)   rI   rm   )rS   r   r   s      r!   iter_subclasseszBaseModel.iter_subclasses6  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)rG   rh   instance__dict__datetimenowtimezoneutcr)   CmfDateauto_nowauto_now_adddate_value_oldCmfDateTimer$   r   __func__rK   rs   copycast	orm_dirty)r_   rX   rY   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        ||       )NrE   u&    для тонкого объекта.Tr   )
rG   r+   simple_objectro   rt   virtualCmfOrmImplicitLazyLoadrh   r   r]   r^   s      r!   ra   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 rE   z! is a backref hence it's readonly.Tr   )rG   r+   readonlycmf
base_errorCmfOrmReadonlyModifyErrorrm   
CmfBackrefNotImplementedErrorr[   r   r   r   setobject__setattr__)r_   r.   r/   rY   r~   s        r!   r   zBaseModel.__setattr__g  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_dbt  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_saverr   gen_idrt   grG   r(   r   r   
is_changedr   _save_data_donesetattr)r_   r   r   rN   ir.   r/   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;   )rI   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   )rI   strr   r@   r   r   includer   )rS   r   tuuidrh   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)rG   r   r   
is_definedrK   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  rt   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;   )rt   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)rS   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rG   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)rS   r   rc   coderd   	parent_idrupobjr%  rG   rh   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!   UiFormFieldr9    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_   rX   rN   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)	rQ   r   r>  r   rG   r(   ro   rC  r   )r_   r   r}   rN   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    rI  r   )dataclassesr   rt   r   rh   )rS   r5  rI  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   rc   r2  rd   r3  r4  r5  
CmfProjectzPPP-PR-BROWSEF)r5  raise_error$   Объект не найден id =  ui_name =  code = Tr,  )r   rT   r2  r3  )check_fieldsr9   z&rup=0-/z/?parent_id=z&vf=z&code=z	&ui_name=#)r   r%  r6  rh   check_project_role_access_acl_check_readCmfPermissionErrorr3  r   r  rd   is_not_nullrG   r&  rc   r4   rT   translit_stripr   r   r2  )rS   r   rc   r2  rd   r3  r4  r5  r%  rG   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$  )rP  CmfDocument	CmfFolderCmfTaskrR  rS  rT  Tr,  r5  )r   r%  r6  rh   r   rc   r2  r   )rS   r}   rN   r%  r5  s        r!   public_get_ui_full_pathz!BaseModel.public_get_ui_full_pathH  sk    )'c''88>> "
 
 =wl|9TIV^bc#s##T=V===r    c                      y r;   r   r_   r}   rN   s      r!   public_nonezBaseModel.public_noneX  s    r    c                      y r;   r   rj  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)   rK   rJ   lenrm   rI   r   r   r   
CmfRelBaser5  s    r!   is_model_objz&BaseModel.asdict.<locals>.is_model_objl  sn    #e}-#c(Q,JtTWXYTZ|]`]g]g]q]qDrGQRUVWRXZdGeDIszz';';<r    rG   r   )rs   r)   rK   rJ   get_values_dictrm   rI   r   r   r   rG   CmfTypeasdict)r_   r5  rG   rs  paramsr   s         r!   rw  zBaseModel.asdicta  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   rs   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.rh   )rO  r   )r   r  r(   rs   r+   r)   r   rG   
CmfM2MBaseCmfBackrefBaser   ru  CmfRelationBaser!  rh   )
r_   rG   r  rr  rX   	field_valrx  r5  field_values
             r!   ru  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)visiblerh   )fr  s    r!   filter_visiblez-BaseModel.meta_fields.<locals>.filter_visible  s$    99'<<4'r    )rG   r   filter)rS   r  rG   r  s    `  r!   meta_fieldszBaseModel.meta_fields  s5     ""$ NF3Fr    rG   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   r3  
project_idcmf_owner_idrT   r2  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   rO  N+u   Синтаксис +field u)    устарел, используй fieldrV  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   rO  )r(   )_BaseModel__fieldscr.   r/   _BaseModel__field_counts       r!   __field_countz4BaseModel._fields_load_expand.<locals>.__field_countU  sD    A ( *1Qq))A* Hr      u_   DEV: WARNING. В запросе используется слишком много полей: uC   . Возможно, где-то используется ** method=z args=z kwargs=)
debug_only)%r   intrs   rm   CmfModelrn   rK   r(   endswithrp  maxry   CmfDeprecatedErrorrw   r   rG   r   	load_moderh   rr   r  r  r*   r  r+   rq  related_modelsr   _fields_load_expandclearr   r
  r%  r   
api_methodapi_args
api_kwargs)rS   rG   r  r  r  r  fields_prefixesasterisk_specsminus_fieldsplus_fieldsrX   
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: {...}}}
        rE   N)rK   r(   	partitionrr   rM   r   _fields_split)rS   rG   full_field_namer  rX   r1   sub_field_names          r!   r  zBaseModel._fields_splite  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)
rS   rG   r  group_byr  start_tsdefault_fields
field_ruletree_fieldsdurations
             r!   r  zBaseModel.full_fields_loadv  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)rG   r   rh   extendget_required_fieldsr  r*   r(   r+   rm   rq  r  rn   _enrich_load_plan)
rS   r  required_fieldsr~   required_fflrX   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_   rG   forcerN   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   rS   r5  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   rq  )r   r  loadedrX   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                  du s2t	        |t
              r|j                  rv|j                  j                  r`|j                  durA|j                  |j                  k7  r(t        d| j                   d|j                   d|       |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	 ^t	        |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 поля запросили для загрузки, но не загружены: .uc   TODO: Попытка сбросить изменения поля при присваивании: rE   r   )r  N)r   r  printr   r)   r  r   r   r   r   rh   r   rK   rs   r   r  apply_changesr   r  r+   r  rq  )r  r  r  missing_fieldsrX   	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/@ 5A
(4	(4	##s*z)_/UZcZiZinwn}n}  oP  oP ''s2y||y||7S
 *  , 7 78):N:N9OqQZP[]^ ^ (1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@@@k5AR %Ys   +NF)r   r   r   r  r   r   r   rs   cmf_verr   rh   _getr+   r   )	r_   r  r*  r+  rN   r   new_instancer  r  s	          @@r!   r  zBaseModel._load_fields  s8   
 	'""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 ->	A'>	A7@>	A>	A~ 	T<(!&r    i  )maxsizec                 d    | j                  |      xs i }| j                  |       t        |      S r;   )r  r  r   )rS   rG   r  s      r!   _build_load_plan_for_tuplez$BaseModel._build_load_plan_for_tuplec  s5     //7=2./!"233r    c                 >    t        |      }| j                  |       |S r;   )r   r  rS   rG   s     r!   _build_load_plan_for_dictz#BaseModel._build_load_plan_for_dictj  s    "6*f%r    c                     t        |t              r| j                  |      S | j                  t	        t        |xs g                   S )u7   Готовим и возвращаем full_fields_load)r)   rs   r  r  rJ   sortedr  s     r!   r  zBaseModel._build_load_planq  s>     fd#008811%v|8L2MNNr    rt  rS   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__TrG   r   Ncmf_ver_head2cur_idr  )_allowed_field_funcsrK   r  rw   r  r  )rS   rG   r}   rN   aggregate_selectrX   resr  s           r!   r+   zBaseModel.gety  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_timeliferG   simple)r  mapper)r  rw   r  r  rt   r+   r  )rS   rG   r}   rN   r  rX   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   r2  r  rV  CmfTaskCodeHistorytask_id)r2  rG   LIKEz%-r   )rG   r+   rr   rt   r   jscache_timelifer  minr   r  r	  r   ry   rh   r  rp  r)   rv  r   r   rg  ro   r  r   r  popr@   isdigit)rS   r  r  r  r}   rN   rX   r~   instis_linkr2  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  )rs   r@   rw   )rS   rG   resultrX   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)r@   )rS   rX   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rQ  r  r   r  u%   Группировка по полю (u   ) запрещена)r   CmfAccessListcheck_admin_moder   r   system_personr@   r  rt   rstripTEXKOM_group_by_allowrh   rF   )rS   rX   	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    )rG   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  rw   r3  r  r  _list)rS   rG   r  r}   rN   r  rX   r  s           r!   rK   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  rG   r  )r  r  r  r  )	r  rw   r3  r  r  r  rt   rK   r5  )	rS   rG   r  r}   rN   r  rX   r  r~   s	            r!   r   zBaseModel.slist9  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   )ro   r+   rr   r:  r   )rS   _kwargsorder_fieldss      r!   _default_kwargszBaseModel._default_kwargs`  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=  rt   r   r  r  r  r  r   rK   )
rS   r  r  r>  r?  r}   rN   rX   r~   	inst_lists
             r!   r5  zBaseModel._listo  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;   )rG  r   rS   r}   rN   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)rS   rG   r}   rN   r  s        r!   r   zBaseModel.count  s5    
 //t=szz4M2BMfMMr    r  c                d    | j                  |      } | j                  j                  |d|i|}|S )rA  r  )r=  r   r   )rS   r  r}   rN   rets        r!   rJ  zBaseModel._count  s8     $$V,cffllDN3CNvN
r    c                 (     | j                   |fi |S )u  
        Метод-обёртка field_options_list для вызова с подстрокой поиска, чтобы избежать кеширования на фронте.
        Сейчас фильтрация идёт на фронте, строка поиска не передаётся. Вероятно этот метод никогда не понадобится.
        )r   )rS   r  searchrN   s       r!   field_options_searchzBaseModel.field_options_search  s     &s%%&9DVDDr    models_filtersall_optionsrN  c                 
   | j                   j                  |      }|st        d| d|  | |      |s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|!d.dd| dgd/dd| dgd0d| dgd1d| dgd2dd| dgd3dd| dgd4dd| dgd5dd| dgd6dd| dgd7dd| dgd8d| dgd9d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d?d| dgd?dd| dggg}!nd|!dd>dd| dgd?dd| dggg}!|j.                  d@k(  rd|!ddAdB|gdCdd| dggg}!||!g} |jD                  dH||dD|}#tG        |d   |z
  d      }$tI        |dE   |d   z
  t=        |      z
  |#      }%|$|$|%z   g}&||#z  }|&d   |#kD  r|jK                   |jL                  dH|
||&|	|dF|       t=        |      |dE   |d   z
  k\  s |S  |S t        dG| d|  ||       c c}w )Iu  
        Метод для получения списка значений для выбора во фронтенде
        :param relation_field_name:
        :param object_id: в некоторых случаях для фильтрации передаётся id объекта - параметра фильтра, но он портит кеш
        :param object_fields: в некоторых случаях для фильтрации передаётся поля объекта - параметры фильтра
        :param all_options: Все возможные значения, используется в т.ч. для фильтрации на фронте.
        :param slice: диапазон значений для пагинации. !! Есть риск зацикливания, если бэк не будет поддерживать.
        :param search: строка поиска для фильтрации значений. no_cache? обсудить.
        :param kwargs:
        :return:
        u   Не нашел поле rf   Tinclude_systemfield_options_list_limitNr   d   zfield_options_list u0    без slice, показали первые 100)SELFoptions_list_bqloptions_list_bql_exclusive)r'  rT   rG   cf_)cmf_model_namerT   rG   %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  rT   ILIKE%z% r2  rg  parent_taskzparent_task.nameANDr  INz	task.epicztask.subproject	CmfPersonrolesc                 $    | j                  d      S )Nzroles.)ry   )r  s    r!   <lambda>z.BaseModel.field_options_list.<locals>.<lambda>\  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_contextrO  )rG   r  slicer   r  u)   Некорректный тип поля r   )'rG   r+   rp   rm   r   rq  rt   r   r  r
  r%  r&   r(   r   rs   CmfCustFieldConfFieldrW  r!  loadsr   rX  ry   CmfCustFieldrh   loggingwarningdefault_options_filterro   r   ninja_reversrp  anybuiltinsr  r   r  r  r  rK   )'rS   r  	object_idobject_fieldsmodels_listcust_field_conf_idrP  r  require_field_filterr   rG   r  rQ  rN  include_hiddenrN   r~   resultsrT  
model_namer  r  
obj_fieldsr.   r/   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'+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   :U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   rO  depth)	r+   rt   r   r   r
  r   r@   rw   r   )rS   leftr  
right_listr5  r~   r`   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  )rh   uuid1r   s    r!   r   zBaseModel.gen_id  s    ..!57),,r    r   c                 
   |dkD  s| j                   syd| _         | j                  d      D ]U  }|j                  s2t        |j                  t
              rt        |j                  dd      rA|j                  |dz          W y)ub   
            сброс состояния объекта после сохранения
        rO  NFTr  r   r  )r   r   r   r)   r   r   rt   flush)r_   r  r/   s      r!   r  zBaseModel.flush  so     19DOO- 	%A99AGGY!?GAGGUhjnDo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  rt   r   ro   r   r)   r  r  )r_   r.   rG   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   rt   )r_   rX   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  rK   rs   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   rO  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   rt   r   rG   cmf_modified_by_idr   r   r   cmf_author_idr   r  
_save_data)r_   r  r  r}   rN   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 endr9  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   rm   r[   rG   CmfJsonr   r   save_only_data_hackrI   r+   r)   rn   r  r  r  ro   r9  r  r   project_notifyr   rP  invalidate_cachemark_full_searchrT   r  import_originalr  disable_permissionsr'  _calc_projectr  r  r   r   r   remover  )r  r  r}   rN   self_idr.   r  r_   s          r!   save_with_flushz5BaseModel.save_flush_wrapper.<locals>.save_with_flush6  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_wrapper5  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 )Nr2  Tr  )r2  r   cmf_created_atr   r   r  r  perm_perm_encryptperm_encrypt_helpperm_policyr  r   )r   r   r   rh   ry   r  r)   r   rG   r   r  r   r   )r_   r2  rN   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  rN   r5  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 )
NrO  FTr  r   rM   notify)r  r  r  invalidate_done)r  r  r  )
r   r)   r   rG   r  r   app	CMF_CACHEr  r   )r  r  	max_depthr  r~   rN   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   Нарушение ограничения целостности.CmfOrmColumnHistoryr9  r  rO  z&!!! --- _save_data::duration too long .1f sec, r,  , r2  ))r  _acl_check_writeverbose_namer   rI   r   r   r  rM   CmfOrmUniqueErrorr   r%  r2  r  	exceptionCmfOrmIntegrityErrorr   r  rh   rt   r   column_historyhistorydeffered_history_columnsrw   r  r   rG   r   )r_   r  r  r}   rN   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   rt   rG   r  r   r   r   r  r  )r_   r}   rN   r~   r   r   s         r!   r   zBaseModel.save9  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_commitZ  s    		r    c                     t        d      )uw   
        Формируем кеш словарь связи объектов по parent_id и tree_parent_id
        
Deprecated)r}  r   r   r   r
  r   r-  CmfAccessRule
CmfCommentr  r   r   rt   sysinternr3  r  r   tree_parent_id)r*  rS  r+  rN   r#  skip_modelsr   obj_datas           r!   _build_relation_cachezBaseModel._build_relation_cache_  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__rh   r   r  r   r}  r  exc_info__exit__r_   r5  rN   r&  r(  s        r!   _delete_child_objectzBaseModel._delete_child_objecty  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_deleterS  r+  r   r3  rb  T)rG   r  TECHCOM_nocacherS  r*  )rG   r*  r   )r"  r   r   r   r  r   r
  r   r  rK   r+  r   r.  )r_   r.  r*  rS  r+  rN   relation_cachechildren_id_setlevel
next_levelr3  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 )	Nr3  rb  r  r   r]  r  r   r3  r  T)rG   r/  r*  rS  r  r+  )r   r   r
  r   r-  r  r  r  r   ro   rw   r  r   rt   r  r  r  r   )	r9  new_id_listr   r   _filterr!  r*  r+  rS  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   r3  rb  T)rG   r  r/  rS  r*  r+  r-  )r   r
  r   r  rK   r+  )r9  r5  r.  r*  r+  rS  rN   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+  r.  rS  )
r   r   r  rp  r   r
  r   r.  r+  union)r9  rA  r<  r4  r6  r.  r@  r*  r+  rS  rN   level_deleter>  r_   s        r!   rD  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    )r9  r
   r;   )r   r   r   )
r_   r.  r*  rS  r+  rN   children_idsr@  rD  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)rG   r  r/  r%  )r   r   r0  rK   r+  )r_   rN   essential_child_model_nameessential_child_modelr5  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  r.  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   rt  r  	CmfNotifyCmfAttachmentr  Fr.  T)	skip_subsu   Нельзя удалить u1   , на него ссылаются потомкиr  )r*  r+  full_searchr   r   ) r  rh   r+   rF  rM  CmfOrmHasReferenceErrorrJ  r)   r  logical_deleter  rr   r   r
  rG   rm   r   r  rw   rt   r   ro   rT  r   CmfFullSearch_text_search_sql_delete_partnor   r   rI   r   r   r  )r_   rN  r  r.  r  r}   rN   children
m2m_fieldsrX   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    rN  c                    d| _         d| _        |j                  dd        | j                  |i |}| j                  dvr&|r | j
                  di | |S | j                          |S )uy   
        Восстановление из корзины логически удаленного объекта
        Fr  TrP  r   )r  tree_node_is_branchrr   r   rh   _children_recursion_restore_essential_children_restore)r_   rN  r}   rN   r  s        r!   restorezBaseModel.restore=	  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.  r`  r   )obj_idr}   rN   r5  r  s        r!   r   zBaseModel.restore_deferredQ	  sH     	
$VH-.##FDAckk4*6*vvr    c                      y r;   r   r   s    r!   tree_child_restore_hookz!BaseModel.tree_child_restore_hook]	  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)rG   r  r/  r*  r+  N)r   r   r0  rK   _restore_child_object)r_   rN   rH  rI  r5  s        r!   r_  z%BaseModel._essential_children_restore`	  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'  r`  r}  r  r(  r)  r*  s        r!   rj  zBaseModel._restore_child_objectr	  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   
        Рекурсивно восстанавливаем все дочерние объекты
        Nr3  rb  r  r]  r;  T)rG   r/  r*  rS  r+  r  z%_children_recursion_restore end levelr   r'  r   r  )rG   r  r   r/  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   ro   rK   r   r	  r  r   r  rj  r   r.  )r_   rS  rN   r1  r2  r   r3  r   r  r!  r4  r5  r6  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  rM   failoperaterZ  r'  result_statusuO   Отказано в модификации системного объекта adminmessageproject_adminFTr  r  r   r9   r+  )r2  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   r/  r   CmfAuditaudit_eventrh   r[  r   r)   rn   r  oldr  r3  r   r   r  newr-  r.  r(   rn  ro   rI   r   acl_admin_modery  r+   r   current_person__member_ofcurrent_userrz  rt   loadr
  r   r  r   r  check_accessr}   r   r&  )r_   force_check_fieldsr}  obj_parent_idobj_owner_idrh   r  
need_checkchanged_field_namechanged_fieldowner_write_fields_allowproject_admins_groupaccept_creationaccept_editr  force_check_fields_setrX   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 - уничтожить флаг
            для некоторых мест (например, поиск) ради скорости игнорируем, что не отобразятся доступные объекты в закрытых проектах
                (где пользователю проект недоступен, но есть доступ через поля объекта)
        rn  public_readNTr  read)r|  r}  r~  r  r  r  r   r  )	r|  r}  r~  r  r  r  r  r   r  u0   Отказано в чтении объекта ro  rp  )r   r)   rn   r  r   r  r3  r   r   r  r  rh   r(   rn  r-  r  r   r   r[  r}   r  r  )r_   rU  TEXKOM_skip_failread_auditTEXKOM_ppp_project_simplecheckr}  r  r  rh   rX   r~   rulesr  s               r!   rZ  zBaseModel._acl_check_readF
  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    )rG   save_kwargsr  c                     | |i |}|si }|j                  d|      |d<    |j                  di | |r| j                  |j                  |      S |S )Nr  rt  r   )r+   r   r   )rS   rG   r  r  r}   rN   r   s          r!   r   zBaseModel.create
  s^    ''K#.??;	#JK $$778;;v766r    c                     | j                   S r;   )rk   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 )NrG   rY  )rh   ui_group_fieldsrL  rG   )rh   APPall_models_metar   rl   rk   r(   ry   rL  rw   r  )rS   _argsr;  r#  modelClsrX   
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*  Fr9  r+  )ro   r+   rr   r   bulk_deleterG  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)rS   r   r}   rN   r/   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  )ro   r+   rr   r   bulk_updaterG  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 )	Nr2  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   ro   r2  r   r  rG   r  rt   r)   r   r   CmfGenericBackrefCmfTUUIDforeign_keyrh   r   r+   r  r   )r_   r  r  rN   rX   	field_objs         r!   rM   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  rO  )r   r}  ud   Фильтр для upsert должен быть простой: [field, =, value], передан: r  Tr,  u8   В фильтре upsert неизвестно поле: u6   , допустимый фильтр: [field, =, value]r  u2   Указан пустой фильтр в upsert: N)r)   rK   rp  r   r
  r%  rG   )
sub_filtersub_sub_filtercheck_simple_filterrS   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  rO  u9   Ключ в фильтре upsert не уникален: r  r,  r   r  r   )rK   rp  r   r
  r%  rM   )rS   r  r  r  rN   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 )NrT   r2  r,  r	  : )	ro   rT   r  r2  rI   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)   rK   r   	from_jsonrs   r  get_cls_by_tuuid_strr(   )r!  r   r  rS   r.   r/   rG   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_   rG   rL  	fieldnamer~   s        r!   to_jsonzBaseModel.to_json1  sM    F $

d
 ; 	(Iu&"ZZC	N	(
 
r    c                 ~    |dk(  rt        j                  |       S |dk(  rt        j                  |       S t               )Nrs   r!  )r   
dumps_dict
dumps_jsonNotImplemented)r_   rI   s     r!   r"  zBaseModel.dumps?  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   rK   r  r   _load_extra_fieldsru  rG   r(   rm   r  r  r+   CmfRelationCmfM2Mr   r   r   dump_data_dictCmfGenericRelationCmfGenericM2Mr  rw   )
rS   	upper_resr  r  r`   	item_dictrX   rY   fk_modelr  s
             r!   r  zBaseModel.dump_data_dictF  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)NNNNNrO  Nr;   )NNTFr$  r  )FF)NNNNNNNNNNFNF)r   r   )FNF)FFFFTFNFF)r!  )r   r   r   r   rl   fields_orderr:  r  verbose_name_pluralr   r  rL  r  r  r   customsmart_notifyr   rK   rH  rx  r   r   r	  r   r   rG  r   r   r   r   r   r   r   r  enable_edit_permenable_delete_permrg   rG   ri   r   r   iconcache_cluster_fieldsrz   classmethodr   r   r   ra   r   r   r   r   r  r  r{   r   r  r  r(   r   r  r  r   r6  rM  r   rh  rk  rm  rw  ru  r  rs   r  r  r  r  r  staticmethodr  r  r	   rJ   r  r  r  Typer   r+   r   r  r%  r  r3  r   r   r=  r5  rH  r   rJ  rO  r   r  r   r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r   r  r"  r+  r7  rF  rJ  rM  r   r`  cmf_deferred_jobr   rg  r_  rj  r^  r
  rZ  r  r   r   r  r  r  r  rM   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  Gv 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 osKO.2HM	B B 	B 03	B BH     - -%%$
 

?
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
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   Автоматически генерируетсяrF   r5  nullableri   r   r  u
   Авторrc  CmfPersonWidget)rF   r  linkabler   r   fullsearch_indexwidgetu   Владелец)rF   r  r   r  r   r  r  u   Родительrn   )rF   
base_modelr  r  u'   Последний изменивший)rF   r  r   r  r   autorn  u$   DEPRICATED. Кто захватил r  )rF   r  r   r   r  rn  u#   DEPRICATED. Дата захвата)rF   r  r   indexrn  u   Дата создания)rF   r  r   r  r   r   r  r  u   Дата изменения)rF   r  r   r  r   r   r  rn  u   Дата просмотра)r  rF   r   r  r   r   rn  u   Удален)rF   r  r   r$   r  r   u   Номер версии
CmfVersion)rF   r  r   r   rn  r  r  c                 ,    t        |       j                  S r;   )rI   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  rE   rt  r  )rw   r  r   r   
user_localr  rt   rK   )	r_   rG   r  rN   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   r2  r  r  r  
cmf_importr  import_raw_jsonr  ext_idrY  )rF   rX   field_qualnamerequiredr  r  r  r  )rw   rG   r   rm   r   r   rh   r  ry   r  rF   r   r  r  r  r  r  )rS   fields_namer#  rG   rX   r~   s         r!   import_shop_fieldszCmfModel.import_shop_fields,  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   )rs   r(   r  ro   r@   r   r   r
  r   r+   rQ   r   )rS   r}   rN   r.   r/   r[   s        r!   r   zCmfModel.createP  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.servicedeskrN  rP  rc  r  )r+   rQ   r   )rS   r  r  rN   r[   s       r!   r   zCmfModel.field_options_list]  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_versionq  sI    &&doox||HLL9BBCSTUXVXYZr    c                      y r;   r   )r_   r  s     r!   r  zCmfModel.project_notifyv  r  r    c                     | j                          t        | d      r| j                  s/| j                  r| j	                  d       n| j	                          t        |   |i |S )Nr  r  r  )r  ro   r  r   r  rQ   r   r_   r}   rN   r[   s      r!   r   zCmfModel.savey  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   r/  r3  r   r  r   ry   r  get_cache_projectperm_parentr  r   rw   ro   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   r/  r   r   rw   r  ro   r  r'  r  r  )r_   r}   rN   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  rQ   r
  )r_   rN   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    или Администратору системы.rt  zPPP-OBJ-CREATErr  ordernozPPP-OBJ-TREE-ORDERr'  r(  zPPP-OBJ-MOVE)r5  use_new_projectri  zPPP-OBJ-TREEMOVEzPPP-OBJ-EDIT)r  r   r  r  r   r   rh   project_perm_allow_fieldsry   r  r  r   r   r  r   r?   rT   r   r   r-  r.  r  r  rY  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&  rt  zPPP-OBJ-DELETErr  )r  r   r  ro   r  r  r   r   r  r   r2  r?   rT   r   r   r-  r.  r  r  rY  )r_   r,  r-  r.  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]  ri  r  r  rG   )r  r   rm   r'  r   rG   r  rh   r   r   rn   ri  r   r   r  rK   )	r_   rL  rS  r;  r#  r   linkedfilter_r  s	            r!   rM  zCmfModel.list_children1  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   
        Хак для доступ к имени проекта для опубликованных документов.
        rP  N)r3  r   get_class_name_by_idr'  r  rT   r   r  s     r!   r  zCmfModel.get_project_namea  sQ     >>g::4>>JlZ;;##%@$++*:*:*@*@@ [>r    r   r;   )rM   r  )TF)2r   r   r   r   rV  r   r   r   r   Fieldr  r   r  r   r   r   rG   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  rM  r  r   r   s   @r!   r  r    s   }$ N*I'' +
 
K 
;E
B } 	J $6u} I ZZ

//"  F 9}	O 6}M BE\`hluy{M+
N -
O -	M K 4edZ^gk  uAB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%   Родительская запись)rF   r   u   Корневая записьN)r   r   r   rn  r   r7  CmfM2MTUUIDr   r  r3  root_idr   r    r!   r@  r@  i  sL    FI	;E
B h(OW[\IH&ETRGr    r@  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   rF   r  r   r    r!   ra  rF  ~      /r    ra  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  rT   rightrQ   r   ro   rT   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   rL  r  r   rI   r   query_deprecatedr?   right_idr   left_idr  r3  r   order_queryallr  r  )rS   r5  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   
CmfStr4096ra  r   r  r^  r   r   s   @r!   rD  rD  {  s.    <j 9 .2 ) )r    rD  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.descriptionrG  TNrH  r   r    r!   ra  rd    rI  r    ra  c                     t        |   |i | d|v r#t        |d   d      r|d   j                  | _        d|v r%t        |d   d      r|d   j                  | _        y y y rK  rM  r  s      r!   r   zCmfM2MModel.__init__  rP  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 )NrL  r  )r   r   r   r   r  r   r   rI   rL  r   rR  r?   rS  r   rT  r  r   rU  rV  )rS   r5  r  r   rW  r?   left_cls	right_clsrZ  rY  r[  r  s               r!   r^  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  r_  r   s   @r!   rb  rb    s+    ;j 9  r    rb  c                       e Zd ZU dZdZeed<   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dd      Z! eeddddd       Z"e#jH                  j'                  e#jH                  jJ                  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#jH                  j'                  e#jH                  j0                  dd+d,      Z,e#jH                  j'                  e#jH                  jZ                  d-ddg .      Z.e#jH                  j'                  e#jH                  j8                  d/d0ddg 1      Z/e#jH                  j'                  e#jH                  j0                  d2ddd3      Z0e#jH                  j'                  e#jH                  j0                  d4ddd5      Z1e#jH                  j'                  e#jH                  j0                  d6ddd3      Z2e#jH                  j'                  e#jH                  jf                  d7d d8      Z4e#jH                  j'                  e#jH                  j@                  d9d:ddd;      Z5e#jH                  j'                  e#jH                  j0                  d<d=      Z6dZ7g Z8d>gZ9e#jH                  j'                  e#jH                  jt                  d?dddd@A      Z;e#jH                  j'                  e#jH                  jx                  dBdCdDdEdFddGH      Z=e>dIefdJ       Z?e@dddKdL       ZAe> fdM       ZBe>ddNeCf fdO       ZDe>dP        ZEddQedRefdSZFe>dT        ZGdU ZHdV ZIddWZJ fdXZKe>dY        ZLe>dZ        ZMe>dd[       ZNe>dd\       ZOe>d]        ZPe>dd^       ZQe>dd_       ZRe>dd`       ZSe>dda       ZTe>ddb       ZUe>ddc       ZVdd ZWde ZXeYdf        ZZdg Z[dh Z\di Z]dj Z^dk Z_dl Z`dm Zadn ZbdoeCfdpZcddqZdd@drdoeefdsZfdt Zgdu Zhddv fdw
ZiddxZjdy Zkdz Zl fd{Zmd| Zne@ eodd}d~      ddIefd              Zpd Zqd@dd fd
ZrddZse@ eodddIgd      d               ZtddZud Zve>d        Zwe>dddddd       Zxd Zyd Zzd Z{d Z|d Z}d Z~d߈ fd	ZdoefdZdedodfdZdd fd
Zd Ze>dddd       Ze@ ed      deCfd              ZddZe>d        Zd Ze#jH                  j'                  e#jH                  j0                  ddd      Ze#jH                  j'                  e#jH                  j0                  ddd      Ze#jH                  j'                  e#jH                  j@                  dddd      Ze#jH                  j'                  e#jH                  j0                  ddd,      Ze#jH                  j'                  e#jH                  jf                  ddd d      Ze#jH                  j'                  e#jH                  j                  dddd      Ze#jH                  j'                  e#jH                  j                  dddd      Ze#jH                  j'                  e#jH                  j                  ddd      Ze#jH                  j'                  e#jH                  jJ                  dd      Ze#jH                  j'                  e#jH                  j0                  dddd      Ze#jH                  j'                  e#jH                  j*                  dd      Zd Ze>dd       Ze>dd       Zd Zd Zd ZddZd Zd Zd ZddÄZe@ eoddg dĢū      	 	 ddƄ              ZdǄ ZdȄ ZdɄ Z fdʄZd˄ Zd̄ Ze>ddededefdЄ       Ze@ eoddҫ      	 ddededededef
dՄ              Z xZS )rn   u   CmfEntity - базовый класс для типичных моделей подлежащих автоматизации на преприятии.

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

    class Task(CmfEntity): pass
    Nacl_parent_fieldF))r2  rT   textr8  r  r3  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.namerl  rm  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_middler`  rN  unlockux_check_permattach_listu   Системный объектu   Нельзя удалять)rF   r5  r  r$   r  u
   Текстu   Текст сущностиu!   Добавить описание)rF   r5  placeholderu   Задачи сущностиrg  r'  )rF   r   backrefr  u#   Документы сущностиre  u'   Комментарии сущностиr  r  	CmfImportu   Импортированimport_objects)r  r   rF   r  r  u,   Исходная версия импортаr  )rF   r  r  rn  r$   u&   Сырые данные импорта)rF   r  r  u"   Ид внешней системы)rF   r   r  u   Объект в архиве)rF   r  r$   r  u   Избранный дляCmfPersonVar	favorites)rF   rL  r   r  r  rn  u3   В избранное всем участникам)r$   rF   r  u!   Родительская нода)rF   r  r   r   u   Ветви дереваri  )rF   r  r  r   r   u(   Есть вложенные узлы old)rF   r  r   r$   u$   Есть вложенные узлы)rF   r$   r  r   u)   Не отображать в деревеu-   DEPRICATED. Корневой Родитель)rF   r  r  u   ПроектrP  )rF   r   r  r  r  u>   Редактирование только владельцем)rF   r$   r'  u   Сортировкаr   )rF   r   r  r  r$   u,   Метод индексации поискаu!   Полная индексацияu%   Только наименованиеu'   Индексация отключена)0_full_index1_name	9_disabler  )rF   rC  r  r$   re  c                     t         r;   )r   )rS   re  s     r!   process_dirty_attachzCmfEntity.process_dirty_attach  s    !!r    )r  rG   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commentsrt  r]  r'  rb  r   r2  )
r   r.  r   rR  r   r   r  r   r   rK   )re  r  rG   r}   rN   r  r5  r5  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)rQ   rM  ui_form_jsonr(   r   )rS   r5  rL  rD  ui_field_datar[   s        r!   rM  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   r1  r   )r  r   NrY  rT   rG   )
r+   r   r   r   ry   r  r   r  rQ   r   )	rS   r  r  r  rN   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$   r2  rT   r  r  )rL  rs   r+   )rS   r}   rN   r  s       r!   _build_ui_formzCmfEntity._build_ui_form  sR    {{6L(V(V"U$0$4$4[$&$I[!r    rT   r2  c                    | j                  dg       | j                  || j                        }|D ]%  }t        ||      s|dk7  st	        ||||          ' ||_        | j                  |      }|j                  d       d|_        |S )u/   
        Копируем обьект
        z**)r2  r(  r   Tr  )	r  r  r(  ro   r   rT   _post_copy_hookr   r   )r_   rT   r2  r}   rN   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)rS   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_eventrj  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  rj  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_workrt  rO  )	recursionall_nested_persons)rK   r%  ry   r  r   rw   r   r  r   r  r  get_all_followersr  r2  r   extract_var_objr  ro   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                          t        | (  |i |}| j                  dd| j                          |S )u   
        Функция сохранения при импорте, чтобы ускорить исключив лишние логики и защиты
        Fz_save_import1 name=r  )r  r  r  r  r  _calc_tree_parentr  
_calc_code_calc_ordernorQ   r  r  rT   )r_   r}   rN   r  r[   s       r!   r  zCmfEntity._save_import,  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_sort?  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 )NrV  rO  )r:  ry   )rS   rX   s     r!   _revers_orderingzCmfEntity._revers_orderingC  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)ry   r   r   r   r   r.  r3  r  r   rP  r  CmfSearchStatre  actionsearch_query	person_idr  
aggregatedr   )rS   r  re  r  r  r3  r5  stats           r!   rw  zCmfEntity.mark_clickedL  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)re  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;re  viewF)mark_viewed_objry   r   r.  r   r  r'  r3  r  r   rP  cur_workflow_version_idr  CmfStatre  r  r  r  
history_idr  r   )
rS   re  obj_id_listr  r  r  r3  rN   r5  r  s
             r!   rx  zCmfEntity.mark_viewedg  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  re  r  )personr5  )r   r   r   r/  r   r
  r%  r   r.  CmfLockry   r   CmfPersonViewr+   r   )rS   re  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'  rt  r  r   )r   r  rG   r@   u   Переиндексация ug   .orderno выполнена частично, так как объектов слишком много.Tr  )orderno_partition_byr   r
  r%  r+   _orderno_filterrw   rK   rp  r'  r   r  )	rS   re  r  rG   r5  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'  rt  r  PPP-TSK-ORDERrr  PPP-OBJ-ORDERr'  r   r1  rO  T)re  	before_idr  reversreindex><r  r   r  rG   r  r  r  r   )r  r  r+   r(  ry   rY  r  rw   r   r'  r  ry  r  absr   )rS   re  r  r  r  r  r;  rG   beforer5  r  	prev_itemdeltas                r!   ry  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                  |       |	j                  d|rdnd	|j                  g       | j                  |rd
ndg|	|      }
|
r&t        |
j                  |j                  z
  dz        }n|rd}nd}|j                  |z   |_        |j                  d       |j                  S )Nr(  r'  rt  r  r  rr  r  r  r  r  r  r  r  r  Tr  )r  r  r+   r(  ry   rY  r  rw   r'  r  r   )rS   re  after_idr  r  r;  rG   r5  afterr  	next_itemr  s               r!   rz  zCmfEntity.move_below  sE   >446FY'#*B*BBggfVg, ;;  ,55o35O55o35O0--/0!!&)y#S%--PQGGFj	%JSajpGq	**U]]:a?@Emme+4 {{r    c                     | j                  ddg|      }|j                  |k(  ry | j                  ||j                  |      S )Nr  r   )rG   r  re  r  r  )r+   r   ry  )rS   re  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   rG   r  )re  r  r  )r+   r  r   rz  )rS   re  r  r  s       r!   r|  zCmfEntity.move_down  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 )	Nr1  r  r  r   rO  rG   r  r  r   r  )r   rK   rp  r   ry  )rS   re  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'  rD  Nr   )r  rw   r  rt   r   )r_   r  partition_filterrX   r~   s        r!   r  zCmfEntity._orderno_filter4  s    12$$!!!"23T667"77 	H
j1 !''S%++(FG	H r    c                    | j                   r| j                  ry | 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)Nmax__orderno)rG   r   r  r  )r   r'  r  r   r&  r+   r   )r_   r  max_ordernos      r!   r  zCmfEntity._calc_ordernoF  s    {{dll%%'  " 	((&' #  l	 	 &-DLDL	 	s    A;;Bc                 R    | j                    d| j                   d| j                   S )Nz/?obj=r  )rd   rc   r2  r   s    r!   hrefzCmfEntity.href^  s&    ..!~QtyykBBr    c                      y r;   r   r   s    r!   r  zCmfEntity._calc_tree_parentb  r  r    c                 H    | j                   s| j                         | _         y y r;   )r2  gen_coder   s    r!   r  zCmfEntity._calc_codee  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   rV  '  r2  r   r   rD  T)r  r*  r+  rO  u8   Превышен лимит поиска кода limit=z model=uA   , возможно надо отключить def gen_code: passz$!!! --- gen_code::duration too long r  r  r,  r  r	  )ro   r  r  r   r&  r  get_code_prefixnext_code_numberr   r   rh   r  rG   r2  )r_   r  r  r2  limitr   r  s          r!   r  zCmfEntity.gen_codei  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;   )re   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   )r2  
SIMILAR TOz[A-Z]+-[0-9]+\Z-cmf_created_atT)r  r   r*  r+  rV  r  )r   r  r2  r@   )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  rO  zlock release error z, lock_name z
, timeout N06)r  REDIS_DBrh   redisru  acquirerH  incrr  r   release
exceptionsr   r   r  rT   r  )r_   redis_dbr  lock_keyru  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_   rX   r}   rN   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   r9   )r   r  rt   _format_for_html_diffr   r}  r	  )r_   
audit_datarX   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 не загруженrk  r  rM   r   r  r      r2  z<br>F)	rq  rZ  r   r'  parent_nameparent_coder%  html_diff_dataignore_transactionr   )"r   r(   r  ry   r)   r   rG   r  _changesr   r   r  rv   r   r  r"  
audit_diff	html_diffrw   r&  rr   r   rT   rh   rk  ro   r2  rs   r   r	  r?   r   r  r  )r_   auditr%  r6  rX   r  r!  _audit_diff
_html_diffinfo_audit_datar  rq  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}   rN   s       r!   r  zCmfEntity.get_all_followers  s	    ur    c                 F    t        j                  j                  dd| i| y )Nr5  r   )r   rQ  place_notifyr_   rN   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_executorsrG   )is_favoriter   favorite_forr  r  rC  rw   r  )r_   	executorsexecutorrC  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   )rQ   r   r   r2  r  )r_   r   r}   rN   r[   s       r!   r   zCmfEntity.__init__   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  rP  r  ui_form_scheme)r   rG   )r  r3  ry   r  r'  r(  r  r   r  rh   r   r  r   rP  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_lockrT   rt  u   Этот реквизит может устанавливать только владелец объекта. Свяжитесь с r,  ul   Владелец запретил изменять настройки объекта. Свяжитесь с )r   r   r   r/  r)  r   rh   ry   r  r  r   r  r  r3  r   r  r'  workflow	scheme_wfr  r   r   r.  r   r
  r%  rT   )r_   r  r)  r~   r  r  r   s          r!   r  zCmfEntity._check_sl_owner_lockR  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 )NrF  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  rO  )rQ   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[  rk  r   r  r   )r_   r[  s     r!   _clean_textzCmfEntity._clean_text  s7    
 	>yy##tyy'8'8%diioo6	r    u6   Обновление дочерних объектов)rc  ra  rb  c           	         t        j                  |       }t        j                  | ddg      }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(  rt  r'  r   rD  r1  )r   r  r.  r   r0  r  rK   r(  	enumerater&  r   )	re  update_bg_progressbar	obj_modelr5  sub_objsr  r   nnsub_objs	            r!   essential_update_project_jobz&CmfEntity.essential_update_project_job  s     ++F3	 ##FD)3DE#:: 	^J--j9EOO

Hc6#:Yckk<Z"[
\^	^ 'x0 	MR!kkGO$$&  % 	 s    CC(	c                     t         j                  j                         r(| j                  | j                  j
                  d       y ddlm}  || j                  | j                  j
                  g       y )NF)r`  r   schedule_deferred_job)r}   )r   CmfDeferredJobis_jobre  r   r   r   rh  )r_   rh  s     r!   _essential_update_project_jobz'CmfEntity._essential_update_project_job  sM      '')--dggmmSX-Y9!$"C"C477==/Zr    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                  r| 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)                  |        | j+                          | j-                          | j/                          | j1                          | j                  r<|r:t2        j5                  d       | j7                          t2        j5                  d       | j9                          | j;                          | j=                          | j?                          | jA                          t2        jB                  rd| _"        n| jD                  rd	| _"        tG        | H  |||d
|}| jI                          | j                  sc| jJ                  j                  rMtL        jO                  dd|  d| jJ                  j&                   d| jJ                          | jQ                          | jS                  |jU                  dd              | jV                  |i | | jY                  d| j
                          |S # 1 sw Y   .xY w)NuN   Запрещено редактировать системный объект Tr,  tree_parent.tree_node_is_branchtree_parent.log_levelr  r  r  Frl  r[  z3CmfEntity.save(): Need update essential models for z
: parent: z -> r7  )r7  z_save1 name=r  )-r]  r  r   r2  r   rT   r   r
  r%  r   rI  r  ri  r  r\  r]  r   r&  r   r  tree_child_deleter  r  r  r  r   r  r  r  r  r  r  r  r  r  rQ   _acl_spread_inheritancer(  r  r  rk  r<  r+   r  r  )r_   r  r  r}   rN   r  r[   s         r!   r   zCmfEntity.save  s   ;;t{{ yy##tyy';';%%(vw{w~w~v  'A  IM%  N&&(yyDI&&?AXYZ++D4D4D4X4X7;  4((* :$$))D)9: ##  $$66t<  	??tGGL!IIKGGJ 	 &&(!%%'==#'D !!#(D glDDCFC$$& {{t||66LL!TUYTZZdeieqeqeueudvvz{  |H  |H  {I   J  K..0 	GT!:;T,V,,tyyk(BC
 
o: :s   /M88Nr9   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  )	rT  r   r  r   r   rT   r   rW  
mark_dirty)r_   r  r  s      r!   r  zCmfEntity.mark_full_search  s     	
CDGGMM?RZ[aZbcdyyGGZ[_[b[b[h[hZiiqrxqyz{''&T]'^r       )
system_jobrc  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)re  rG   u   celery_full_search_index: Не индексируем поскольку объект не найден или удален в бд (включая запись CmfFullSearch) obj_id:)r2  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   rW  r  ERRORr   r{  r|  r}  '_text_search_sql_delete_obj_with_childsfull_search_index)re  r}   rN   r   r5  
search_rawerr_strs          r!   celery_full_search_indexz"CmfEntity.celery_full_search_index)  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   )Pathr5  r  rv  T)exist_okz.metar'  r}  )rc  url_preview_imgurl_previewr2  r  )#shutilurllibpathlibr  ospathr?   r  
UPLOAD_DIRr   r@   r	  rp  rh   rH  r'  mkdirmover   rmtreer   rR  rK   rc  r   r  r  r   rk  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_dirB  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_personr3  r  placerh   relation_personschanged_fieldschanged_relationsr  __DEFERRED_all_relation_personsTr  )r<  r   r  r  r:  r9  .zemit: FIXME is changed bug rE   uR   DEV: INFO Могла не прийти инвалидация для old-поля rM   r  r  jsurlr9   session_tab_id)&collectionsr   rh   r   r  r   r  r+   r  r   r   r   ro   r3  r  r  r  rw   r   r(   rt   r   r  r  r)   r   rG   rq  r  r4  rK   rv   r  r   r  r   r  r  )r_   r   r  r  bodyr  r.   r/   r~   r  r5  r1   r   s                r!   r  zCmfEntity.emito  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_  )stripr@   rp  rw   formatr?   )rS   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  rG   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  r3  r]  r2  r}  fields_filterr^  )rT   rk  r2  r   rD  r  )r  r+   rw   r   is_tuuidrh   rK   )rS   r  rG   r  r  r}   rN   stemmed_queryr3  r=  r  r  s               r!   rN  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   rp   r   rv  r   s    r!   rv  zCmfEntity.lock_ping  s*    wwjll  ))r    c                 n    | j                   st        d      t        j                  | j                         S )ut   
        Из редиса заберём структуру, где есть данные
        :return:
        r  )r   rp   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  rP  zPPP-PR-ADMINrr  i  )r   rp   r
  rh   rY  r   ru  r   s    r!   ru  zCmfEntity.lock
  s\    
	wwjll
 ??l***>t*D||DGGW--r    c                 n    | j                   st        d      t        j                  | j                         S )u>   
        Снятие захвата
        :return:
        r  )r   rp   r   r~  r   s    r!   r~  zCmfEntity.unlock  s*    
 wwjll~~dgg&&r    c                 4    d| _         | j                  d      S )NTr  r8  r   rj  s      r!   archivezCmfEntity.archive&  s     yy4y((r    c                 4    d| _         | j                  d      S )NFTr  r  rj  s      r!   archive_restorezCmfEntity.archive_restore*  s    !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  ri  ro  rn  rT   u<   Нельзя удалять системный объект  (r	  Tr,  rz  ry  rt  r1   r  r   r/  r   F)rq  rZ  r   r'  r0  r1  r3  r%  r  CmfAutomationCrudTriggerbefore_save)r  r.  
after_savezdelete1 name=rp  r   ),r  r  r  ro   r   r
  r%  rT   r   r  generate_delete_prefixapply_delete_prefixr   r  r   rc  r   global_settingslogin_reuse_lockrz  r   deleted_loginry  ri  rq  r  r   rh   rk  r  r&  r  r  r   r	  r2  r  r  r  r  	crud_hookrQ   r   r  )
r_   r  r%  r.  rN   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,}\Zr1   Nr  )	r  r  r  r2  rematchr   
max_lengthrT   )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+  rG   r9   rz  ry  )rz  ry  r  rt  r  r   r/  r`  F)rq  rZ  r   r'  r0  r1  r3  restoredrN  )#r  r  r\  r   r.  r  r(  ri  rg  rT   r  r  rs  r   r3   r2  ro   rz  r  ry  r   rh   rk  r  r   r  r  r   r   r	  r  r  r  rQ   r`  )r_   rN  r}   rN   ri  r;  r[   s         r!   r`  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   rD  r1  FTr  )	r]  r  
tree_nodesr  r   r   r   r&  r   )r_   r6  r   r5  s       r!   rq  zCmfEntity.tree_child_delete  s    '',,.__335 	E**&6dgg%FtUZU]U]H^$_*`C	
 $)   " 	&III%	& 	& 	&s   B$$B-)r  r*  c                   ddl m}m} |j                  j	                  ddd      }|j                         s |dd       y		 t        t        j                         j                  d
      | j                  ||      }t        d|       	 |j                          y	# t        $ r"}	t        j                  d|	        Y d	}	~	y	d	}	~	ww xY w# 	 |j                          w # t        $ r"}	t        j                  d|	        Y d	}	~	w d	}	~	ww xY wxY w)uD  
        Синхронизируем настройки полей с фронта
        Получаем список полей с фронта, в нужном порядке для ui_group.
        Приводим в соответствие модель, БД, и запрашиваемый список.
        Поля которые удалили(нет в fields) убираем из ui_group, но оставляем в базе(!!! важно) и в модели
        (в модели поля может не быть, если её удаляли).
        r   )r  r%  z(lock::cmf__base_model__custom_field_sync  r  blocking_timeoutu   Невозможно изменить список полей, так как уже запущен процесс изменения. Попробуйте снова через минуту.Tr,  Nr  )meta_versionr  r  r*   BaseModel:custom_fields_gen_metaz'custom_field_sync:: release lock error )cmf.appr  r%  r  ru  r  rs   r   r   r  rh   cmf_emit_server_eventr  r   r   r  )
rS   r  r*  r}   rN   r  r%  
redis_lockdatar  s
             r!   rt  zCmfEntity.custom_field_sync  s     	0^^(()S]atu(v
!!#  W  _c  d	G(?(?(O#&>>#(79D ""DdKG""$ GA!EFFGG""$ GA!EFFGsO   AC	 
B 	C$CC	D
CD
	D%D=D
DD
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::r  r  u<   custom_fields_gen_meta Блокировка полученаr  z-BaseModel:custom_fields_gen_meta: already genr  rX  rZ  r}  r  r]  rT   NOT IN)dirtyr}  T)r   r'  r   T)r  rG   r*  Fr  rJ  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  ru  rH  	read_text
write_textrs   r   r   CmfCustomClassrh   rw   custom_fieldsr  rK   r  r   rT   r   r   r  r   r   CmfCustomField	from_dictr  save_changesr  )r  rN   r  r  meta_ver_pathhostnamer  r  rS   custom_classr=  r  r  r  custom_field_datas                  r!   custom_fields_gen_metaz CmfEntity.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                     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-)r  r  r!  r   r  )r_   r5  r}   rN   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_name4  s     (r    c           	           j                   j                         D cg c]  \  }}|j                  s| }}} j                   j                  |z           j
                  dk(  r j                  rt        j                   j                  j                  j
                        j                  sVt        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+        |j,                  xs d      dd       dd z   z  }V ||d<   d|vrb j.                  sVt        j                   j                   d       t        j                  j!                   j                  j                         y j
                  |d<    j0                  |d<    j2                  r2 j4                  j7                         j                  j                  |d<   n j                  j                  |d<   |j9                  d j:                  j                         |j9                  d j.                  j                          j<                  r|d   |d<   |j9                  d j>                  j                         |j9                  d j@                  j                         |j9                  d jB                         |j9                  d jD                  j                         |j9                  d jF                  xr   jF                  j.                  j                  xs d       |j9                  d jH                  xr   jH                  j.                  j                  xs d       |j9                  d jJ                  xr   jJ                  j.                  j                  xs d       |j9                  d jL                  j                         tO         d      r&|j9                  d jP                  j                         |j9                  d jR                  j                         |j9                  d  jT                  j                          fd!} |       }|r||d"<   nd|d"<    fd#}	 |	       |d$<    fd%}
t        jV                  jY                  d&d'tY         |
             gd(g)      }g }|D ]4  }|jZ                  s|j]                  |jZ                  j                         6 |rd*j_                  |      |d+<   d5fd,	d}d}d}d- j                   v rD j`                  r j`                  j.                  nd} j`                  j                  j                  }d} jD                  r%   jD                  j                  |||.      \  }}}d/ j                   v r; jP                  r/tb        je                   jP                        }|r|j.                  nd}d|vr9t        j                  j)                  t+         j,                  xs d            |d<   ||d0<   ||d1<   ||d2<    jf                  j                  |d3<    j.                   d*|xs d d*|xs d d*| ji                         |d4<   t        j                  jj                  d6i | yc c}}w )7u   
        Медленный метод для вызова из celery или из массовых индексаций
        rR  u3    Объект с model full_search=False mark_cleanNcomments_textr9   c                     | j                   S r;   )r  )r  s    r!   rf  z-CmfEntity.full_search_index.<locals>.<lambda>W  s    q?O?O r    T)r  reverser  r   r  r  i   rT   ud    Объект без имени в поиск добавлять бессмысленно mark_cleanr  model_verbose_namere  r  rk  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_date  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 )Nr9   rz  ry  r  )r	  rT   r4   r2  ro   rz  ry  )r   rT   r2  rz  ry  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   r9   )rG   r(   r  rt   r  r)   r   	CmfMarkupr   rW  
strip_htmlr	  r   r   r   r  r  r?   	CmfChoiceCmfChoiceIntrC  r+   r  rF   )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_dict  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)rT   r   r(  r9   )rw   rT   r   r   ri  r  r'  r3  rG   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_idrG  
spectatorsr  2   )r   r  r  r   rG   r'  r  r  rG  r)   r   rc  r   r(  r  discard)related_personr`   r5  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   rb  rz  r2  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'  r3  rq  zcompany.name
company_idT)rG   r*  r   u'   ERROR! CmfFullSearch у объекта u2    указан несуществующий parent=rr  r  )company_nametmp_breadcrumbs)r	  ry   r   r.  r  rG   rr  rT   r   r   r)   r   rP  r'  r3  )r5  r3  r0  r/  r1  _tmp_parentobj_tmp_breadcrumbs_fieldss         r!   r3  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    rr  )r5  r3  r0  r/  r1  r(  r$  r0  obj_company_idrp  text_prefix)NNNNr   )6rG   r(   r  r  r  rh   r'  r   r0  r   rT  r   r  r   r   rW  
mark_cleanr  r  r!  r  r	  rk  rT   r  r  cmf_ver_headr  rr   r2  r  r8  r  r  r3  r   r   r   r  ro   r  r  r<  rc  rK   rz  rw   r?   rr  r  r  rp  r  index_object)r_   rN   r.   r/   addon_fieldsr  r5  r!  r"  r%  r,  r  releated_person_loginspr/  r0  r$  r1  r(  r3  s   `                  @r!   r  zCmfEntity.full_search_index:  s	    '+kk&7&7&9PdaQ=O=OPP 	88<GH ??o-$++gF_F_`d`k`k`q`q`|`|F}  GJ  GJGGtwwiRST  ++DGGMM:&(
 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}))3F3k Qs
   [9[9u8   Разрешить публичный доступ DELME)r  rF   r$   u-   Задать права для объектаr-  u<   Список для проверки прав доступа)r   r   r  rF   u!   Наследовать праваu#   Наследуем права от )r  r   r  rF   u*   Кеш Владельца Родителя)r   r  rF   r  u;   Наследуемый список прав доступа)r   rF   r  r  u;   Эффективный список прав доступа)r   r  rF   u   Кеш неразвернутых записей Уровней безопасности, которым разрешен доступ)rF   r  u   Шифрованныйu5   Для просмотра требуется ключ)r$   r  rF   r5  u7   Подсказка к паролю шифрования)rF   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'  rM   PPP-COM-EDIT-OWNrr  PPP-COM-EDIT-ALLr   PPP-COM-DELETE-OWNPPP-COM-DELETE-ALLFT)r   r.  rZ  r
  r)   r   r  r  r   r  r   r(  rY  r'  r[  )rS   re  rX   permr5  rG   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.projectrt  rP  r  )rM   r   r@  )r   publiczview-workflowFzPPP-PR-VIEW-WORKFLOWrr  u/   Недопустимый параметр perm=Tr,  rM   rA  rB  r   rC  rD  r   zPPP-COM-ADDProjectCreators)
group_codeuP   У пользователя нет прав на созднаие проектаrH  PPP-DOC-SHAREzPPP-DOC-EDIT)r  r%  r   r.  r'  rh   rZ  r
  r(  rY  r[  r   r  r   r  r   rP  is_adminr  r  in_person_groupre  )rS   r5  rX   rE  r'  r%  rG   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   ri  r   r'  r>  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   r>  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_acl8  s    r    c                    | j                   j                  s?| j                  j                  s)| j                  j                  s|s| j	                         syd}| j
                  ro| j                  dk(  r`| j                  j                  rJ| j                  j                  r4t        j                  | j
                        }|j                  d|        d}| j
                  r^| j                  dk(  rO| j                  j                  r9| j                  j                          | j                  j                  d|        d}| j                          | j                   r'| j                  st         j#                  |       | _        | j                  rS| j                    | j                  _        | j                  | j                  _        | j                  | j                  _        | j(                  r| j                  nd| j                  _        |rVt,        j.                  j0                  j3                         5  | j                  j4                  j7                          ddd       n$| j                  j4                  j7                          t,        j.                  j0                  j3                         5  | j                  j9                          | j;                          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.
        NFre  rK  rr  TzPPP-DOC-TREEMOVE)r'  )r=  r   r  r   _acl_subjects_is_changedr  rh   perm_policy_anonymousperm_policy_guestr  r  rY  r(  r  r>  perm_aclr   r-  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??t=$BZBZBeBeLLLL223E42PL T]]"000=DM== *.):):%:DMM"&*nnDMM#)-DMM&GKGXGX4+C+C^bDMM([[((446 /MM'',,./ / ##((*$$002 %,,.""$% % / /
% %s   2%K!,+K-!K*-K6c                      y r;   r   r   s    r!   r[  zCmfEntity._acl_scaffoldj  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)policyrV  zrules.disabledzrules.sys_typeTr  r  )
r  r>  rU  r  rV  r  sys_typer   r   r   )r_   r;  rules      r!   r&  zCmfEntity.disable_aclm  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)r=  perm_acl_idrX  r  r  )r=  r   rX  rU  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_jobrg  )re  spread_model_namescmf_owner_is_changedperm_effective_acl_is_changedrN   )r  r   r  r   r  r   r  r   rh  rh   r   rP  _acl_spread_inheritance_jobr   )r_   spread_modelsr   rh  re  r  s         r!   rr  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)re  rf  rg  )rc  rw  rx  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  rt  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_idr3  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   rO  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   r0  r.  r   r  rn   r   r   rc  r   _ddSessionexecuterg   r  r   r   rK   r   r   r  invalidate_idsrh   rp  r  r6  rw   )re  re  rf  rg  rj  r~  r5  _spread_modelschild_modelr  row	processedcur_stage_parent_id_listnew_stage_parent_id_listbatch_count	upd_countr  cur_parent_batchs                     r!   ri  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   ro   r  r   s    r!   rR  z"CmfEntity._acl_subjects_is_changedV  s1    >>$$4/0T5N5N5Y5Yr    c                     g }| j                   r|j                  | j                          t        | d      r<| j                  j	                          | j                  D ]  }|j                  |        |S )Nr  )r   rw   ro   r  r  )r_   r#  r  s      r!   _acl_subjects_list_level_writez(CmfEntity._acl_subjects_list_level_write^  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_readi  s    	r    c                 X   | j                   r| j                  r| j                  j                  }|j                  j	                  | j                         }|r|j
                  s| j                  }| j                  }| j                  j                  j                  s| j                  j                  dg       t        j                  j                  d|j                  j                  |j                  ||j                  |j                  j                  ||d	       t!        | D  di |S )Nr  r{  F)	r|  r}  r~  r  r  r  r  r  r   r   )rj  r'  r   rG   r+   rn  r  r  r  r  r  r   r-  r  rh   r   rQ   r
  )r_   rN   r'  parent_fieldr  r  r[   s         r!   r
  zCmfEntity._acl_check_writem  s      T[[[[&&F!==,,T-B-BCL L$7$7!__
#88{{88CCKK++-D,EF$$11!(&:V:V:\:\!'!2!2L!-!8!8$iioo
\b  2 " w'1&11r    c                     t        t        d      r2d}| j                  rd}t        j                  j	                  | |d       y y )Nr  rM   r   r  )ro   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   rM   r  )ro   r   r  r  r   r@  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$  rg  up   Обработка может занять несколько минут, ожидайте оповещения.)cls_namer  r  notify_person_idr  rh  )
r  r%  r   rh  _group_changes_jobrh   r   r   r   r   )rS   r  r  r  r%  rh  s         r!   group_changeszCmfEntity.group_changes  sR    %5  E  	F""NN&&$%$4$4$7$7$=$=(<		
r    u#   Массовое изменение)ra  rb  r  r  c           
      8   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      } ||j                  di             \  }}d }|r|j                         }t!        d|j#                  ||z              D ]  }|	j%                  dd|d   g||z  ||z  |z   g|      D ]  }	 |dk(  r6|j'                         D ]  \  }}t)        |||        |j+                          n^|dk(  rD|j'                         D ]   \  }}t-        ||      j/                  |       " |j+                          n|dk(  r|j1                          |j2                  j5                            |dk(  sU|sYt=        t>              }|j                         }|	j%                  dd|d   g|      }|D ];  }|D ]4  }t-        ||      }||j@                  }|s!||   jC                  |       6 = |j'                         D ]D  \  }}t-        |	|      jD                  }tF        jI                  |dt%        |      ||   dg|       F * 	 d d d        |rd}
ddjK                  |       }t        j                  j                  ||
|dd       y #  |j2                  j7                          |j/                   ||             t8        j;                  d|        Y ,x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 )NrE   rO  )r(   r@   rr   )changesdirectrelatedr~   valr  r3   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">)rh   taskr  rT   r2  rr  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    )rg  r  CmfTestcaseCmfTestcaseRunCmfTestcaseRunHistoryCmfTestplanTestcaseTrO  )r  rT   r.  force_notify_current_personry  uL   Успешное завершение массового изменения.uO   Массовое изменение закончилось без ошибок.rU  r   rb  r9  r1  r  )r  r  rG   rM   rw   r   u)   Не удалось обработать r2  )r9  r  )r  r  r  r  u8   Ошибки при массовом изменения.uA   Обнаружены ошибки при изменении:</br>z</br>)&mathr   rg  r  r  r  r  r  r  rQ  r?  r   disable_notifyr   r   r+   rangeceilrK   r(   r   r   rt   rw   r   r   r  rollbackr  r  r   r   r   r  r   rn   r  r?   )r  r  r  r  r  r  r  r  r  rS   notify_name
notify_msgerror_hrefssubgroupstepr  direct_changesrelated_changesrG   r   r5  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##%;= 7	% 6iidHY4G'HiI2@iY[A\2]/!)..0Fq$))C$J"78 aA"xxdHY<O/P784xTD6Q7=  (  ? aa(H48F8L8L8N !C$4Iu$+CE$B!C #
!*h!68F8L8L8N !J$4Iu$+C$;$B$B5$I!J #
!*h!6 #

FFMMOaa* (_#.s#3L#2#7#7#9L88D$8K+LUa8bD# 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 
Y67	r TK\]d]i]iju]v\wxJ%%#(, 	& 	
EaFFOO-'../@/EF#--0YZ]Y^._`;7	 7	s;   BN%B3L?	N#N'ANA2N?AN
NNr  r;   )r   Fr$  )NNNNNNr  r  r  )Tr9   )FFF)NrM   )NNrM   Nr  )r   r   r   r   rj  r	  rH  rT  r  menu_tree_parent_idmenu_tree_ordernor   r  compilers  r  rz   r   r   r7  CmfNamerT   CmfCoder2  r=  r  r  rk  r  tasks	documentsr  r  r
  r  r   rG   r  r  CmfStrr  r8  r  rF  rE  r  ri  r  has_tree_nodesr]  tree_hiddenr8  root_parentr(  r  r  r  r:  CmfIntr'  r  rp  r  r  r  r  rM  rs   r   r  r   r  r  r  r  r  r  r  rw  rx  r  r  ry  rz  r{  r|  r}  r  r  r{   r  r  r  r  r	  r  r
  r  r"  r&  r<  r   r  rA  rI  r   r  r  r)  r  r]  r  re  rk  r   r  r  r  r  r  rN  rv  r  ru  r~  r  r  r   r  r  r`  rq  rt  on_server_eventr  r  r  r  perm_publicr=  rU  rX  r  r  r  r  r  r  r  	CmfStr256r  r>  rF  r  r  r  r  r  r[  r&  r  rr  ri  rR  r}  r  r
  r  r  rK   rG  r  r  r   r   s   @r!   rn   rn     sM    !c  K" #JJ'89((+EELI&& *
 
K$ >D>D1-F -7	D /{E 5I 9~H {k9CS]bd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 # Q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  > Q Q O O Q Q$ 0 C C(0 (.* JX 23  :
= %* ,('TAoH
Y	7 2j  AE  FS  F 2[ !" JX_ xj[\]: ^ :.+Zc*L I I !#DT  4*
*.&'))
N`? ?G# G$ G (- *EX& ,15 G G6 ?@:/T :/ A :/zg( ( (
[4N	 **""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
'--%^"&;"'!R  Gh i?C^cW1i W1r	2:Xq 
S 
D 
PT 
 
 "G]ab =An
n
"%n
26n
n
59n
 c n
r    rn   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 <   e&d%d!efd"       Z'd# Z(d$ Z)y)&r  Nrh   
field_typeui_group_name	ui_groupsrk   rF   r  r  db_typedb_column_namedb_table_namer  r   r   rC  disabled_choicesFdb_need_create_choice_tabledb_choice_table_namer$   rL  r  r  r5  Tr  r   r  options_list_paramsoptions_list_show_columnsoptions_list_search_columns
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 )NrC  )r  r  r  rk   r  r  r  r  rk   r   )r   r(   r)   rK   r  caption_to_name__dataclass_fields___calc_db_choice_table_name)
rS   r  r   rk   ui_meta_nativerN   r.   r/   choicer  s
             r!   r  zCmfCustomField.from_dict8  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                 P   dj                  | j                  j                  d      D cg c]  }|j                          c}      }|j                   | d}t	        |      dkD  r;t
        j                  j                  ddt	        |j                        z
   dd	       |S c c}w )
Nr9   r1   Ch@   u8   Имя поля не должно быть больше    u    символовTr,  )r?   rh   r@   r<   rp  r   r
  r%  )r_   r   r;  r  s       r!   gen_db_choice_table_namez'CmfCustomField.gen_db_choice_table_nameM  s    !ww@U@UVY@Z'[1'[\"'"2"2!34H3IL#$r)KK!!$\]dehiniyiyez]z\{  |M  #N  VZ!  [## (\s   B#c                     t        | dd       }|sy |dk(  rHd| _        | j                  |      | _        | j                  | _        | j                  | j
                  d<   y || j                  |      k(  r|| _        y y )Nr   CUSTOM_CHOICE_MODELT)rt   r  r  r  r   rk   )r_   r   	rel_models      r!   r  z)CmfCustomField._calc_db_choice_table_nameU  s{    D'40	--/3D,(,(E(Ee(LD%22DJ$(JJDLL!$77>> )2D% ?r    r;   )*r   r   r   rh   r	  rH  r  r  r  r   rk   rs   rF   r  rG  r  r  r  r   r  r  r   r   rC  r  r  r  r$   rL  r  r  r5  r  r   r  r  r  r  r  r  r  r  r   r    r!   r  r    sn   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4  ($2r    r  c                       e Zd Zdee   fdZdee   fdZd Z	d Z
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  rX  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!                         }t#        t$              }| j                   j&                  j)                         D cg c]   }|j*                  j                  d      s|" c}D ]  }|j-                  |j*                        }d }d }	d }
t/        |t0        t2        f      rst5        t6              j-                  |j8                  j-                  d            }|r| j                   j                  j                  j;                  |      ret=               }
nZt/        |t>              r'|j*                   d}||v r|jA                  |      nd }
n#|j*                  }||v r|jA                  |      nd }
t6        jB                  j-                  |j*                  dg      }|s8tD        jG                  |jI                         |	      }|
| j                  jK                  |       |d
| _         | j                  D ci c]  }|j*                  | c}| _        y c c}w c c}w c c}w )Nz.bkFrT   rY  r   r  r   r  rJ  T)&rX  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_columnsrg   ry   r   r   rK   rG   r   rh   r+   rm   r  r  r   r   rk   	has_tablers   r  r  r  r  r  r   rw   )r_   rX  columnr  fields_ui_groupsr/   rY   r  r  _db_table_namedb_field_info	cmf_modelr  
field_datas                 r!   r   zCmfCustomClass.__init__i  s   ">B=?59*.68HL 7;7P7P7R595I5I5U5UV[5\
 ..++77MMdnnNfNfg
f~((/ 6NF"

 __))+
 '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 M
 g6 $ls   3!L+ L	L	'LrG   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  rC  r  N)r  rh   r+   rw   r   rX  rG   r  r  ro   rC  r  )r_   rG   r-  
cur_fieldsr  custom_fieldr~   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                 V   | j                   D ]	  }t        t        j                  |j                        }t        |t              r
t               |j                  r|j                  r| 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        |t&              r*|j                   d}t        j                  j(                  }n|j                  }| j                  j                  j                  j+                  | j                  j"                  ||        | j-                          y)uP   Создадим поля в базе и сохраним файл модели.r1   r  N)r  rt   r   rG   r  rm   r  r  r  r  rX  r   r   add_custom_choice_modelrh   add_custom_m2m_modelr  rg   r<   r  r  add_custom_column_write_custom_model_file)r_   r  r  r  
table_namecolumn_names         r!   r  zCmfCustomClass.save_changes  s   // 	oJ Z-B-BCJ*n5$&&0099NN%%11II*JiJij$(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NN));;DNN<T<TVacmn+	o0 	%%'r    c                    ddl m} 	 d }	 t        j                  d        |         |d	d
| j                  j                  i       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  rH  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() после откатаzBaseModel:custom_field_syncrZ  )r   r  r   r  r  SubprocessErrorr  r  r  rH  r  renamer  r  rX  rh   )r_   r  r  s      r!   r  zCmfCustomClass.apply_changes  s    5Y
	\ 	GGnoG 	;>NPTP^P^PiPi=jk )) 	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 |
jB                  |_!        |
jD                  |_"        t        j                  d|	 d| d|         t;        |      D ]  }	|	j?                  | jF                  jH                   d      s?|	j?                  | jF                  jH                   | jF                  jH                   d      sjtK        t0        |	t9        ||	              t        j                  d       |jM                          t        j                  d       i tN        _(        i tN        _)        | jF                  jT                  jV                  jX                  j[                  | jF                  jH                        r?| jF                  jT                  jV                  jX                  | jF                  jH                  = t        j                  d       t0        j\                  j_                          t        j                  d|j                                 y)u   
        без перезагрузки обновляем в памяти модели и поля, добавляя кастомные
        r   )r  )r   N)models_orig_pathuu   CmfCustomClass.reload_models_and_fields: НАЧАЛО - перезагружаем мету в инстансе, PID=rW  r9   rE   r  custom_modelsu\   CmfCustomClass.reload_models_and_fields: загружаем модуль custom_models из uc   CmfCustomClass.reload_models_and_fields: модуль custom_models успешно загруженu   CmfCustomClass.reload_models_and_fields: начинаем обновление кастомных полей для всех моделейrY  z/CmfCustomClass.reload_models_and_fields: model=z
 cf_added=z cf_removed=CfuQ   CmfCustomClass.reload_models_and_fields: сбрасываем CMF_CACHE.flushdb()ug   CmfCustomClass.reload_models_and_fields: сбрасываем кеш меты для фронтендаux   CmfCustomClass.reload_models_and_fields: пересчитываем кеш полей RelationCache.build_fields_cache()uv   CmfCustomClass.reload_models_and_fields: ЗАВЕРШЕНО - мета успешно перезагружена, PID=)0r  r  r   r  cmf.make_modelsr  r   r  getpidr	  r  r  r  r  	importlibreloadimport_moduleutilspec_from_file_locationmodule_from_specr  modulesloaderexec_moduler   r  rZ  rC  rt   r   rG   ry   rw   rk   r  rX  rh   r   flushdbr  r  cache_cust_field_config_schemer   r   models_registryr+   RelationCachebuild_fields_cache)r_   r  r   r  r  module_pathmodule_namespecr  r  custom_modelrX  addedremovedrX   s                  r!   reload_models_and_fieldsz'CmfCustomClass.reload_models_and_fields  s    	&4	  H  IK  IR  IR  IT  HU  V  	W$../776;M;M:Na8PRTU]]^acfghkikl00=> &	no  oA  B  	C~~55k3GWCXY!77=#0K .	uv 	
  ^  	_ --<<DD 	z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 4I(4(D(DI%GGEj\Q[\a[bbnovnwxy%	z, }- 	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
 	
cd	yz -/*>>((88<<T^^=V=VW!!--==dnn>W>WX 	
  K  	L//1	  I  JL  JS  JS  JU  IV  W  	Xr    rF   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,  rU  rY  r  r1   u#   Такое имя уже есть: r,  r	  )r   r
  r%  r  r  r  r  )r  rF   	name_baserc  rX   s        r!   calc_field_namezCmfCustomClass.calc_field_name?  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_coderH   r9   c              3   `   K   | ]&  }|j                         r|j                         nd  ( yw)r1   N)isalnumr4   )r=   r  s     r!   r>   z1CmfCustomClass.caption_to_name.<locals>.<genexpr>P  s#     HaQYY[	c9Hs   ,.)r   r?   )rF   rT   s     r!   r  zCmfCustomClass.caption_to_nameM  s)    tdCwwH4HIr    rY   c                     | j                   D ]5  }t        |dd       }t        |t              s!|j	                  d      s3|c S  y )Nrh   Cmf)__mro__rt   r)   r	  ry   )rY   rW   base_class_names      r!   _field_type_namezCmfCustomClass._field_type_nameS  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)r  c                 h    t        | t              r!dj                  | j                  dd            S | S )Nz'''{}'''z'''z""")r)   r	  r  r  )xs    r!   rf  z9CmfCustomClass._write_custom_model_file.<locals>.<lambda>a  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_templaterX  	__bases__r   ry   rH  r  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/fieldsr0  rW  rE   Nr.  z/custom/T)parentsr  z__init__.pyr  u   Создан z[A-Z][a-z0-9]+r1   z.py)r  r  r  r  rX  rd   r6  r   ry   r?   r@   r  rH  openr  r  r  findallrh   r4   )r_   fields_dir_pathrS   postfixpkg_init_file_pathname_word_rewordmodel_filenames           r!   r  z#CmfCustomClass._get_model_file_pathp  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}  rG   r  rJ  )r   r  rK   rZ  rw   r(   r   r0  r  r  r   r  r  )	rS   fields_to_model_namer  r  r  rX  
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5l6K6K6MU^5_
((//
;< //1	2r    N)r   r   r   r  rn   r   r   r  r  r  r  r  r  r	  r"  r  rP   r,  r  r  r  rG  r   r    r!   r  r  h  s    3l$y/ 3lj+4#7 +4(8$lNAXH 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   rd   r3  rc   r2  sharelink_hashvfrT   )r   r   r   r   r	  rH  rd   r3  rc   r2  rJ  rK  rT   r   r    r!   rI  rI    sT    BN IsIsGS D#NCBND#r    rI  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  r1  Fr]  )default_factoryr  r'  T
allow_movechildren_countr  r`  only_archivedr8  )r   r   r   r  r	  rH  r1  r]  rG  rK  r~   rK   r  r'  r  rO  rP  r  r`  rQ  r8  r   r    r!   rM  rM    s    
 NCK %%({((>J>GSJNCFDHcM4L$r    rM  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!   UBQLParseErrorrT    s    r    rU  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   rE   u   У модели u    не найдено поле r  FTu0   Не найдено поле у моделей: )	itertoolsro   rU  rh   rt   rm   r   rG   rq  r  r   r@   chainr   rn   r   r  rM   rK   )rS   r   
field_pathrW  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)r2  )r   rg  CmfListrP  re  rP  rc  ry  
CmfOrgUnitCmfRoleCmfWorkflowCmfTagCmfRelationOptionCmfLogicTyperf  r{  CmfActivityr+   r   r   )rS   r2  
model_listr   r5  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 без кавычек
        r9   )rb  r  r  zNOT LIKEr^  z	NOT ILIKEr  zNOT SIMILAR TOrg  z
NOT EXISTSr]  ra  r  z([^"'])z\1"z"\2)flagsr   []rO  r  ,)"')rj  rk  rl  )rn  rm  )g.current_userg.now()g.date())TrueFalseNonerm  )r  r3   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_ubql`  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)Nro  z'__G_CURRENT_USER'rp  z	'__G_NOW'rq  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   TrO  orderbyr  )r]  ra  rg  r  )	r)   rJ   rK   rp  r	  r4   r\  rw   rg  )r  skip_orderbyblqrX   rf  r  exists_filter_val
tuuid_valsr   r   _recursive_ubql_processrS   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  rO  r  r   Nr  c                     g }| D ]O  }t        |t              r|j                   |             +|dk(  r1|j                  |j	                                Q |S )Nr   )r)   rK   r  rw   r4   )
field_list_resrX   rec_parse_order_bys      r!   r  zTUbqlConverter.ubql2bql.<locals>._recursive_ubql_order_by.<locals>.rec_parse_order_by5  sZ    D&0 <
%j$7 KK(::(FG'3.$ KK
(8(8(:;<  Kr    r   )r)   rJ   rK   rp  r	  r4   rw   )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_evalrK   rU  r   r
  r%  r}   )rS   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']]])rT   r   testr]  )r'  r   /CmfProject:6597795c-95ce-11ea-9023-6f4fdd48682b)rq  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']]])rT   r   r  z^[['name', '=', 'test'], ['OR', ['parent', '=', 'evateam'], ['name', '=', ['test2', 'test3']]]]rT   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'  rb  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   rg  rS   r  r  r   r  s        r!   test_ubql2bqlzUbqlConverter.test_ubql2bqlT  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"]rT   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}  rU  r  r\  rg  r  r	  r{  r  rK   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   )Ir  rK  r  r  r  r   r  r   r   r   collections.abcr   r   r   	functoolsr	   typingr
   r   r   r   typesr   
contextlibr   r  redis.exceptionsr  r  r   sqlalchemy.ormr   transliterater   
cmf.fieldsr   r   cmf.util.immutablesr   r   cmf.utilr   cmf.base_errorr   r   r   r   r#   r   r  r  r2   rq   r&   r*   r7   r	  rA   rI   rC   TypeVarr   r   r  r@  rD  rb  rn   r  r  rI  rM  r   r   r    r!   <module>r     s      
  ! < < #   1 1  " 
   & " "     E   NCNN66 N-3>>55 -  

#56   5=C =v)D v)r T%K+- K+\VYAy YAxS9 S$8< 8v', 'Tu(
 u(
pQ L2 L2 L2^q2 q2j	   2 M  &` `r    