Odoo에서 커스텀 설정 옵션 추가하는 방법

Odoo의 공식 문서에는 새로운 구성 옵션을 추가하는 방법에 대한 상세한 가이드가 부족한 경우가 많습니다. 본 글에서는 Odoo 시스템에 자체적인 설정 항목을 정의하고 적용하는 과정을 단계별로 설명합니다.

1. 모델 정의: TransientModel 상속

새로운 설정을 만들기 위해서는 먼저 res.config.settings를 상속받는 모델을 정의해야 합니다. 이 모델은 마법사(Wizard) 역할을 하는 TransientModel이어야 하며, 데이터는 영구적으로 저장되지 않고 일시적으로만 보관됩니다. 따라서 실제 값이 DB에 반영되려면 별도의 로직이 필요합니다.

class CustomAppSettings(models.TransientModel):
    _inherit = 'res.config.settings'
    _name = 'custom.app.settings'

Odoo는 필드 이름의 접두사를 기반으로 네 가지 유형의 설정 처리 방식을 자동으로 구분합니다.

1.1 기본값(Default) 설정

필드 이름이 default_로 시작하면 해당 값은 지정된 모델의 특정 필드에 대한 전역 기본값으로 설정됩니다. 예를 들어, default_customer_id라는 필드를 만들면 sale.order 모델의 partner_id 필드 기본값이 변경됩니다.

class CustomAppSettings(models.TransientModel):
    _inherit = 'res.config.settings'
    _name = 'custom.app.settings'

    # sale.order 모델의 partner_id 필드 기본값 설정
    default_partner_id = fields.Many2one(
        'res.partner', 
        string='Default Customer',
        default_model='sale.order'
    )

1.2 그룹(Group) 권한 설정

부울(Boolean) 타입 필드이며 이름이 group_로 시작할 경우, 이는 사용자 그룹 권한과 연동됩니다. 체크박스가 활성화되면 implied_group에 정의된 그룹이 group에 정의된 상위 그룹에 포함됩니다. 이는 기능 접근 제어를 위해 유용하게 사용됩니다.

class CustomAppSettings(models.TransientModel):
    _inherit = 'res.config.settings'
    _name = 'custom.app.settings'

    group_manager_access = fields.Boolean(
        string='Enable Manager Access',
        group='base.group_user',       # 기본 대상 그룹
        implied_group='custom_app.group_managers'  # 부여될 권한 그룹
    )

1.3 모듈(Module) 설치 설정

부울 타입 필드이며 이름이 module_로 시작하면, 해당 옵션이 활성화될 때 지정된 이름의 모듈을 자동으로 설치하거나 제거합니다. 주의할 점은 필드명에서 module_ 접두사를 제외한 나머지가 실제 모듈 기술 이름(Technical Name)과 일치해야 한다는 것입니다.

class CustomAppSettings(models.TransientModel):
    _inherit = 'res.config.settings'
    _name = 'custom.app.settings'

    # 'advanced_inventory' 모듈을 제어함
    module_advanced_inventory = fields.Boolean(string='Install Advanced Inventory')

1.4 기타 커스텀 저장 로직

위 세 가지 유형에 속하지 않는 일반 필드는 기본적으로 저장 시 무시됩니다. 이를 해결하기 위해서는 set_<field_name> 형식의 메서드를 구현하여 값을 수동으로 저장해야 합니다. 또한 초기 화면 표시를 위해 get_default_<method_name> 메서드를 사용할 수 있습니다.

예를 들어, 현재 사용자의 회사 정보를 설정 화면에서 수정하고 저장하는 경우:

class CustomAppSettings(models.TransientModel):
    _inherit = 'res.config.settings'
    _name = 'custom.app.settings'

    company_legal_name = fields.Char(string='Legal Company Name')
    company_tax_id = fields.Char(string='Tax ID')

    @api.model
    def get_default_company_info(self, fields):
        """
        설정 화면 로드 시 현재 회사 정보로 필드 초기화
        """
        current_company = self.env.user.company_id
        return {
            'company_legal_name': current_company.name,
            'company_tax_id': current_company.vat,
        }

    @api.multi
    def set_company_info(self):
        """
        저장 버튼 클릭 시 회사 레코드 업데이트
        """
        for record in self:
            target_company = self.env.user.company_id
            target_company.write({
                'name': record.company_legal_name,
                'vat': record.company_tax_id,
            })
        return True

2. 뷰(View) 정의

모델 정의 후, 설정 화면을 위한 XML 뷰를 작성해야 합니다. 일반적인 폼 뷰와 유사하지만, 상단에 저장 및 취소 버튼을 명시적으로 배치해야 합니다.

<record id="view_custom_settings_form" model="ir.ui.view">
    <field name="name">Custom App Settings</field>
    <field name="model">custom.app.settings</field>
    <field name="arch" type="xml">
        <form string="Custom Configuration" class="oe_form_configuration">
            <header>
                <button string="Save" type="object" name="execute" class="oe_highlight"/>
                <button string="Cancel" type="object" name="cancel" class="oe_link"/>
            </header>
            
            <group string="Company Information">
                <field name="company_legal_name"/>
                <field name="company_tax_id"/>
            </group>

            <group string="Access Control">
                <field name="group_manager_access"/>
            </group>

            <group string="Modules">
                <field name="module_advanced_inventory"/>
            </group>
        </form>
    </field>
</record>

3. 액션(Action) 및 메뉴(Menu) 등록

마지막으로 뷰를 연결하는 윈도우 액션을 생성하고, 설정 메뉴 하위에 해당 액션을 호출하는 메뉴 항목을 추가합니다.

<!-- 액션 정의 -->
<record id="action_custom_settings" model="ir.actions.act_window">
    <field name="name">Custom App Configuration</field>
    <field name="res_model">custom.app.settings</field>
    <field name="view_mode">form</field>
    <field name="target">inline</field>
    <field name="context">{'module': 'custom_app'}</field>
</record>

<!-- 메뉴 등록 (설정 > 일반 설정 하위 등) -->
<menuitem id="menu_custom_settings" 
          name="Custom App Settings" 
          parent="base.menu_config" 
          action="action_custom_settings"/>

위 절차를 완료하면 Odoo의 '설정' 메뉴 내에 새로운 탭이나 섹션으로 커스텀 설정 항목이 나타나며, 사용자가 입력한 값은 각 유형에 따라 적절히 처리되어 시스템 전체에 반영됩니다.

태그: Odoo res.config.settings python XML View ERP Configuration

9월 25일 15:27에 게시됨