
    *`mh                       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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!T d dl#Z"d dl#T d dl$m%Z%m&Z& d dl'm(Z( d dl)Z"d dl'm*Z*  G d de"j+        j,                  Z- G d de"j+        j,                  Z.dZ/e01                    d          Z2i Z3 G d d          Z4d Z5d Z6de7fdZ8 G d de9          Z: e;dd           Z< G d! de:"          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>          ZBe G d- d.                      ZC G d/ d0          ZDej         G d1 d2                      ZEej         G d3 d4eE                      ZF G d5 d6          ZGdS )7    N)	dataclass)OrderedDictdefaultdict
namedtuple)Mapping)deepcopy)	lru_cache)IterableListDictOptional)
MethodType)	LockError)aliased)translit)*)imutable_deep_copymutable_deep_copy)cmfutil)
cmf_exportc                       e Zd ZdZdS )CmfOrmFieldsSpecErroruC   Недопустимые правила загрузки полейN__name__
__module____qualname____doc__     ./cmf/models/base_model.pyr   r      s        MMMMr   r   c                       e Zd ZdZdS )CmfOrmNotLoadedErroru"   Объект не загруженNr   r   r   r    r"   r"   #   s        ,,,,r   r"   defaultz(?<!^)(?=[A-Z])c                       e Zd ZdZdS )
_NamespacezNamespace classNr   r   r   r    r%   r%   -   s        r   r%   c                     |                                 D ]G\  }}t          |t                    r(t          |                     |i           |          | |<   B|| |<   H| S )zupdate nested dicts)items
isinstancer   _dict_mergeget)dukvs       r    r)   r)   1   s`    		  1a!! 	quuQ||Q//AaDDAaDDHr   c                 \    t                               d|                                           S )N_)_camel_to_snake_regexsublowerss    r    camel2snaker6   ;   s$     $$S!,,22444r   r5   c                 f    d                     d |                     d          D                       S )N c              3   >   K   | ]}|                                 V  d S N
capitalize).0r2   s     r    	<genexpr>zsnake2pascal.<locals>.<genexpr>@   s,      <<3>>##<<<<<<r   r0   )joinsplitr4   s    r    snake2pascalrA   ?   s-    77<<qwws||<<<<<<r   c                   p     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 ]r}t          |t                    r[|j                                        D ]A\  }}t          |t          |g          |d         |d          d| |j        d          ||<   Bst          |                                          D ]\  }}	t          |	t                    rmi }
|d         |
d<   |d         dz   |z   |
d<   |	j        |
d<   |

                    |	j                   t          |t          |	j        g          |
          ||<   ||= t          |	t                    r|	||<   ||= ||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   s    ! 
	 
	H(M22 	-5_-B-B-D-D  )J	)-"yk***3L*A/8/H,W,W:,W,W'0'8 * *F:&& **++ 	! 	!DAq!Y'' 
!%'"3<\3J"<05>~5NQT5TWX5X">201	"9-"))!(333 E16(OO5GHHq	aLLA{++ !q	aL$	(wwsD%;;;r   c                 ^    | j                             |          x}r|S t          ||           r:   )rG   r*   AttributeErrorselfitemrY   s      r    __getattr__zBaseModelMeta.__getattr__i   s5    ---9 	 T4(((r   c                    t          | j                  | _        | j        | _        g | _        i | _        di i| _        | j        st          | t                    rd}|D ],}t          | |          st          d| d| j                   -d}|D ]W}t                              |t                                 t          |         }t          | |          }||v r||         }| ||<   X| j                                        D ]]\  }}	| |	_        | j         d|	j         |	_        |	j        | j        d         |<   |	j        r| j                            |	j                   ^t+          |           D ]b}
|
                    d          r|
| j        v r"t          | |
          }t1          |t2                    rHt5          |          rX|| j        |
<   cd S )NrG   )ui_name	ui_modulecode_prefixu   Заполните поле     в классе )rc   re   rE   r0   )r6   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   #CL11
n| 	1
3	 : : 	1<F n nsE** n$%lE%l%l\_\j%l%lmmmn 1F 1 1$//tvv>>>&:5&A#U++///"5e"<K .1#E**%(Z%5%5%7%7 	; 	;!J	'*I$+.>(R(RI<P(R(RI%090ACK!*-$ ;&&y'9:::S 	 	A||C   C$$$QA!X&& {{ CKNN	 	r   c                     ddl m} | j        r| j        d         nt          }| 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   sq     	988888-0-=Uc&q))CUjnn[)) 	*,;cBBBC&)CJ{#
r   c                 @    | j         j                            |           S r:   )r   data_driverdp_modelrS   s    r    r   zBaseModelMeta.dp_model   s    v!**3///r   c                 *    t          | j                  S )u!   метаданные модели)r6   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   s         < < < < <B) ) )1 1 1f 	 	 X	 0 0 X0 ) ) X) ) ) ) )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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<   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Z-d Z.d Z/d Z0ddZ1d Z2d Z3d Z4e5d             Z6e*d             Z7ddZ8ddZ9ddZ:d Z;d Z<e*d ed!efd"            Z=e*dd$            Z>e*d%             Z?e*dd&            Z@e*d'             ZAd( ZBe*d)             ZCe*dd*            ZDdd+ZEe*dd,            ZFe*dd-eGfd.            ZHe*d-eGfd/            ZIe*dd-eJfd0            ZKe*d1eGfd2            ZLdd3ZMdd4ZNe* eOd56          d-ePfd7                        ZQe*d-eGfd8            ZRe*dd9            ZSe*dd:d;eTeU         d!eUfd<            ZVe*dd:d;eTeU         d!eUfd=            ZWe*ddd>d?            ZXe*d;eTeU         fd@            ZYe*dA             ZZe*dB             Z[e*dddCd;eTeU         d!e\eU         fdD            ZJe*dddCd;eTeU         d!e\fdE            Z]e*dF             Z^e*dddddGdH            Z_e*dI             Z`e*dd:dJ            Zae*ddKdL            Zbe*ddM            Zce*	 	 	 	 ddNeGdOedPefdQ            Zde*dR             Zee*dS             ZfddUZgdV ZhdW ZidX ZjdY ZkdZ Zld[ Zmd\ Znddd]d^Zod_ Zpd` ZqddaZrdb ZsddcZtdTddddeZudf Zvdg Zwexddh            Zydi ZzddjZ{ddkZ|dl Z}ddmZ~dddddndoZddpdqZdr Zds Zdt ZdduZddvZddwZdx Ze*ddddydz            Ze*d{             Ze*d|             Ze*d}             Ze*d~             ZdddZe*dddd            Zd Zexd             ZddZddZe*dd            Zd ZdS )r   NTFr   r#   acl_typeacl_allow_createacl_static_user_write_fieldsacl_static_owner_write_fieldsacl_static_self_write_fields	api_allow)countcreatedeleteexport2filefield_options_listr*   sgetrK   slistubql2bqlrM   upsertget_ui_full_pathget_meta)$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   essential_child_modelsdisable_auditr   api_methodscsvc                 D    | j         }t          j        ||||||          S )N)rh   field_namesbqlformat_fileinclude_archivedorder_by)rh   r   r   )rS   r   r   r   r   r   rh   s          r    r   zBaseModel.export2file$  s4    ^
%2=*-2=7G/79 9 9 	9r   c              #      K   ddl m} t          |                                          D ]+}t	          |t
                    rt          ||           r|V  ,d S )Nr   models)cmf.includer   varsr   r(   rI   rm   )rS   r   r   s      r    iter_subclasseszBaseModel.iter_subclasses.  sp      &&&&&&&\\((** 	 	E%&& :eS+A+A 	 	r   c                    |s| j         |         }|s|j        } |            }| |_        || j        |<   |st                              t          j                  }t          |t                    rB|j
        s|j        r4|                                |_        |                                |_        nt          |t                    r|j
        s|j        r||_        ||_        nt          |j        t"                    r=|j                                        |_        |j                                        |_        nt          |j        t&          t(          f          r3t+          |j                  |_        t+          |j                  |_        n>|                    |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_field6  s    	0J/I 	."-J	$)j! 	#,,x|,,C%)) 7u~ 7AS 7"xxzz XXZZ

E;// 7U^ 7uGY 7" 

EM:66 	7$}5577"]3355

EMD$<88 7#EM22!%-00

$zz%-88"ZZ66
"EOr   c                 2   | j                             |          x}rl| j        rMt          | j        |          rt	          | j        |          S |j        st          | j         d| d| |          |                     ||d          S t          ||           )NrE   u&    для тонкого объекта.Tr   )
rG   r*   simple_objectro   rt   virtualCmfOrmImplicitLazyLoadrh   r   r]   r^   s      r    ra   zBaseModel.__getattr__T  s    ---9 	@! @4-t44 ="4#5t<<< ( @0DO1r1rd1r1r1rtxz~??4$????T4(((r   c                    | j                             |          }|r| j        r(t          j                            d|  d| d|           t          |t          j         j                  r t          d| j	        j
         d| d          | j                            |d          x}du r|                     ||d	          }|                    | |           d S t                              | ||           d S )
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___  s
   KOOA&&	 		+} un>>?sPT?s?slm?s?spq?s?sttt)SZ%:;; s)*q4>3J*q*qQ*q*q*qrrr**1c222s::9DAAIIdAtQ*****r   c                     d| _         dS )u   
        Помечаем что обьект уже создан в бд
        Эту опцию нельзя использовать в бизнес логике
        TN)_BaseModel__exists_in_dbr_   s    r    mark_exists_in_dbzBaseModel.mark_exists_in_dbl  s    
 #r   c                 T   d| _         d| _        || _        | j        r,d| _         d}|r!t          j                            d| |          |                                  |s|                    d|                                            dD ] }||v rt          t          dd           ||<   !| j                                        D ]\  }}|                     |||           d| _        d| _        d| _        d | _        |                                D ]\  }}t%          | ||           d S )NTFuh   Нелья передавать поля для инициализации вместе с simple_objectid)
cmf_author	cmf_ownercmf_modified_bycurrent_personr   )is_newr   r   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__s  sk    #* 	NDKE Nn00~  AE  GMN N N 	 	3dDKKMM222C ? ?;;#A'7>>q		))++ 3 311E2222!&# LLNN 	  	 DAqD!Q	  	 r   c                 >    | j                                         }|d= |S )Nsave)r   r   )r_   r+   s     r    __getstate__zBaseModel.__getstate__  s!    M  fIr   c                 <    || _         |                                  d S 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    DG}}r   c                 *    t          |           j        S r:   )rI   r   r   s    r    r   zBaseModel.dp  s    Dzz}r   c                     t          |          t          k    s|j        }n|}|                    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  sM    Bxx3HEEE[[%%a(
CK&''
33r   c                      |du r fd j         D             S |du r fd j         D             S t           j                   S )uP   
            Ключи инициализированных полей
        Tc                 J    g | ]}|j         v j         |         j        | S r   )r   r   r=   r-   r_   s     r    
<listcomp>z"BaseModel.keys.<locals>.<listcomp>  5    aaa!a4=.@.@T]STEUE`.@A.@.@.@r   c                 J    g | ]}|j         v j         |         j        | S r   )r   
is_definedr  s     r    r  z"BaseModel.keys.<locals>.<listcomp>  r  r   )rG   rK   r_   r  r   s   `  r    keyszBaseModel.keys  sc     aaaat{aaaa4aaaat{aaaa$$$r   c                 J      fd                      ||          D             S )uo   
            пары ключ:значение для инициализированных полей
        c                 4    g | ]}|t          |          fS r   rt   r  s     r    r  z#BaseModel.items.<locals>.<listcomp>  s(    ggg!GD!$$%gggr   r  r   r  r  s   `  r    r'   zBaseModel.items  s1     hgggtyyJ[ey/f/fggggr   c                 J      fd                      ||          D             S )ug   
            возвращает списком инициализированные поля
        c                 0    g | ]}t          |          S r   r  r  s     r    r  z$BaseModel.values.<locals>.<listcomp>  s#    bbbQa  bbbr   r  r  r  s   `  r    r   zBaseModel.values  s1     cbbb$))zV`)*a*abbbbr   c                 X    	 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                 Z    	 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                 p    t                               ||           }t                              |d          S )NF)ensure_ascii)UbqlConverterr   jsondumps)rS   r!  r   s      r    r   zBaseModel.ubql2bql  s-    $$T3//zz#Ez222r      c                 :   ddl m} g d}	|s|rt          j        ||	dd          }nd|rU|rSt          j        |          }
|
s |dd           d S 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66 	n 
]+Bvtcghhh ]T ]$>wGG
! IKSWXXXXF1*==-dE&Z^nrsss	OW[\\\\ n	`hlmmmm
r   c                     t           j         G d d                      t           j         G fdd                      } |t          t          |j                            }|S )Nc                       e Zd ZdS )5BaseModel.get_automation_ui_form.<locals>.UiFormFieldNr   r   r   r   r   r    UiFormFieldr?    s         Dr   rA  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                 v                 }t          | ||           |D ]}t          ||||                    d S r:   )r   )r_   rX   rN   ui_form_fieldoptrA  s        r    r   z;BaseModel.get_automation_ui_form.<locals>.UiForm.init_field  sR     +j-888! = =CM3s<<<<= =r   c                     t                      j        |i | d| _        || _        | j        j                                        D ]/\  }}i }t          |d          r
|j        |d<    | j        |fi | 0d S )NTchoices)	rQ   r   rD  r   rG   r'   ro   rI  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11!
"
151B1H1H1J1J > >-M: Gz955 @-7-?	*#DOM==W====	> >r   )r   r   r   bool__annotations__r   r   r   )r[   rA  s   @r    UiFormrC    s]         KKK= = = = =	> 	> 	> 	> 	> 	> 	> 	> 	>r   rO  r   )dataclassesr   rt   r   rh   )rS   r;  rO  ui_formrA  s       @r    get_automation_ui_formz BaseModel.get_automation_ui_form  s    			 	 	 	 	 	 	 
		 
		> 	> 	> 	> 	> 	> 	> 	> 	> 
		>& &wvs~>>???r   c                    ddl m} dg}	|s|                     |||||d|          }|j        dk    r/|                    d|d	          s |d
|d|d|d           n@	 |                    g d           n&# t          $ r  |d
|d|d|d           Y nw xY w|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                                        }d}|j        rt          j        |j        j        d          }d|
 d|j         d| d| d|j         d|j         | d| }|S )Nr   r*  r,  r(  )r   rc   r8  rd   r9  r:  r;  
CmfProjectzPPP-PR-BROWSEF)r;  raise_error$   Объект не найден id =  ui_name =  code = Tr2  )r   rT   r8  r9  )check_fieldsr8   z&rup=0-/z/?parent_id=z&vf=z&code=z	&ui_name=#)r   r+  r<  rh   check_project_role_access_acl_check_readCmfPermissionErrorr9  r   r	  rd   is_not_nullrG   r,  rc   r3   rT   translit_stripr   r   r8  )rS   r   rc   r8  rd   r9  r:  r;  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  sn   )))))) ! 	I++r7Ybnw}~  EH+  I  IC >\)) 00cW\0]] h	ZBZZGZZQUZZbfggggh##1T1T1T#UUUU% h h h	ZBZZGZZQUZZbfggggggh MPMl/>>HH_b_l=$ 	&MMM%M  	&%M!88G+9SZ+G+Gs''S[M^M^M`M` "8 	P$+$:38>3$O$O!I- I I#& I Im I I I I]`]e I I+I'.I I1FI I
s   #A< < BB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*  )rU  CmfDocument	CmfFolderCmfTaskrW  rX  rY  Tr2  r;  )r   r+  r<  rh   r   rc   r8  r   )rS   r}   rN   r+  r;  s        r    public_get_ui_full_pathz!BaseModel.public_get_ui_full_path=  s    ))))))'c'888> "
 
 
 IVVVVVTVV^bcccc#s#T=V======r   c                     d S r:   r   r_   r}   rN   s      r    public_nonezBaseModel.public_noneM  s    tr   c                     d S r:   r   ro  s      r    public_none_classmethodz!BaseModel.public_none_classmethodQ  s	     tr   c                    d }|s|S t          |           ||          rdt          |t          t          f          rfd|D             S t	          t          |          t          j        j                  r |j	        di S n^t          |t          t          f          r|S t	          t          |          t          j
        j                  r|                                S |S )u   
        Конвертация в дикты с последующей серилизацией
        :param relation_load_only:
        :param relation_load:
        :param obj:
        :param filter_fields:
        :return:
        c                 ^   t          | t          t          f          rbt          |           dk    rOt	          t          | d                   t          j        j                  st          | d         t                    rdS t	          t          |           t          j        j                  rdS dS )Nr   TF)
r(   rK   rJ   lenrm   rI   r   r   r   
CmfRelBaser;  s    r    is_model_objz&BaseModel.asdict.<locals>.is_model_obja  s    #e}-- #c((Q,,JtTWXYTZ||]`]g]qDrDr,GQRUVWRXZdGeGe 3?tDIIsz';<< tur   rG   c                 *    g | ]} |j         d i S r   get_values_dict)r=   r   paramss     r    r  z$BaseModel.asdict.<locals>.<listcomp>p  s-    AAA))33F33AAAr   r   )rs   r(   rK   rJ   rm   rI   r   r   r   r}  rG   CmfTypeasdict)r_   r;  rG   rx  r~  s       @r    r  zBaseModel.asdictV  s    	 	 	  	JV$$$< 	 #e}-- 5AAAASAAAADIIsz';<< 5*s*44V4445dE]++ 	 JS		3:#566 	 ::<<
r   c                 8   t                      }d
d} |             ||r|                     |          }|                     d          D ]\  }}t          |r|                    |          p|          |r||vr3t          |t          j        j        t          j        j	        f          rfd|j
        D             }n@t          |t          j        j                  r|j
        r |j
        j        di }n|j        }|du rd}|||<   | j        |d	<   |S )uy   
        Функция превращает instance в dict для дальнейшей серилизации
        r(  c                     	 dt           vrt                      t           _        n# t          $ r}Y d }~d S d }~ww xY wdt           j        vr| t           j        d<   d S t           j        dxx         | z  cc<   d S )Nprofiler_data	obj_count)r   rs   r  	Exception)nr  s     r    inc_obj_countz0BaseModel.get_values_dict.<locals>.inc_obj_count  s    "!++&*ffAO   !/11/0,,,,,,1,,,,,s   !$ 
99NTr  full_fields_loadc                 *    g | ]} |j         d i S r{  r|  )r=   r;  r~  s     r    r  z-BaseModel.get_values_dict.<locals>.<listcomp>  s-    XXX2s2<<V<<XXXr   .rh   )r(  r   )r   r  r'   rs   r*   r(   r   rG   
CmfM2MBaseCmfBackrefBaser   CmfRelationBaser}  r&  rh   )	r_   rG   r  rr  rX   	field_valfield_valuer~  s	           @r    r}  zBaseModel.get_values_dicty  sn   
 MM
	2 
	2 
	2 
	2 	# A#'#8#8#@#@ %)ZZ4Z%@%@ 	( 	(!J	+;+`@P@T@TU_@`@`+tdtuuuF J6F$F$F 
 5sz7PQ  - YXXX	XXXIsz'ABB -y -=io=GGGG'nc!!"'AjMM /,r   c                 h    | j                                         }fd}t          ||          }|S )Nc                 <    | j         k    rdS | j        dk    rdS dS )NTr   F)visiblerh   )fr  s    r    filter_visiblez-BaseModel.meta_fields.<locals>.filter_visible  s,    9''4<4''4ur   )rG   r   filter)rS   r  rG   r  s    `  r    meta_fieldszBaseModel.meta_fields  sM     ""$$     NF3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
                    r-i |	d<   i |	d<   i |	d	<   i |	d
<   i |	d<   i |	d<   i |	d<   i |	d<   i |	d<   |dk    rd}t          |                                          D ]\  }
}|
                    d          rmd}|t          |
          k     r)|
|dz             dk    rn|dz  }|t          |
          k     )|
d|          }||||f<   t          ||         |          ||<   ||
= |
                    d          rt          d|
 d          |
                    d          r6||
= |
dd         }
|                    |
           |rt          d|
||          | j                                        D ]}|j        dk    r*|r(|r|j        dk    r|                    |j        i            t          |t(          t*          f          r{|                                D ]e\  }}|j        dk    s|rS|j                            |          r9|dk    r3|                    |j        i           }t-          |||df                    ft          |t.                    r|                                D ]}\  }}|j        dk    s|rk|j                            |          rQ|dk    rK|                    |j        i           }t-          |||df                    t-          |||df                    ~x|                                D ]M\  }}|j        dk    s|r;|j                            |          r!|dk    r|                    |j        i            N|D ]	}
|
|v r||
= 
|	                                D ]+\  }
}|                    |
i           }t-          ||           ,|                                D ]\  }
}| j                            |
          }|rt          |t2                    r|                                }|st
          g}i }|D ];}t7          |          }|                    |||
||            t-          ||           <|                                 t-          ||           fd! |          }|d"k    rMt<          j                             d#| d$tB          j"         d%tB          j#         d&tB          j$         d'           dS dS )(u  
        Разворачиваем мета-правила
        - вначале *, **, ***, включая <prefix>*, ... - пока маски только для префиксов
        - затем -field_name
        - затем +fild_name - deprecated
        --Fr   r9  
project_idcmf_owner_idrT   r8  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_cacher-  Tr   r   r(  N+u   Синтаксис +field u)    устарел, используй fieldr[  u=   У "-" не может быть вложенных полейalwayslogic_prefixlazy      )fields_is_lazyrelation_field_nameauto_fieldshack_parent_noalwaysc                 j    d}|                                  D ]\  }}|dz  }|r| |          z  }|S )Nr   r(  )r'   )_BaseModel__fieldscr-   r.   _BaseModel__field_counts       r    __field_countz4BaseModel._fields_load_expand.<locals>.__field_countB  sP    A (( * *1Q *q)))AHr     u_   DEV: WARNING. В запросе используется слишком много полей: uC   . Возможно, где-то используется ** method=z args=z kwargs=)
debug_only)%r   intrs   rm   CmfModelrn   rK   r'   endswithru  maxry   CmfDeprecatedErrorrw   r   rG   r   	load_moderh   rr   r  r  r)   r  r*   rv  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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!$'' 	N "K Nc8,, 5/1K,02K- 35K/c9-- N*,K'*,K'13K.68K 23;=K 789;K 5646K 01:<K 67KMK GH (**#'  '+6<<>>&:&: 	Q 	Q"J
""3'' QC
OO++!CE(+s221HC C
OO++ $EcTE* 1;}-*-of.Es*K*K':&&&s++ Q(){j){){){|||&&s++ QJ''^
##J/// Q/0oq{  ~H  JP  Q  Q  Q Z&&(( 	@ 	@E(**{*DX*\a\lp~\~\~!!%"2B777%*n!=>> @ -<,A,A,C,C M M(FL611V1 % 0 ; ;F C C 2HTXYHYHY%+%6%6u7G%L%L
#J{0KLLLM E?33 @,;,A,A,C,C M M(FL611V1 % 0 ; ;F C C 2HTXYHYHY%+%6%6u7G%L%L
#J{0KLLL#J{0KLLLM -<,A,A,C,C @ @(FL611V1 % 0 ; ;F C C 2HTXYHYHY))%*:B???@ ' 	' 	'JV##:& ,7+<+<+>+> 	5 	5'J**:r::J
O4444 '-llnn 	8 	8"J
JNN:..E 8E:66 8 &+%9%9%;%;") 5*3&!#%7 @ @M &.j%9%9N!55nUc  zD  R]  tH5  I  I  I????  """J777	 	 	 	 	 $mF++ K!! #c  EP #c #c,-L#c #c@A
#c #cTUT`#c #cos " u u u u u r   c                 n   t          |                                          D ]d\  }}|                    d          \  }}}||k    r@|                    |i                               |i                               |           ||= e|                                D ]}|r|                     |           dS )u   
        Структурируем плоские имена полей.
        Например: {field.sub_field...: {}} => {field: {sub_field: {...}}}
        rE   N)rK   r'   	partitionrr   rM   r   _fields_split)rS   rG   full_field_namer  rX   r0   sub_field_names          r    r  zBaseModel._fields_splitR  s     ,0+?+? 	, 	,'OZ,;,E,Ec,J,J)J>_,,!!*b11<<^RPPWWXbccc?+ --// 	. 	.J .!!*---	. 	.r   c                 R   ddl }|                                 }|rg }nt          j        }d |p|D             }|                     |           |s|                     ||           |                                 |z
  }|dk    r$t
                              d| d|dd	|             |S )
u  
        Преобразуем список правил загрузки полей, во вложенную структуру,
         которая содержит имена полей для каждого уровня.

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

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

        :return: Структура загружаемых полей.
        :rtype: dict
        r   Nc                     i | ]}|i S r   r   )r=   
field_rules     r    
<dictcomp>z.BaseModel.full_fields_load.<locals>.<dictcomp>{  s    QQQ*z2QQQr   )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tree_fieldsdurations	            r    r  zBaseModel.full_fields_loadc  s    " 	99;; 	7NN#6NQQ8P.QQQ+&&&  	P##K#OOO99;;)c>>GGeFeeeee`ceefffr   r  c                 &   g }| j                                         D ]2}|j        |v r'|                    |                                           3|r%|                     |          }t          ||           |                                D ]\  }}|                    |          }|s| j                             |          }|rMt          |t                    r8|                                }|st          g}|D ]}	|	                    |           dS )uF   Рекурсивно добавим _id поля, если нужно.N)rG   r   rh   extendget_required_fieldsr  r)   r'   r*   rm   rv  r  rn   _enrich_load_plan)
rS   r  required_fieldsr~   required_fflrX   r  	field_fflr  r  s
             r    r  zBaseModel._enrich_load_plan  sA    Z&&(( 	D 	DE#333&&u'@'@'B'BCCC 	8//@@L(,777&6&<&<&>&> 	? 	?"J
(,,Z88I JNN:..E ?E:66 ?%*%9%9%;%;") 5*3&%7 ? ?M!33I>>>>	? 	?r   c                 D     | 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&IIIr   c                    ddl m} | j        st          d| j                    dS t          |          }dt          dt          ffd | |          rdS | j        st          d           dS t          |          | j	                 
                    | j        d	|||
          }|fdt          dt          dt          ffd | |           | S )u   
        Прогрузим поля по правилам fields
        Вложенные объекты уже могут быть прогруженны, важно догрузить только то, чего не хватает.
        r   r   uB   SKIP!!! попытка _load_fields при not __exists_in_db. id=Nr   fflc           	         d}|                                  D ]}||v r| |         }|j        du rd}t          |t                    r%|j        r |j        ||                   r||= Qd}Tt          |t
          t          f          r0d}|j        D ]%} |t          ||                             sd} n&t          |t                    rJ |S )u   
            Проверим всё ли загружено рекурсивно. Уберём из ffl, что грузить не требуется.
            Вернём True, если всё загружено
            T.FN)	r  r   r(   r  r   r  r  r   rv  )r   r  loadedrX   r~   list_loadedrel_instance	strip_ffls          r    r  z)BaseModel._load_fields.<locals>.strip_ffl  s   
 F&mmoo A A
$$$Z0EzS((!& !%99 A ; /(yc*oFF /$'
OO).#EJ+GHH 
A&* -2K & &L#,9\8C
O;T;T#U#U &). %& $.eZ#@#@@@@Mr   uL   fSKIP2!!! попытка _load_fields при not __exists_in_db id={self.id}T)include_deleted_oncer  r0  r1  dst_instancesrc_instancec           
      x   t          |                                          t          |                    d                    z
  }|t          |                                          z  }|rt          d|           |                    d          D ]%}||         }| |         }|j        du r|j        |_        |j        du rqt          |j        t          t          f          rt          |j                  |_        n|j        |_        t          |t                    r|                                 t          |t                    r|j        r,|r)|                    |                    |i                      |r>|j        |j        k    r. 	|j        |j        |                    |i                      *|r)|                    |                    |i                      Wt          |t          t           f          rd |j        D             }|j        D ]}|j        j        |v r@ 	|||j        j                 |                    |i                      ||j        j        = P|j        r)|                    |                    |i                      t          |t$                    rJ 'dS )un   Если поле изменилось, то доводим новое значение до кондиции.Tr  ue   DEV: merge_fields поля запросили для загрузки, но не загружены: .)r  c                 (    i | ]}|j         j        |S r   r   r   )r=   src_is     r    r  z@BaseModel._load_fields.<locals>.merge_fields.<locals>.<dictcomp>
  s    $X$X$XuUX^U$X$X$Xr   N)r   r  printr   r   r   r(   rK   rs   r   r  apply_changesr  r   r  r*   r  r   rv  )
r  r  r  missing_fieldsrX   	src_field	dst_fieldsrc_instancesdst_imerge_fieldss
            r    r  z,BaseModel._load_fields.<locals>.merge_fields  s   
 !__s<3D3DPT3D3U3U/V/VVN+c,2C2C2E2E.F.FFN O}  @N  O  O  O*//4/@@ *A *A
(4	(4	#s**'0I$>S((!)"2T4LAA :)-i.>)?)?	)2)9	!)Z88 2!//111i99 A + L$ L%22377:r3J3JKKK$ LIO)K)K(L )$'GGJ$;$;= = = = = ' L%22377:r3J3JKKK	J+GHH A$X$X	$X$X$XM!* 	L 	L 8>]::(L %}UX^'D$'GGJ$;$;= = = = !.ehn = =(3 L % 2 2377:r3J3J K K K	L  *)Z@@@@@@U*A *Ar   )r   r   r   r  r   r   r   rs   r   rh   _get)	r_   r  r0  r1  rN   r   new_instancer  r  s	          @@r    r  zBaseModel._load_fields  sY   
 	'&&&&&" 	`W[W^``aaaF,-=>>		 	 	 	 	 	 	 	@ 9T+,, 	F " 	-`aaaF  <<8==dEUgv+ > - -L -3	A 3	A'3	A7@3	A3	A 3	A 3	A 3	A 3	A 3	Ah 	T<(((r   i  )maxsizec                 x    |                      |          pi }|                     |           t          |          S r:   )r  r  r   )rS   rG   r  s      r    _build_load_plan_for_tuplez$BaseModel._build_load_plan_for_tuple,  sA     //77=2.///!"2333r   c                 N    t          |          }|                     |           |S r:   )r   r  rS   rG   s     r    _build_load_plan_for_dictz#BaseModel._build_load_plan_for_dict3  s(    "6**f%%%r   c                     t          |t                    r|                     |          S |                     t	          t          |pg                               S )u7   Готовим и возвращаем full_fields_load)r(   rs   r
  r  rJ   sortedr	  s     r    r  zBaseModel._build_load_plan:  sS     fd## 	O0088811%v|8L8L2M2MNNNr   ry  rS   c                   d}|r"|D ]}d|v r|                      |          rd} n |r | j        |d|i|}|r|d         S dS | j        r|sg }d|vr|                    d           |                     |          } | j        |d|i|S )	x   
        fields - список мета-правил для указания какие поля грузить
        F__TrG   r   Ncmf_ver_head2cur_idr  )_allowed_field_funcsrK   cmf_verrw   r  r  )rS   rG   r}   rN   aggregate_selectrX   resr  s           r    r*   zBaseModel.getB  s    
 ! 	$  
:%%//
;; +/( 	#(D::6::C 1v4 ; 	5 $F223444//77sxK0@KFKKKr   c                P   | j         r|sg }d|vr|                    d           |                     |          }|                                D ]I}t	          | |d          }|st	          |dd          r"t	          |dd          r | j        |d|i|c S J | 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     ; 	5 $F223444//77 +//11 	? 	?JCT22E ui// ?GEC[]a4b4b ?sw>V>v>>>>>sx0@\\U[\\\r   )r  r  c                   d| j         v r-|                    d          s|s|                    dd           |rn|D ]k}t          | |d          }t          |dd          rGt          j        s|j        t          _        Bt          t          j        |j                  t          _        l | j        j        |d|i|}| j	        rT|rRt          |j                                      | j         d          }|r!d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        }	|	rnd|	v rj| t&          j        k    rZt+          t&          d          rEt&          j                            |	dg          }
|
r!dd	|
j        g|d
<    | j        j        |d|i|}|sd|v r|                    d          }	t!          |	t"                    r|	j        }	|	d|	v r| t&          j        k    r[t+          t&          d          rFt&          j                            |	dg          }
|
r!dd	|
j        g|d
<    | j        j        |d|i|}nt| t&          j        k    rnc|sa|	                    d          d         }|                                r2t          |          dk    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_deletedr0  FNr  r  z:Hr   r   r  r  r   r8  r  r[  CmfTaskCodeHistorytask_id)r8  rG   LIKEz%-r   )rG   r*   rr   rt   r   jscache_timelifer  minr   r  r  r   ry   rh   r  ru  r(   r  r   r   rl  ro   r  r   r  popr@   isdigit)rS   r  r  r}   rN   rX   r~   instis_linkr8  task_code_historycode_numbers               r    r  zBaseModel._getw  s    CJ&&vzz:K/L/L&Ui&mU333 	c. c c
Z665":DAA c- c-2-I**-01CUEa-b-b*svz@$4@8>@ @ ; 	O4 	O$'ll--.C.C.CDDG O$(#t/G#Hx !svzNN3CNvNN
  		^F**s6(3C/D/D/I/IfU]N^_`NaekNkNk(#A&D$(( "z ^t&.((WV=Q-R-R((.(A(F(FDZcYd(F(e(e%( ^,0#7H7P+Qx()svz4]BR]V\]] 	b&((::f%%D$(( "z
 C4KK &.((WV=Q-R-R((.(A(F(FDZcYd(F(e(e%( ^,0#7H7P+Qx()svz4]BR]V\]]F555   b&*jjoob&9&..00 bS5E5E5I5I06@R[@R@R/SF8,#-36:t#aFV#aZ`#a#aDr   c                     t                      }|s|S |D ]B}d|v r<|                    d          \  }}||vrg ||<   ||                             |           C|S )Nr  )rs   r@   rw   )rS   rG   resultrX   funcs        r    _parse_aggregate_fieldsz!BaseModel._parse_aggregate_fields  sz     	M  	0 	0Jz!!#-#3#3D#9#9 jv~~#%F4Lt##J///r   c                 J    g d}|                     d          \  }}||v rdS dS )N)sumavgr   r   r  r  TF)r@   )rS   rX   allowed_funcsr)  s       r    r  zBaseModel._allowed_field_funcs  s:    ===%++D11j=  4ur   c                    t           j                            d          st          j        t          j        k    rd S d|v r|                    d          \  }}d }|                    d          r$t          | |	                    d          d           }|st          | |d           }|r"|j
        sJ d|j         d|j         d            d S d S )	NFrV  r  r   _idu%   Группировка по полю (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CC 	qGW[\[jGjGjF:$.$4$4T$:$:!Izt$$ 	AC!2!25!9!94@@E 	3CT22E 	O.  O  O  1OX]Xh  1O  1Okpkx  1O  1O  1O  O  O  O	O 	O O  Or   )rG   r  c                z   |}|s$|r"|D ]}d|v r|                      |          rd} n |rld|vr|                    d           |r|D ]}||vr|                    |           |D ]}|                     |           |                     |          }|d= n|                     |          } | j        ||||d|S )r  r  Tr  r   )r  r  r  )r  rw   r9  r  r  _list)rS   rG   r  r}   rN   r  rX   r  s           r    rK   zBaseModel.list  s>   
 $ 	F 	$  
:%%//
;; +/( 	<6!!d### 2"* 2 2J!//j111$ 4 4
''
3333"33F;; &&"33F;;sy$1AHgw  C  C  |B  C  C  	Cr   c                8   |}|s$|r"|D ]}d|v r|                      |          rd} n |rld|vr|                    d           |r|D ]}||vr|                    |           |D ]}|                     |           |                     |          }|d= n|                     |          }|                                D ]I}t          | |d          }|st          |dd          r"t          |dd          r | j        |d	|i|c S J | j        ||||d
d|S )r  r  Tr  r   Nr   Fr  rG   r  )r  r  r  r  )	r  rw   r9  r  r  r  rt   rK   r;  )	rS   rG   r  r}   rN   r  rX   r  r~   s	            r    r   zBaseModel.slist  s    $ 	F 	$  
:%%//
;; +/( 	<6!!d### 2"* 2 2J!//j111$ 4 4
''
3333"33F;; &&"33F;;*//11 	@ 	@JCT22E ui// @GEC[]a4b4b @sx?f??????sy$1AHgw  AI  T  T  MS  T  T  	Tr   c                 >   t          | d          r+|                    d          s|                    dd           t          | d          r@|                    d          s+|                    d          s|                    dd           t          | d          r+|                    d          s|                    dd           t          | d          rF|                    d	          s1| j        pg }|                    d	|                                           |S )
Nr  r0  Fcmf_archivedr   is_dummyr1  orderingr   )ro   r*   rr   r@  r   )rS   _kwargsorder_fieldss      r    _default_kwargszBaseModel._default_kwargs)  s(   3&& 	5w{{;L/M/M 	5}e4443'' 	6<N0O0O 	6X_XcXcduXvXv 	6~u5553
## 	2GKK,H,H 	2z5111 3
## 	@GKK
,C,C 	@<-2Lz<+<+<+>+>???r   )r  r  include_veronly_ver_headc                   |                      |          }|rn|D ]k}t          | |d          }t          |dd          rGt          j        s|j        t          _        Bt          t          j        |j                  t          _        l|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  )	rC  rt   r   r  r  r   r  r   rK   )
rS   r  r  rD  rE  r}   rN   rX   r~   	inst_lists
             r    r;  zBaseModel._list8  s)    $$V,, 	c. c c
Z665":DAA c- c-2-I**-01CUEa-b-b* 	F; 	t h} hAGg&"<"<"<==MgMgMg tGMs&"B"B"BCCSsSsSsCFK8HQWbb[abb	r   c                 6    t           | j        |i |          S r:   )rM  r   rS   r}   rN   s      r    existszBaseModel.existsS  s#     ICIt.v..///r   c                N    |                      ddg          } | j        |d|i|S )r  r  r   r  )r  _count)rS   rG   r}   rN   r  s        r    r   zBaseModel.countX  s9    
 //t==sz4M2BMfMMMr   r  c                X    |                      |          } | j        j        |d|i|}|S )rG  r  )rC  r   r   )rS   r  r}   rN   rets        r    rP  zBaseModel._count`  s:     $$V,,cflDN3CNvNN
r   c                      | j         |fi |S )u  
        Метод-обёртка field_options_list для вызова с подстрокой поиска, чтобы избежать кеширования на фронте.
        Сейчас фильтрация идёт на фронте, строка поиска не передаётся. Вероятно этот метод никогда не понадобится.
        )r   )rS   r  searchrN   s       r    field_options_searchzBaseModel.field_options_searchj  s      &s%&9DDVDDDr   models_filtersall_optionsrT  c                 J
   | j                             |          }|st          d| d|  | |          |sg }g }|rd|d<   t          |t          j         j                  r|pt          |dd          }|rd |D             }n|                                }|s'dd	g}t          j        	                    d
| d           d}|rIt                      }|                                D ]\  }}t          |||           t          |          }d}d}|rXt          j                            ||ddg          }|r2|j        r+t"                              |j        j                  }|j        }|                    d          r_t          j                            | j        |ddg          }|r4|2|j        r+t"                              |j        j                  }|j        }||j        }|j        }|r0|.t0                              d| j         d| d|d|d           g S d}|D ]}|r|}nP|pi                     |j                  }|	|j        p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    r1|
r/d*|
v s#t?          tA          j!        d+ |
                    rd| d*d,| gg} |j        d-k    r|d.k    r~d| d/dd| dgd0dd| dgd1d| dgd2d| dgd3dd| dgd4dd| dgd5dd| dgd6dd| dgd7dd| dgd8dd| dgd9d| dgd:dd| dgd;d| dgd<d| dgd=d| dgd>dd| dgg} |j        d)k    rNt=          |          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} || g} |j"        dE||dA|}"tG          |d         |z
  d          }#tI          |dB         |d         z
  t=          |          z
  |"          }$|#|#|$z   g}%||"z  }|%d         |"k    r|%                     |j&        dE|
||%|	|dC|           t=          |          |dB         |d         z
  k    r nnt          dD| d|  ||           |S )Fu  
        Метод для получения списка значений для выбора во фронтенде
        :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_limitNc                 8    g | ]}t          t          |          S r   )rt   r   )r=   
model_names     r    r  z0BaseModel.field_options_list.<locals>.<listcomp>  s"    !i!i!i*'&*"="=!i!i!ir   r   d   zfield_options_list u0    без slice, показали первые 100)SELFoptions_list_bqloptions_list_bql_exclusive)r-  rT   rG   cf_)cmf_model_namerT   rG   z%sz.field_options_list(z): require_field_filter=z and field_filter=z is None, return []
cmf_hiddenOR)rc  r   F)rc  r   Nr  rT   ILIKE%z% r8  rl  parent_taskzparent_task.nameANDr  INz	task.epicztask.subproject	CmfPersonrolesc                 ,    |                      d          S )Nzroles.ry   )r  s    r    <lambda>z.BaseModel.field_options_list.<locals>.<lambda>%  s    Q\\(=S=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)r  filter_contextr(  )rG   r  slicer   r  u)   Некорректный тип поля r   )'rG   r*   rp   rm   r   rv  rt   r  r  r+  r%   r'   r   rs   r   CmfCustFieldConfFieldr_  r&  loadsr   r`  ry   CmfCustFieldrh   loggingwarningdefault_options_filterro   r   ninja_reversru  anybuiltinsr  r   r  r   r  rK   )&rS   r  	object_idobject_fieldsmodels_listcust_field_conf_idrV  r  require_field_filterr   rG   r  rW  rT  include_hiddenrN   r~   resultsrZ  r  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_listr  s   $ 
233 	@d9Ldd_bddfik~ 	F 	,'+F#$eSZ233 \	t'2'fgeE_ae6f6f$' 8!i!iPh!i!i!i!&!5!5!7!7 CC%%  'B<O  'B  'B  'B  C  C  C!N 7'\\
+1133 . .FQJ1----!%:!6!6!6  L%)" " b )/(D(H(H-4G.0LM )I )O )O% ) b,= b'+zz2G2X2^'_'_1F1a.
 #--e44 	W#044#&>8K.0LM 5 O O
  W#+
0K+'+zz*2M2S'T'T1;1V.
 #$5).)I&# (< ~ W W;N W W,W W4@W W WX X X 	  O# @ @) u#/LL %3$8b#=#=al#K#KL#+'('?'E2 >(4f'=# D(4l'C) uwq,/G/G u(4t=W=W=WYrYrYr6s't ]A ")!5f!=!=J6{{Q)-$g&|||<$g~F~~~>$g*/?/?/?@$g/AJ/A/A/AB$g&|||<$g~F~~~>) *.$g}6}}}=$g/@:/@/@/@A$g}6}}}=) |y005HM5Y5Y/3/-f---H/:Kj:K:K:KL6 /+
 !)"!4"0$FW8X!Y) 33" 4#v--"8?3S3SU[#\#\]] . !)$h>)@
 |z116IX6U6U ),g}6}}}E('=v===A,g&|||D('f<<<@-wFF-wFF3Wm&mmmL-wFF*G]]]]C)7MMMMB#Wlll;+Wm&mmmD('f<<<@*G\\\B'V,,,?%wF>%)* |{22v;;?? $ -!%%,g&|||$D%,g~F~~~$F%,g&|||$D%,g~F~~~$F	!"	-MM !% -!%%,g}6}}}$E%,g}6}}}$E!"-M %1-#@L%agc\.cc\bcc!%(_"<a@@"58eAh#6W#E{SS*K,,FG;.q>K//AF A%l+X`'5A A9?A AB B B w<<58eAh#666E 7 fffadffhmorsssr   c                 t   |                      |d                   }t          ||          }|D ]}t          t          j        j                  |d                             d          d                                       |d                   }|                    |           |                    d           d S )Nr   r  r   r(  depth)	r*   rt   r   r   r  r   r@   rw   r   )rS   leftr  
right_listr;  r~   r`   item_objs           r    m2m_add_valueszBaseModel.m2m_add_valuesm  s    ggd4j!!011 	  	 DCK.//T
0@0@0E0Ea0HIMMT
 H LL"""JJQJ	  	 r   c                 2    | j          dt                       S )Nr  )rh   uuid1r   s    r    r   zBaseModel.gen_idx  s    .,,577,,,r   r   c                    |dk    s| j         sdS d| _         |                     d          D ]S}|j        s1t          |j        t
                    rt          |j        dd          r:|                    |dz              TdS )ub   
            сброс состояния объекта после сохранения
        r(  NFTr  r   r  )r   r   r   r(   r   r   rt   flush)r_   r  r.   s      r    r  zBaseModel.flush|  s     199DO9F-- 	% 	%A9 AGY!?!? GAGUhjnDoDo GG%!)G$$$$		% 	%r   c                       fd                      d          D             } fd|D             }|r                     |           d S d S )Nc                 B    g | ]}t          |          j        d u |S ).)rt   r   r  s     r    r  z2BaseModel._load_changed_fields.<locals>.<listcomp>  s1    XXX74;K;K;PTW;W;W!;W;W;Wr   Tr   c                 Z    g | ]'}t          t          |          t                    %|(S r   )r(   rt   r  r  s     r    r  z2BaseModel._load_changed_fields.<locals>.<listcomp>  s2    VVVJwtQ7G7G,T,TV!VVVr   )r  r  )r_   rG   s   ` r    _load_changed_fieldszBaseModel._load_changed_fields  sr     YXXXTYY$Y77XXXVVVVVVVV 	%V$$$$$	% 	%r   c                     d S r:   r   r_   rA  s     r    before_save_hookzBaseModel.before_save_hook      r   c                     d S r:   r   r  s     r    before_save_data_hookzBaseModel.before_save_data_hook  r  r   c                     g S r:   r   r   s    r    save_preload_fieldszBaseModel.save_preload_fields  s	     	r   c                 *   dd l }|                                 }|                                 }|r|                     |           |                                 |z
  dk    r4t                              d|                                 |z
              d S d S )Nr   g?zPROF save_prepare got )r  r  r  r   r  )r_   r  prof_str  s       r    save_preparezBaseModel.save_prepare  s    ))++"6688 	2011199;; 3&&GGDTYY[[7-BDDEEEEE '&r   c                     d S r:   r   r   s    r    check_edit_permzBaseModel.check_edit_perm  r  r   c                     d S r:   r   r   s    r    check_delete_permzBaseModel.check_delete_perm  r  r   )	only_dataemitc                6   |                                  D ]}|j        durt                              t          j                  }t          |t                    r |j        r|	                                |_
        t          |t                    r|j        r||_
        | j        rXt          |t                    r |j        r|	                                |_
        t          |t                    r|j        r||_
        t          t          dd           }|rwd| j        v r| j        j        du r|j        | _        | j        r#d| j        v r| j        j        du r|j        | _        | j        r#d| j        v r| j        j        du r|j        | _         | j        |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   cmf_author_idr   r  
_save_data)r_   r  r  r}   rN   r~   r   r   s           r    _save_importzBaseModel._save_import  s    [[]] 	& 	&E|3&&,,x|,,C%)) )en )!hhjj%-- "%. "!{ &eW-- -%2D -"%((**EKe[11 &e6H &"%EK $4d;; 	6 DK//D4K4RVY4Y4Y*8*;'{ 7|t{::t?UY\?\?\%3%6"{ 6{dk99dn>SWZ>Z>Z$2$5!t:4:6:::r   c                      ddd fd
}|S )NF)r  save_importc                 4   j         r#t          j                            d d          t	                    }|t
          j        v rR| r j        dd| i|S t          	                    dd
                    t          j                                         S 	 t
          j                            |           d_                            d          D ]d}|         j        rt#          |         j        t          j        j                  s;|         j        |         j        k    rd|         _        et
          j        rd} t
          j        s| s|rodt
          _         t1                    j        g|R dt
          j        i|}| rdt
          _        |                    d	d          r0t5          t6                    rj        r                                 t5          t:                    r`t=          d
          rj        sIt=          d          rj         s2j!        r"                    d           n"                                 t5          t6                    r#                    d           |rBdt
          _        $                                 j!        rd_%        &                                 n t1                    j        g|R ddd| $                                 t
          j'        dk    rPt5          t6                    r'j!        sj(        j        r)                                 *                                  j+        di | d_,         t1                    j-        g|R d| i| j,        st]          d          d_!        t
          j        /                    |           d_        n+# t
          j        /                    |           d_        w xY w0                                 S )Nr   z is readonly, try save()r  z(BaseModel.save(): skip recursion save %s
Tr  Fr  r?  is_templateinsertinitiator_actioncelery)r  
invalidatez@BaseModel.save_with_flush(): _save_data do not run during save()r   )1r   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  ro   r?  r  r   project_notifymark_full_searchr  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_flush  sf   } pn>>?nPT?n?n?nooo
 hhG!000 J +4?IIYI&IIIGS\SiSkSkIlIlmmmd/&**7333)-& d33 2 2AAw) ! %d1g&79KLL ! Aw~a55-1Q* ( & %I( F(I F( F(,0A)-T

-deTeeeQEZe^deeA  @05- "::fd33 (
48S8S (X\Xg ( IIKKK%dH55 6)0z)B)B6GK}6)0})E)E6JNJZ6  ${ 6 $ 3 3X 3 N N N N $ 3 3 5 5 5%dI66 @ 111???" ,05-))+++; 837D0))+++& *DJJ)$bbbRWbb[abbb %%''',44 &dI66 1DK 14;Ka 1 ..000,,...)D)33F333+0D(#DJJODO4OOO9OOOO/ t)*lnrsss
 #(DK&--g666).&& &--g666).&....JJLLLKs   LO (Pr   )r_   r  r  s   `  r    save_flush_wrapperzBaseModel.save_flush_wrapper  s;    -2 x	 x	 x	 x	 x	 x	 x	r r   c                 D    |                      | j                  | _        d S r:   )r  r   r   s    r    r   zBaseModel.wrap_saveV  s    ++DI66			r   c                    | j                             |          }|                     d          D ]}|j        dv r|j                            d          r"|j        dk    s|j        dk    s|j        dk    sH|j                            d	          rct          |t          j        j	                  rt          ||j        |j                   |S )
Nr8  Tr  )r8  r   cmf_created_atr   r   systemperm_perm_encryptperm_encrypt_helpperm_policyr1  )r   r   r   rh   ry   r  r(   r   rG   r   r   r   )r_   r8  r  r~   s       r    clonezBaseModel.cloneY  s    gmmm&&[[D[11 	8 	8E#hhh**733 $66'+>>>'=88((// %!677 C)5;7777
r   c                     dS )u4   
        Вычисляем кеш поля
        Nr   r   s    r    _update_cache_fieldszBaseModel._update_cache_fieldsl  s	     	r   c                      | j         dddi|}|r/t          |           t          j        vr|                                  |S )u'   Метод вместо save(only_data)r  Tr   )r  r   r   r  r  )r_   r  r  rN   r;  s        r    	save_datazBaseModel.save_datar  sM     do77777 	RXXQ%;;;JJLLL
r   )r  r  c                n    d|f fd	}ddl }|                                 }                                   j        r j        nd}	  j        s8d _         t	                     j        j         g|R i   |||           nD                                   |||            t	                     j        j         g|R i  n# t          $ rC}	ddl
m}
  |
d	| d
 j         dd           t                              |	           Y d}	~	nGd}	~	wt          $ r7}	ddl
m}
 t                               |	            |
dd           Y d}	~	nd}	~	ww xY w|                                 |z
  }|dk    r5t%          d|dd j         d j         dd j        v o j         d	           d _         S )u)  
            Финальное низкоуровневое сохранение в базу
            Умышленно не разделяем save() на update() и create(), т.к.
            обычно в бизнес-логике очень много общего кода.
        Fc                    d}d}||k     rʉ                     d          D ]}t          |t          j        j                  rV|sTd}j        r&t          j        j                            d           n%t          j        j                            d           dv r |	                    || d         d           |	                    || d	           d S d S )
Nr(  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9 [ [E!%)>?? 
M
  / M.2O#{ M # 1 < <T8 L L L L # 1 < <T8 L L L6))

)FS[L\nr
ssss

)UY
ZZZZ# ! [ [r   r   Nu   объектаT)r  r  r*  u   Код  uS    уже существует. Укажите уникальное значение.r2  uA   Нарушение ограничения целостности.r(  z&!!! --- _save_data::duration too long .1f sec, r2  , r8  ))r  _acl_check_writeverbose_namer   rI   r   r   r  rM   CmfOrmUniqueErrorr   r+  r8  r  	exceptionCmfOrmIntegrityErrorr   r  r  rh   r   rG   r   )r_   r  r  r}   rN   r  r  startr  r  r+  r  s   `   `       r    r  zBaseModel._save_dataz  s    ',5 	[ 	[ 	[ 	[ 	[ 	[ 	[0 			,0,=St((CS	h& <&*#$T

$T;D;;;F;;;)5AAAAA ))+++)5AAAA %T

$T;D;;;F;;;  	! 	! 	!------ I  N  N  Nty  N  N  N  VZ  [  [  [  [a        # 	h 	h 	h------GGAJJJ IZbfggggggggg	h 99;;&a<<ZL Z ZOZ Z&*gZ Z28DK2G1VTYZ Z Z[ [ [  $s%   	BC 
E9DE"-EEc                    |                                  D ]}|j        durt          j        rt                              t          j                  }t          |t                    r |j
        r|                                |_        t          |t                    r|j
        r||_        | j        rb|j        durt          |t                    r |j        r|                                |_        t          |t                    r|j        r||_        t!          t          dd          }|rd| j        v r2t          j        rt          j        r| j        j        du r|j        | _        | j        r#d| j        v r| j        j        du r|j        | _        | j        r#d| j        v r| j        j        du r|j        | _         | 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  )r_   r}   rN   r~   r   r   s         r    r   zBaseModel.save  s   
 [[]] 	& 	&E|3&&1=&,,x|,,C%)) )en )!hhjj%-- "%. "!{ &<s**eW-- -%2D -"%((**EKe[11 &e6H &"%EK $4d;; 	6 DK//} @ @$:Q:X\_:_:_.<.?D+{ 7|t{::t?UY\?\?\%3%6"{ 6{dk99dn>SWZ>Z>Z$2$5!"",,V,,,t////r   c                 `    |                                   | j                                         | S r:   )r   r   commitr   s    r    _test_save_commitzBaseModel._test_save_commit  s&    		r   c                      t          d          )uw   
        Формируем кеш словарь связи объектов по parent_id и tree_parent_id
        
Deprecated)r  r   r   r   r  r   r3  CmfAccessRule
CmfCommentr  r   r   rt   sysinternr9  r  r   tree_parent_id)r0  rY  r1  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|                                 d}|j        | j        v rd|d<   	 t          	                    d|             |j
        dddi| n"# t          $ r t          j                    } w xY w	 t          j        j        | j        k    r |j        |  d S d S # 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_   r;  rN   r  r  s        r    _delete_child_objectzBaseModel._delete_child_object  s+    )++$"333!!####
 >T888)-F%&	0GGICIIJJJCJ,,T,V,,,, 	 	 	|~~H	 -
 "d&777$$h//// 87q"d&777$$h/// 8s   ,B C B$$C 'C7c           	      :   |p|}|p|}|p|} | j         d||||d|}t                      }| j        j        h}|rUt                      }	|D ]@}
|
|v r:||
         D ]1}||v r|                    |           |	                    |           2A|	}|Ut
          j        j        j        	                    dgdd|gddd          D ]} | j
        |f||||d| |D ]?}t
          j        j                            |dg|          x}r | j
        |f||||d| @d S )	Nr0  TEXKOM_db_deleterY  r1  r   r9  ri  T)rG   r  TECHCOM_nocacherY  r0  )rG   r0  r   )r  r   r   r   r  r   r  r   r  rK   r  r   r4  )r_   r   r0  rY  r1  rN   relation_cachechildren_id_setlevel
next_levelr9  child_idcommentchilds                 r    %_depricated_children_recursion_deletez/BaseModel._depricated_children_recursion_delete  s   *=o);^(9M33 3+>N_m'3 3+13 3 %% 		J" 1 1	..$29$= 1 1#66$'++H555"x0000E  		 {)499uk4%I[_#T : ; ; 	l 	lG &D%g laq5CS`l ldjl l l l ( 	p 	pH+99(C5bq9rrru p))% pcs9GWdp phnp p p	p 	pr   c                     	 pppdfd	d fdddt           dt           f	 f	d  j        j        f            	 j        j        g          } |           d S )	Nid_listr
   c           	         t                      }t          j        j        j        t          j        j        j        t          j        j        j        f}t                                          D ]}g }||v r
t          |d          r|
                    dd| g           t          |d          r0|r|                    dd           |
                    dd| g           |su|                    g dd|          D ]|}t          |dd           r,|                    t          j        |j                             t          |dd           r,|                    t          j        |j                             }|S )	Nr9  ri  r  r   rd  r  r   r9  r  T)rG   r!  r0  rY  r  r1  )r   r   r  r   r3  r  r  r  r   ro   rw   r  r   rt   r  r  r  r   )	r+  new_id_listr  r   _filterr  r0  r1  rY  s	         r    list_children_idsz?BaseModel._children_recursion_delete.<locals>.list_children_idsA  s   %%K K&4K&4K&1K "1133 A AK''5+.. ANNKw#?@@@5"233 F /q...NN$4dG#DEEE  %3^3^3^pt<K\jsz:G !, !I !I A AH xd;; A#
8;(?(?@@@x)94@@ A#
8;(?(?@@@A r   c           	          t           j        j        j                            dgdd| gddd          D ]} j        |fd d S )Nr   r9  ri  T)rG   r  r!  rY  r0  r1  r  )r   r  r   r  rK   r  )r+  r'  r   r0  r1  rY  rN   r_   s     r    delete_commentsz=BaseModel._children_recursion_delete.<locals>.delete_comments_  s    ;-8==u#T73 $# $+ >     *)$3%5#1"/      r   id_setc           	      ~  	 |t                      } |           }|r7t                              dt          |           d            ||            |            | D ]D}||vr>t          j        j                            |dg          x}r j        |f	d
 E|	                    |            d S )Nu   Удаляем u    обьектовr   r/  )r0  r1  r   rY  )
r   r   r  ru  r   r  r   r4  r  union)r+  r3  r.  r&  r(  r   r2  r0  r1  rY  rN   level_deleter0  r_   s        r    r6  z:BaseModel._children_recursion_delete.<locals>.level_deleter  s-   ~++G44K 2M#k*:*:MMMNNN[&111OG$$$ $ C C6)) # 3 A A(TWSXjy  JW A  !X  !X  Xu C11%  Chu  IY  jx  C  C  |B  C  C  CLL!!!!!r   )r+  r
   r:   )r   r   r   )
r_   r   r0  rY  r1  rN   children_idsr2  r6  r0  s
   `````` @@@r    _children_recursion_deletez$BaseModel._children_recursion_delete<  s&   *=o);^(9M	 	 	 	 	 	 	 	<	 	 	 	 	 	 	 	 	 	 	&	" 	"# 	"s 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	"( 	()))(($'-99\"""""r   c                     | j         D ]E}t          j        |          }|                    dgdd| gd          D ]} | j        |fddi| Fd S )Nr   r-  r   T)rG   r  r!  r  )r   r   r6  rK   r  )r_   rN   essential_child_model_nameessential_child_modelr'  s        r    _essential_children_deletez$BaseModel._essential_children_delete  s    *.*E 	T 	T&$+$=>X$Y$Y!055cUHVY[_K`rv5ww T T *)'SSDSFSSSST	T 	Tr   c                     |ri ng S )u(   Получим всех потомковr   )r_   group_by_modelsrA  s      r    list_childrenzBaseModel.list_children  s    $,rr",r   )	recursiver  r   r  c                *   |                      dg           | j        dvrq|s|r+|                    dd          o||d<    | j        dd|i| nB|s,|                     d          x}rt          d	|  d
|          |                                  t          | t                    r3| j	        r,|s*d| _
        |                    dd            | j        |i |S |                                  g }| j        D ]A}	t          | j        |	         t           j        j                  r|                    |	           B|r`|                      |dd           |D ]E}	t'          | |	          r3t)          | |	g            t'          | |	                                           Ft+          | d          r1| j        r*t.          j                            | j        j        d            t9          |           j        j        | g|R i |}
|                                  |
S )Nr   ry  r  	CmfNotifyCmfAttachmentr  Fr   T)	skip_subsu   Нельзя удалить u1   , на него ссылаются потомкиr  )r0  r1  full_searchr   r   ) r  rh   r*   r8  r?  CmfOrmHasReferenceErrorr<  r(   r  logical_deleter  rr   r   r   rG   rm   r   r  rw   rt   r   ro   rF  r   CmfFullSearch_text_search_sql_delete_partnor   r   rI   r   r   r  )r_   r@  r  r   r  r}   rN   children
m2m_fieldsrX   r  s              r    r   zBaseModel.delete  s   &&& ?"NNN 2, 2#)::h#>#>#I6x //\\AQ\U[\\\\ 2D,>,>,>,N,N N 2-  /ET  /E  /E  /E  GO  P  P  P //111dH%% 	.$*= 	.FV 	.#Dk400049d-f---
+ 	. 	.J$+j13:3HII .!!*--- 	5ZTRRR( 5 5
4,, 5D*b111D*--224444'' 	RD,< 	R ??qQQQ"d4jjm"49$999&99


r   r@  c                    d| _         d| _        |                    dd            | j        |i |}| j        dvr$|r | j        di | n|                                  |S )uy   
        Восстановление из корзины логически удаленного объекта
        Fr  TrB  r   )r  tree_node_is_branchrr   r   rh   _children_recursion_restore_essential_children_restore)r_   r@  r}   rN   r  s        r    restorezBaseModel.restore  s     ! $) +t,,,di(((?"NNN 300::6:::: 00222
r   c                     d S r:   r   r   s    r    tree_child_restore_hookz!BaseModel.tree_child_restore_hook  r  r   c                    | j         D ]}t          j        |          }|dk    r4|                    dgdd| gg dgddd          D ]} | j        |fi | P|                    dgdd| gddd          D ]} | j        |fi | dS )	u   
        Восстановление дочерних объектов которые являются неотьемлемой частью объекта
        Вложения, комментарии и т.д.
        r  r   r-  r   )tree_parent==NT)rG   r  r!  r0  r1  N)r   r   r6  rK   _restore_child_object)r_   rN   r:  r;  r;  s        r    rQ  z%BaseModel._essential_children_restore  s    +/*E 
	> 
	>&$+$=>X$Y$Y!)\99055cUXWZ\`Lab}b}b}K~  QUFJZ^ 6 ` ` > >C.D.s==f====> 155cUHVY[_K`rvHL\` 6 b b > >C.D.s==f====>
	> 
	>r   c                    t          j                    }t          j        j        | j        k    r|                                 d}	  |j        di | n"# t          $ r t          j
                    } w xY w	 t          j        j        | j        k    r |j        |  dS dS # t          j        j        | j        k    r |j        |  w w xY w)uP   
        Восстановление дочернего объекта
        r  Nr   )r   r  r   r   r   r  r  rR  r  r  r  r  r  s        r    rX  zBaseModel._restore_child_object  s     )++$"333!!####	0CK!!&!!!! 	 	 	|~~H	 "
 "d&777$$h//// 87q"d&777$$h/// 8s   A B A22B 'Cc           	      ^   t                      }| j        j        h}t          j        j        j        t          j        j        j        t          j        j        j        f}|rt                      }t          
                                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h|                    g ddd|d|          D ]E}	t          |	j                  }
|
|v r|                    |
           |                    |
           F|}|t                               d	           t          j        j        j                            d
dgddd|gdd| ggdgdd          D ]} | j        |fi | t                               d           |D ];}
t          j        j                            |
d
gdd          x}r | j        |fi | <t                               d           dS )ul   
        Рекурсивно восстанавливаем все дочерние объекты
        Nr9  ri  r  rd  r-  T)rG   r!  r0  rY  r1  r  z%_children_recursion_restore end levelr   r-  r   r  )rG   r  r   r!  r0  z3_children_recursion_restore end restore CmfCommentsr/  z7_children_recursion_restore end restore children_id_set)r   r   r   r   r  r   r3  r  r  r  r   ro   rK   r   r  r  r   r  rX  r   r4  )r_   rY  rN   r#  r$  r  r%  r   r  r  r&  r'  r(  s                r    rP  z%BaseModel._children_recursion_restore  s    %% K,K,K)
  	J!1133 - -K''#5+.. D$/tE{{#CL5"233 M# M(,l=MtUYZ_U`U`<a'b(8$U'L#  %3^3^3^pt<@Q_os3? !, !A !A - -H  #8;//H?22 #''111NN8,,,,- E1  	2 	
8999 {)499X{D/BXsTXDYZ*+ $d	 : < < 	: 	:G
 'D&w99&9999	FGGG' 	< 	<H+99(C5bfvz9{{{u <**5;;F;;;	JKKKKKr   c                 d   t           j        rd S | j        dk    rd S | j        dk    rYt           j        t           j        k    r?t
          j                            d| j        | d           t          d| j
                   t          | t                    o| j        j        }t          | t                    o| j        j        }| j        r5t          | t                    o| j        r| j        j        n| j        j        }n!t          | t                    o| j        j        }| j        }| j        dk    rt           j        t           j        k    rd S 	 t
          j                            d| j
                    n7# t          $ r*}t
          j                            d|| d           |d }~ww xY wd S | j        d	k    rkd
}|                     d          D ]\  }}	|	j        dk    r
|dk    rd} nd}
t3          t5          |           d          rPt5          |           j        r<|                     d          D ]%\  }}	|	j        r|t5          |           j        vrd
}
&|sd S t           j        st           j        rd S t           j        t           j        k    rd S t
          j                            dd
          rd S t
          j                            g dd          }| j        dk    r?| j        o|j
        j        t           j         v }| j         o|t           j!        j
        k    o|
}nV| j        o|j
        j        t           j         v }| j         o.|t           j!        j
        k    o|j
        j        t           j         v o|
}|s|rRt3          | d          r@| j"        r9tG          | | j"                  $                                %                                 d S t
          j                            d|| d           | j        rt          d          t          d| j
         d|           	 t          | tL          j        j                  o| j'        j        }tQ                      }|rtQ          |          }|                     d          D ]^\  }}||v r|)                    |           |j        r&t
          j        *                    d||||| j
        j        || | j        |
  
         _|rM|D ]L}| |         }|j        rt
          j        *                    d||||| j
        j        || | j        |
  
         Kd S d S # t          $ rk}|j+        d| j
         fz   |_+        tY          j-                    5  t
          j                            d| j        | d            # 1 swxY w Y   Y d }~d S d }~ww xY w)Nno_aclr  rM   failoperaterb  r-  result_statusuO   Отказано в модификации системного объекта adminmessageproject_adminFTr  r  r   r8   r0  )r8  rW  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   r5  r   CmfAuditaudit_eventrh   r`  r   r(   rn   r  oldr  r9  r   r   r  newr3  r4  r'   r\  ro   rI   r   acl_admin_moderg  r*   r   current_person__member_ofcurrent_userrh  rt   loadr   r   r  r   r  check_accessr}   r   r  )r_   force_check_fieldsrk  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<	  s&     	F=H$$F=H$$)9Q_)L)LO''aeu{'|||$  &Aw{w~  &A  &A  B  B  B$T955X$:T:X"422It~7I   	P%dH55 Q)-O!%%$:K:O L &dH55O$:K:OL_
=G##1?22$55  ?Z  QU  QX  ?Z  ?Z5  [  [  [  [%   ++HZ`dtz+{{{ F=O++ J59ZZ4Z5P5P  1"M '4//4FJ[4[4[!%JE (,$tDzz#BCC 9T

Hp 99=t9T9T 9 95&$+ ! )d1YYY380 $ (8 1?22#44RU4KK #)#8#<#<DcDcDctx#<#y#y 
 "222"&+"n2F2I2OSTSn2n"&+op,!.BS2SpXp"&+"n2F2I2OSTSn2n"&+o |,!.BS2S |"6"9"?1C^"^|c{  +  4!BCC bHl bD$"FGGLLNN__aaaO''\`6< ( > > >{ _( *\ ] ] ] ) *^fjfm *^ *^ P\*^ *^ _ _ _%	4>tSZEY4Z4Z  5N_c  `J  `N1%(UU"! A),-?)@)@&%)ZZ4Z%@%@ 	o 	o!
E!777*11*===< $11!(/!+\Xb"gmm]a;Hm	 2 o o o o
 & 	s"8 s sJ ,E| ! (55%,o%/\f"&'--ae#{Lq	 6 s s s s	s 	ss s  " 	 	 	Ve\`\ceehhAF$&&  ++HT_eiy+  A  A  A             	sO   (E7 7
F+%F&&F+(DT: :
V/+V*/*VV	V* V	!V**V/c                     | j         dk    s| j         dk    rdS t          | t                    o| j        j        }t          | t
                    o| j        }t          | t          j        j                  o| j	        j
        }| j        }	 |                     d          D ]\  }}	|	j        r|r7t          j                            d|||| j        j        || j        |          }
n7t          j                            d|||| j        j        || | j        |	  	        }
d|
vrt$          dS # t$          $ rI}|j        d	| j         fz   |_        |s(t          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 - уничтожить флаг
            для некоторых мест (например, поиск) ради скорости игнорируем, что не отобразятся доступные объекты в закрытых проектах
                (где пользователю проект недоступен, но есть доступ через поля объекта)
        r\  public_readNTr  read)rj  rk  rl  rn  r  ro  r   rq  )	rj  rk  rl  rn  r  ro  rp  r   rq  u0   Отказано в чтении объекта r]  r^  )r   r(   rn   r  r   r  r9  r   r   r  rt  rh   r'   r\  r3  rz  r   r   r`  r}   rr  rs  )r_   rZ  TEXKOM_skip_failread_auditTEXKOM_ppp_project_simplecheckrk  r|  r  rh   rX   r~   rulesr  s               r    r_  zBaseModel._acl_check_read	  s    =H$$(F(FF$T955Z$:T:Z"422Et~0:4AU0V0V  1J[_  \F  \J-_
'	%)ZZ4Z%@%@ - -!
E< 1 "0==%+_%/j"&'--#{8] >  EE #0==%+_%/j"&'--(,T[8] >  E &&,, ')- -B " 	 	 	V[RVRY[[^^AF- ++F4?cgw}+~~~G	s   	BD* *
E=4AE88E=c                     d S r:   r   r   s    r    _check_sl_owner_lockzBaseModel._check_sl_owner_lock	  s    r   )rG   save_kwargsr  c                     | |i |}|si }|                     d|          |d<    |j        di | |r|                      |j        |          S |S )Nr  ry  r   )r*   r   r   )rS   rG   r  r  r}   rN   r   s          r    r   zBaseModel.create
  sx    3''' 	K#.??;	#J#JK $$$$$ 	7778;v7666r   c                     | j         S r:   )rk   r   s    r    r   zBaseModel.get_meta
  s
    {r   c                 v   | j         t          j        vrg }|                                 D ]e}|j        r
d |j        d                                         D             }|s|j        r)|                    |j         |j	        |j        |d           f|t          j        | j         <   t          j        | j                  S )Nc                 D    i | ]\  }}|                     d           ||S ra  rm  )r=   rX   
field_metas      r    r  z-BaseModel.all_models_meta.<locals>.<dictcomp>
  sB     & & &/Ez:!,,U33&
& & &r   rG   )rh   ui_group_fieldsrR  rG   )
rh   APPall_models_metar   rl   rk   r'   rR  rw   r  )rS   _argsrA  r(  modelClscustom_fields_metas         r    r  zBaseModel.all_models_meta
  s     >!444F//11  $ & &IQIYZbIcIiIiIkIk& & &" & )9 MM&.&9+3+C#+#3"4	# #    39C/"3>22r   c                    t          | d          r+|                    d          s|                    dd           t          | d          r+|                    d          s|                    dd            | j        j        | g|R i |S Nr  r0  Fr?  r1  )ro   r*   rr   r   bulk_deleterM  s      r    r  zBaseModel.bulk_delete)
      3&& 	4vzz:K/L/L 	4mU3333
## 	1FJJ,G,G 	1j%000!sv!#7777777r   c                    t          | d          r+|                    d          s|                    dd           t          | d          r+|                    d          s|                    dd            | j        j        | g|R i |S r  )ro   r*   rr   r   bulk_updaterM  s      r    r  zBaseModel.bulk_update1
  r  r   )r  c                   | j         sBt          j        | j                   t	          | d          rt          j        | j                   |                                  | j                                        D ]}||vrt          | |          }t          |t          j        j        t          j        j        f          rHt          |t                    r>|j        s|j        dk    r,|d d         |vrt#          | |d d         ||                    t#          | |||                    |si }|                    dd           |d= |                                   | j        di |S )Nr8  r   r  r   )TEXKOM_no_cacher   cache_obj_lock_getr   ro   r8  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.update9
  s   # 	6&tw///tV$$ 6*49555+**,, 	: 	:J''j11I)cj&;SZ=Y%Z[[ )X.. I4I YMaeiMiMi "#2#&00D*SbS/6*3EFFFD*fZ&89999 	K??;--9K(!!###ty'';'''r   )r  r  c                     i  fd              j         di ddd}|s              g}t          |          dk    r't          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 ]} |           dS t          |           dk    s
| d         dvr't          j                            d|  d d           | d         j        vr.t          j                            d	| d          d d
d           | d         | d         <   dS t          j                            d|  d d           dS )u   Соберём в key_values значения полей из фильтра, и проверим, что фильтр простой.r   r  r(  )r   rW  ud   Фильтр для upsert должен быть простой: [field, =, value], передан: r  Tr2  u8   В фильтре upsert неизвестно поле: u6   , допустимый фильтр: [field, =, value]r  u2   Указан пустой фильтр в upsert: N)r(   rK   ru  r   r  r+  rG   )
sub_filtersub_sub_filtercheck_simple_filterrS   r  
key_valuess     r    r  z-BaseModel.upsert.<locals>.check_simple_filterh
  sp    jmT22 >*4 < <++N;;;;< < :!++z!}K/O/O--G0:G G>DG GNR . T T T "!}CJ66--UWabcWd U Uhn U U U\` . b b b 1;1Jz!}---%%&q[e&q&qio&q&qy}%~~~~~r   T)r   r  )
for_updater  r(  u9   Ключ в фильтре upsert не уникален: r  r2  r   r  r   )rK   ru  r   r  r+  rM   )rS   r  r  r  rN   obj_listr  r  s   ``    @@r    r   zBaseModel.upsertZ
  s     
	 	 	 	 	 	 	 	* 	F###38HHjHTHHHH 	wHx==1K!!"r^f"r"rjp"r"rz~!=={=f==={r   c                    t          | d          rAt          | d          r1t          |           j         d| j        j         d| j        j         dS t          |           j         d| j        r| j        j        n| j         dS )NrT   r8  r2  : r  )ro   rI   r   r8  r   rT   r   r   r   s    r    __repr__zBaseModel.__repr__
  s    4   	TWT6%:%: 	T4jj)SSDI,<SS	@PSSSSt**%ccAS(`(:(=(=Y]Y`ccccr   c                    t          | t                    rd | D             S t          | t                    rPd| v rL| d         }t                              |          }d |                                 D             } |di |ddiS | S )Nc                 B    g | ]}t                               |          S r   r   	from_json)r=   r   s     r    r  z'BaseModel.from_json.<locals>.<listcomp>
  s&    999qI''**999r   r   c                 J    i | ] \  }}|t                               |          !S r   r  r=   r-   r.   s      r    r  z'BaseModel.from_json.<locals>.<dictcomp>
  s,    IIIDAqa,,Q//IIIr   r   Tr   )r(   rK   rs   r  get_cls_by_tuuid_strr'   )r&  r1  rS   rG   s       r    r  zBaseModel.from_json
  s    dD!! 	:99D9999dD!! 	-ddllt*C//44CIIDJJLLIIIF3,,,,t,,,,r   c                 h    |sg }i }|                      d          D ]\  }}||vr
|j        ||<   |S )NTr  )r'   r&  )r_   rG   rR  	fieldnamer~   s        r    to_jsonzBaseModel.to_json
  sV     	F $

d
 ; ; 	( 	(Iu&&"ZC	NN
r   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
  sB    6>>%d+++V^^%d+++r   c                    t                      }|r| j        |v r|S |r"t          di | j        t                      i|}nt                      || j        <   |                     dg          }| j                            |          D ]}|                     ||           |                                }| j                                        D ]k\  }}t          |t          t          f          r||v r||= |                    |          rxt          |t          t          f          r\|r
|j        |v rf|j        |v rp|j        | j        k    rt!          t"                    |j                 }|                    |          }|                    |          rt          |t&          t(          f          r|j        st+          d| d           |j        D ]`}	|r|	|v r	|	|v r|	| j        k    r|	t!          t"                    vr1t!          t"                    |	         }|                    |          }am|| j                                     |           |S )uT  
        Дампим все обьекты класса и ссылки в dict для последующей серилизации
        :param upper_res: предыдущий дамп для исключения повторений и правильной последовательности
        :return: словарь
        r   r  u   WARNING: поле u    без modelsr   )r   r   rK   r  r   _load_extra_fieldsr}  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_dict
  s    mm 	22 	'DDtvv 6D)DDCC $C//66FKK1AKBB )	0 )	0D""4)9:::,,..I),)9)9);); #; #;%
Ii/>)JKK 2!Y..%j1==,, ;IU[G\1]1] ;  !Y_	%A%A  #--  #,66 #F||IO<H"11#66CC]]:.. ;:iJ\JWJY 4Z 4Z ;$+ !M:MMMNNN &/&6 ; ;
$ %y)@)@$%,,$%55$%T&\\99$#'<<
#;&55c::$$Y////
r   c                     t          |t                    r| j        |j        k    S t          |t                    r|j        j        rdS | j        |j        k    S dS NF)r(   r   r   r  is_null)r_   others     r    __eq__zBaseModel.__eq__
  s[    eY'' 	'7eh&&e_-- 	'x u7eh&&ur   )NNr   FNNNF)FNNN)NNNNNr(  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  rR  r  r  r   customsmart_notifyrf  r   r   r  rN  r   r   rM  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   r<  rS  r   rm  rp  rr  r  r}  r  rs   r  r  rK   r  r  r  r  r	   rJ   r  r
  r  Typer   r*   r   r  r*  r  r9  r   r   rC  r;  rN  r   rP  rU  r   r  r   r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r   r
  staticmethodr  r  r)  r8  r<  r?  r   rR  rT  rQ  rX  rP  r   r_  r  r   r   r  r  r  rM   r   r  r  r  r'  r  r  r   r   r    r   r      s/        LHLHLMOGO!FLN
 H Hc'!d!!!(, #,,,)-!3---(, #,,,It
 
 
K& G  IFKND L6 9 9 9 [9   [   <	) 	) 	)+ + +# # #           D  
       X 4 4 [4	% 	% 	% 	%h h h hc c c c" " "" " " 33 33 3 3 3 [3    [& % % [%N ( ( ( [(T > > [>     [       [ D. . . .`    [ Vu Vu Vu Vu Vu [Vup .4 . . . [.  " "d " " " ["H ? ? ? ? [?4J J J Jq q q qJ Ys4 4 4 4  [4
 t    [ O O O [O )- L L Lb LB L L L [L8 *. ] ] ]$r( ]R ] ] ] []. *.U G G G G [GR 
T"X 
 
 
 [
   [ O O [O *. C C C$r( CDQSH C C C [C8 +/$ $T $T $T48 $TT $T $T $T [$TL   [ +/%_d     [4 0 0 [0 !% N N N N [N ,0     [ E E E [E osKO.2HM	x x x 	x 03	x x x [xt     [  - - [-% % % %% % %      F F F,     -1u ; ; ; ; ;6z z zx7 7 7   &      '(5 E E E E EN0 0 0B  
    \20 0 0."p "p "p "pHL# L# L# L#\T T T- - - - ',55Y] ) ) ) ) )V (-     (  > > >$0 0 0">L >L >L >L@A A A AF< < < <|   "&DE     [   [ 3 3 [3* 8 8 [8 8 8 [8 *. ( ( ( ( (B #'T ) ) ) ) [)Vd d 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          Z e	eddddd
gd          Ze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!d5d&Z"e#d6d'            Z$e# fd(            Z%e#d6 fd)	            Z&d* Z'd7d,Z( fd-Z)d. Z*d/ Z+ fd0Z,d8d1Z-d2 Z.d9d3Z/d4 Z0 xZ1S ):r  us   Базовый класс, содержит стандартные поля для типовых объектов.T)r  F)all_relation_persons
get_ownersget_project_name)   Идентификатор объекта3   Автоматически генерируетсяrF   r'  nullableri   r   r  u
   Авторrj  )rF   r  linkabler   r   fullsearch_indexu   Владелец)rF   r  r   r  r   r  u   Родительrn   )rF   
base_modelr  r  u'   Последний изменивший)rF   r  r   r  r   autor\  u$   DEPRICATED. Кто захватил r  )rF   r  r   r   r  r\  u#   DEPRICATED. Дата захвата)rF   r  r   indexr\  u   Дата создания)rF   r  r   r  r   r  r  r  u   Дата изменения)rF   r  r   r  r   r  r  r\  u   Дата просмотра)r  rF   r   r  r   r  r\  u   Удален)rF   r  r   r#   r  r  u   Номер версии
CmfVersion)rF   r  r   r  r\  widgetr"  c                 *    t          |           j        S r:   )rI   r   r   s    r    r   zCmfModel.db_name~  s    Dzz!!r   Nc                    g d}|r$dD ]!}|D ]}|                     | d|            "|                     |           t                      }| j        r,|| j        j        |k    r|                    | j                   t          | dg           D ]$}||j        |k    r|                    |           %t          |          S )N)r   cmf_owner_assistantszcmf_owner.user_localzcmf_owner_assistants.user_local)r   r  rE   ry  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vv 	C%H C C! C CA&&*;'A'Aa'A'ABBBBC,,,> 	+!T^%>*%L%L

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

5!!!F||r   c                    g }g }|r&|D ]"}|                     | j        |                    #n| j                                        D ]o}t          |t          j        j                  r"|j        dv r,|j        dk    r|j                            d          rR|j        sZ|                     |           p|D ]I}|                     |j	        |j        |j
        |j        o|j        | j        | j        |j        d           J|S )N)r   r8  r  cmf_versionr  
cmf_importr  import_raw_jsonext_idr1  )rF   rX   field_qualnamerequiredr  r  r  )rw   rG   r   rm   r   r   rh   r  r  rF   r   r  r  r  r  )rS   fields_namer(  rG   rX   r~   s         r    import_shop_fieldszCmfModel.import_shop_fields  sP    	%) 6 6
cj455556 **,, 
% 
%eSZ%:;; # (\ \ \#x//E4D4M4Me4T4T/} e$$$$ 	h 	hEMMem5CS-2-?U^Mm`e`m+.+;SXY^Yeg g h h h h r   c                 
   t          |                                                                          D ]\  }}|                    d          rt          | |                    d          d                   rs|rqd|vrmt          t          j        j                  |                    d          d                  	                    |          ||                    d          d         <    t                      j        |i |S )Nr1  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.create  s    ((..00 	 	DAq

5!! gc1775>>!3D&E&E "!++ -11C,D,DGGCLLO-##)) qwwu~~a() uww~t.v...r   c                 H   |g }|dv r~|dk    rx|                     dd           rb|d                              dd           dk    rB|                     dd           r,d|vri |d<   dg i|d<    t                      j        |fd	|i|S  t                      j        |fd	|i|S )
N)r   r   r  r   r  parent_logic_prefixzproject.servicedeskrT  rV  rj  r  )r*   rQ   r   )rS   r  r  rN   r[   s       r    r   zCmfModel.field_options_list  s    >F"UUU
 #k11JJ55 2?+//0EtLLPeee::h-- d'v5535/00;R/@F+,557756IccRXc\bccc)uww)*=WWfWPVWWWr   c                     | j         j        s| j        sd S t          t                              t
          j                                      d          d d                   | _         d S )Nz%Y%m%d%H%M%S%fr  )r  r   r  r   r   r   r   strftimer   s    r    _increment_versionzCmfModel._increment_version  s]    & 	do 	Fx||HL99BBCSTTUXVXUXYZZr   rM   c                     d S r:   r   )r_   r  s     r    r  zCmfModel.project_notify  r  r   c                     |                                   t          | d          r| j        s2| j        r|                     d           n|                                   t                      j        |i |S )Nr  r  r  )r  ro   r  r   r  rQ   r   r_   r}   rN   r[   s      r    r   zCmfModel.save  s    !!!m,, 	&1A 	&{ &##X#>>>>##%%%uww|T,V,,,r   c                    |                      ddg           t          j        g}| j        }| j        j        r%| j        j        }|r|                     ddg           |s|S |j        j        r |                    |j        j                   n|                    |j                   t          |d          rP|j	        j        r%|j	        j        D ]}|                    |           n|j	        D ]}|                    |           |S )Nparent.cmf_owner_assistantsparent.cmf_ownerr  r   )
r  r   r5  r-  r   rt  r   rw   ro   r  )r_   r(  perm_parentr  s       r    get_parent_ownerszCmfModel.get_parent_owners  s1   79KLMMM/"k;! 	O+/K O'')?(MNNN 	M + 	1MM+/34444MM+/000; 677 	)/: )(=A ) )EMM%(((() )= ) )EMM%((((r   c                 
   |                      g d           t          j        g}| j        j        r |                    | j        j                   n|                    | j                   t          | d          rP| j        j        r%| j        j        D ]}|                    |           n| j        D ]}|                    |           | j	        r'|
                    |                                            d |D             S )u   
        Все владельцы обьекта
        fixme метод используется для проверки прав доступа, но не для всех владельцев сейчас реализован доступ.
        )r   r  r  r  r  c                     g | ]}||S r   r   )r=   r  s     r    r  z'CmfModel.get_owners.<locals>.<listcomp>  s    333%U3333r   )r  r   r5  r   r   rw   rt  ro   r  r-  r  r  )r_   r}   rN   ownersr  s        r    r  zCmfModel.get_owners  s-   
 	 M M M 	N 	N 	N/" >$ 	*MM$.,----MM$.)))4/00 	)(3 )!6: ) )EMM%(((() "6 ) )EMM%((((; 	4MM$00223333363333r   c                     | j         s.| j        j        r"t          j        |                                 v rd S  t                      j        di |S )Nr   )r   r   r   r   r   r  rQ   r   )r_   rN   r[   s     r    r   zCmfModel._acl_check_write  sU    { 	t~8 	4#9#9#;#;;;'uww'11&111r   c           	         | j         sd S t          j        rd S | j        s(| j        rd S d}|                     d          D ]S}|j        |                                 vr6|j                            d          s|j        	                    d          sd}T|r| 
                                }t          j        |vrt          t          j                  t          d |D                       z  sZd|  dd	                    d
 t          |          D                        d}|r||z  }t          j                            |           d S | j        r| j                            d|            d S |st                      }|                     d          D ]k}|j        |                                 vrN|j                            d          s4|j        	                    d          s|                    |j                   ld|v r1| j                            d|            |                    d           d|v sd|v r| j        j        rB| j        j        r6| j        j        | j        j        k    r| j                            d|            | j        j        s| j        j        r$| j        r| j                            d| d           d|v r|                    d           d|v r|                    d           d|v r|                    d           d|v r1| j                            d|            |                    d           |r| j                            d|            d S d S )NFTr  cache_r1  c                     g | ]	}|j         
S r   r  r=   os     r    r  z,CmfModel.check_edit_perm.<locals>.<listcomp>/  s    B\B\B\A14B\B\B\r   u   Это действие над v    разрешено только владельцам объекта и владельцам его родителя: r  c                 &    g | ]}|j         j        S r   rT   r   r  s     r    r  z,CmfModel.check_edit_perm.<locals>.<listcomp>1  s    ,S,S,SaQV\,S,S,Sr   4    или Администратору системы.rb  zPPP-OBJ-CREATErw  ordernozPPP-OBJ-TREE-ORDERr-  r.  zPPP-OBJ-MOVE)r;  use_new_projectrV  zPPP-OBJ-TREEMOVEzPPP-OBJ-EDIT)r  r   r  r.  r   r   rh   project_perm_allow_fieldsry   r  r  r   r   rw  r?   r   r3  r4  r^  r  r  r   rt  ru  r-  )r_   changed_fields_to_checkadditional_error_msgr~  r~   
all_ownersmsgs          r    r  zCmfModel.check_edit_perm  s   $ 	F  	F| 	{ J55 & &(0N0N0P0PPP % 0 ; ;H E E Q % 0 9 9% @ @ Q "&J K!__..
#:55q:;;cB\B\Q[B\B\B\>]>]] KV V V"&)),S,S3z??,S,S,S"T"TV V V 0 8#77C,==c=JJJF; 	L223C2NNNF ' 	B&)ee#55 B B(0N0N0P0PPP % 0 ; ;H E E Q % 0 9 9% @ @ Q ,//0@AAA ///L223GT2RRR#**9555 ...)?V2V2V|& Q4<+; Q@PTXT`Td@d@d66~46PPP& i$,*A it| i667GTcg6hhh222'..x888333'..y999 777'..}=== 333L223E42PPP#**=999" 	ML22>t2LLLLL	M 	Mr   c                    | j         sd S t          j        rd S t          | d          r| j        s|                                 }t          j        |vr~t          t          j                  t          d |D                       z  sKd| j	         dd
                    d |D                        d}t          j                            |           d S | j                            d	| 
           d S )Nr.  c                     g | ]	}|j         
S r   r  r  s     r    r  z.CmfModel.check_delete_perm.<locals>.<listcomp>p  s    >X>X>Xqt>X>X>Xr   u   Удаление r  r  c                 &    g | ]}|j         j        S r   r  r  s     r    r  z.CmfModel.check_delete_perm.<locals>.<listcomp>r  s    (J(J(J!(J(J(Jr   r  rb  zPPP-OBJ-DELETErw  )r  r   r  ro   r.  r  r   r   rw  r8  r?   r   r3  r4  r^  )r_   r"  r#  s      r    r  zCmfModel.check_delete_perme  s   & 	F  	FtY'' 
	t| 
	**Jz111677#>X>XZ>X>X>X:Y:YY GRdi R R"ii(J(Jz(J(J(JKKR R RC (99#9FFFF../?T.JJJJJr   c                    |ri ng }t                                           D ]R}d}t          |j        t          j        j                  r| j        |j        j        v rd}n| j        |j        j	        k    rd}|sft          |t                    rQt          |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$|                    |          x}r
|||j        <   &|                    |                    |ddg	                     T|S )
ur  
        Получим всех потомков
        Пока только parent and tree_parent
        Может логику через модель надо определять, т.к. связи разные могут быть...
        Поддержка soft_link? Связи, которые надо разрывать при удалении.
        FTr-  r   )r3  rd  rV  r  r  rG   )r  r   rm   r-  r   rG   r  rh   r   r   rn   rV  r   r   r  rK   )	r_   r>  rE  rA  r(  r   linkedfilter_r  s	            r    r?  zCmfModel.list_childrenz  s    '.B--// $	\ $	\E F%,
(EFF "?el&999!F?el&888!F &j	:: &e/1NOO &%*;*BBB!%%*;*AAA!% d+G U-1LLL U-1DDD%++ F=#t*DE \"'++W+"="==; ;/:F5+, ejjPX@YjZZ[[[[r   c                     | j         rGt          j        | j                   dk    r,| j                                        o| j        j        j        S dS dS )u   
        Хак для доступ к имени проекта для опубликованных документов.
        rU  N)r9  r   get_class_name_by_idr-  ry  rT   r   r  s     r    r  zCmfModel.get_project_name  sY     > 	Ag:4>JJlZZ;##%%@$+*:*@@	A 	AZZr   r   r:   )rM   r  )TF)2r   r   r   r   rH  r   r   r   r   Fieldr  r   r  r   r   r   rG   CmfSubclassedGenericRelationr-  r   cmf_locked_byr   cmf_locked_atCmfCreateDateTimer  cmf_modified_atcmf_viewed_atCmfBoolr  	CmfBigIntr  r{   r  r   r  r  r   r   r   r  r  r   r  r  r   r  r  r?  r  r   r   s   @r    r  r  
  s       }}$ N*I' +
 +
 +
 
K 
;E
 
 
B }  J $6u}	  I Z
/"   F e9}	 	 	O E6}  M EBE\`hluy{ { {MU+
 
 
N e-
 
 
O E-	 	 	M %  K %4edZ^gk  uAB B BK " " " " X"        [0 
/ 
/ 
/ 
/ [
/ X X X X X [X&[ [ [
   - - - - -  24 4 422 2 2 2 2JM JM JM JMXK K K*. . . .`A A A A A A Ar   r  c            	       r    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
d	S )
BaseM2MModelTFr  r  r  u%   Родительская запись)rF   r  u   Корневая записьN)r   r   r   r\  r   r.  CmfM2MTUUIDr   r  r9  root_idr   r   r    r8  r8    st        FI	;E
 
 
B h(OW[\\\IeH&ETRRRGGGr   r8  c                   Z     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dS )CmfGM2MModel.description   Описание связиTNr   r   r   rF   r  r   r   r    descriptionr>            /r   rA  c                      t                      j        |i | d|v r(t          |d         d          r|d         j        | _        d|v r*t          |d         d          r|d         j        | _        d S d S d S Nr  rT   rightrQ   r   ro   rT   left_name_cacheright_name_cacher
  s      r    r   zCmfGM2MModel.__init__      $)&)))Vv ? ?#)&>#6D f&!A!A$*7O$8D!!! r   T)r  c                   g }| j         }|j        }|r[| j                                        D ]>}|                    |          }|                    t          |                    }	|                    |           }
t          |	          }|                    |          }|                    |
|
j	        |j
        k              }|                    ||
j        |j
        k              }|                    |
j        dk              }|                    |j
        |j
        j        k              }|                                }|                                }|                    |           @nY| j                                        D ]>}|                    |           }
|                    |          }	|                    t          |                    }t          |          }|                    |	          }|                    |
|
j        |	j
        k              }|                    ||
j	        |j
        k              }|                    |
j        dk              }|                    |j
        |j
        j        k              }|                                }|                                }|                    |           @|S )u*  
        Получаем список обьектов через связанную таблицу с проверкой существования обьектов по обе стороны
        TODO TODO1 перенести в драйвер и прожать по full_fields_load
        N)r   r   rE  r  r   rI   r   query_deprecatedr?   right_idr   left_idr  r9  r   order_queryallr  r  )rS   r;  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  sw    V^  	$ Y5577 $ $	!#Y!7!7 "DII 6 6!{{3//(/(>(>%)).99hh|\-BnFW-WXXhh) (,A,DDF F jj!74!?@@jj!6!9SV\!IJJoo''ggiis####$" !X4466 $ $	!{{3// "I 6 6!#T#YY!7!7)0)@)@&))-88hh|\-A]EU-UVVhh* )-C-FFH H jj!74!?@@jj!7!:cfl!JKKoo''ggiis####r   
r   r   r   r   
CmfStr4096rA  r   r  rW  r   r   s   @r    r<  r<    s        <<    j   9 9 9 9 9 .2 ) ) ) ) [) ) ) ) )r   r<  c                   V     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dS )CmfM2MModel.descriptionr?  TNr@  r   r   r    rA  r]    rB  r   rA  c                      t                      j        |i | d|v r(t          |d         d          r|d         j        | _        d|v r*t          |d         d          r|d         j        | _        d S d S d S rD  rF  r
  s      r    r   zCmfM2MModel.__init__  rI  r   Tc                    | j         }|j        }d}t          t                    | j        j                 }|j        t          |          j        k    rd}t          t                    | j        j                 }|	                    |          }|	                    |          }	|	                    |           }
|dk    r|
                    |	          }|                    |
|
j        |	j        k              }|                    ||
j        |j        k              }|                    |j        |j        j        k              }|                                }n|
                    |          }|                    |
|
j        |j        k              }|                    |	|
j        |	j        k              }|                    |	j        |j        j        k              }|                                }|                                }|S )NrE  r  )r   r   r   r   r  r   r   rI   rE  r   rK  r?   rL  r   rM  r  r   rN  rO  )rS   r;  r  r   rP  r?   left_cls	right_clsrS  rR  rT  r  s               r    rW  zCmfM2MModel.select_related  s   V^<</S		 222DLL1	H--Y//{{3''6>>%%n55C((<)>.BS)STTC((=,*>-BR*RSSC**]-=>>C//##CC%%m44C((<)=AQ)QRRC((><+@NDU+UVVC**^.#&,>??C//##Cggii
r   r  rX  r   s   @r    r[  r[    s        ;;    j   9 9 9 9 9    [    r   r[  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                    d          Zej        dz   ZdZej        g d	z   Z eed
ddddg          Z G d d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#j$                            e#j$        j%        d(dd)          Z& ee'd*dd+          Z( eed,ddd-          Z) ee*d.dd/d0dd1          Z+e#j$                            e#j$        j        dd2d3          Z,e#j$                            e#j$        j-        d4ddg 5          Z.e#j$                            e#j$        j        d6d7ddg 8          Z/e#j$                            e#j$        j        d9ddd:          Z0e#j$                            e#j$        j        d;ddd<          Z1e#j$                            e#j$        j        d=ddd:          Z2e#j$                            e#j$        j3        d>d d?          Z4e#j$                            e#j$        j         d@dAdddB          Z5e#j$                            e#j$        j        dCdD          Z6dZ7g Z8dEgZ9e#j$                            e#j$        j:        dFddddGH          Z;e#j$                            e#j$        j<        dIdJdKdLdMdNddOP          Z=e>dddQdR            Z?e@ fdS            ZAe@dT             ZBddUedefdVZCe@dW             ZDdX ZEdY ZFddZZG fd[ZHe@d\             ZIe@d]             ZJe@dd^            ZKe@dd_            ZLe@d`             ZMe@dda            ZNe@ddb            ZOe@ddc            ZPe@ddd            ZQe@dde            ZRe@ddf            ZSdg ZTdh ZUeVdi             ZWdj ZXdk ZYdl ZZdm Z[dn Z\do Z]dp Z^dq Z_ddrZ`dGdsdteafduZbdv Zcdw Zdddx fdy
ZeddzZfd{ Zgd| Zh fd}Zid~ ZjdGdd fd
ZkddZle> emdddgd          d                         ZnddZod Zpe@d             Zqe@dddddd            Zrd Zsd Ztd Zud Zvd Zwd Zxddd fd
Zydd fd
Zzd Z{e@dddd            Z|e> e}d          de~fd                        ZddZddZe@d             Zd Ze#j$                            e#j$        j        ddd          Ze#j$                            e#j$        j        ddd          Ze#j$                            e#j$        j         dddd          Ze#j$                            e#j$        j        ddd3          Ze#j$                            e#j$        j3        ddd d          Ze#j$                            e#j$        j        dddd&          Ze#j$                            e#j$        j        ddd&d          Ze#j$                            e#j$        j        ddd          Ze#j$                            e#j$        j%        dd          Ze#j$                            e#j$        j        dddd          Ze#j$                            e#j$        j        dd          Zd Ze@dd            Ze@dd            Zd Zd Zd ZddZd Zd Zd ZddZe> emddg dâĦ          	 	 ddń                        ZdƄ ZdǄ ZdȄ Z fdɄZdʄ Zd˄ Ze@dedefd΄            Ze> emddЦ          dedededefdӄ                        Z xZS )rn   u   CmfEntity - базовый класс для типичных моделей подлежащих автоматизации на преприятии.

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

    class Task(CmfEntity): pass
    Nacl_parent_fieldF)r8  rT   textr>  r  r9  logic_type.codeactivity.codezcmf_owner.namezcmf_author.namezcmf_modified_by.namer  r  r3  r  zcomments.textzcomments.log_levelresult_textzresponsible.namezexecutors.namecache_status_typez	tags.namere  rf  rc  r  r  z^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_middlerR  rT  unlockux_check_permattach_listu   Имя объектаu   object.name - статичное поле для представления в ui, аналог repr, генерируем методом если не заданоr#   gin_trgm)rF   r'  r  index_usingc                   B     e Zd ZdZdZddgZdZdZdZdZ	dZ
 fdZ xZS )	CmfEntity.codeu   КодTr#   rw  u3   Код в реальном мире из жизниr:   r  c                    ddl m} |s|S |                                }| j        dk    rCt	          |          | j        k    r+|d | j        dz
            d|                    |d           }t                                          |          S )Nr   )cmf_hashlibr     r[     )	cmf.utilr|  striptruncateru  
max_lengthshort_str_encrQ   r   )r_   r   r|  r[   s      r    r   zCmfEntity.code.castk  s    ,,,,,, KKMME}&&3u::+G+G !5$/A"5!56^^9R9RSXZ[9\9\^^77<<&&&r   )r   r   r   rF   r  rx  uniquer   r'  r  	log_levelr   r   r   s   @r    r8  rz  a  se         *-E		' 	' 	' 	' 	' 	' 	' 	' 	'r   r8  u   Системный объектu   Нельзя удалять)rF   r'  r  r#   r  u
   Текстu   Текст сущностиu!   Добавить описание)rF   r'  placeholderu   Задачи сущностиrl  r-  )rF   r   backrefr  u#   Документы сущностиrj  u'   Комментарии сущностиr  r  	CmfImportu   Импортированimport_objects)r  r   rF   r  r  u,   Исходная версия импортаr  )rF   r  r  r\  r#   u&   Сырые данные импорта)rF   r  r  u"   Ид внешней системы)rF   r   r  u   Объект в архиве)rF   r  r#   r  u   Избранный дляCmfPersonVar	favorites)rF   rE  r   r  r  r\  u3   В избранное всем участникам)r#   rF   r  u!   Родительская нода)rF   r  r   r   u   Ветви дереваrV  )rF   r  r  r   r   u(   Есть вложенные узлы old)rF   r  r   r#   u$   Есть вложенные узлы)rF   r#   r  r   u)   Не отображать в деревеu-   DEPRICATED. Корневой Родитель)rF   r  r  u   ПроектrU  )rF   r   r  r  r  u>   Редактирование только владельцем)rF   r#   r  u   Сортировкаr   )rF   r  r  r  r#   u,   Метод индексации поискаu!   Полная индексацияu%   Только наименованиеz
Summary AIu'   Индексация отключена)0_full_index1_name2_summary_ai	9_disabler  )rF   rI  r  r#   )r  rG   c           	      0   g }|sg }t          j        | dg          }|rGt          j                            dddt          d |j        D                       gdd|gg|          }n/t          j                            ddd|j        gdd|gg|          }|S )	Ncommentsry  rd  r-  ri  c                 &    g | ]}|j         j        S r   r  )r=   r'  s     r    r  z)CmfEntity.attach_list.<locals>.<listcomp>
  s     P~P~P~fmQXQ[QaP~P~P~r   r   r)  )r   r4  r   rD  r   r   r  rK   )obj_idr  rG   r}   rN   r  r;  s          r    rv  zCmfEntity.attach_list  s     	F#FJ<@@@ 	@&,,THdCP~P~qtq}P~P~P~LL  <A  DL  NQ  SV  CW  5X  ag,  h  hCC&++D8T3<:X[cehjmZn3ox~+C
r   c                     t                                          |          }|j        d                                         D ]\  }} |j        |fi | |S )N	ui_fields)rQ   rS  ui_form_jsonr'   r   )rS   r;  rR  rJ  ui_field_datar[   s        r    rS  z CmfEntity.get_automation_ui_form  se    ''0055,/,<[,I,O,O,Q,Q 	? 	?(M=G}>>>>>>r   c                     | j         }|st                      }d|d<   d|d<   d |d<   |                    dt                                |d<   |S )Nr#   r8  rT   r1  r  )rR  rs   r*   )rS   r}   rN   r  s       r    _build_ui_formzCmfEntity._build_ui_form  s\    { 	"66L(V(V"U$0$4$4[$&&$I$I[!r   rT   c                 4   |                      dg           |                     |          }|D ]/}t          ||          r|dk    rt          ||||                    0||_        |                     |          }|                    d           d|_        |S )u/   
        Копируем обьект
        z**r  r   Tr  )r  r  ro   r   rT   _post_copy_hookr   r   )r_   rT   r8  r}   rN   obj_copyr  s          r    r   zCmfEntity.copy!  s     	$   ::4:(( 	4 	4Cx%% 4#++#vc{333''11%%%r   c                     |                                  |                                 |                                 |                                 |                                 |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_hook1  sa    ""$$$**,,,##%%%!!!))+++r   c                     | j         rt          j        j        | dg|R i | d S t          j        j        | dg|R i | d S )Ncreatedupdated)r   r   CmfEventdo_eventro  s      r    _do_event_savezCmfEntity._do_event_save:  sc    ; 	GO$T9FtFFFvFFFFFO$T9FtFFFvFFFFFr   c                 <    t          j        j        | dg|R i | d S )Ndeleted)r   r  r  ro  s      r    _do_event_deletedzCmfEntity._do_event_deleted@  s-     yB4BBB6BBBBBr   c                    t                      }|dk    rt          d| dd           |                    d          sdS |dk    r8|                     g d	           | j        r|                    | j                   |d
k    rJ|                     g d           | j                                        r|                    | j                   |dk    rt          j	        gS |dk    r'|
                    |                                            |dk    r+|
                    |                     ddg                     g }|D ]}|j        j                            d          r9|
                    |                     |j        j        |dz   |                     Z|j        rbt#          |d          r|j        rz|                    |           |S )u?  
        Получение значение по шаблонным объектам.

        Возвращает список (в том числе пустой), если передан шаблонный объект
            или None, если объект не является шаблонным
        
   un   Зацикливание рекурсии в раскрытии var-пользователя: extract_var_obj(r  Tr2  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_workry  r(  )	recursionall_nested_persons)rK   r+  ry   r  r   rw   r   ry  r   rx  r  get_all_followersr  r8  r   extract_var_objr  ro   r  )r_   obj_coder  r  	var_usersres_var_usersvar_users          r    r  zCmfEntity.extract_var_objC  sG    FF	r>>  S  HP  S  S  S  [_  `  `  `  `""6** 	4{""^^^___~ 1  000|##aaabbb##%% 2  111)))N##&&T3355666...T66}o>^6__``` ! 		+ 		+H}"--f55 $$T%9%9(-:MYbcdYdM_ &: &a &a b b b# x11 h6L   ****r   c                    |                                   |                                  |                                  |                                  |                                  |                                  |                                  |                                  |                                   t                      j
        |i |}|                     d           |S )u   
        Функция сохранения при импорте, чтобы ускорить исключив лишние логики и защиты
        Fr  )r  r  r  r  r  _calc_tree_parentr  
_calc_code_calc_ordernorQ   r  r  )r_   r}   rN   r  r[   s       r    r  zCmfEntity._save_importo  s     	   &&(((!!!%%'''   "egg"D3F33U+++
r   c                 "    | j         od| j         v S )N-ordernor@  r   s    r    _is_orderno_descending_sortz%CmfEntity._is_orderno_descending_sort  s    |:
cl ::r   c                 @    | j         s| j         S d | j         D             S )Nc                 V    g | ]&}|                     d           r
|dd         nd | 'S )r[  r(  Nrm  )r=   rX   s     r    r  z.CmfEntity._revers_ordering.<locals>.<listcomp>  sP     , , , )33C88NJqrrNN>N*>N>N, , ,r   r  r   s    r    _revers_orderingzCmfEntity._revers_ordering  s9     | 	 <, ,!l, , , 	,r   c                    |                     d          s|                     d          sd S |st          j        j        }|st	          j        |          }|j        }t	          j        |          t          j	        ur t          
                    d| d           d S t                                          }||_        d|_        ||_        ||_        ||_        ||_        d|_        |                                 d S )NCmfDocument:CmfTask:zproject_id "z-" is not a valid CmfProject obj_id, aborting;clickF)ry   r   r   r   r   r4  r9  r	  r   rU  r  CmfSearchStatr  actionsearch_query	person_idr  
aggregatedr   )rS   r  r  r  r  r9  r;  stats           r    rm  zCmfEntity.mark_clicked  s    !!.11 	V5F5Fz5R5R 	F 	,(+I 	''//CJ":..f6GGGGG^J^^^___F##%%(""$		r   c                    |s|sd S |s|r|D ]}|                      ||           |r|                      ||          }|s|g}|D ]}|                    d          s+|                    d          s|                    d          rHt          j        |dgdd          }|st                              d| d	           }|s0|                    d          r|j        r|j        j        }n|j        }|s|st          j        |          t          j
        urt                              d
| d           |s|j        }|s.|                    d          r|j                                        }t                                          }	||	_        d|	_        ||	_        ||	_        ||	_        ||	_        d|	_        |	                                 d S )N)r  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;rj  viewF)mark_viewed_objry   r   r4  r   r  r-  r9  r	  r   rU  cur_workflow_version_idry  CmfStatr  r  r  r  
history_idr  r   )
rS   r  obj_id_listr  r  r  r9  rN   r;  r  s
             r    rn  zCmfEntity.mark_viewed  s?     	k 	F 	E+ 	E" E E##3)#DDDD 	?++FI>>I 	#!(K! )	 )	F  00 (F4E4Ej4Q4Q (U[UfUfgwUxUx (+FH:W[koppp GGMMMMNNN! 3(()9:: 3: >),)=J%(]
! ! *:66f>OOOGGlJlllmmm  . #I! Df&7&7&F&F D!$!<!A!A!C!CJ~~''$$!*",",!*"'		S)	 )	r   c                 T   |st           j        j        }|t           j        j        k    rPt           j        t           j        k    r!t          j                            dd           t          j        |          }nt           j        }t          j	        d|j         d| d          5  |
                    d          rUt          j                            |j        |d	          s.t                              ||
                                           d d d            n# 1 swxY w Y   |S )NzKDEV: FATAL self.id != g.current_person.id and self.id != g.system_person.idTr2  zCmfEntity.mark_viewed:r     timeout)r  r  zCmfComment:)r  r  r  )personr;  )r   r   r   r5  r   r  r+  r   r4  CmfLockry   r   CmfPersonViewr*   r   )rS   r  r  r  s       r    r  zCmfEntity.mark_viewed_obj  sq    	,(+I(+++1?22%%emq & s s s*955FF%F_JfiJJ&JJTVWWW 	G 	G  !LMM G & 4 8 869U[hl 8 m mG$$F$??DDFFF	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G s   &A+DD!$D!c                 6   | j         s%t          j                            d|  d           d S dg| j         z   }|                     ||          }|                                g}|r|                    |           d}|                     dg||ddg          }t          |          dk    r#t          j                            d|  d	           |D ]G}|j	        |k     r#||_	        |
                    d
           |dz  }0t          |j	                  dz   }Hd S )Nu"   DEV: Переиндексация uW   .orderno не выполнена, так как не указан orderno_partition_by.r  ry  r  r   )r   r  rG   r@   u   Переиндексация ug   .orderno выполнена частично, так как объектов слишком много.Tr  )orderno_partition_byr   r  r+  r*   _orderno_filterrw   rK   ru  r  r   r  )	rS   r  r  rG   r;  orderno_filtercur_ordernofix_obj_listfix_objs	            r    _orderno_reindexzCmfEntity._orderno_reindex  sr   ' 	K!!  #ds  #d  #d  #d  e  e  eFs77ggfVg,,--//0 	*!!&)))xx)^TZcdeibjxkk|$$K!!  #o#  #o  #o  #o  p  p  p# 	: 	:G,,"-t,,,t#!'/22T9	: 	:r   c           	         ||                                  }g d| j        z   }|                     ||          }|                     ||          }	|	j        rN|                    d          r|	j                            d|	           n|	j                            d|	           |	                                g}
|r|
                    |           |sN|                     |
dd|j	        gg	          d
k    r*| 
                    ||	            | j        d||||dd|S |
                    d|rdnd|j	        g           |                     |rdndg|
|          }|ryt          |j	        |j	        z
  dz            }|sWt          t          |j	        |j	        z
                      d
k    r*| 
                    ||	            | j        d||||dd|S n|rd}nd}|j	        |z
  |	_	        |	                    d           |	j	        S )N)r.  r  r-  ry  r  PPP-TSK-ORDERrw  PPP-OBJ-ORDERr  r   r(  r(  T)r  	before_idr  reversreindex><r  r   r  rG   r  r  r  r   )r  r  r*   r.  ry   r^  r  rw   r   r  r  ro  r  absr   )rS   r  r  r  r  r  rA  rG   beforer;  r  	prev_itemdeltas                r    ro  zCmfEntity.move_above  s   >4466F111C4LL622ggfVg,, ; 	P  ,, P55o35OOOO55o35OOO--//0 	*!!&))) 	}399^ifn=],^9__bccc   777!3>|9V\blp||t{|||y*@##S&.QRRRGG6&Iiiz%JSajpGqq	 
	)*;;q@AAE As3v~	8I'I#J#JKKqPP$$VF$;;;%s~  AVyQW`fpt  A  Ax  A  A  A nu,4   {r   c                    ||                                  }ddg| j        z   }|                     ||          }|j        rN|                    d          r|j                            d|           n|j                            d|           |                     ||          }|                                g}	|r|	                    |           |	                    d|rdnd	|j        g           |                     |rd
ndg|	|          }
|
r t          |
j        |j        z
  dz            }n|rd}nd}|j        |z   |_        |
                    d           |j        S )Nr.  r  ry  r  r  rw  r  r  r  r  r  r  r  r  Tr  )r  r  r*   r.  ry   r^  r  rw   r  r  r   )rS   r  after_idr  r  rA  rG   r;  afterr  	next_itemr  s               r    rp  zCmfEntity.move_below8  s   >4466FY'#*BBggfVg,, ; 	P  ,, P55o35OOOO55o35OOO00--//0 	*!!&)))y*@##S%-PQQQGGF&Ijj	%JSajpGqq	 	*U]:a?@@EE me+4   {r   c                     |                      ddg|          }|j        |k    rd S |                     ||j        |          S )Nr  r   )rG   r  r  r  r  )r*   r   ro  )rS   r  r  r  s       r    rq  zCmfEntity.move_upX  sG    tV<<9F~~Vvy~PPPr   c                     |                      |                                 ddg|          }|j        |k    rd S |                     ||j        |          S )Nr  r   )r   rG   r  )r  r  r  )r*   r  r   rp  )rS   r  r  r  s       r    rr  zCmfEntity.move_down`  sV    !5!5!7!7tU[\\8vF~~Vehv~NNNr   c                     |                      |          }|dz  }|                     ddg|||dz   g          }t          |          sd S |d         }|j        |k    rd S |                     ||j        |          S )	Nr(  r  r  r   r(  rG   r  r  r   r  )r   rK   ru  r   ro  )rS   r  r  
count_objs	half_objsbefore_listr  s          r    rs  zCmfEntity.move_middleh  s    YYfY--
!O	hhtTl6)U^abUbIchdd; 	FQ9F~~Vvy~PPPr   c                     g dg}| j         rhg }|                    |           |                     | j                    | j         D ]/}t          | |          }|                    |d|j        g           0|S )N)r  rJ  Nr   )r  rw   r  rt   r   )r_   r  partition_filterrX   r~   s        r    r  zCmfEntity._orderno_filterw  s    1112$ 	H!!!"2333T6777"7 	H 	H
j11 !''S%+(FGGGGr   c                 
   | j         r| j        rd S |                                 }t          j                    5  |                     dgg |          j        }d d d            n# 1 swxY w Y   |r|dz   | _        d S d| _        d S )Nmax__orderno)rG   r   r  r  )r   r  r  r   r  r*   r   )r_   r  max_ordernos      r    r  zCmfEntity._calc_orderno  s    { 	dl 	F%%'' "" 	 	((*+! #   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	  	 &-DLLLDLLLs   A##A'*A'c                 4    | j          d| j         d| j         S )Nz/?obj=r  )rd   rc   r8  r   s    r    hrefzCmfEntity.href  s$    .BBBBtyBBBr   c                     d S r:   r   r   s    r    r  zCmfEntity._calc_tree_parent  r  r   c                 J    | j         s|                                 | _         d S d S r:   )r8  gen_coder   s    r    r  zCmfEntity._calc_code  s)    y 	(DIII	( 	(r   c                    t          | d          r| j        s|                                  t          j                    5  dd l}|                                }|                                 dz   |                                 z   }d}d}|                     dd|gdd| j	        ggd	d	
          rq|dz  }|                                  d|                                  }||k     sJ d| d| j
         d            |                     dd|gdd| j	        ggd	d	
          q|                                |z
  }|dk    r5t          d|dd| j
         d| j	         dd| j        v o| j         d	           |cd d d            S # 1 swxY w Y   d S )Nr.  r   r[  '  r8  r   r   rJ  T)r  r0  r1  r(  u8   Превышен лимит поиска кода limit=z model=uA   , возможно надо отключить def gen_code: passz$!!! --- gen_code::duration too long r  r  r2  r  r  )ro   r  r  r   r  r  get_code_prefixnext_code_numberr   r   rh   r  rG   r8  )r_   r  r  r8  limitr   r  s          r    r  zCmfEntity.gen_code  sV   4## 	!DO 	!    "" 	 	KKKIIKKE''))C/$2G2G2I2IIDEA))VS$$7$dg9N#Oaeuy)zz eQ..00LL43H3H3J3JLL5yyy #e]b #e #ekokz #e #e #eyyy ))VS$$7$dg9N#Oaeuy)zz e yy{{U*H!||^8N ^ ^^ ^*.'^ ^6<6K5ZQUQZ^ ^ ^_ _ _ #	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   D2E>>FFc                     | j         S r:   )re   r   s    r    r	  zCmfEntity.get_code_prefix  s    r   c                     d}|                      g ddgdd          }|r-t          |j                            d          d                   }|S )Nr   )r8  
SIMILAR TOz[A-Z]+-[0-9]+\Z-cmf_created_atT)r  r   r0  r1  r[  r  )r   r  r8  r@   )r_   
max_numberlasts      r     _get_current_code_number_from_dbz*CmfEntity._get_current_code_number_from_db  sa    
yy I I IUfTg$(  > > 	7TY__S11"566Jr   c                    t           j        }d| j         }| j         d}|j                            |d          }|                                 	 |                    |          r|                    |          }n-|                                 dz   }|	                    ||           	 |
                                 n# t          j        j        $ r7}t                              d| d|j         d|j                    Y d	}~npd	}~ww xY w# 	 |
                                 w # t          j        j        $ r7}t                              d| d|j         d|j                    Y d	}~w d	}~ww xY wxY w|d
S )uN    Высчитывает следующий номер для кода
        znext_code_number-z.lock   r  r(  zlock release error z, lock_name z
, timeout N06)r  REDIS_DBrh   redisrk  acquirerN  incrr  r   release
exceptionsr   r   r  rT   r  )r_   redis_dbr  lock_keyrk  r
  r  s          r    r
  zCmfEntity.next_code_number  s    <3$/33o,,,~""8R"88
	bs## 4#+==#5#5  #'#H#H#J#JQ#N S"2333b#- b b b`a``TY``RVR^``aaaaaaaabb#- b b b`a``TY``RVR^``aaaaaaaab #'''sO   AD +C   D-DDE3D%$E3%E09-E+&E3+E00E3c                     d S r:   r   r   s    r    gen_namezCmfEntity.gen_name  s    tr   c                     | |         j         S r:   )r  )r_   rX   r}   rN   s       r    _get_field_log_levelzCmfEntity._get_field_log_level  s     J))r   c                    | j         rd S |sd S i }g }|                     d          D ]\  }}|dv r|                    d          r!|                    d          r7t	          |t
          j        j                  r	|j        s^nF|j	        du r#t                              d|j         d           |j	        dur|j        |j        k    r|                     |          }|d	k    r|                                }|s|||<   |                                }|s|d
k    r|j        }|r|                    | d|            |sd S d}	| j        rd}	| j        }
| j        dk    r| j        r| j        dd         }
|
st/          | d          r| j        }
t3          |	| j        t          j        | t7          |
          t7          | j                  |d                    |                    }t;          j        j        di | |S )NTr  )
r4  cache_fieldsr   r3  r  viewslikesstatus_closed_atstatus_modified_atstatus_in_progress_endr1  r  .u&   DEV: INFO. Возможно, поле uI    не попало в аудит, т.к. его old не загруженrd  r  rM   r   r  r      r8  z<br>)r_  rb  r   r-  parent_nameparent_code
audit_datahtml_diff_datar   ) r   r'   r  ry   r(   r   rG   r  _changesr   r   r  rv   r   rt  r!  
audit_diff	html_diffrw   r   rT   rh   rd  ro   r8  rs   r   r  r?   r   rr  rs  )r_   auditr-  r1  rX   r  r  _audit_diff
_html_diffr_  tmp_namerA  s               r    _system_auditzCmfEntity._system_audit  s    	F 	F
	%)ZZ4Z%@%@ "	@ "	@!J	 b b b ""5)) $$X..  )SZ%:;;  )  >S((GG fAZ  f  f  fg g g>,,IM1Q1Q11*==IB#..00K %0Jz"",,..J -*"6"6&_
 @  J!>!>*!>!>???  	F; 	G9?l**ty*y3'H 	!GD&11 	!yH?'HDI!!;;y11	
 	
 	
 	#..g...r   )r  r"  c                    t                      S r:   )r   )r_   r  r}   rN   s       r    r  zCmfEntity.get_all_followers:  s    uur   c                 6    t          j        j        dd| i| d S )Nr;  r   )r   rC  place_notifyr_   rN   s     r    _place_notifyzCmfEntity._place_notify=  s'    %99$9&99999r   c                 L   | j         j        r| j                                         |                     ddg          }|D ]c}|j                                         |j        D ]>}| j         r| j                            |           $| j                            |           ?bd S d S )NT
person_var)inherit_executorsrG   )is_favoriter   favorite_forry  r  r=  rw   r  )r_   	executorsexecutorr=  s       r    _calc_executors_favoritesz#CmfEntity._calc_executors_favoritesA  s    & 		=""$$$11DR^Q_1``I% = =#((***"*"5 = =J' =)00<<<<)00<<<<	=		= 		== =r   r   c                     t                      j        |d|i| |s)| j        s$| j        s|                                 | _        d S d S d S d S )Nr   )rQ   r   r   r8  r  )r_   r   r}   rN   r[   s       r    r   zCmfEntity.__init__M  sq    $6e6v666 	,T/ 	,9 , MMOO				, 	, 	, 	,, ,r   c                 X   | j         s\| j        rU| j                            d          r;|                     g d           | j        | _        |s|                                  d S | j        r,| j        j         j        s| j                            dg           | j        r| j        j         }n| j        dk    r| j	        }nd }| j         |k    r[|r[| j        
                                 t          j                            |ddg          | _        |s|                                  d S d S d S d S )NCmfProject:)zparent.task_code_prefixz&parent.task_code_use_logic_type_prefixzlogic_type.obj_code_prefixr  rU  r  ui_form_scheme)r   rG   )r  r9  ry   r  r-  r.  r  r  rh   r   ry  r   rU  r*   )r_   skip_project_perms_checkr  s      r    r  zCmfEntity._calc_projectU  sc     	4> 	dn6O6OP]6^6^ 	 < < < = = =  ;DL+ '$$&&&F; 	4t{5@ 	4K##\N333; 	/JJ_,,JJJ?j((Z(L!,00JXhGi0jjDL+ '$$&&&&& )(((
' 'r   c                    | j         rd S t          j        t          j        k    rd S d}|                                 }|                     d          D ]A}|j        |vr6|j                            d          s|j                            d          sd}B|sd S | j	        }| j	        j
        r| j	        j        r| j	        j        }| j        }|sQ| j        rJ| j        j                            d          s+| j        r$| j        j        r| j        j	        }| j        j        }| j        dv r=|                     dd	g           | j        j        sd S | j        j	        }| j        j        }| j        d
k    r=|                     ddg           | j        j        sd S | j        j	        }| j        j        }|sd S t          j        j        |k    rBt+          j        |dg          }t.          j                            d|j         d           d S d S )NFTr  r  r1  rF  )	CmfStatusCmfTransCmfTransValidCmfTransActionCmfTransFilterzworkflow.cmf_ownerzworkflow.sl_owner_lockCmfSchemeWfRulezscheme_wf.cmf_ownerzscheme_wf.sl_owner_lockrT   ry  ul   Владелец запретил изменять настройки объекта. Свяжитесь с r2  )r   r   r   r5  r  r   rh   ry   r  r  r   rt  sl_owner_lockr9  r   r-  r  workflow	scheme_wfrx  r   r   r4  r   r  r+  rT   )r_   r~  r  r~   r  rP  r   s          r    r  zCmfEntity._check_sl_owner_locks  s|   ; 	F q..F
$($B$B$D$D![[D[11 	" 	"E$,EEE!,77AA F!,55e<< F "
 	F (' 	1D,=,A 	1,0L* 	>~ >dn&:&E&Em&T&T >; >4;#< >#';#;L$(K$=M ? T T T24LMNNN=. =5L M7M ?///35NOPPP>/ >6L N8M 	F>,,-lF8LLLIK!!  #b  R[  R`  #b  #b  jn!  o  o  o  o  o -,r   c                     dgS )Nr@  r   r   s    r    r  z#CmfEntity.project_perm_allow_fields  s     
 	
r   c                 N    t                                                      g dz   S )N)r  r  zparent.project_idr  rP  zparent.sl_owner_lock)rQ   r  )r_   r[   s    r    r  zCmfEntity.save_preload_fields  s6     ww**,, 0Y 0Y 0Y Y 	Yr   c                 z    ddl m} | j        j        r| j        j        rdS  || j        j                  | _        dS )u   
        Защита от инжектов которые могут написать пользователи системы которые не всегда являются сотрудниками
        :return:
        r   )markup_html_cleanN)cmf.util.cmf_clean_textrV  rd  r   r  r   )r_   rV  s     r    _clean_textzCmfEntity._clean_text  sN    
 	>=====y# 	ty'8 	F%%dio66			r   r  r  c                   |                                   | j        rH| j        sA| j        j        s| j        j        r)t          j                            d| j	         d           | 
                                 | j        s|                                 | _        | j        j        r|                     dg           | j        j        r^| j        j        sRd| j        _        t!          j                    5  | j                            d           d d d            n# 1 swxY w Y   | j        j        r| j        j                            |            |                                  |                                  |                                  |                                  | j        r|r|                                  |                                  |                                  |                                  |                                  |                                  t>          j         rd| _!        n| j!        rd| _!         tE                      j        |||d|}| #                                 | $                    |%                    dd          	            | j&        |i | | '                                 |S )
NuN   Запрещено редактировать системный объект Tr2  tree_parent.tree_node_is_branchr  FrY  r2  )r2  )(rX  r  r   r8  r   rT   r   r  r+  r   rC  r  rV  r  ra  rO  r   r  r   rt  tree_child_deleter  r  r  r  r  r  r  r  r  r  r   r  r  rQ   _acl_spread_inheritancer6  r*   r  r  )r_   r  r  r}   rN   r  r[   s         r    r   zCmfEntity.save  s   ; 	Nt{ 	N y# Nty'; N%%  'Aw{w~  'A  'A  IM%  N  N  N&&(((y 	(DI& 	=?@AAA+ :D4D4X :7; 4(** : :$))D)999: : : : : : : : : : : : : : : # = $66t<<<    	? 	t 	IIKKK 	   &&(((!!!%%'''= 	)#'D  ! 	)#(D egglDDCCFCC$$&&&
 	GT!:!:;;;T,V,,,
 
s   2DD!Dc                     | j         sd S t                              d| j        j         d|            t
          j                            | j        j        |           d S )Nz1mark_full_search run CmfFullSearch.mark_dirty id=z celery=)
fast_index)rF  r   r  r   r   r   rI  
mark_dirty)r_   r  s     r    r  zCmfEntity.mark_full_search  sb     	F 	
cDGMcc[accddd''&'IIIIIr   r  r~  )
system_job	only_onceonly_once_argspriorityc                    t                               d|             t          j                                        rt                               d           d S t          j        |           }|                    | |j        dd          }|st                               d           d S |                                 t                               d|             d S )NzStart celery_full_search_index uJ   Не индексируем поскольку запущен импортTr/  ui   Не индексируем поскольку объект удален с флагом TEXKOM_db_deletezEnd celery_full_search_index )	r   r  r   enable_import_modeimport_is_runningr	  r*   full_search_fieldsfull_search_index)r  r}   rN   r   r;  s        r    celery_full_search_indexz"CmfEntity.celery_full_search_index  s     	
:&::;;;%7799 	GG`aaaF'//iiu'?QUeiijj 	GG  A  A  AF	88899999r   c           	      ^	   dd l }dd l}ddlm} t          j                            t          j        d| j	        
                    d          d         t          | j	                            } |d| j	        
                    d          d         t          | j	                  d t          | j                  dz            t          | j	                            }t          j                            |          r |t          j        |          }|                                s2|j                            d           |                    ||           n+|                    ||           |                    |           | d}t          j                            |          r|                    ||j                   t(          j                            d	d
| gg d          D ]}	|	j        j        }
|	j        j        }|	j        j        }d |	_        |	                                 |
|	j        k    r7| j        j                            |
|	j        j                  | _        | j        j                            |j                            |
          |	j        j                  | _        | j        j                            |j                             |
          |	j        j                  | _        | j        j                            ||	j        j                  | _        | j        j                            |j                            |          |	j        j                  | _        | j        j                            |j                             |          |	j        j                  | _        | j        j                            ||	j        j                  | _        | j        j                            |j                            |          |	j        j                  | _        | j        j                            |j                             |          |	j        j                  | _        | j!        r|                     d           |r |t          j        |          }t          |          S )Nr   )Pathr;  r  r~  T)exist_okz.metar-  rW  )rh  url_preview_imgurl_previewr)  r  )"shutilurllibpathlibrl  ospathr?   r  
UPLOAD_DIRr   r@   r  ru  rh   rN  r-  mkdirmover   rmtreer   rD  rK   rh  r   rn  ro  r   rd  replaceparsequote
quote_plusr   )r_   absoluterp  rq  rl  old_pathrt  new_pathold_meta_pathattachold_urlold_url_preview_imgold_url_previews                r    get_files_dirzCmfEntity.get_files_dir#  s         7<< 15$'--:L:LQ:OQTUYU\Q]Q]^^tE47==--a0TW>Ws4??S?SVW?W>W1XZ]^b^eZfZfgg7>>(##  	.tF-t44H??$$ (%%t%444Hh////Hh///h''''...Mw~~m,, <M8?;;; .33Hd4;P  ZC  ZC  ZC3  D  D . . **&,&<&B#"("4":!
fj(( $	 7 7AQ R RDI $	 7 78J8J78S8SU[U_Ue f fDI $	 7 78O8OPW8X8XZ`ZdZj k kDI $	 7 78KVMcMi j jDI $	 7 78J8JK^8_8_agakaq r rDI $	 7 78O8OPc8d8dflfpfv w wDI $	 7 7I[Ia b bDI $	 7 78J8J?8[8[]c]g]m n nDI $	 7 78O8OP_8`8`bhblbr s sDI? .III--- 	14)400D4yyr   c                 
   ddl m} 	 | j        dk    rt          j        rd S ddlm}  |d| j         ddt          j        g           t          	                    d	          }|si }i t          _
        |	                    | j        j                  }|ci }| j        j        |d
<   t          j        o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 ]'}|d                             |j        j                   (|	                    d          pg }| j        rb|                     d          D ]J\  }}|dv rt+          | |          }	|	j        dur;|	j        |j        k    r+t                              d| j         d|	j                    _t3          |	t4          j        j                  rt3          |	t4          j        j                  r-|	j        D ]$^}
}}|                    |j        j                   %nt3          |	j        t>                    s,|	j        %|                    |	j        j        j                   nCt3          |	j        t>                    r)|	j        D ]!}|                    |j        j                   "|	j        du r"t                              d|	j                     |	j        durt3          |	t4          j        j                  rt3          |	j        t>                    s,|	j        %|                    |	j        j        j                   nCt3          |	j        t>                    r)|	j        D ]!}|                    |j        j                   "|d                             |           L|d         !                    |           d}
| j"        rd}
| j#        j        r| j#        dk    rd}
|d                             |
           t?          tI          |d                             |d<   t?          tI          |d                             |d<   t?          tI          |d                             |d<   t?          tI          |d                             |d<   dt          v rt          j%        |d<   nd|d<   d t          v rt          j&        |d <   nd|d <   |t          j
        | j        j        <   d S )!Nr   )r   r  cmf_emit_eventzevent-z1this event DEPRECATED, use is\_changed-class_namer\  )rV   event_persons	emit_listr   event_current_personr9  r  placerh   relation_personschanged_fieldschanged_relationsr  Tr  )r3  r   r4  cmf_viewed_byr1  r0  .zemit: FIXME is changed bug rE   uR   DEV: INFO Могла не прийти инвалидация для old-поля rM   r  r  jsurlr8   session_tab_id)'collectionsr   rh   r   r  r   r  r   r   r*   r  r   ro   r9  r  r  r  r  rw   r   r'   rt   r   rt  r  r(   r   rG   rv  r  r/  rK   rv   r  r   r  r   r  r  )r_   r   r  r  bodypr  r-   r.   r~   r  r;  r0   r   s                 r    r  zCmfEntity.emitO  s   ++++++	 ?k))am)F......)))+^jm~  O  ~P  	Q  	Q  	Q  	QEE+&&	 	IAK}}TW]++<DDJ+,+;+Y@P@S@YD'( $D $D DM!%D')D#$%'D!"(*D$%DN4$$ 	5)B 	5 $ 4D4$$ 	5)B 	5 $ 4D4   	-TZ%: 	- J,DM**,, 	8 	8A#$++ADJ7777 HH%899?R?  	1zzTz22 1 1! G G G a(( :S((UY!'-A-AGG^$/^^EL\^^___eSZ%:;; 
A!%)>?? 	A 05~ C COFC!-44SV\BBBBC'T:: Au{?V)001EFFFF#EK66 A!& A AA-44QTZ@@@@:$$GG  Iqv  rG  I  I  J  J  J:S((Zsz?T-U-U(%ei66 A59;P)001CDDDD#EIt44 A!& A AA-44QTZ@@@@%&--a0000 !(():;;;; 	F& 	4+;t+C+CFXf%%%c4>2233X!%c$/?*@&A&A!B!B$(T2E-F)G)G$H$H !#'D1C,D(E(E#F#F a<<GDMMDMq  %&%5D!""%'D!"%)DGM"""r   c           
         g }|                                                     d          }|D ]k}t          |          dk    rA|                    d                    |d t          |          dz
                                V|                    |           ld                    d                    |                               d                    S )Nr  r  z{}%r  z%{}%rf  )r  r@   ru  rw   formatr?   )rS   querystemmed_query_wordswordsws        r    _get_stemmed_queryzCmfEntity._get_stemmed_query  s     ##C(( 	. 	.A1vv||#**5<<+3q66A:++G+GHHHH#**1----}}chh':;;BB3GGHHHr   r8   )r  rG   r  r  c                   |                      |          }|                    d          }ddd|gg}	d|v r1|                    d          D ]}
|	                    |
d|g           nbdD ]}
|	                    |
d|g           |                    | j                  r+t          |          d	k    r|	                    d
d|g           |r|	|g}	|r|	                    d
d|g           |                     ||	|          }|S )N)r  r9  rd  r8  rW  fields_filterre  )rT   rd  r8  ,   r   rJ  r  )r  r*   rw   ry   rh   ru  rK   )rS   r  rG   r  r  r}   rN   stemmed_queryr9  r/  r  r  s               r    rT  zCmfEntity.search  sC   ..U.;;JJ{++	T5!
 f$$ZZ00 < <7M:;;;;< . < <7M:;;;;// 4CJJ"4D4DdE2333 	('G 	4NND$	2333hhfWEhBB
r   c                 `    | j         st          d          t          j        | j                   S )NK   Блокировка объектов без id не реализована)r   rp   r   rl  r   s    r    rl  zCmfEntity.lock_ping  s/    w 	mklll )))r   c                 `    | j         st          d          t          j        | j                   S )ut   
        Из редиса заберём структуру, где есть данные
        :return:
        r  )r   rp   r   	lock_infor   s    r    r  zCmfEntity.lock_info  s1    
 w 	mklll )))r   c                     	 | j         st          d          |                                  | j        dk    r|                     d|            t          j        | j         d          S )u`   
        Захват объекта на редактирование
        :return:
        r  rU  zPPP-PR-ADMINrw  i  )r   rp   r   rh   r^  r   rk  r   s    r    rk  zCmfEntity.lock  so    
	w 	mklll
 ?l****>t*DDD|DGW---r   c                 `    | j         st          d          t          j        | j                   S )u>   
        Снятие захвата
        :return:
        r  )r   rp   r   rt  r   s    r    rt  zCmfEntity.unlock  s0    
 w 	mklll~dg&&&r   c                 <    d| _         |                     d          S )NTr  r>  r   ro  s      r    archivezCmfEntity.archive  s     yy4y(((r   c                 <    d| _         |                     d          S )NFTr  r  ro  s      r    archive_restorezCmfEntity.archive_restore  s    !yy4y(((r   )r  r  c          
         |                                   |                     g d           | j        rp|snt          | d          r3t          j                            d| j         d| j         dd           n)t          j                            d| j         d           d S |s| 	                                 dt                                                              d	           }| j        rrt                              d
| j        j                  sM| j        sF| d| j         d | j        j                 | _        | d| j         d | j        j                 | _        t'          j        | j                  t*          j        u rt.          j        j        smt          | d          r]t          | d          rM|                     ddg           | j        r.| j        j        | _        | d| j         | _        | j        | _        | j        r| j                            |            | j        s| j        s| j        }| j         dk    r/| j!        "                                 | j!        r| j!        dd         }t*          j#        $                    d| j         t.          j%        | tM          |          tM          | j        j'                              | j(        |i | | )                    d           t*          j*        +                    | dd            tY                      j-        |d|i|}t*          j*        +                    | dd           | .                                 |S )N)r  r   r.  r  rV  r[  rT   u<   Нельзя удалять системный объект  (r  Tr2  DEL%Y%m%d%H%M%Sz[A-Z]+-\d{4,}\Zr0   r  r  r  ry  r  r   r*  r   r_  rb  r   r-  r+  r,  r  before_saver  
after_save)/r  r  r  ro   r   r  r+  rT   r   r  r   r   r  r8  rematchr   r  r  r   r	  r   rj  r   global_settingslogin_reuse_lockr  deleted_loginr  rV  r\  r   rh   rd  ry  rr  rs  r   r  rt  r  r  CmfAutomationCrudTrigger	crud_hookrQ   r   r  )	r_   r  r  r}   rN   r  r5  r  r[   s	           r    r   zCmfEntity.delete
  s   |||}}}; 	u 	tV$$ |%%&|eien&|&|rvry&|&|&|  EI%  J  J  J  J%%&neiel&n&nvz%{{{F 	%""$$$ Ax||~~..~>>@@9 	GRXX&8$)/JJ 	GSWSc 	G!//DI//0E1E0EFDI!//DI//0E1E0EFDI #DG,,0@@@!2 AdG$$ A)0w)?)? A Wg$6777z (%)Z%5" &5555
!Z
 	5..t444 	;% 89?l22INN$$$y 4#'9QsU#3++$#'? / #H #DIM 2 2 ,    '&7777:::'11$-PPPeggnd:%:6::'11$,OOO
r   rM  c          
         |                      g d           | j        j        rIt          j        | j        ddddg          }|r(|j        r| j        | _        n|                                 | j	        rZt                              | j        | j	        j                  r0t                              | j        d| j	        j                  | _	        | j        rZt                              | j        | j        j                  r0t                              | j        d| j        j                  | _        t!          | d          rLt!          | d          r<|                      g d	
           | j        r| j        j        | _        | j        | _        | j        s| j	        }| j        dk    r/| j                                         | j        r| j        dd         }t0          j                            d| j        t6          j        | t;          |          t;          | j        j                             t1          j        j         | dg|R i |  tC                      j"        |d|i|S )N)r  r-  r.  Tr  rO  )r0  r1  rG   r8   r  r  )r  r  r  ry  r  r   r*  rR  r  restoredr@  )#r  r  ra  r   r4  r  r.  rV  rT  rT   r  r  ri  r   r2   r8  ro   r  r  r  r   rh   rd  ry  r   rr  rs  r   r   r  rt  r  r  rQ   rR  )r_   r@  r}   rN   rV  r5  r[   s         r    rR  zCmfEntity.restoreL  sT   @@@AAA* 	:!/0CUYim8EG\7]_ _ _K :* :'+|D$$779999 	P$"<dioNN 	Pt92tyOODI9 	P$"<dioNN 	Pt92tyOODI4!! 	(gdG&<&< 	($G$G$GHHHz (!/5
!Z
! 	HyH,..	   9 0#y3/HO''!#+MM	.. (    O$T:GGGGGGGuwwD	DVDDDr   c                 `   | j                                         sdS | j                                        D ]/}|                    dd| j        gdd|j        gg          }|r dS 0d| _         t          j                    5  |                     d	           ddd           dS # 1 swxY w Y   dS )
u    Убирает метку дерева у объекта при удалении узлов, при перемещении узлов Nr  rW  r   rJ  r(  FTr  )	rO  ry  
tree_nodesr  r   r   r   r  r   )r_   r(  r   r;  s       r    r\  zCmfEntity.tree_child_deletew  s   ',,.. 	F_3355 	 	E**&6dg%FtUZU]H^$_*``C  $)  "" 	& 	&III%%%	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	&s   ?B##B'*B')r  r0  c                l   ddl m}m} |j                            ddd          }|                                s |dd           d	S 	 t          t                                          	                    d
          | j
        ||          }t          d|           	 |                                 d	S # t          $ r(}	t                              d|	            Y d	}	~	d	S d	}	~	ww xY w# 	 |                                 w # t          $ r'}	t                              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   Невозможно изменить список полей, так как уже запущен процесс изменения. Попробуйте снова через минуту.Tr2  Nr  )meta_versionr\  r  r0   BaseModel:custom_fields_gen_metaz'custom_field_sync:: release lock error )cmf.appr  r+  r  rk  r  rs   r   r   r  rh   cmf_emit_server_eventr  r   r   r  )
rS   r  r0  r}   rN   r  r+  
redis_lockdatar  s
             r    rj  zCmfEntity.custom_field_sync  s    	0///////^(()S]atu(vv
!!## 	I  W  _c  d  d  d  dF	G(?(?(O(O#&>#(79 9 9D ""DdKKKG""$$$$$ G G GE!EEFFFFFFFFFGG""$$$$ G G GE!EEFFFFFFFFGsO   
AC( B3 3
C%=C  C%(D3*C?>D3?
D0	D+&D3+D00D3r  )channelr  c                 *   ddl m} ddl}t          j        t
          j                  dz  dz  }|                                }t          d| d           |j	        
                    d| dd	d	
          }|5  t          d           |                                r;|                                | d         k    rt          d           	 ddd           dS |                    | d                    t                      }t          t                     | d                  }t#          |          }	dd|j        gg}
| d         s,|
                    dddd |	j        D             gg dg           t           j                            |
g dd          D ]V}|j        s"|                                ||j        j        <   nd|	_        |j        rd|_        |                    d           W|s|	j        rg }|                                D ]1}|                    t>                               ||                     2t          d|            |	!                    |           t          d           |j	        
                    d d	d	
          5  t          d!           |	"                                 ddd           n# 1 swxY w Y   t          d"           |	#                                 ddd           n# 1 swxY w Y   t          d#           dS )$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\  )rQ  rb  rW  r  rd  rT   NOT INc                     g | ]	}|j         
S r   rh   )r=   r  s     r    r  z4CmfEntity.custom_fields_gen_meta.<locals>.<listcomp>  s    'Y'Y'Y'Y'Y'Yr   )dirtyrW  T)r   r-  r   T)r  rG   r0  Fr  rP  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  socketrr  rl  r  PROJECT_DIRgethostnamer  r  rk  rN  	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  custom_field_datas                 r    custom_fields_gen_metaz CmfEntity.custom_fields_gen_meta  sE    	%$$$$$V%7885@CXX%%''  O[c  O  O  O  	P  	P  	P^(()e()e)e)eos  GK(  L  L
 ,	- ,	-PQQQ##%% -*A*A*C*CtNG[*[*[EFFF,	- ,	- ,	- ,	- ,	- ,	- ,	- ,	- $$T.%9:::Iv,,tL12C)C888L($?@G= ,X'Y'Yl>X'Y'Y'YZ))) + , , ,
 %166"777$( 7   4 4

 "- 37A7J7J7L7LIjo344 /3L+# 4',J$OOdO333 -L3 - ")2)9)9);); a a%!(()A)ABS[^)A)_)_````PPPQQQ))-888  N  O  O  O^(()cmq  EI(  J  J 0 0jkkk --///0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 <===**,,,Y,	- ,	- ,	- ,	- ,	- ,	- ,	- ,	- ,	- ,	- ,	- ,	- ,	- ,	- ,	-Z 	+,,,,,s>   9AK9F7K9$J?3K9?K	K9K	&K99K= K=c                     ddl m} |j        dk    r) |d| j         |                                            d S  |d| j         |                                            d S )Nr   r  ztask-comment-)r  zaudit-task-comment-)r  r  r  r   r  )r_   r'  r}   rN   r  s        r    _comment_save_hookzCmfEntity._comment_save_hook  s     	+*****!!N44744DD]D]D_D_``````N:::$JcJcJeJeffffffr   c                 j   g ddd| j         gg}|r|                    dd|g           g }|D ]1}t          t          j        |          r|                    |           2t          j                            ||          D ]2}|D ]}t          ||||                    |                                 3d S )N)statusrW  openr  rW  r  r)  )r   rw   ro   r   rC  rK   r   r   )r_   r  rN   r/  _fieldsr-   r  r  s           r    _update_opened_notifiesz!CmfEntity._update_opened_notifies  s    +++hdg-FG 	;NNKy9::: 	" 	"Av'++ "q!!!&++77+KK 	 	F . .6!9----KKMMMM	 	r   c                     dS )uE    Базовый шаблон почтовых уведомлений zmail_notification.htmlr   r   s    r    +get_default_mail_notification_template_namez5CmfEntity.get_default_mail_notification_template_name  s
     ('r   c                 N    d  j                                         D             }                      j        |z              d|vrNt	           j                  dz   t          j                            t	           j	        pd                    z   |d<   d|vrUd} j
        D ]F}|j        dk    r9|dt          j                            t	          |j	        pd                    z   z  }G||d<   d|vrT j        sMt                               j         d	           t          j                             j        j                   d
S  j        |d<    j        r' j                                        j        j        |d<   n j        j        |d<   |                    d j        j                   |                    d j        j                    j        r|d         |d<   |                    d j        j                   |                    d j        j                   |                    d j                   |                    d j        j                   |                    d j        r j        j        j        pd
           |                    d j        r j        j        j        pd
           |                    d j        r j        j        j        pd
           |                    d j        j                   tA           d          r |                    d j!        j                   |                    d j"        j                   |                    d j#        j                    fd} |            }|r||d<   nd
|d<   t          j        j$        di | d
S )u   
        Медленный метод для вызова из celery или из массовых индексаций
        c                 &    g | ]\  }}|j         |S r   )r  r  s      r    r  z/CmfEntity.full_search_index.<locals>.<listcomp>  s$    PPPdaQ=OPPPPr   rd  r  r8   comments_textr   r  rT   ud    Объект без имени в поиск добавлять бессмысленно mark_cleanNr\  r  r  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                     g }                      d          D ]"\  }}|j        r|j        t          |t          j        j                  r|j        j        }nt          |t          j        j                  r d	                    d |D                       }n[t          |t          j        j
        t          j        j        f          r|j                            |d          }nt          |          }|r|dk    r|                     d	                    t!          |          |j        |f                     $d	                    |           S )NTr  r  c              3   F   K   | ]}|j         j        |j         j        V  d S r:   r  r=   r.   s     r    r>   zNCmfEntity.full_search_index.<locals>.obj_addon_fields_2_str.<locals>.<genexpr>L  s/      /\/\qv|/\/\/\/\/\/\/\r   r8   r  )r'   r  r   r(   r   rG   r  r8  r  r?   	CmfChoiceCmfChoiceIntrI  r*   r  rw   rA   rF   )r(  r  r~   result_valuer_   s       r    obj_addon_fields_2_strz;CmfEntity.full_search_index.<locals>.obj_addon_fields_2_strD  s8   F$(JJ$J$?$? d d 	5) dek.E!%)CDD 2',z'7#E3:+@AA 2'*xx/\/\e/\/\/\'\'\#ECJ,@#*BY+Z[[ 2',}'8'8'C'C'*5zz' !<3+>+> MM#((L,C,CU]T`+a"b"bccc99V$$$r   obj_addon_fieldsr   )%rG   r'   r  rh  r  rT   r   rI  
strip_htmlrd  r  r  r   r  r   
mark_cleanr   rh   r  cmf_ver_headry  rr   r8  r  r>  r  r  r9  r   r   r   r  ro   r  r  r3  index_object)r_   rN   addon_fieldsr  r'  r  r  s   `      r    ri  zCmfEntity.full_search_index  s    QPdk&7&7&9&9PPP 	0<?@@@
  ^^c1F4H4S4STWX\XaXgegThTh4i4iiF6N&(( M= e e$))!TF,@,K,KCPWP\Pb`bLcLc,d,d%ddM&3F?#	GGtw  E  E  E  F  F  F ++DGM:::F#|< 	-#05577:@F8#w}F8*dio666&$)/222 	,#F^F6N.$*;*ABBB-)9)?@@@*di000/4>+?@@@*DN,Xt~?R?X,`\`aaa+T_-[AUA[-c_cddd0$2F2j4K_KdKj2rnrsss.0C0IJJJ 4&& 	G.0EFFF*D,?,EFFF+T-A-GHHH	% 	% 	% 	% 	%* 2133  	.)9F%&&)-F%& 	)33F33333r   u8   Разрешить публичный доступ DELME)r  rF   r#   u-   Задать права для объектаr3  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   r'  u7   Подсказка к паролю шифрования)rF   r  c                 4    |                      g d           d S )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  s3     2 2 2 	3 	3 	3 	3 	3r   rM   c                    t          j        |          }	 |r|gnd}|dk    r|                    |           n|                    |           t	          |t
          j                  r|                    ddg           |dk    rYt          j	        |j
        k    r"|j                            d|j                   n|j                            d	|j                   n^|d
k    rXt          j	        |j
        k    r"|j                            d|j                   n!|j                            d|j                   n# t          $ r Y dS w xY wdS )u   
        Метод чисто для вызова с фронта для красоты
        perm = create|update|read|delete
        Nr  r{  r.  r-  rM   PPP-COM-EDIT-OWNrw  PPP-COM-EDIT-ALLr   PPP-COM-DELETE-OWNPPP-COM-DELETE-ALLFT)r   r4  r_  r   r(   r   r  r  r   rx  r   r.  r^  r-  r`  )rS   r  rX   permr;  rG   s         r    OLD_ux_check_permzCmfEntity.OLD_ux_check_perm  sx    #F++	%/9j\\TFv~~##F++++$$$??? #v011 dH 56668##~66==>PVYV`=aaaa==>PVYV`=aaaaX%%~66==>RX[Xb=cccc==>RX[Xb=ccc " 	 	 	55	 ts   D'D> >
EEc                    ddl m} |r t          j        |ddg          }|j        }n"| j        dk    rt          j        |dg          }	 |r|gnd }|dk    r|                    |           n\|dv r|                    |	           nA|d
v rn<|dk    r&|j        sdS |j        	                    d|           n |d| d           n# t          $ r Y dS w xY w	 | t          j        u r|dk    rb|j        rYt          j        |j        k    r#|j        	                    d|j                   n|j        	                    d|j                   nq|dk    rb|j        rYt          j        |j        k    r#|j        	                    d|j                   n,|j        	                    d|j                   n	|dk    r$|j        r|j        	                    d|           n|dk    rn |d| d           n| t          j        u r_|dk    rXt          j        j        sGt          j        s;t          j        s/t          j                            d          st          d          nZ| t          j        u rL|dk    r|j        	                    d|           n)|dk    r#|j        r|j        	                    d|           n# t          $ r Y dS w xY wdS ) Nr   r*  r.  zparent.projectry  rU  r  )rM   r   r  )r   publiczview-workflowFzPPP-PR-VIEW-WORKFLOWrw  u/   Недопустимый параметр perm=Tr2  rM   r  r  r   r	  r
  r   zPPP-COM-ADDProjectCreators)
group_codeuP   У пользователя нет прав на созднаие проектаr  PPP-DOC-SHAREzPPP-DOC-EDIT)r  r+  r   r4  r-  rh   r_  r   r.  r^  r`  r   r  r   rx  r   rU  is_adminr  rv  in_person_grouprj  )rS   r;  rX   r  r-  r+  rG   s          r    ru  zCmfEntity.ux_check_perm  s    	&%%%%% 	G'Y@P4QRRRCZFF^|++*69+FFFF	%/9j\\TFv~~##F++++---$$$????---(({ ! 5556LRU5VVVV	RDRRZ^____! 	 	 	55	
'	f'''8##{ f>S]::KAABTZ]ZdAeeeeKAABTZ]ZdAeeeX%%{ h>S]::KAABV\_\fAggggKAABV\_\fAgggX%%~ \@@TZ@[[[V^^IVPTVV^bccccc)))8##>2 MA<Q MUVUe M#$>#A#AM^#A#_#_ M&8  :L  'M  'M  !M***8##K99/s9SSSSX%%{ W==nRU=VVV
 " 	 	 	55	 ts,   AC -C 
CCG(K 
KKc                     | j         s| j        j        s| j        j        sd S |                                  d }| j        r| j        }n| j        r| j        }|| _        d S r:   )r   rV  r   r-  r  r  )r_   r  s     r    r  zCmfEntity._calc_perm_parent.  su     	t/: 	dk>T 	F    	&*KK[ 	&+K&r   c                     | j         j        sd S |                                  | j         r@| j                             ddg           | j         j        | _        | j         j        | _        d S d | _        d | _        d S )Nr  r  )r  r   r  r  r  r  r  r  r   s    r    r  z#CmfEntity._calc_perm_inherit_acl_id:  s    * 	F    	-((*A>)RSSS'+'7'MD$(,(8(ED%%%'+D$(,D%%%r   c                     d S r:   r   r   s    r    r  zCmfEntity._calc_perm_has_aclG  s    r   c                 >   | j         j        s0| j        j        s$| j        j        s|s|                                 sdS d}| j        rZ| j        dk    rO| j        j        rC| j        j        r7| j	        
                                 | j	                            d|            d}|                                  | j         r'| j        s t                              |           | _        | j        r3| j          | j        _        | j        | j        _        | j        | j        _        | j        r| j        nd| j        _        |rZt(          j        j                                        5  | j        j                                         ddd           n# 1 swxY w Y   n| j        j                                         t(          j        j                                        5  | j                                         |                                  ddd           dS # 1 swxY w Y   dS dS )u   TODO2 записать: нужно разобраться с ролевой моделью на правила АЦЛ:
        - кто может менять правила АЦЛ у объекта проектного/нет
        - - нужно ли проектное право на это
        - кто имеет право редактирвоать другие опции объекта, связанные с правами

        Args:
            force (bool, optional): _description_. Defaults to False.
        NFrj  r  rw  T)r-  )r  r   r  r   _acl_subjects_is_changedr  rh   perm_policy_anonymousperm_policy_guestr.  ry  r^  r  perm_aclr   r3  disabledobject_ownerperm_inheritinherit_acl_idr   r  r   r  r   r   clear_auto_acl_acl_scaffold)r_   r  can_skip_acls      r    r  zCmfEntity._calc_perm_aclJ  s    !,	+6	 >,	 		
 0022	 F? 	 t==$B\Bg=lp  mC  mN=LL22?2MMML    	>T] 	>"000==DM= 	% *.):%:DM"&*nDM#)-DM&GKGX+b4+C+C^bDM( +[(4466 / /M',,.../ / / / / / / / / / / / / / / #((***$0022 % %,,...""$$$% % % % % % % % % % % % % % % % % %	% 	%s$   FFF.HHHc                     d S r:   r   r   s    r    r!  zCmfEntity._acl_scaffoldu  s    4r   c                    |                                   |                                  | j        r| j                            g d           d| j        _        | j        j        D ]?}|j        dk    r|                                 "d|_        |                    d           @| j        j	                                         |                     d           d S )N)policyr  zrules.disabledzrules.sys_typeTr  r  )
r  r  r  r  r  r  sys_typer   r   r   )r_   rA  rules      r    r  zCmfEntity.disable_aclx  s     	   = 
	'M%%&`&`&`aaa%)DM"+ . .=F**KKMMMM$(DMIII----M$$&&&		D	!!!!!r   c                     | j         j        s&| j        j        s| j        j        s| j        j        sd S |                     g d           d }| j         r| j        j        }n| j        r| j        }|| _        d S )N)r  perm_acl_idr  r  r  )r  r   r  r  r  r  r   r  )r_   r  s     r    r  z"CmfEntity._calc_perm_effective_acl  s    !,	$/	 =+	 +6		 Fkkk	m 	m 	m $ 	=$(M$4!! 	=$($<!%:"""r   c                 (   ddl }| j        rdS | j        j        s| j        j        sdS t
                              d           ddlm} d}|rd |D             } |t          j
        j        | j        || j        j        | j        j        d           dS )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_jobschedule_deferred_jobc                     g | ]	}|j         
S r   r  )r=   r  s     r    r  z5CmfEntity._acl_spread_inheritance.<locals>.<listcomp>  s    !F!F!F1!,!F!F!Fr   )r  spread_model_namescmf_owner_is_changedperm_effective_acl_is_changedrN   )r  r   r  r   r  r   r  r   r,  r   rU  _acl_spread_inheritance_jobr   )r_   spread_modelsr   r,  r.  s        r    r]  z!CmfEntity._acl_spread_inheritance  s    ( 	 ; 	F*5 	9J9U 	F	YZZZ555555! 	G!F!F!F!F!Ff/K,0G8J:>:K:VCGC]Ch	&  & 	! 	! 	! 	! 	! 	!r   )r  r/  r0  )rb  ra  rc  c           	      n
   d }|rd |D             }t          j        | ddg          }t                              d           |rt                              d|            |}|t                                          }|D ]}t          j        j        j	        
                                                    d|j        z  |j        j        |j        j        d          }t!          |          }t"          j        j                            |j        d	 |D                        t                              d
t-          t!          |                                t                              d           |rg }	g }
|j        j        g}|rd}|d |         }
||d          }|}|t                                          }|D ]}t          j        j        j	        
                                                    d|j        z  |j        j        |
d          }t!          |          }d}t"          j        j                            |j        d |D                        |D ]p}|dz  }|d         |	v r%t                              d|d          d           6t          j        |d                   dk    rU|                    |d                    q|	|
z   }	t                              dt-          |	           dt-          |                      |t                              dt-          |	                      t                              d           |	rd}|	d |         }|	|d          }	|}|t                                          }|D ]}t          j        j        j	        
                                                    d|j        z  |j        j        |d          }t"          j        j                            |j        d |D                        t          j        j        j	        
                                                    d|j        z  |j        j        |d          }t!          |          }t"          j        j                            |j        d |D                        t                              dt-          |           dt-          |	                      |	t                              d           t                              d           t                              d           d S ) Nc                 6    g | ]}t          j        |          S r   )r   r6  )r=   r  s     r    r  z9CmfEntity._acl_spread_inheritance_job.<locals>.<listcomp>  s#    VVVaW6q99VVVr   r  r  ry  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_idr9  c                     h | ]
}|d          S r  r   r=   rows     r    	<setcomp>z8CmfEntity._acl_spread_inheritance_job.<locals>.<setcomp>  s    IcIcIcX[#d)IcIcIcr   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   c                     h | ]
}|d          S r  r   r8  s     r    r:  z8CmfEntity._acl_spread_inheritance_job.<locals>.<setcomp>      MgMgMg\_cRViMgMgMgr   r(  r   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
                                        c                     h | ]
}|d          S r  r   r8  s     r    r:  z8CmfEntity._acl_spread_inheritance_job.<locals>.<setcomp>>  r=  r   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
                                            c                     h | ]
}|d          S r  r   r8  s     r    r:  z8CmfEntity._acl_spread_inheritance_job.<locals>.<setcomp>P  r=  r   z_acl_spread_inheritance: DoneuH   _acl_spread_inheritance: Шаг 3. Перезагружаем кеш ACL)r   r4  r   r  rn   r   r   rj  r   _ddSessionexecuterg   r  r   r   rK   r   r  r  invalidate_idsrh   ru  r  r-  rw   )r  r.  r/  r0  r3  r;  _spread_modelschild_modelr  	processedcur_stage_parent_id_listnew_stage_parent_id_listbatch_count	upd_countr  cur_parent_batchs                   r    r2  z%CmfEntity._acl_spread_inheritance_job  s     	WVVCUVVVM #FND[3\]]]	  M  	N  	N  	N 	XGGnilnnooo*N%!*!:!:!<!<- X X&)-5577?? 	A "+	A, %($4$:!$. .  3ii!001GIcIc_bIcIcIcdddVc$s))nnVVWWWW	vwww( _	5I')$(+~$* &[#+CL[L+Q(+CKLL+Q(!.!)%.%>%>%@%@N#1 A AK !*-199;;CC E &/E0 251J1P*B2 2 C s))C !IG%44[5KMgMgcfMgMgMghhh  A A!Q	T7i//GG$xaPTg$x$x$xyyy$"7$@@LPP$077$@@@@A &(@@	  ZQTU^Q_Q_  Z  Zz}  W  {X  {X  Z  Z  [  [  [M + &[N GGaQTU^Q_Q_aabbbGG  W  X  X  X /S##,\k\#: %kll3	!.!)%.%>%>%@%@N#1 'i 'iK *-199;;CC E, /:.CED  251J1P*:F F C& G%44[5KMgMgcfMgMgMghhh *-199;;CC E0 3>2GEH 251J1P*:J J C s))CG%44[5KMgMgcfMgMgMghhhh  RQTUeQfQf  R  R  BE  FO  BP  BP  R  R  S  S  S_  /S` GG3444	Z[[[ 	
/00000r   c                 ^    | j         j        rdS t          | d          r| j        j        rdS dS )NTr  F)r   r   ro   r  r   s    r    r  z"CmfEntity._acl_subjects_is_changeda  s>    >$ 	44/00 	T5N5Y 	tur   c                     g }| j         r|                    | j                    t          | d          r| j        D ]}|                    |           |S )Nr  )r   rw   ro   r  )r_   r(  r  s      r    _acl_subjects_list_level_writez(CmfEntity._acl_subjects_list_level_writei  sd    > 	*MM$.)))4/00 	%2 % %e$$$$r   c                     g S r:   r   r   s    r    _acl_subjects_list_level_readz'CmfEntity._acl_subjects_list_level_reads  s    	r   c                    ddl m} | j        r| j        r| j        j                            d          d         }t          ||d           }|o|j                            | j                  }| j	        r| j
        j        n| j
        j        }|r|j        s`| j        j        r| j        nd }|j                            d| j        j        || j        j        | j        | j        j        ||| j	        	  	          t+                      j        di |S )Nr   r   r  ri  )	rj  rk  rl  rm  rn  r  ro  rp  r   r   )r   r   rc  r  r   r  rt   rG   r*   r   r  ru  rt  r\  r-  r  r3  rz  r  r  r9  rQ   r   )	r_   rN   r   parent_class_nameparent_modelparent_fieldr  r-  r[   s	           r    r   zCmfEntity._acl_check_writew  s(   &&&&&&  	(T%8 	( $ 3 9 C CC H H K"6+<dCCL'ZL,?,C,CDDY,Z,ZL04T,,ATJ (|': ((,(>HD$11!($:R:X!2DD]Dc!%!6"n2Zag; 2 ( ( ( (uww'11&111r   c                 ^    d}| j         rd}t          j                            | |d           d S )NrM   r   r  )r   r   r  r  )r_   rA  crud_actions      r    r  zCmfEntity.before_save_hook  s7    ; 	#"K'11$]SSSSSr   c                 Z    t           j                            | | j        rdndd           d S )Nr   rM   r  )r   r  r  r   r:  s     r    r  zCmfEntity.before_save_data_hook  s0    '11$DK8]U]_klllllr   	operation	subgroupsc                     ddl m} ddlm}  |d            || j        | j        ||t          j        j        j	        d           d S )Nr   r*  r+  up   Обработка может занять несколько минут, ожидайте оповещения.)cls_namerX  rY  notify_person_idr1  )
r  r+  r   r,  _group_changes_jobrh   r   r   r   r   )rS   rX  rY  r+  r,  s        r    group_changeszCmfEntity.group_changes  s    %%%%%%555555	  E  	F  	F  	F" #!*!*()(8(;(A 	
 	
 	
 	
 	
 	
r   u#   Массовое изменение)rA  show_bg_progressbarr[  r\  c                    dd l }t          j        t          j        t          j        t          j        t          j        d}| |                                v r	||          }n&t          j        	                    |||dd           d S d}d}|D ]}	d}
|
                    d	d
|	d         g          }d }|	                    d          r|	d                                         }g }t          d|                    ||
z                      D ]}}|                    d	d
|	d         g||
z  ||
z  |
z   g|          D ]L}	 |dk    rF|	d                                         D ]\  }}t!          |||           |                                 nx|dk    rX|	d                                         D ](\  }}t%          ||                              |           )|                                 n|dk    r|                                 |j                                         #  |j                                         |                    d|j         d|j         d|j         d           t6                              d|            Y KxY w|rd}dd                    |           }t          j        	                    |||dd           d S )Nr   )rl  CmfTestcaseCmfTestcaseRunCmfTestcaseRunHistoryCmfTestplanTestcaseTr(  )r  rT   r#  force_notify_current_personrd  uL   Успешное завершение массового изменения.uO   Массовое изменение закончилось без ошибок.r]  r   ri  r+  r(  changes)r  r  rG   rM   rw   r   z	<a href="z">r  z)</a>u)   Не удалось обработать u8   Ошибки при массовом изменения.uA   Обнаружены ошибки при изменении:</br>z</br>)mathr   rl  ra  rb  rc  rd  r  rC  r9  r   r*   rangeceilrK   r'   r   r   rt   rw   r   r   r	  rollbackr  rT   r8  r  r  r?   )r[  rX  rY  r\  rg  r  rS   notify_name
notify_msgsubgroupstepr  rG   error_hrefsr   r;  r  r   s                     r    r]  zCmfEntity._group_changes_job  sE    	"(.&,&8)/)>060L.4.H	  {''))))h'CC))' ,0 *    Fdf
! 	] 	]HD))D$0C#D)EECF||I&& 2	*//11K1diid
3344 ] ]88D$8K+L34t8QX_2M39 $ ; ; ] ]C]$004<Y4G4M4M4O4O ? ? 0	5 'Y > > > >HHJJJJ&(224<Y4G4M4M4O4O F F 0	5 'Y 7 7 > >u E E E EHHJJJJ&(22JJLLL])))#**+^sx+^+^38+^+^sx+^+^+^___))*[VY*[*[\\\\\%]](  	yTKx]d]i]iju]v]vxxJ%%#(, 	& 	
 	
 	
 	
 	
s   :CHA&J	r:   )r   Fr  )NNNNNNr  r  r  r  )NrM   )NNrM   Nr  )r   r   r   r   rc  r  rN  rF  rh  menu_tree_parent_idmenu_tree_ordernor   r  compileri  r  rz   r   r   r.  	CmfStr256rT   CmfStr64r8  r5  r  	CmfMarkuprd  r  tasks	documentsr  r  r  r  r   rG   r  r  CmfStrr  r>  r  r@  r?  r  rV  r  has_tree_nodesrO  tree_hiddenr/  root_parentr.  rP  r  r  r@  CmfIntr  r  full_search_typer  rv  r  rS  r  r   r  r  r  r  r  r  r  rm  rn  r  r  ro  rp  rq  rr  rs  r  r  r{   r  r  r  r  r	  r  r
  r  r!  r6  r   r  r;  rC  r   r  r  r  r  rX  r   r  cmf_deferred_jobrj  r  r  r  rT  rl  r  rk  rt  r  r  r   rR  r\  rj  on_server_eventrs   r  r  r  r  ri  perm_publicr  r  r  r  r  r  r  r  r  r  r  r  r  ru  r  r  r  r  r!  r  r  r]  r2  r  rN  rP  r   r  r  rK   r^  r]  r   r   s   @r    rn   rn   )  s          !c    K" " " #JJ'899(+EELI& *
 *
 *
 
K$ 5'k *-  D' ' ' ' 'x ' ' '( U1-  F 5-7	  D E/{  E 5  I u9~  H {k9CS]bd d dJeG-[ejv~  HL  V[  \  \  \Oj&&
8	 '  O U4	  F 5.  L 5+  L *""
E	 #  K *""
%3UT #  K !!
$)=%Z^ "  J Z%%
$NX]hlv{ & } }N***
$JTYchsw + y y*""
$OY^imw| # ~ ~K *""
/9h  vA  KP # Q QK j
   G J$$
P %  M L
 {Hj
#9u_cmn  p pG z''
>?=(B	
 
  (   *.t 	 	 	 	 \	     [   [  #        [G G GC C C* * * *X    & ; ; [; , , [,    [4 9 9 9 [9v   [" : : : [:, & & & [&P    [> Q Q Q [Q O O O [O Q Q Q [Q  $     0 C C XC  ( ( (  0       ( ( (.  * * *E E E EN 23       : : :
= 
= 
= %* , , , , , , ,' ' ' '<8o 8o 8ov
 
 
Y Y Y Y Y	7 	7 	7 !" D D D D D D DLJ J J J xj[\]]]: : ^] \:* * * *X_* _* _*D I I [I !#DT     [4* * *
* * *. . .&' ' ') ) )) ) ) #(% @ @ @ @ @ @ @D (- )E )E )E )E )E )E )EV& & & ,15 G G G G [G6 _?@@@:-T :- :- :- A@ \:-zg g g g(    ( ( [(
]4 ]4 ]4R *""3:#5u  OI  SX"  Y  YK :##CJ$6O~  IN#  O  OL z
z_tUM   O OH
 :##
D2U_d $ f fL *""
/Ze5 # 7 7K :++
dECo  |D , E E ***
d4qE + + +  J,,
zT5B - A A -0J,<,<
 Y -= - -) :##
E5(2i $ k kL 
((
I )  3 3 3 % % % [%N O O O [Od
' 
' 
'- - -  )% )% )% )%V  " " "&; ; ;"'! '! '! '!R  Gh Gh Gh i i i?C^cW1 W1 W1i i \W1r      2 2 2 2 20T T Tm m m 
S 
D 
 
 
 [
 "G]abbb9
C 9
3 9
$ 9
Y\ 9
 9
 9
 cb \9
 9
 9
 9
 9
r   rn   c                   0   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)dS )&r  Nrh   
field_typeui_group_name	ui_groupsrk   rF   r  r  db_typedb_column_namedb_table_namer  r   r   rI  disabled_choicesFdb_need_create_choice_tabledb_choice_table_namer#   rE  r  r  r'  Tr  r   r  options_list_paramsoptions_list_show_columnsoptions_list_search_columns
field_dictc                 2   t          |          }i }d }i }|                                D ]K\  }}|dk    r!t          |t                    rd |D             }|| j        v r|||<   |dvr|||<   |dk    r|}L | dd|p|i|}|                    |           |S )NrI  c                 D    i | ]}t                               |          |S r   )r  caption_to_name)r=   choices     r    r  z,CmfCustomField.from_dict.<locals>.<dictcomp>  s(    TTT^33F;;VTTTr   )r  r  r  rk   r  r  r  r  rk   r   )r   r'   r(   rK   __dataclass_fields___calc_db_choice_table_name)	rS   r  r   rk   ui_meta_nativerN   r-   r.   r  s	            r    r  zCmfCustomField.from_dict  s    j))
$$&& 
	# 
	#DAqI~~*Q"5"5~TTRSTTTC,,,q	 U U U 
I~~!"c>>.3G>v>>&&u---
r   c                 &   d                     d | j                            d          D                       }|j         | d}t          |          dk    r:t          j                            ddt          |j                  z
   dd	
           |S )Nr8   c                 6    g | ]}|                                 S r   r;   )r=   r  s     r    r  z;CmfCustomField.gen_db_choice_table_name.<locals>.<listcomp>  s     '['['[1'['['[r   r0   Ch@   u8   Имя поля не должно быть больше    u    символовTr2  )r?   rh   r@   ru  r   r  r+  )r_   r   r  s      r    gen_db_choice_table_namez'CmfCustomField.gen_db_choice_table_name  s    !ww'['[@U@UVY@Z@Z'['['[\\"'"2L4HLLL#$$r))K!!  #N]dehiniyezez]z  #N  #N  #N  VZ!  [  [  [##r   c                     t          | dd           }|sd S |dk    r>d| _        |                     |          | _        | j        | _        | j        | j        d<   d S ||                     |          k    r	|| _        d S d S )Nr   CUSTOM_CHOICE_MODELT)rt   r  r  r  r   rk   )r_   r   	rel_models      r    r  z)CmfCustomField._calc_db_choice_table_name!  s    D'400	 	F---/3D,(,(E(Ee(L(LD%2DJ$(JDL!!!$77>>>> )2D%%% ?>r   r:   )*r   r   r   rh   r  rN  r  r  r  r   rk   rs   rF   r  rM  r  r  r  r   r  r  r   r   rI  r  r  r  r#   rE  r  r  r'  r  r   r  r  r  r  r  r  r  r  r   r   r    r  r    sU        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11 4    [($ $ $2 2 2 2 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ej        fdZd ZdS )r  rQ  c                 V   || _         d | _        g | _        d | _        d | _        g | _        d | _        |                                 | _        | j        	                    d          | _
        d| _        d | j         j        j                            | j         j                  D             | _        | j                                        }t!          t"                    }d | j         j                                        D             D ]}|                    |j                  }d }d }d }t-          |t.          t0          f          rtt3          t4                                        |j                            d                    }	|	r2| j         j        j                            |	          rt;                      }n]t-          |t<                    r&|j         d}||v r|                    |          nd }n"|j        }||v r|                    |          nd }t4          j                             |j        dg          }
|
s;tB          "                    |
#                                |	          }|| j        $                    |           d
| _        d | j        D             | _        d S )N.bkFc                 V    i | ]&}|d                               d          |d          |'S )rT   ra  rm  )r=   columns     r    r  z+CmfCustomClass.__init__.<locals>.<dictcomp>B  sF     
 
 
f~((//
6NF
 
 
r   c                 F    g | ]}|j                             d           |S r  )rh   ry   r  s     r    r  z+CmfCustomClass.__init__.<locals>.<listcomp>M  s.    fffq|G^G^_dGeGef!fffr   r   r1  r   )rT   rG   rP  Tc                     i | ]
}|j         |S r   r  )r=   
field_datas     r    r  z+CmfCustomClass.__init__.<locals>.<dictcomp>h  s    #k#k#k*J$9:#k#k#kr   )%rQ  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   r   r   rK   rG   r   r*   rh   rm   r  r  r   r   rk   	has_tablers   r  r!  r  r  r  r   rw   )r_   rQ  r  fields_ui_groupsrY   r  r  _db_table_namedb_field_info	cmf_modelr  r  s               r    r   zCmfCustomClass.__init__5  s   ">B=?59*.68HL 7;7P7P7R7R595I5U5UV[5\5\
 
.+7MMdnNfgg
 
 

 _))++
 't,, gfT^%:%A%A%C%Cfff 	' 	'I(,,Y-ABBI!N!N M)nj%ABB 	i LL,,Y->-B-B7-K-KLL	 +!2!>!H!H!S!S +$(FFMI77 i$-$8!=!=!=BPT^B^B^
~ > > >dh!*!5BPT^B^B^
~ > > >dh,00i6JTWSX0YYJ '11*2E2E2G2Gy1YYJ ("))*5555"&#k#kX\Xj#k#k#k   r   rG   c                 "   d | j         D             }|D ]}|                    |j                  }|s#| j                             |           d| _        |}|j        | j        j        vrA|j        | j        vr2|j        dz   | j        vr!| j                            |           d| _        | j        j        |j                 }t          |d          r|j
        |j
        k    rd| _        t          |d          r|j        |j        k    rd| _        dS )u  
        Получим список новых полей, которые надо создать.
        Соберём новые группы на основе системного значения и списка полей.
        Поля удалять нельзя, т.к. данные могут быть бесценны. TODO удалять, если данных нет.
        c                     i | ]
}|j         |S r   r  r  s     r    r  z/CmfCustomClass.merge_fields.<locals>.<dictcomp>p  s    BBB!alABBBr   Tr1  rI  r  N)r  r*   rh   rw   r   rQ  rG   r  r  ro   rI  r  )r_   rG   
cur_fieldsr  custom_fieldr~   s         r    r  zCmfCustomClass.merge_fieldsj  s2    CBt/ABBB
  	+ 	+J%>>**?@@L *"))*555"&)&dn.CCC*$/AAlF]^cFckokzFzFz)00>>>&*DO-l.EF5),, +1E1V1V&*DO5"455 +,:W[`[q:q:q&*DO#	+ 	+r   c                 F   | j         D ]}t          t          j        |j                  }t          |t                    rt                      |j        rj|j	        rb| j
        j        j                            |j                   | j
        j         |j         }| j
        j        j                            |           t          |t                     rc| j
        j         d|j         }| j
        j         |j                                         }| j
        j        j                            |           .t          |t&                    r|j         d}t          j        j        }n|j        }| j
        j        j                            | j
        j        ||           | j                            d          }| j                                        r| j                            | j                   |                     |           |                    | j                   dS )uP   Создадим поля в базе и сохраним файл модели.r0   r1  r  N)r  rt   r   rG   r  rm   r  r  r  r  rQ  r   r   add_custom_choice_modelrh   add_custom_m2m_modelr  rg   r<   r  r  add_custom_columnr  r  rN  renamer  _write_custom_model_file)r_   r  r  r\  
table_namecolumn_namemodel_tmp_paths          r    r  zCmfCustomClass.save_changes  s    / 	o 	oJ Z-BCCJ*n55 4$&&&0 49 SN%1II*Jijjj$(N$=!`z?^!`!`JN%1FFzRRRJ
33 
4 $ 8RR:;PRR
 $ 9_:;P;[;[;];]__
!-BB:NNNJ88 4!+!6;;; Z0

(3N);;DN<TVacmnnnn -99%@@&&(( 	< ''(:;;;%%n555d233333r   c                 8   ddl m} dd l}	 d }	  |             n# t          j        $ r t
                              d           | j        rS| j                                        r:t
          	                    d           | j        
                    | j                   nU| j        rM| j                                        r4t
          	                    d           | j                                         n  |              w xY w |dd| j        j        i           d S )	Nr   )r  c                      t          j        t          j                   } dD ]2}| dz  |z  }|                                r|                                 3t          j        g dd           d S )N)z__autogen_models.pyz__autogen_models_tmp.pyz__autogen_models.tsr  )z/usr/bin/envpython3z	manage.pyautogenT)check)rr  rl  r  r  rN  unlink
subprocessrun)project_pathautogen_filenameautogen_file_paths      r    applyz+CmfCustomClass.apply_changes.<locals>.apply  s    "<6+=(?@@L$k / / $0$67G$G!$++-- /%,,...NNNNVZ[[[[[[r   uG   Ошибка применения новой кастом модели.u=   Есть backup file попробуем откатиться.uA   Попробуем откатиться удалив custom file.zBaseModel:custom_field_syncrb  )r   r  geventr  SubprocessErrorr  r  r  rN  r  r  r  r  rQ  rh   )r_   r  r  r  s       r    r  zCmfCustomClass.apply_changes  sN   555555Y	\ 	\ 	\	EGGGG) 	 	 	ghhh! d&8&?&?&A&A \]]]"))$*>????% $*>*E*E*G*G `aaa$++----EGGG	 	;>NPTP^Pi=jkkkkks
   
 C$C?c           	         ddl m} ddlm} t          | j                                      t          j         dd                              dd          dd         }t          	                    t          
                    |                     d	}t          j                            |d
          }t          j                            |          }|t          j        |<   |j                            |           t$          j        j        j        D ]}t-          ||          }t/          t$                    |         }	|j        D ],}
|
                    d          r|j        |
         |	j        |
<   - ||	j                  D ](}
|
                    d          r|
|j        vr|	j        |
= )|j        |	_        |j        |	_        t/          |          D ]v}|                    | j        j         d          s.|                    | j        j         | j        j         d          r$t=          t$          |t-          ||                     w|                                 i t@          _!        i t@          _"        | j        j#        j$        j%        &                    | j        j                  r!| j        j#        j$        j%        | j        j        = t$          j'        (                                 dS )u   
        без перезагрузки обновляем в памяти модели и поля, добавляя кастомные
        r   )r  )r   r\  r8   rE   Nr  custom_modelsz /opt/eva-app/__autogen_models.pyra  Cf))r  r  r   r  r  ry  r  r  	importlibreloadimport_moduleutilspec_from_file_locationmodule_from_specr  modulesloaderexec_moduler   r  rb  rI  rt   r   rG   ry   rk   r  rQ  rh   r   flushdbr  r  cache_cust_field_config_schemer   r   models_registryr*   RelationCachebuild_fields_cache)r_   r  r   module_pathmodule_namespecr  r\  custom_modelrQ  rX   s              r    reload_models_and_fieldsz'CmfCustomClass.reload_models_and_fields  s    	&%%%%%$.//776;M8P8P8PRTUU]]^acfgghkikhkl00==>>> &~55kCeff!77==#0K ... !-<D 	E 	EJ"=*==LVZ0I*1 S S
((// S3?3Fz3RI$Z0"d9#344 5 5
((// 5JlFY4Y4Y!(4 , 4I(4(DI%% }-- 	P 	PJ$$(A%E%E%EFF P*J_J_cgcqc|  a\  C  M  X  a\  a\  a\  K]  K] P
GM:,N,NOOO 	 -/*>(8<<T^=VWW 	Y!-=dn>WX 	//11111r   rF   r"  c                 L   |s!t           j                            dd           |                     |          }t	          d          D ]3}d| }|s|                    d          r|d| z  }|| j        vr|c S 4t           j                            d| d	| d
d           d S )NuM   У настраиваемого поля не указано названиеTr2  r]  ra  r1  r0   u#   Такое имя уже есть: r2  r  )r   r  r+  r  rh  r  r  )r  rF   	name_basennrX   s        r    calc_field_namezCmfCustomClass.calc_field_name  s     	K!!"qy}!~~~ 0099	** 	" 	"B*y**J 'Y''.. 'h"hh&
!888!!!! 9 	ZIZZPWZZZbfgggggr   c                 h    t          | dd          }d                    d |D                       }|S )NruT)language_coderH   r8   c              3   j   K   | ].}|                                 r|                                nd V  /dS )r0   N)isalnumr3   )r=   r  s     r    r>   z1CmfCustomClass.caption_to_name.<locals>.<genexpr>  s;      HHaQYY[[9			cHHHHHHr   )r   r?   )rF   rT   s     r    r  zCmfCustomClass.caption_to_name
  s;    tdCCCwwHH4HHHIIr   rY   c                     | j         D ]A}t          |dd           }t          |t                    r|                    d          r|c S Bd S )Nrh   Cmf)__mro__rt   r(   r  ry   )rY   rW   base_class_names      r    _field_type_namezCmfCustomClass._field_type_name  se     ") 	' 	'H%hdCCO/3// 'O4N4Nu4U4U '&&&&	' 	'r   	file_pathc                    t                               t                               t          j                            t          j        d          g                    }d |j        d<   |	                    d          }| j
        j        D ]}|j                            d          s nd}|                    d          5 }|                    |                    | |	                     ddd           dS # 1 swxY w Y   dS )
u^   Дампим кастомные поля в файл используя шаблон и jinja2zcmf/templates)r  c                     t          | t                    r)d                    |                     dd                    n| S )Nz'''{}'''z'''z""")r(   r  r  ry  )xs    r    rn  z9CmfCustomClass._write_custom_model_file.<locals>.<lambda>  s;    ]ghikn]o]o/vz/@/@5RWAXAX/Y/Y/Yuv r   r{  zcmf_model.tmpltcustom.Nr  )r  r  )jinja2EnvironmentFileSystemLoaderrs  rt  r?   r  r  filtersget_templaterQ  	__bases__r   ry   r  ri  render)r_   r  	jinja_envtemplater  
model_files         r    r  z'CmfCustomClass._write_custom_model_file  sT   &&**BGLL9K_,],]+^__ ' a a	 &w%v	'"))*;<<.2 	 	J(33I>>  J^^C   	RJX__DZ_PPQQQ	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	Rs   ?+C77C;>C;c                    t          j        t          j         d| j        j         d          }| j        j        D ]}|j                            d          r[d	                    |j        
                    d          dd                   }t          j        t          j         d| d          } nZd	                    |j        
                    d          dd                   }t          j        t          j         d| d          } |                    d	d	
           |dz  }|                                s@|                    d          5  	 ddd           n# 1 swxY w Y   t          d|            t                              d          }d	                    d |                    | j        j                  D                       }|| dz  S )uY   Возвращает путь к файлу где будут кастомные поляz/custom/modules/z/fieldsr  r\  rE   Nr)  z/custom/T)parentsrm  z__init__.pyr  u   Создан z[A-Z][a-z0-9]+r0   c                 6    g | ]}|                                 S r   )r3   )r=   words     r    r  z7CmfCustomClass._get_model_file_path.<locals>.<listcomp>>  s     "l"l"lD4::<<"l"l"lr   z.py)rr  rl  r  r  rQ  rd   r  r   ry   r?   r@   rv  rN  r  r  r  rr  findallrh   )r_   fields_dir_pathrS   postfixpkg_init_file_pathname_word_remodel_filenames          r    r  z#CmfCustomClass._get_model_file_path)  s   !,&*<'o'odnNf'o'o'opp>+ 		 		C~((33 ((3>#7#7#<#<SbS#ABB"),&2D/W/Ww/W/W/W"X"X ((3>#7#7#<#<SbS#ABB"),&2D/^/^g/^/^/^"_"_dT:::,]:!((** 	8#((--                6"466777zz"233"l"lL<P<PQUQ_Qj<k<k"l"l"lmm.55555s   EE#&E#N)r   r   r   r  rn   r   r   r  r  r  r  r  r  r  r  r  rP   r  rr  rl  r  r  r   r   r    r  r  4  s?       3l$y/ 3l 3l 3l 3lj+4#7 + + + +44 4 4B!l !l !lH02 02 02f hs hs h h h \h     \
 'K ' ' ' \'R', R R R R"6 6 6 6 6r   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	<   dS )
CmfUiFullPathNr   rd   r9  rc   r8  sharelink_hashvfrT   )r   r   r   r   r  rN  rd   r9  rc   r8  r  r  rT   r   r   r    r  r  C  s         BNNN IsIsGS D#NCBNNND#r   r  c                       e Zd ZU dZeed<   dZeed<   dZeed<    e	j
        e          Zeed<   dZeed<   d	Zeed
<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dS )CmfUiMenuNodeNr  r,  FrO  )default_factoryr  r  T
allow_movechildren_countr  r&  only_archivedr>  )r   r   r   r  r  rN  r,  rO  rM  rQ  r~   rK   r  r  r  r  r  r  r&  r  r>  r   r   r    r  r  ]  s         
 NCK %%%%({(>>>J>>>GSJNCFDHcM4L$r   r  c                       e Zd Z G d de          Zed             Zed             Zede	fd            Z
ed             Zede	defd	            Zed
             Zed             ZdS )r%  c                       e Zd ZdS )UbqlConverter.UBQLParseErrorNr@  r   r   r    UBQLParseErrorr  r  s        r   r  c                    dd l }d|vrut          ||          s |                     d|j         d|           t	          ||          }t          |t          j        j                  sd S |	                                S t                      }|                    d          d         }d}|                    t          j        j                                        t          j        g          D ]j}t          ||          rXd}t	          ||          }t          |t          j        j                  r'|                    |	                                           k|s|                     d|           t%          |          S )	Nr   rE   u   У модели u    не найдено поле r  FTu0   Не найдено поле у моделей: )	itertoolsro   r  rh   rt   rm   r   rG   rv  r  r   r@   chainr   rn   r   CmfGanttTaskrM   rK   )rS   r   
field_pathr  r~   r  right_field_namefound_field_flags           r    _get_field_model_listz#UbqlConverter._get_field_model_listu  s    j  5*-- z(()xE<L)x)xlv)x)xyyyE:..EeSZ%:;; t'')))ee%++C004 __SZ%9%I%I%K%KfNaMbcc 	? 	?Eu.// ?#' '788eSZ%:;; ?&&u';';'='=>>> 	l$$%jXh%j%jk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 ]-}||vr|                    |          }|r|j        j        c S .|D ](}|                    |          }|r|j        j        c S )|S )Nr  )r   rl  CmfListrU  rj  rJ  rj  rg  
CmfOrgUnitCmfRoleCmfWorkflowCmfTagCmfRelationOptionCmfLogicTyperk  
CmfCompanyCmfActivityr*   r   r   )rS   r8  
model_listr   r;  s        r    _convert_code_to_uuidz#UbqlConverter._convert_code_to_uuid  s     nfnf6GI[&(8&:OQWQbnf&8&-Ia)6+;V=NPVPbd 	$ 	$E J&&)))&&C $v|###$   	$ 	$E)))&&C $v|###$ r   r!  c                 ^   d}d}d}d}|D ];}d|vrt                               d|z   dz   d|z   dz   | t           j                  } <|                                 } | d         d	k    rd	|  d
} | D ]<}|rG||z  }||k    r;|dd                                         |v r|                                }||z  }d}d}L|dk    rd}|dv r|                                r||z  }r|}|}w|dv r|                                }|s<|dk    r|d         d
k    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}|                                |v r|                                }|d|z   dz   z  }||z  }d}7||z  }>|S )uU   
        Расстановка кавычек в UBQL без кавычек
        r8   )ri  r  r  zNOT LIKEre  z	NOT ILIKEr  zNOT SIMILAR TOro  z
NOT EXISTSrd  rh  r  z([^"'])z\1"z"\2)flagsr   []r(  r  ,)"')r1  r2  r3  )r5  r4  )g.current_userg.now()g.date())TrueFalseNoner4  )r  r2   Ir  upper)r!  r  	cur_tokencur_string_symbolorm_operatorsoperr  s          r    
quote_ubqlzUbqlConverter.quote_ubql  s   
 	k " 	k 	kD$66.4/-?$QWAWY]egei6jjDDzz||7c>>t;;;D A	 A	A  Q	))) !2,,..-??$-OO$5$5	9$C "I(*%Cxx J??$$ NI %&!	O##%OO--	  
CxxCGsNNs2wj7P7P !CxxCxCGsNNs
1HCQ<:--9$C1HC "I III$(AAA9$C1HC "I??$$55 ) 1 1IsY,,q	NII
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                              |          }t          d&           t          |           t          d'           t          |           ||k    r-t          d(           t          |           t          d)           t                       t                       d S )*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%  rB  )
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66&0 	 	"T>**400C(OOO$KKK'NNN#JJJn$$.///n%%%'(((GGGGGGG	 	r   r"  c                     t                               |          }|                    dd          }|                    dd          }|                    dd          }|                    dd          }t          j        |          } fd	d
t
          dt
          ffd	  |          } |          }nG#  j        $ r:}t          j        	                    d|j
        d          d           d }Y d }~nd }~ww xY w|S )Nr6  z'__G_CURRENT_USER'r7  z	'__G_NOW'r8  z
'__G_DATE'z$self.z	'__SELF.'c                    t          | t                    rt          |           } t          | t                    s| S d}t          |           dk    rt          | d         t                    rw| d                                         dv rd}t          | d         t                    r>| d                                         dk    r | d                                         dk    rd}t          |           d	k    r?t          | d         t                    r#| d         d
vr|s| }| d         }                    |          }|r| d         }|s|S t          |t                    r| d         dk    r7g }|D ] }|                     |                     !| d         | d         |g}ng }|D ]K}d| d         v r|                    |           "|                                        ||                     L| d         | d         |g}n)d|vr%| d         | d                             ||          g}|S |S g }	| D ] }
|	                     |
                     !|	S )NFr  r   zorder byr   Tr(  orderbyr  )rd  rh  ro  r  )	r(   rJ   rK   ru  r  r3   r"  rw   r.  )r!  skip_orderbyblqrX   r-  valexists_filter_val
tuuid_valsr   r   _recursive_ubql_processrS   r   s              r    rW  z7UbqlConverter.ubql2bql.<locals>._recursive_ubql_process  s   $&& "Dzz dD))  L 4yy1}}DGS!9!9}7==??&>>>#'Ld1gs++ (Q70J0JtTUw}}bfOfOf#'L 4yyA~~*T!Wc":":~47mC[C[dpC[!!W
 66ujII
 q'C #"
!#t,, ]7h..,.M(+ T T - 4 45L5LT5R5R S S S S#'7DG]"CCC *,J(+ c c#&$q'>>$.$5$5d$;$;$;$;$.$5$5c6O6OPTV`6a6a$b$b$b$b#'7DGZ"@CCC#AwQ1J1J3PZ1[1[\J
C 7 7

221556666Jr   r!  r"  c                    t          | t                    rt          |           } t          | t                    s| S t          |           dk    rt          | d         t                    re| d                                         dk    rGt          | d         t                    r,| d                                         dk    rdg| dd         z   } t          |           dk    rTt          | d         t                    r9| d                                         dv rfd	 | dd                   }dd
|gS g }| D ] }|                     |                     !|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   rO  r(  rP  r   NrN  c                     g }| D ]d}t          |t                    r|                     |                     6|dk    r=|                    |                                           e|S )Nr   )r(   rK   r  rw   r3   )
field_list_resrX   rec_parse_order_bys      r    r\  zTUbqlConverter.ubql2bql.<locals>._recursive_ubql_order_by.<locals>.rec_parse_order_by  s~    D&0 < <
%j$77 < KK(:(::(F(FGGGG'3..$ KK
(8(8(:(:;;;;Kr   r   )r(   rJ   rK   ru  r  r3   rw   )r!  r   r   r   r\  _recursive_ubql_order_bys       @r    r]  z8UbqlConverter.ubql2bql.<locals>._recursive_ubql_order_by  sj    $&& "Dzz dD))  4yy1}}DGS!9!9}d1gmmooQX>X>X"47C00 ?Y59!W]]__5L5L"|d122h.4yyA~~*T!Wc":":~tAw}}Rj?j?j
  
  
  
  
  .-d122h77"C22C 8 8

33A667777Jr   u&   Ошибка обработки UBQL: r   u   . UBQL отключен)r%  rB  ry  astliteral_evalrK   r  r   r  r+  r}   )rS   r!  r   filter_ubql
filter_bqlr  r]  rW  s   ` `   @@r    r   zUbqlConverter.ubql2bql~  sS   ''-- ||,.CDD||I|44||J66||Hl33&t,,6	 6	 6	 6	 6	 6	 6	p,	$ ,	4 ,	 ,	 ,	 ,	 ,	 ,	\	00==J11*==JJ! 	 	 	K!!"m16RS9"m"m"mnnnJJJJJJ	 s   'B> >
D0C==D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 ]\  }}|                     |t          j                  }t          d            t          |           t          d!           t          |           ||k    r-t          d"           t          |           t          d#           t                       t                       d S )$NzZ[['name', '=', 'test'], ['OR', ['parent', '=', 'evateam'], ['parent.name', '=', 'test2']]])rT   r   testrd  )r-  r   /CmfProject:6597795c-95ce-11ea-9023-6f4fdd48682b)zparent.namer   test2zh[['name', '=', 'test'], ['OR', ['parent.parent.parent', '=', 'evateam'], ['parent.name', '=', 'test2']]])zparent.parent.parentr   rd  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   re  z^[['name', '=', 'test'], ['OR', ['parent', '=', 'evateam'], ['name', '=', ['test2', 'test3']]]]rT   r   re  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-  ri  rd  z/CmfProject:8e97dfe2-7113-11eb-b9c1-7571d63a6e0dz!['cmf_modified_at', '<', g.now()])r3  r  __G_NOWz"['cmf_modified_at', '=', g.date()])r3  r   __G_DATEz(['cmf_modified_by', '=', g.current_user])r   r   __G_CURRENT_USERrD  rE  rF  rG  rH  r  r   r   rl  rS   rI  r!  r   r  s        r    test_ubql2bqlzUbqlConverter.test_ubql2bql  s    q&&&/q/q/q  tQ  tQ  tQ  )R  S &&&///  B_  B_  B_  )`  a }&&&/U/U/UWtWtWt(uv j&&&/q/q/q  tJ  tJ  tJ  )K  L u&&&/q/q/qtz|  CJ  LS  BT  tU  )V  W x y&&&/M/M/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33 9444 ?<<<?#

J 	5666% 	 	KT3,,tV^44C(OOO$KKK'NNN#JJJczz.///c


'((( GGGGGGG	 	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 ]\  }}|                     |t          j                  }t          d           t          |           t          d           t          |           ||k    r-t          d           t          |           t          d           t                       t                       d S )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:rE  rF  rG  rH  rk  rl  s        r    test_ubql2bql_oreder_byz%UbqlConverter.test_ubql2bql_oreder_by2  s'    ;S#4"56 BS6+;"<= @S#4f"=> AS#4f"=>

" 	>???% 	 	KT3,,tV^44C(OOO$KKK'NNN#JJJczz.///c


'(((GGGGGGG	 	r   N)r   r   r   r  r  r  r"  r.  r  r  rB  rK  rK   r   rm  ro  r   r   r    r%  r%  q  s,               ! ! [!:   [. X X X X \Xt t t \tn yC y4 y y y [yv 5 5 [5n   [  r   r%  )Hr  rQ  rr  r  r  r   r  r   r   r   collections.abcr   r   r   	functoolsr	   typingr
   r   r   r   typesr   base64r^  redis.exceptionsr  r  r   sqlalchemy.ormr   transliterater   
cmf.fieldsr   r   cmf.util.immutablesr   r   r  r   cmf.base_errorr   r   r   r   r"   r   r  rr  r1   rq   r%   r)   r6   r  rA   rI   rC   TypeVarr   r   r  r8  r<  r[  rn   r  r  r  r  r%  r   r   r    <module>r|     s*         



     ! ! ! ! ! ! < < < < < < < < < < # # # # # #             1 1 1 1 1 1 1 1 1 1 1 1        



         & & & & & & " " " " " " " " " " " "                 E E E E E E E E                N N N N NCN6 N N N- - - - -3>5 - - -  

#566           5 5 5=C = = = =v) v) v) v) v)D v) v) v)r WT%%%s( s( s( s( s(- s( s( s( s(lQzA zA zA zA zAy zA zA zAzS S S S S9 S S S$8 8 8 8 8< 8 8 8v' ' ' ' ', ' ' 'Tx"
 x"
 x"
 x"
 x"
 x"
 x"
 x"
vE L2 L2 L2 L2 L2 L2 L2 L2^K6 K6 K6 K6 K6 K6 K6 K6^        2     M   &` ` ` ` ` ` ` ` ` `r   