콘텐츠로 건너뛰기

Odoo의 Monetary Field: 작동 원리와 활용 시기 안내

Odoo 데이터 모델에서 통화 값을 정확하게 처리하는 실무 가이드
2026년 3월 6일 작성자
Odoo의 Monetary Field: 작동 원리와 활용 시기 안내
Dasolo
| 아직 댓글이 없습니다

소개


Monetary 필드는 Odoo에서 가장 유용하면서도 오해받기 쉬운 필드 유형입니다. 보기에는 숫자지만 내부 동작과 표시 방식에서 일반 Float와는 다른 규칙을 따릅니다. 이 차이를 이해하면 가격, 합계, 예산 같은 금전 값을 단순 Float로 처리하는 실수를 더 이상 하지 않게 됩니다.


판매 주문의 합계, 세금이 포함된 인보이스 총액, 제품 단가를 살펴본 적이 있다면 이미 Monetary 필드를 접한 것입니다. Odoo 모델 전반에 분포하며 통화 기호, 소수 자리수, 반올림 규칙 같은 포맷팅과 정밀도 처리를 조용히 담당합니다.

이 가이드는 Odoo 개발자, 컨설턴트, 또는 기술적 이해를 가진 실무자들이 Monetary 필드의 실제 동작 원리를 이해하도록 돕기 위해 작성되었습니다. 커스텀 모듈을 만들거나 필드 동작 때문에 금액이 의도와 다르게 반올림될 때 문제 원인을 찾는 데 필요한 핵심 참조 자료입니다.

Odoo의 Monetary 필드란 무엇인가


fields.Monetary는 Odoo 프레임워크의 핵심 필드 타입 중 하나로, 가격·금액·합계·예산 등 통화 단위로 표현되는 수치를 저장하도록 설계되었습니다.


일반 Float와 다른 핵심 요소는 통화와의 필수적 연계입니다. Monetary 필드는 항상 어떤 통화(currency)를 기준으로 하는지 알고 있으며, 그 통화를 바탕으로 소수 자리수와 반올림 규칙을 결정합니다.


화면에서의 표시 방식

Odoo UI에서 Monetary 필드는 연동된 통화에 맞춰 포맷되어 보입니다. 예컨대 유로라면 "€ 1,234.50"처럼, 달러라면 "$ 1,234.50"처럼 표시됩니다. 소수 자릿수는 해당 통화 레코드의 설정을 따릅니다.


이 필드는 폼 뷰에서 직접 편집 가능하고 리스트 뷰에서도 깔끔하게 표시되며 피봇이나 재무 리포트에도 자연스럽게 통합됩니다. 최종 사용자는 별도 포맷을 신경 쓸 필요 없이 값만 입력하면 됩니다.


저장되는 데이터 타입

DB 관점에서는 Monetary 값이 PostgreSQL의 double precision(부동소수점)로 저장됩니다. 통화 정보는 같은 컬럼에 함께 저장되지 않고, 동일한 모델에 있는 별도의 Many2one 필드를 통해 연결된 res.currency 레코드에서 가져옵니다.


값과 통화를 분리해 저장하는 것은 의도적인 설계입니다. 이렇게 하면 금액 값과 통화를 독립적으로 관리할 수 있어, 필요에 따라 통화를 변경하더라도 데이터 구조가 깔끔하게 유지됩니다.


동작 방식


Monetary 필드의 내부 작동을 이해하면 올바르게 활용할 수 있고, 커스텀 개발 시에 흔히 발생하는 반올림이나 표시 문제를 예방할 수 있습니다.


currency_field 파라미터

모든 Monetary 필드는 res.currency로 연결되는 Many2one 필드와 쌍을 이뤄야 합니다. 기본적으로 Odoo는 같은 모델에서 currency_id라는 필드를 찾지만, currency_field 파라미터로 변경할 수 있습니다.


예시: amount = fields.Monetary(string='Amount', currency_field='currency_id')

만약 특정 레코드에 통화 필드가 비어 있으면 Odoo는 회사의 기본 통화로 대체합니다. 치명적인 오류는 막아주지만 다중 통화 환경에서는 잘못된 포맷팅을 초래할 수 있으니 통화 필드를 항상 명시적으로 선언하는 것이 안전합니다.


반올림과 정밀도

Monetary와 Float의 주요 차이는 반올림 처리 방식에 있습니다. res.currency 모델에서 각 통화의 소수 자릿수와 반올림 단위를 정의합니다. Odoo는 Monetary 값을 읽거나 표시할 때 이 규칙을 자동으로 적용합니다.

따라서 EUR 통화의 필드에 1.2349999 같은 값이 저장되어 있으면 화면에는 1.23으로 보일 수 있습니다. 세금 계산이나 인보이스 합계 등에서는 이런 반올림 규칙이 매우 중요합니다. 단순 Float를 사용하면 결국 추적하기 어려운 반올림 오차가 쌓입니다.


ORM과의 상호작용

Odoo ORM에서 Monetary 필드를 읽으면 항상 파이썬 float를 반환합니다. 통화 정보는 같은 레코드의 연결된 통화 필드에서 가져옵니다. 계산을 수행할 때는 통화의 round() 메서드를 사용해 정밀도를 유지하는 것이 좋습니다.


예시: rounded_value = self.currency_id.round(self.amount)

이렇게 하면 다중 라인 합계나 반복 계산에서 발생할 수 있는 부동소수점 누적 오차를 피할 수 있습니다.


QWeb 리포트에서의 처리

QWeb 템플릿에서는 Monetary 필드 전용 위젯을 사용해 PDF나 웹 리포트에 올바르게 포맷된 값을 출력할 수 있습니다.


예시: <span t-esc="record.amount"
      t-options='{"widget": "monetary", "display_currency": record.currency_id}'/>

이렇게 하면 문서로 출력할 때에도 통화 기호와 소수 자리수가 레코드 통화에 맞춰 정확하게 표시됩니다.

비즈니스 활용 사례


표준 Odoo 모듈 전반에 Monetary 필드가 광범위하게 사용됩니다. 다음은 실제 업무 흐름에서 이 필드가 왜 중요한지 보여주는 다섯 가지 사례입니다.


1. 영업: 제품 단가와 주문 합계

판매 주문과 주문 라인의 price_unit, price_subtotal, amount_total 같은 필드는 모두 Monetary입니다. 고객 주문에 설정된 통화 문맥을 자동으로 따르기 때문에 회사의 운영 통화와 달라도 올바르게 표시됩니다.


예를 들어 영업 담당자가 회사 기본 통화가 유로인데 고객 주문을 달러로 입력하면, Monetary 필드는 해당 주문의 통화 문맥에서 표시·반올림·변환을 적절히 처리합니다.


2. 회계: 인보이스 금액과 세금 항목

회계 모듈에서는 인보이스의 모든 금액 컬럼(amount_untaxed, amount_tax, amount_total)이 Monetary 필드입니다. 인보이스에 설정된 통화가 이 값들의 반올림을 결정합니다.


이는 단순한 표시 문제가 아닙니다. 세금 항목의 반올림 오류는 분개 불균형을 초래해 조정·대응에 큰 비용이 듭니다. Monetary의 통화 기반 반올림이 이런 문제를 근본에서 막아줍니다.


3. CRM: 영업 기회의 예상 매출

CRM의 expected_revenue 필드는 Monetary로 처리됩니다. 영업팀은 잠재 고객의 통화로 파이프라인 가치를 입력하고, 대시보드나 리포트에서는 회사 통화로 환산해 분석할 수 있습니다.


이 흐름이 자연스럽게 작동하는 이유는 Monetary 필드가 수치와 함께 통화 문맥을 함께 다루기 때문입니다.


4. 구매: 공급업체 가격과 구매 주문

구매 주문 역시 단가와 합계에 Monetary를 사용하며, 공급업체와 합의한 통화에 따라 처리됩니다. 엔화로 된 공급청구서든 유로든 동일한 방식으로 정밀도와 표시가 관리됩니다.


5. 커스텀 필드: 예산 및 목표 관리

프로젝트, 부서, 맞춤 모델에 예산, 매출 목표, 비용 한도 같은 필드를 추가할 때 Monetary가 적절한 선택입니다. 회사 통화와의 연계, 폼·리스트·리포트에서의 일관된 표시와 내보내기 동작을 자연스럽게 지원합니다.

단순히 Float로 처리할 수도 있지만 다중 통화 상황이 되면 포맷 불일치와 반올림 문제가 곧 생깁니다.


필드 생성 및 커스터마이즈 방법


Odoo 모델에 Monetary 필드를 추가하는 방법은 크게 두 가지입니다: 코드 없이 Odoo Studio를 쓰거나, 파이썬 모듈을 통해 직접 선언하는 방법입니다.


Odoo Studio 사용하기

Studio의 필드 생성 패널에 Monetary 타입이 포함되어 있습니다. Studio로 필드를 추가하면 해당 모델에 currency_id 필드가 없다면 자동으로 생성해주므로 개발 지식 없이도 기본적인 요구는 충족됩니다.


주의할 점은 Studio가 만든 필드는 x_ 접두사를 사용한다는 점입니다(예: x_studio_budget). 모델에 기존 currency_id가 있으면 새 Monetary 필드는 이를 사용하지만 없으면 Studio가 별도의 통화 필드를 만듭니다. 동일 모델에 여러 Monetary 필드가 있고 각기 다른 통화를 의도한다면 이 공유 통화 필드 구조를 사전에 점검해야 합니다.


간단한 사용 사례에서는 Studio가 가장 빠른 방법이며, 개발 권한이 없는 비즈니스 사용자가 필드를 추가할 때 적합합니다.


기술적 접근: 파이썬 필드 선언

커스텀 모듈에서 Monetary 필드를 만들 때는 필드 본체와 연동되는 통화 필드, 두 개를 선언해야 합니다. 이것이 Odoo 파이썬 개발의 표준 패턴입니다.


예시 코드(패턴):
from odoo import fields, models

class ProjectTask(models.Model):
    _inherit = 'project.task'

    x_budget = fields.Monetary(
        string='Budget',
        currency_field='x_budget_currency_id',
    )
    x_budget_currency_id = fields.Many2one(
        comodel_name='res.currency',
        string='Budget Currency',
        default=lambda self: self.env.company.currency_id,
    )

회사 통화를 기본값으로 설정하면 대부분의 내부 필드에서 실무적으로 편리합니다. 새 레코드를 열었을 때 통화 필드가 비어 포맷이 깨지는 상황을 방지해줍니다.


계산된 Monetary 필드

Monetary 필드는 계산 필드(computed)로도 잘 동작합니다. 라인 합계를 내거나 특정 수식 결과를 금전 값으로 표현해야 할 때 표준 패턴을 따르세요.


예시 패턴:
x_total_budget = fields.Monetary(
    string='Total Budget',
    currency_field='currency_id',
    compute='_compute_total_budget',
    store=True,
)

@api.depends('x_line_ids.x_amount')
def _compute_total_budget(self):
    for record in self:
        record.x_total_budget = sum(record.x_line_ids.mapped('x_amount'))

만약 이 필드를 리스트 뷰나 리포트에서 검색·정렬·집계하려면 store=True를 반드시 설정하세요. 저장되지 않은 계산 필드는 ORM 도메인이나 SQL 기반 뷰에서 사용될 수 없습니다.


API를 통한 필드 추가

XML-RPC 같은 API로 원격 구성 스크립트에서 필드를 생성해야 할 경우, ir.model.fields를 통해 Monetary 필드를 만들 수 있습니다.


예시 호출:
models.execute_kw(ODOO_DB, uid, ODOO_API_KEY,
    'ir.model.fields', 'create',
    [{
        'name': 'x_budget',
        'field_description': 'Budget',
        'model_id': model_id,
        'ttype': 'monetary',
        'currency_field': 'currency_id',
        'state': 'manual',
    }]
)

이 방식은 XML-RPC API를 통한 Odoo 커스터마이즈 도구의 일부이며, 더 상세한 내용은 블로그의 다른 글에서 다룹니다.

모범 사례


Monetary 필드는 패턴만 알면 사용 자체는 간단합니다. 다음 권장 사항을 따르면 구현을 깨끗하게 유지하고 문제를 예방할 수 있습니다.


1. 재무 값에는 절대 Float를 사용하지 마세요

금전값을 표현해야 한다면 반드시 fields.Monetary를 사용하세요. Float 필드는 통화 인식이 없고 다중 통화 간에 올바르게 반올림하지 못합니다. Monetary 필드는 바로 이런 문제를 해결하기 위해 존재합니다.


2. 통화 필드를 항상 명시적으로 선언하세요

Odoo의 자동 대체 동작에 의존하지 마시고, currency_field 파라미터를 분명히 설정하고 대응하는 Many2one을 선언하세요. 이렇게 하면 다중 통화 환경에서 조용히 잘못 표시되는 상황을 막을 수 있습니다.


3. 기본 통화를 설정하세요

대부분 내부 필드가 회사 통화를 사용할 경우 통화 필드에 기본값(default=lambda self: self.env.company.currency_id)을 지정하세요. 새 레코드에서 비어 있는 통화로 인해 UI에서 기호·포맷이 사라지는 문제를 예방할 수 있습니다.


4. 검색용 계산 Monetary 필드에는 store=True를 사용하세요

계산된 Monetary 필드를 리스트 필터나 리포트에서 사용하려면 store=True로 저장하세요. 저장되지 않은 계산 필드는 ORM 도메인에서 사용할 수 없어 대시보드 제작 시 혼란을 초래합니다.


5. 중간 계산에서는 통화의 round()를 사용하세요

여러 단계의 산술 연산을 수행할 때는 의미 있는 단계마다 self.currency_id.round(value)를 적용하세요. 부동소수점 오차는 누적되기 쉬우므로 단계별 반올림이 총액 불일치를 막아줍니다.


6. 다중 통화 리포트는 의도적으로 설계하세요

다른 통화가 섞인 레코드들을 합산할 때는 원시 숫자들을 그냥 더하지 마세요. 먼저 res.currency.compute()로 공통 통화로 환산하거나, 특정 통화 단위로 리포트를 고정해야 합니다. 단위가 다른 금액을 그대로 합하면 수치는 맞지만 재무적으로는 의미가 없습니다.

자주 겪는 문제점


경험 많은 개발자도 Monetary 필드로 실수를 합니다. 다음은 가장 흔한 실수와 피하는 방법입니다.


문제 1: 통화 필드 누락

가장 흔한 실수는 연관된 Many2one 통화 필드를 만들지 않는 것입니다. 모델에 currency_id가 없으면 일부 상황에서는 회사 통화로 조용히 대체되고, 다른 상황에서는 에러를 냅니다. 예상치 못한 동작을 피하려면 Monetary 필드와 함께 통화 필드를 항상 선언하세요.


문제 2: 서로 다른 의미의 두 Monetary 필드에 통화 필드를 공유함

같은 모델에 두 개의 Monetary 필드가 있고 각각 다른 통화를 담고자 한다면 단일 currency_id를 공유하면 안 됩니다. 예: 고객 가격(EUR)과 공급가(USD)는 서로 다른 통화 참조를 가져야 합니다. 하나의 통화 필드로 공유하면 한 통화 설정이 두 필드를 덮어쓰게 되어 데이터와 UI가 혼란스러워집니다.


문제 3: 통화가 다른 레코드 집계시 반올림 차이

다른 통화의 Monetary 값을 그대로 합하면 합계가 이상해 보입니다. 다중 통화 기업에서 리포팅 오류가 발생하는 흔한 원인입니다. 집계 전에 반드시 동일한 기준 통화로 정규화하세요.


문제 4: ORM 검색에서의 부동소수점 비교

Monetary 필드를 정확한 값으로 비교(예: amount = 10.0)하면 DB에 저장된 부동소수점 표현 때문에 원하는 결과를 놓칠 수 있습니다. 작은 허용 오차를 둔 비교(>=, <=)를 사용하거나 비교 전에 통화 반올림을 적용해 검색 로직을 작성하세요. 이 문제는 일반적인 Float 기반 필드의 한계지만, 금전값에서는 더 민감합니다.


문제 5: 데이터 임포트 시 통화 반올림 무시

CSV나 XML-RPC로 Monetary 값을 임포트할 때는 제공된 숫자가 그대로 저장됩니다. 소스에 허용 자릿수보다 많은 소수점이 있으면 저장 후 표시가 달라지거나 합계 불일치가 발생할 수 있습니다. 임포트 전 스크립트에서 통화 반올림을 적용해 전달하세요.


결론


Monetary 필드는 겉보기에는 단순하지만 내부에는 중요한 동작 로직이 숨어 있습니다. 통화 레코드와의 긴밀한 연계가 올바른 반올림, 일관된 표시, 리포트 전반의 통화 인식 동작을 가능하게 합니다.


항상 통화 필드와 쌍으로 사용하고, 금전값에 Float를 대신 쓰지 않으면 운영 중 추적하기 어려운 미묘한 버그를 예방할 수 있습니다. Odoo 데이터 모델에서 이 필드 타입이 핵심으로 설계된 데는 분명한 이유가 있습니다.


개발 가이드나 표준 모듈 커스터마이즈, 신규 기능 개발 어느 쪽이든 Monetary 필드를 제대로 설계하는 것은 Odoo가 돈을 다루는 방식의 신뢰성을 좌우하는 기본 결정 중 하나입니다.

Odoo 도입 지원이 필요하신가요?


Dasolo에서는 기업의 Odoo 도입·커스터마이즈·최적화를 규모와 상황에 맞춰 지원합니다. 데이터 모델 정리, 커스텀 필드 전략, 다중 통화 지원, 전체 롤아웃 등 기술적·업무적 역량을 바탕으로 정확한 구현을 도와드립니다.


Monetary 필드나 Odoo 전반에 대한 질문이 있으시면 언제든 상담해 드립니다. 문의하기 귀하가 추진 중인 프로젝트에 대해 이야기해봅시다.

Odoo의 Monetary Field: 작동 원리와 활용 시기 안내
Dasolo 2026년 3월 6일
이 게시물 공유하기
로그인 의견을 남기기