o
    š�ži?^  ã                   @   sv   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	m
Z
mZ e  e¡ZG dd„ dejƒZG dd„ dejƒZdS )	é    N)Úliteral_eval)ÚapiÚmodelsÚ_)ÚAccessErrorÚRedirectWarningÚ	UserErrorc                   @   sP   e Zd ZdZdZdZdd„ Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ Zdd„ ZdS )Ú	ResConfigzú Base classes for new-style configuration items

    Configuration items should inherit from this class, implement
    the execute method (and optionally the cancel one) and have
    their view inherit from the related res_config_view_base view.
    ú
res.configÚConfigc                 C   s   |   ¡ S ©N)Únext©Úself© r   ú>/home/minischoggi19/odoo/odoo/addons/base/models/res_config.pyÚstart   s   zResConfig.startc                 C   s
   dddœS )z*
        Reload the settings page
        úir.actions.clientÚreload©ÚtypeÚtagr   r   r   r   r   r      s   þzResConfig.nextc                 C   s   t dƒ‚)aY   Method called when the user clicks on the ``Next`` button.

        Execute *must* be overloaded unless ``action_next`` is overloaded
        (which is something you generally don't need to do).

        If ``execute`` returns an action dictionary, that action is executed
        rather than just going to the next configuration item.
        z-Configuration items need to implement execute)ÚNotImplementedErrorr   r   r   r   Úexecute#   s   	ÿzResConfig.executec                 C   s   dS )aµ   Method called when the user click on the ``Skip`` button.

        ``cancel`` should be overloaded instead of ``action_skip``. As with
        ``execute``, if it returns an action dictionary that action is
        executed in stead of the default (going to the next configuration item)

        The default implementation is a NOOP.

        ``cancel`` is also called by the default implementation of
        ``action_cancel``.
        Nr   r   r   r   r   Úcancel/   s   zResConfig.cancelc                 C   ó   |   ¡ p|  ¡ S )a   Action handler for the ``next`` event.

        Sets the status of the todo the event was sent from to
        ``done``, calls ``execute`` and -- unless ``execute`` returned
        an action dictionary -- executes the action provided by calling
        ``next``.
        )r   r   r   r   r   r   Úaction_next=   ó   	zResConfig.action_nextc                 C   r   )a   Action handler for the ``skip`` event.

        Sets the status of the todo the event was sent from to
        ``skip``, calls ``cancel`` and -- unless ``cancel`` returned
        an action dictionary -- executes the action provided by calling
        ``next``.
        ©r   r   r   r   r   r   Úaction_skipH   r   zResConfig.action_skipc                 C   r   )a½   Action handler for the ``cancel`` event. That event isn't
        generated by the res.config.view.base inheritable view, the
        inherited view has to overload one of the buttons (or add one
        more).

        Sets the status of the todo the event was sent from to
        ``cancel``, calls ``cancel`` and -- unless ``cancel`` returned
        an action dictionary -- executes the action provided by calling
        ``next``.
        r   r   r   r   r   Úaction_cancelS   s   zResConfig.action_cancelN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú_nameÚ_descriptionr   r   r   r   r   r   r    r   r   r   r   r	      s    	r	   c                       sÔ   e Zd ZdZdZdZ‡ fdd„Zd#dd„Zej	d	d
„ ƒZ
ej	d#dd„ƒZej	dd„ ƒZej	‡ fdd„ƒZdd„ Zdd„ Zdd„ Zdd„ Zej	dd„ ƒZej	dd„ ƒZej	dd„ ƒZej‡ fdd „ƒZd!d"„ Z‡  ZS )$ÚResConfigSettingsa   Base configuration wizard for application settings.  It provides support for setting
        default values, assigning groups to employee users, and installing modules.
        To make such a 'settings' wizard, define a model like::

            class MyConfigWizard(models.TransientModel):
                _name = 'my.settings'
                _inherit = ['res.config.settings']

                default_foo = fields.type(..., default_model='my.model'),
                group_bar = fields.Boolean(..., group='base.group_user', implied_group='my.group'),
                module_baz = fields.Boolean(...),
                config_qux = fields.Char(..., config_parameter='my.parameter')
                other_field = fields.type(...),

        The method ``execute`` provides some support based on a naming convention:

        *   For a field like 'default_XXX', ``execute`` sets the (global) default value of
            the field 'XXX' in the model named by ``default_model`` to the field's value.

        *   For a boolean field like 'group_XXX', ``execute`` adds/removes 'implied_group'
            to/from the implied groups of 'group', depending on the field's value.
            By default 'group' is the group Employee.  Groups are given by their xml id.
            The attribute 'group' may contain several xml ids, separated by commas.

        *   For a selection field like 'group_XXX' composed of 2 string values ('0' and '1'),
            ``execute`` adds/removes 'implied_group' to/from the implied groups of 'group',
            depending on the field's value.
            By default 'group' is the group Employee.  Groups are given by their xml id.
            The attribute 'group' may contain several xml ids, separated by commas.

        *   For a boolean field like 'module_XXX', ``execute`` triggers the immediate
            installation of the module named 'XXX' if the field has value ``True``.

        *   For a selection field like 'module_XXX' composed of 2 string values ('0' and '1'),
            ``execute`` triggers the immediate installation of the module named 'XXX'
            if the field has the value ``'1'``.

        *   For a field with no specific prefix BUT an attribute 'config_parameter',
            ``execute``` will save its value in an ir.config.parameter (global setting for the
            database).

        *   For the other fields, the method ``execute`` invokes `set_values`.
            Override it to implement the effect of those fields.

        The method ``default_get`` retrieves values that reflect the current status of the
        fields like 'default_XXX', 'group_XXX', 'module_XXX' and config_XXX.
        It also invokes all methods with a name that starts with 'get_default_';
        such methods can be defined to provide current values for other fields.
    zres.config.settingszConfig Settingsc                    s(   |dv p|j dv o|dv ptƒ  ||¡S )N)Údefault_modelÚconfig_parameter©ÚbooleanÚ	selection)ÚgroupÚimplied_group)r   ÚsuperÚ_valid_field_parameter)r   ÚfieldÚname©Ú	__class__r   r   r0   —   s
   ÿýz(ResConfigSettings._valid_field_parameterNc                 C   s   t tdƒƒ‚)NzCannot duplicate configuration!)r   r   )r   Údefaultr   r   r   Úcopyž   s   zResConfigSettings.copyc                 C   s"   d}|  dd„ ¡}|r| ¡ }|S )z• Install the requested modules.

        :param modules: a recordset of ir.module.module records
        :return: the next action to execute
        Nc                 S   s
   | j dkS )NÚuninstalled)Ústate)Úmoduler   r   r   Ú<lambda>ª   s   
 z4ResConfigSettings._install_modules.<locals>.<lambda>)ÚfilteredÚbutton_immediate_install)r   ÚmodulesÚresultÚto_install_modulesr   r   r   Ú_install_modules¡   s
   z"ResConfigSettings._install_modulesc                    s¨  ˆj d }ˆj d ‰ ˆj d }‡ ‡fdd„‰|du rˆj ¡ }g g g g f\}}}}|}|D ]ž}	ˆj|	 }
|	 d¡rRt|
dƒsDtd	|
 ƒ‚| |	|
j|	d
d… f¡ q-|	 d¡rŽ|
jdvrbtd|
 ƒ‚t|
dƒsmtd|
 ƒ‚t	|
ddƒ 
d¡}|j‡fdd„|D ƒŽ }| |	|ˆ|
jƒf¡ q-|	 d¡rª|
jdvržtd|
 ƒ‚|| |	dd… ¡7 }q-t|
dƒrÆ|
jrÆ|
jdvr½td|
 ƒ‚| |	|
jf¡ q-| |	¡ q-|||||dœS )aÞ   return a dictionary with the fields classified by category:

            .. code-block:: python

                {   'default': [('default_foo', 'model', 'foo'), ...],
                    'group':   [('group_bar', [browse_group], browse_implied_group), ...],
                    'module':  [('module_baz', browse_module), ...],
                    'config':  [('config_qux', 'my.parameter'), ...],
                    'other':   ['other_field', ...],
                }
        zir.module.modulezir.model.dataz
res.groupsc                    s   ˆ   | ¡\}}ˆj|  |¡S r   )Ú_xmlid_to_res_model_res_idÚenvÚbrowse)Úxml_idÚ	res_modelÚres_id)ÚIrModelDatar   r   r   ÚrefÁ   s   z5ResConfigSettings._get_classified_fields.<locals>.refNÚdefault_r(   z*Field %s without attribute 'default_model'é   Úgroup_r*   z0Field %s must have type 'boolean' or 'selection'r.   z*Field %s without attribute 'implied_group'r-   zbase.group_userú,c                 3   s   � | ]}ˆ |ƒV  qd S r   r   )Ú.0Úit)rH   r   r   Ú	<genexpr>Ö   s   € z;ResConfigSettings._get_classified_fields.<locals>.<genexpr>Úmodule_é   r)   )r+   ÚintegerÚfloatÚcharr,   Úmany2oneÚdatetimezdField %s must have type 'boolean', 'integer', 'float', 'char', 'selection', 'many2one' or 'datetime')r5   r-   r9   ÚconfigÚother)rB   Ú_fieldsÚkeysÚ
startswithÚhasattrÚ	ExceptionÚappendr(   r   ÚgetattrÚsplitÚconcatr.   Ú_getr)   )r   ÚfnamesÚIrModuleÚGroupsÚdefaultsÚgroupsÚconfigsÚothersr=   r2   r1   Úfield_group_xmlidsÚfield_groupsr   )rG   rH   r   r   Ú_get_classified_fields°   s@   












z(ResConfigSettings._get_classified_fieldsc                 C   s   i S )zY
        Return values for the fields other that `default`, `group` and `module`
        r   r   r   r   r   Ú
get_valueså   s   zResConfigSettings.get_valuesc              
      s*  t ƒ  |¡}|s
|S | jd }| jd  ¡ }|  |¡}|d D ]\}}}| ||¡}	|	d ur2|	||< q|d D ]$\}}
‰ t‡ fdd„|
D ƒƒ||< | j| jdkr[t	t
|| ƒƒ||< q7|d D ]}|jd	v |d
|j› �< q`d}|d D ]—\}}| j| }| ||jrˆ| | ¡nd¡}	|	du�r|jdkr»z| j|j  t
|	ƒ¡ ¡ j}	W na ttfyº   t ||	||¡ d}	Y nMw |jdkrÜzt
|	ƒ}	W n@ ttfyÛ   t ||	||¡ d}	Y n,w |jdkrýzt|	ƒ}	W n ttfyü   t ||	||¡ d}	Y nw |jdk�rt|	ƒ}	|	||< qt| |  ¡ ¡ |S )Nú
ir.defaultúir.config_parameterr5   r-   c                 3   s   � | ]}ˆ |j v V  qd S r   )Úall_implied_ids)rM   r-   ©r.   r   r   rO   þ   s   € z0ResConfigSettings.default_get.<locals>.<genexpr>r,   r9   )Ú	installedz
to installú
to upgraderP   zEError when converting value %r of field %s for ir.config.parameter %rrW   FrU   rR   r   rS   g        r+   )r/   Údefault_getrB   Úsudorl   rb   ÚallrY   r   ÚstrÚintr8   r2   Ú	get_paramr5   Úcomodel_namerC   ÚexistsÚidÚ
ValueErrorÚ	TypeErrorÚ_loggerÚwarningrS   ÚboolÚupdaterm   )r   ÚfieldsÚresÚ	IrDefaultÚIrConfigParameterÚ
classifiedr2   Úmodelr1   Úvaluerg   r9   ÚWARNING_MESSAGEÚicpr3   rq   r   rt   ì   sb   

€€


 þ
þ
þ
zResConfigSettings.default_getc                    s¼  ˆ j dd�‰ ˆ  ¡ }ˆ  tˆ  ¡ ƒ¡}ˆ jd  ¡ }|d D ]6\}}}tˆ | tj	ƒr?ˆ j
| jdkr9ˆ | j}n
ˆ | j}nˆ | }||vsM||| krT| |||¡ qt|d ‡ fdd„d	�D ]'\}}}	| ¡ }|	 ¡ }	ˆ | || krwqatˆ | ƒrƒ| |	¡ qa| |	¡ qaˆ jd
  ¡ }
|d D ]G\}}ˆ j
| }ˆ | }|
 |¡}|jdkr´|p®d ¡ p²d}n|jdv rÂ|r¿t|ƒnd}n|jdkrÊ|j}|t|ƒksÔ||krÕq”|
 ||¡ q”dS )zV
        Set values for the fields other that `default`, `group` and `module`
        F©Úactive_testrn   r5   rU   r-   c                    s   ˆ | d  S )Nr   r   )Úkr   r   r   r:   >  s    z.ResConfigSettings.set_values.<locals>.<lambda>)Úkeyro   rW   rT   Ú )rR   rS   N)Úwith_contextrl   rt   ÚlistÚ
fields_getrB   ru   Ú
isinstancer   Ú	BaseModelrY   r   r|   ÚidsÚsetÚsortedrx   Ú_apply_groupÚ_remove_groupry   ÚstripÚreprrw   Ú	set_param)r   r‡   Úcurrent_settingsr…   r2   rˆ   r1   r‰   rg   r.   r†   r‹   Úcurrent_valuer   r   r   Ú
set_values(  sH   €"




ïzResConfigSettings.set_valuesc                    sä   ˆ   ¡  ˆ j ¡ sttdƒƒ‚ˆ jdd�‰ ˆ  ¡ }ˆ  ¡  |d  ‡ fdd„¡}|d  ‡ fdd„¡}|s7|r<ˆ j 	¡  |rLdd	td
ƒddd|j
idœS ˆ  |¡}|sU|r[ˆ jj ¡  ˆ jd  ¡ pci }| d¡dvrm|S dddœS )an  
        Called when settings are saved.

        This method will call `set_values` and will install/uninstall any modules defined by
        `module_` Boolean fields and then trigger a web client reload.

        .. warning::

            This method **SHOULD NOT** be overridden, in most cases what you want to override is
            `~set_values()` since `~execute()` does little more than simply call `~set_values()`.

            The part that installs/uninstalls modules **MUST ALWAYS** be at the end of the
            transaction, otherwise there's a big risk of registry <-> database desynchronisation.
        z+Only administrators can change the settingsFrŒ   r9   c                    s   ˆ d| j › � o| jdkS )NrP   rr   ©r2   r8   ©Úmr   r   r   r:   w  s    z+ResConfigSettings.execute.<locals>.<lambda>c                    s   ˆ d| j › �  o| jdv S )NrP   )rr   rs   r¡   r¢   r   r   r   r:   y  s    úir.actions.act_windowÚnewzUninstall modulesÚformzbase.module.uninstallÚdefault_module_ids)r   Útargetr2   Ú	view_moderE   Úcontextr
   r   )zir.actions.act_window_closer   r   r   )Ú
ensure_onerB   Úis_adminr   r   r‘   rl   r    r;   Ú	flush_allr–   r@   ÚtransactionÚresetr   Úget)r   r‡   Ú
to_installÚto_uninstallÚinstallation_statusrW   r   r   r   r   ]  s@   

ÿ
ÿ
ÿú
þzResConfigSettings.executec                 C   s2   | j d jdd| jfgdd�}|r| ¡ d S i S )Nr¤   rE   Ú=é   ©Úlimitr   )rB   Úsearchr%   Úread)r   Úactionsr   r   r   r   œ  s   zResConfigSettings.cancelc                 C   s0   | j d jdd| jfgdd�}|jp| j| _dS )zu Override display_name method to return an appropriate configuration wizard
        name, and not the generated name.r¤   rE   r´   rµ   r¶   N)rB   r¸   r%   r2   Údisplay_name)r   Úactionr   r   r   Ú_compute_display_name£  s   z'ResConfigSettings._compute_display_namec                 C   s   | j  |¡}|j|jjfS )aß  
        Fetch the path to a specified configuration view and the action id to access it.

        :param string menu_xml_id: the xml id of the menuitem where the view is located,
            structured as follows: module_name.menuitem_xml_id (e.g.: "sales_team.menu_sale_config")
        :return: a 2-value tuple where

          - t[0]: string: full path to the menuitem (e.g.: "Settings/Configuration/Sales")
          - t[1]: int or long: id of the menuitem's action
        )rB   rH   Úcomplete_namer¼   r|   )r   Úmenu_xml_idÚ
ir_ui_menur   r   r   Úget_option_path©  s   z!ResConfigSettings.get_option_pathc                 C   s*   |  dd¡\}}| j|  |g¡| d S )ap  
        Fetch the human readable name of a specified configuration option.

        :param string full_field_name: the full name of the field, structured as follows:
            model_name.field_name (e.g.: "sale.config.settings.fetchmail_lead")
        :return: human readable name of the field (e.g.: "Create leads from incoming mails")
        :rtype: str
        Ú.rµ   Ústring)ÚrsplitrB   r“   )r   Úfull_field_nameÚ
model_nameÚ
field_namer   r   r   Úget_option_name¸  s   
z!ResConfigSettings.get_option_namec           	      C   s”   |   ¡ } d}tj||tjd�}i }d}|D ]"}| d¡\}}|dkr,|  |¡\||< }q|dkr7|  |¡||< q|rDt|| |tdƒƒS t	|| ƒS )a^  
        Helper: return a Warning exception with the given message where the ``%(field:xxx)s``
        and/or ``%(menu:yyy)s`` are replaced by the human readable field's name and/or
        menuitem's full path.

        Usage:
        ------
        Just include in your error message ``%(field:model_name.field_name)s`` to obtain the
        human readable field's name, and/or %(menu:module_name.menuitem_xml_id)s to obtain the
        menuitem's full path.

        Example of use:
        ---------------

        .. code-block:: python

            raise env['ir..config.settings'](_(
                "Error: this action is prohibited. You should check the "
                "field %(field:sale.config.settings.fetchmail_lead)s in "
                "%(menu:sales_team.menu_sale_config)s."))

        This will return an exception containing the following message:

            Error: this action is prohibited. You should check the field Create
            leads from incoming mails in Settings/Configuration/Sales.

        What if there is another substitution in the message already?
        -------------------------------------------------------------
        You could have a situation where the error message you want to upgrade already contains
        a substitution.

        Example:

            Cannot find any account journal of %s type for this company.

            You can create one in the menu:
            Configuration/Journals/Journals.

        What you want to do here is simply to replace the path by
        ``%menu:account.menu_account_config)s``, and leave the rest alone.
        In order to do that, you can use the double percent (``%%``) to escape your new
        substitution, like so:

            Cannot find any account journal of %s type for this company.

            You can create one in the %%(menu:account.menu_account_config)s.
        z %\(((?:menu|field):[a-z_\.]*)\)s)ÚflagsNú:Úmenur1   zGo to the configuration panel)
ru   ÚreÚfindallÚIr`   rÁ   rÈ   r   r   r   )	r   ÚmsgÚ
regex_pathÚ
referencesÚvaluesÚ	action_idÚitemÚref_typerH   r   r   r   Úget_config_warningÅ  s   1€z$ResConfigSettings.get_config_warningc           
         sÄ   |D ]Y}| j  ¡ D ]Q}|j|v r|jr|jrq	|j d¡^}}||vr$q	| j | }| | || | ¡| ¡}|D ]}tt	|ƒ|ƒ| }q7| | ||j | ¡| ¡}	||	krZ| 
|j¡ q	qtƒ  |¡S )NrÂ   )rY   rÒ   r2   ÚrelatedÚreadonlyr`   Úconvert_to_recordÚconvert_to_cacher   ÚiterÚpopr/   Úcreate)
r   Ú	vals_listÚvalsr1   Úfname0rc   Úfield0Ú	old_valueÚfnameÚ	new_valuer3   r   r   rÝ     s*   
ÿÿ€êzResConfigSettings.createc                 C   sr   | j d  d¡}t| j d  ¡  dd¡ƒ}| j d  |¡}| ¡ s'ttdƒƒ‚||d< | j  	d	¡j
d
gg|d< |S )Nzir.actions.actionszbase.action_res_usersro   zbase.template_portal_user_idÚFalsez	res.usersz4Invalid template user. It seems it has been deleted.rF   zbase.view_users_formr¦   Úviews)rB   Ú_for_xml_idr   ru   ry   rC   r{   r   r   rH   r|   )r   r¼   Útemplate_user_idÚtemplate_userr   r   r   Úaction_open_template_user.  s   z+ResConfigSettings.action_open_template_userr   )r!   r"   r#   r$   r%   r&   r0   r6   r   rˆ   r@   rl   rm   rt   r    r   r   r½   rÁ   rÈ   rÖ   Úmodel_create_multirÝ   rê   Ú__classcell__r   r   r3   r   r'   b   s6    1

4
;5?


G r'   )ÚloggingrÌ   Úastr   Úodoor   r   r   Úodoo.exceptionsr   r   r   Ú	getLoggerr!   r   ÚTransientModelr	   r'   r   r   r   r   Ú<module>   s   
V