소개
Odoo 데이터 모델에는 비교적 잘 알려지지 않았지만 다수의 회사(멀티컴퍼니)를 다룰 때 큰 차이를 만드는 설정이 있습니다. 바로 특정 필드가 회사별로 다른 값을 가질 수 있게 하는 기능으로, 다수 법인을 운영하는 시스템에서 특히 중요합니다.
일반적으로 레코드의 필드는 데이터베이스 전반에 걸쳐 하나의 값만 가집니다. 그런데 동일한 제품을 여러 법인이 공유하는데 법인별 내부 코드나 회계 계정은 달라야 한다면 어떻게 해야 할까요? 이럴 때 단일 레코드를 중복 생성하지 않고도 법인별로 다른 값을 저장해야 합니다.
이 문제를 해결하는 것이 바로 company_dependent 속성의 역할입니다. Odoo 개발이나 커스터마이징, 또는 프레임워크를 탐색하는 과정에서 이 개념을 이해하면 멀티컴퍼니 프로젝트 설계와 구현에서 큰 이점을 얻습니다.
Odoo에서 회사별 필드란 무엇인가
회사별 필드는 동일한 레코드에 대해 각 회사마다 별도의 값을 저장하는 필드입니다. 같은 레코드를 볼 때 사용자가 속한 회사에 맞는 값이 표시되며, 다른 회사 사용자는 각자 다른 값을 보게 됩니다.
사용자 관점에서는 평범한 필드와 똑같이 보이고 다루어집니다. 차이점은 데이터가 어떻게 읽히고 저장되는지를 처리하는 내부 구조에 있습니다.
UI에서의 표시 방식
Odoo 화면에서는 회사별 필드가 일반 필드와 구분되지 않습니다. 사용자에게 따로 표시해주지 않는 것이 의도된 동작으로, 값이 회사별로 달라도 인터페이스는 투명하게 동작합니다.
개발자 관점에서 이 필드는 여러 기본 타입(Char, Boolean, Integer, Float, Many2one 등)에 적용할 수 있습니다. 모델 필드 선언에 company_dependent=True를 추가하면 ORM이 해당 동작을 활성화합니다.
Odoo Studio에서는 몇몇 표준 모델의 회사별 필드가 이미 노출되어 있습니다(예: 제품 관련 회계 필드). 하지만 Studio 버전과 설정에 따라 이 속성에 대한 완전한 지원은 제한적일 수 있습니다.
동작 원리
내부 구조는 일반 필드와 크게 다릅니다. 구현 메커니즘을 알면 커스터마이징이나 디버깅 시 의외의 동작을 피할 수 있습니다.
ir.property에 저장되는 방식
Odoo 16 이하 버전에서는 회사별 필드의 값이 해당 모델 테이블에 직접 저장되지 않습니다. 대신 ir.property라는 별도 시스템 테이블에 저장됩니다.
ir.property의 각 항목은 다음 항목들을 연결합니다:
- 특정 레코드(예: ID가 42인 제품)
- 특정 필드(예: property_account_income_id)
- 특정 회사
- 그리고 그 조합에 대한 실제 값
이 구조 때문에 사용자는 값이 투명하게 보입니다. ORM이 현재 회사 컨텍스트에 따라 ir.property에서 자동으로 값을 가져오고 저장하기 때문입니다.
Odoo 17 이후의 변화
Odoo 17부터는 저장 방식이 리팩토링되어 회사별 값이 모델 자체의 테이블에 jsonb 컬럼 형태로 저장됩니다. 각 회사의 값은 JSON 딕셔너리로 보관되어 성능이 크게 개선되고 쿼리가 단순해졌습니다.
UI와 개발자용 API는 동일하게 유지되지만, 대규모 데이터에서 회사별 필드에 대한 조회 성능이 눈에 띄게 좋아졌습니다.
기본값 처리
회사별 필드는 회사별 기본값도 지원합니다. 특정 회사에 대해 값이 없으면 필드 정의에 설정된 기본값을 사용합니다. Odoo 16 이하에서는 ir.property를 통해, Odoo 17 이상에서는 모델 자체에 기본값을 두는 방식으로 관리됩니다.
ORM과의 상호작용
Odoo ORM에서 회사별 필드에 접근하면 항상 현재 환경의 회사(self.env.company)를 따릅니다. 그래서 다음과 같은 특성이 생깁니다:
- 읽기 시 활성 회사에 해당하는 값을 반환합니다.
- 쓰기 시 활성 회사의 값만 갱신합니다.
- 특정 회사를 지정하고 읽거나 쓰려면 record.with_company(company)를 사용하면 됩니다.
실무 적용 사례
회사별 필드는 단순한 기술적 장치가 아니라 실제 업무 문제를 해결합니다. 멀티컴퍼니 환경에서 자주 마주치는 대표적인 사용 사례들을 살펴보면 그 효용을 바로 알 수 있습니다.
1. 회계: 법인별 매출·비용 계정 설정
제품의 property_account_income_id, property_account_expense_id 같은 필드가 대표적인 예로 회사별 값을 가질 수 있습니다.
실무 예: 회사 A와 B가 같은 상품을 팔더라도 계정과 회계 규칙은 다릅니다. 제품 레코드를 복제하지 않고도 각 법인이 자신들 계정과 연결된 값을 설정할 수 있어 공유 데이터와 법인별 회계를 분리할 수 있습니다.
2. 영업·CRM: 법인별 가격정책(pricelist)
그룹 내 여러 영업법인이 서로 다른 가격 정책을 운영할 때, 공유 고객 레코드에 각 법인이 기본으로 사용할 가격표를 따로 지정할 수 있습니다.
이로써 CRM 데이터는 중앙에 남기되, 거래를 처리하는 법인별로 상업 규칙을 유연하게 적용할 수 있습니다.
3. 재고: 법인별 재고평가 방식
국가별 규정이나 회계 정책 차이로 동일 제품에 대해 한 법인은 FIFO, 다른 법인은 평균법을 사용해야 할 수 있습니다. 제품 또는 카테고리에 회사별 필드를 두면 카탈로그 중복 없이 이 요구를 충족시킬 수 있습니다.
4. 제조: 법인별 기본 공급사 설정
공유 제품을 법인별로 다른 공급사에서 구매해야 하는 경우, res.partner를 참조하는 Many2one 회사별 필드로 법인별 선호 공급사를 저장할 수 있습니다. 각 법인은 자신만의 공급사 정보를 보게 됩니다.
5. 규제·컴플라이언스용 커스텀 필드
다국적 운영 시 관세코드(HS code)나 세무 분류처럼 관할 구역별로 다른 규제 정보를 같은 레코드에 보관해야 할 때, 회사별 Char 필드로 간단히 해결할 수 있습니다. 모델을 여러 버전으로 나눌 필요가 없어 관리 부담이 줄어듭니다.
필드 생성 및 커스터마이징 방법
회사별 필드를 만드는 방법은 크게 Studio를 이용하는 방법과 코드로 직접 선언하는 방법 두 가지입니다.
Odoo Studio 활용
Odoo Studio는 코딩 없이 필드를 추가할 수 있게 해주지만 모든 버전에서 company_dependent 토글을 노출하지는 않습니다. Odoo 16·17 일부 버전에서는 표준 모델에 새 필드를 추가할 때 옵션이 보이기도 합니다.
정교한 제어가 필요하면 직접 개발하는 편이 더 안전합니다. Studio는 단순한 경우에 유용하지만 고급 커스터마이징에는 한계가 있습니다.
기술적 접근: 파이썬 필드 선언
커스텀 모듈에서 회사별 필드를 선언하는 것은 비교적 간단합니다. 다음이 표준 패턴입니다:
from odoo import fields, models
class ProductTemplate(models.Model):
_inherit = 'product.template'
x_internal_ref = fields.Char(
string='Internal Reference (per company)',
company_dependent=True,
)
x_preferred_carrier_id = fields.Many2one(
comodel_name='res.partner',
string='Preferred Carrier',
company_dependent=True,
)
필드 선언에 company_dependent=True만 추가하면 ORM이 저장과 조회를 자동으로 처리합니다.
회사별 기본값 설정 방법
Odoo 16 이하에서는 ir.property를 통해 회사별 기본값을 설정할 수 있습니다. 이렇게 하면 모든 레코드에 대해 회사 수준의 기본값을 강제할 수 있습니다:
self.env['ir.property']._set_default(
'x_internal_ref',
'product.template',
'DEFAULT-VALUE',
company_id=self.env.company.id,
)
Odoo 17 이상에서는 기본값이 모델 레코드에 직접 저장되고 필드 정의를 통해 접근할 수 있습니다.
Studio 필드와 한계
커스텀 필드는 x_ 접두사가 필수이고, Studio UI에서 회사별 동작이 명확히 보이지 않을 수 있습니다. 개발자 모드로 기술 메뉴에 접근하면 추가 설정이 가능할 때가 있습니다.
권장 관행
회사별 필드를 다루는 데 도움이 되는 권장 관행들을 정리하면 다음과 같습니다.
1. 값이 진짜로 법인마다 달라지는 경우에만 사용하세요
복잡도를 늘리지 않으려면 모든 법인에서 동일한 값이라면 일반 필드를 사용하세요. company_dependent는 값이 법인별로 달라질 때만 적용해야 합니다.
2. 항상 멀티컴퍼니 환경에서 테스트하세요
테스트 환경에 최소 두 개의 법인을 활성화해 테스트하지 않으면 단일법인 환경에서는 보이지 않던 문제가 운영에서 발생할 수 있습니다.
3. cross-company 작업엔 with_company()를 사용하세요
다른 법인의 값을 읽거나 쓸 필요가 있는 코드에서는 record.with_company(target_company)를 사용해 안전하게 처리하세요. 환경의 company를 수동으로 바꾸는 방식은 피해야 합니다.
4. 내보내기·가져오기 시 주의하세요
회사별 필드가 포함된 데이터를 내보내면 내보낸 사용자의 회사 컨텍스트에 해당하는 값이 기록됩니다. 다른 법인으로 동일 파일을 가져오면 그 법인에 값이 설정됩니다. 마이그레이션이나 데이터 이관 시 의도한 동작인지 명확히 해야 합니다.
5. 어떤 필드가 회사별인지 문서화하세요
사용자들은 어떤 필드가 법인별로 달라지는지 모르는 경우가 많습니다. 내부 문서나 온보딩 자료에 간단히 명시해 두면 사용자가 법인을 전환할 때 혼란을 줄일 수 있습니다.
6. 구조화된 데이터는 Char보다 Many2one을 선호하세요
법인별 값이 다른 레코드를 참조해야 한다면 이름 텍스트를 저장하지 말고 Many2one 회사별 필드를 쓰는 편이 데이터 무결성과 보고의 정확성에 유리합니다.
자주 발생하는 실수
숙련된 개발자도 회사별 필드에서 문제를 겪습니다. 대표적인 실수를 알고 있으면 디버깅 시간을 크게 줄일 수 있습니다.
실수 1: 자동화 작업에서 회사 컨텍스트를 간과하는 경우
스케줄된 액션이나 서버 액션은 종종 데이터베이스의 첫 번째 회사 컨텍스트로 실행됩니다. 회사별 필드를 다루는 자동화는 with_company()로 명시적으로 회사 컨텍스트를 설정해 둬야 안전합니다.
실수 2: 계산 필드처럼 동작한다고 가정하는 경우
회사별 필드는 compute 메서드를 갖는 계산 필드가 아닙니다. 값의 차이는 저장 위치에 의해 발생합니다. compute와 company_dependent를 함께 쓰려 하면 예기치 않은 오류가 발생할 수 있습니다.
실수 3: 회사 간 검색을 간과하는 경우
표준 ORM 검색은 현재 회사 컨텍스트에 맞는 결과만 반환합니다. 모든 회사에서 검색해야 할 경우 Odoo 16 이하라면 ir.property를 직접 조회해야 하고, Odoo 17 이상이라면 jsonb 컬럼을 적절히 다뤄야 합니다. 보고서나 데이터 추출 시 흔한 혼란 포인트입니다.
실수 4: 모든 법인에 기본값을 설정하지 않는 경우
라이브 시스템에 회사별 필드를 추가하면 기존 레코드는 값이 설정되지 않은 법인에서 False 혹은 None을 반환합니다. 비즈니스 로직이 기본값을 기대한다면 데이터 마이그레이션으로 모든 관련 법인에 미리 기본값을 채워두어야 합니다.
실수 5: 접근권한과 혼동하는 경우
company_dependent는 어떤 사용자나 법인이 필드를 볼 수 있는지를 제어하지 않습니다. 필드를 완전히 숨기려면 레코드 규칙이나 권한 설정을 사용해야 합니다.
맺음말
회사별 필드는 필요할 때 보이지 않다가도 반드시 필요한 도구입니다. 동일한 레코드에 대해 법인마다 다른 값을 가져야 하는 모든 상황—회계, 가격정책, 규제 정보 등—에 적절한 해법을 제공합니다.
ORM 수준에서의 동작 방식, 어떤 버전에서 저장 방식이 바뀌었는지, 그리고 피해야 할 실수들을 알고 있으면 멀티컴퍼니 프로젝트에서 많은 시간을 절약할 수 있습니다. 실무에서 이 필드를 제대로 다루는 능력은 Odoo 전문성의 중요한 척도입니다.
Odoo 프레임워크 위에서 법인별 데이터를 깔끔하게 다루고자 한다면 company_dependent=True는 실무에서 찾던 답입니다.
Odoo 도입에 도움이 필요하신가요?
Dasolo에서는 복잡한 멀티컴퍼니 환경을 포함해 기업의 Odoo 도입·커스터마이징·최적화를 지원합니다. 데이터 모델 설계, 회사별 필드 전략, 또는 전체 Odoo 롤아웃 같은 과제를 기술적·업무적 관점에서 함께 해결해 드립니다.
회사별 필드나 Odoo 도입 전반에 관해 궁금한 점이 있으면 언제든 도와드리겠습니다. 문의하기 지금 진행 중인 프로젝트에 대해 이야기해 보세요.