소개
Odoo에서는 데이터 구조와 저장 방식을 '모델'이라는 단위로 정의합니다. 영업 주문, 송장, 분개 내역처럼 비즈니스에서 다루는 모든 데이터는 각기 대응되는 모델 안에 저장됩니다.
모델을 이해하는 것은 개발자와 기능 컨설턴트 모두에게 필수입니다. 모델은 Odoo 데이터 아키텍처의 기초로서 필드, 관계, 비즈니스 로직을 규정합니다.
이 글은 회계 관련 핵심 모델인 account.move를 중심으로 설명합니다. 맞춤 리포트 작성, 외부 시스템 연동, 청구 흐름 설정 등 회계 업무를 다루다 보면 이 모델을 반드시 접하게 됩니다.
account.move 모델이란 무엇인가
account.move는 Odoo에서 분개(journal entry)를 나타내는 모델입니다. Odoo 13 이후로 고객 송장, 공급업체 청구서, 외상 및 수동 분개로 나뉘던 항목들이 한곳으로 통합되어 account.move 안에서 관리됩니다.
이 모델은 회계 모듈의 핵심이며 account.move.line의 부모 모델입니다. 각 분개나 송장 한 건이 account.move 레코드로 존재하고, 세부적인 차변·대변 항목은 line_ids에 저장됩니다.
account 모듈 안에서 정의되며, 다른 모듈이 모델 상속을 통해 기능을 확장합니다. 예를 들어 판매 모듈은 주문에서 송장을 생성하는 로직을 추가하고, 구매 모듈은 청구서 관련 확장을 더합니다. 핵심 구조는 중복하지 않고 필요 부분만 확장합니다.
모델의 핵심 필드
다음은 account.move에서 특히 자주 사용하는 주요 필드들입니다. 이들 필드를 이해하면 송장, 청구서, 분개를 다루는 작업이 훨씬 수월해집니다.
1. name
유형: Char. 분개나 문서의 번호 또는 표시 이름을 담습니다. 보통 저널 시퀀스에서 자동 생성되며 목록이나 인쇄 문서에 표시됩니다.
2. move_type
유형: Selection. 분개의 성격을 결정합니다: 수동 분개(entry), 고객 송장(out_invoice), 고객 환불(out_refund), 공급업체 청구서(in_invoice), 공급업체 환불(in_refund) 등. 이 값에 따라 화면과 워크플로우가 달라집니다.
3. state
유형: Selection. 문서 상태를 나타냅니다: draft, posted, cancel. 초안 상태는 수정 가능하고, posted는 잠겨 일반원장에 영향을 줍니다. cancel은 효력을 제거합니다.
4. date
유형: Date. 문서의 날짜로 보고, 연령배치, 회계 기간 마감에 사용됩니다. 송장의 경우 보통 송장일과 연결됩니다.
5. journal_id
유형: Many2one (account.journal). 해당 분개가 속한 저널입니다. 매출, 구매, 은행, 기타 저널이 저마다 시퀀스와 기본 계정을 가집니다.
6. company_id
유형: Many2one (res.company). 멀티컴퍼니 환경에서 어느 회사 소속인지 표시합니다. 가시성 및 연결·통합에 영향을 줍니다.
7. partner_id
유형: Many2one (res.partner). 거래처(고객 또는 공급업체)를 가리킵니다. 송장·청구서에 필수이며 연령보고서, 결제매칭, 문서 머리말에 쓰입니다.
8. currency_id
유형: Many2one (res.currency). 문서의 통화입니다. 금액은 이 통화로 기록되며 다중통화 환경에서는 회사 통화로 환산하여 보고합니다.
9. amount_total
유형: Monetary. 문서의 총액입니다. 송장에서는 미결제 금액(청구 총액)을 의미하며, line 항목에서 계산됩니다.
10. amount_residual
유형: Monetary. 아직 지급되지 않은 잔액입니다. 완납된 송장에서는 0이 되며 연령·결제 흐름에서 핵심으로 사용됩니다.
11. payment_state
유형: Selection. 결제 상태를 나타냅니다: not_paid, in_payment, paid, partial, reversed 등. 결제 알림 및 보고에 활용됩니다.
12. line_ids
유형: One2many (account.move.line). 분개의 개별 라인들이며 각 라인에 계정, 차변, 대변이 기록됩니다. 차변 합계와 대변 합계는 반드시 일치해야 합니다.
13. invoice_line_ids
유형: One2many (account.move.line). 상품·서비스 항목들이며, 문서 확정 시 하나 이상의 분개 라인으로 변환됩니다.
14. invoice_date
유형: Date. 송장 발행일로서 과세기간과 청구 처리에 사용됩니다. 경우에 따라 move의 date와 다를 수 있습니다.
15. invoice_date_due
유형: Date. 지급 기한일입니다. 결제 조건으로 계산되거나 수동으로 설정할 수 있으며 연체 관리에 사용됩니다.
16. ref
유형: Char. 외부 참조나 공급업체 문서 번호를 저장합니다. 외부 문서와의 대조 및 계정조정에 유용합니다.
17. invoice_origin
유형: Char. 소스 문서(예: 주문번호)를 보관합니다. 주문에서 생성된 송장의 출처 추적에 도움을 줍니다.
18. create_date
유형: Datetime. 레코드 생성 시각을 자동으로 기록합니다.
19. write_date
유형: Datetime. 마지막 수정 시각을 자동으로 기록합니다.
20. narration
유형: Text. 내부 메모나 설명을 담습니다. 인쇄된 분개에는 나오지만 고객용 송장에는 노출되지 않습니다.
21. fiscal_position_id
유형: Many2one (account.fiscal.position). 과세 규칙을 결정하는 회계처리 위치입니다. 거래처와 국가에 따라 적용되는 세금을 바꿉니다.
22. invoice_payment_term_id
유형: Many2one (account.payment.term). 결제 조건(예: 결제일 기준 30일)을 저장하며 invoice_date_due 계산과 분할 결제에 사용됩니다.
23. invoice_user_id
유형: Many2one (res.users). 송장 담당자(영업 담당자 등)를 지정합니다. 커미션과 보고에 활용됩니다.
24. reversed_entry_id
유형: Many2one (account.move). 되돌리기 항목의 경우 원본 분개와 연결해 감사 추적을 제공합니다.
25. to_check
유형: Boolean. 검토가 필요한 분개를 표시하는 플래그입니다. 은행조정이나 예외 처리 워크플로우에서 사용됩니다.
26. active
유형: Boolean. 소프트 삭제 플래그입니다. False로 설정하면 레코드가 보이지 않게 아카이브됩니다. 일반적으로 취소된 분개는 active=False로 처리됩니다.
27. sequence_number
유형: Integer. 저널 시퀀스에서 부여되는 순번입니다. 정렬·표시에 사용되며 시퀀스 믹스인에서 관리됩니다.
28. amount_untaxed
유형: Monetary. 세금 전 소계입니다. 송장의 경우 라인 합계에서 세금을 제외한 금액입니다.
29. amount_tax
유형: Monetary. 총 세액입니다. 송장 라인과 세금 설정을 기반으로 계산됩니다.
30. invoice_source_email
유형: Char. 이메일로 수신된 공급업체 청구서의 발신 주소를 저장하는 데 사용됩니다. 자동 청구서 수집 프로세스에서 유용합니다.
업무 흐름에서 이 모델의 활용 방식
1. 고객 송장 처리
판매 주문이 납품되면 Odoo는 move_type이 out_invoice인 account.move 레코드를 생성합니다. 주문 라인이 invoice_line_ids로 옮겨지고, 문서를 게시하면 대응하는 분개 라인이 생성되어 매출채권이 업데이트됩니다.
2. 공급업체 청구서
구매 주문에서 청구서가 생성되거나 수동으로 입력할 수 있습니다. 각 청구서는 move_type이 in_invoice인 account.move이며 partner_id는 공급업체로 설정됩니다. 게시하면 매입채무가 반영됩니다.
3. 결제 및 대조
결제는 amount_residual와 payment_state를 기준으로 송장과 매칭됩니다. 대조 작업을 통해 결제 분개가 송장 분개와 연결되어 잔액이 소거됩니다.
4. 수동 분개 작성
회계 담당자는 조정·발생·정정 목적으로 move_type이 entry인 분개를 직접 생성합니다. 계정과 차변·대변 라인을 수동으로 추가하며, 게시 전에는 반드시 분개가 균형을 이루어야 합니다.
5. 계산서 취소와 환불
환불은 out_refund 또는 in_refund 유형의 move로 처리되어 원래 송장·청구서의 효과를 반대로 합니다. reversed_entry_id로 원본과 연결해 감사 가능성을 유지합니다.
개발자가 이 모델을 확장하는 방법
개발자는 여러 패턴으로 account.move를 확장합니다. 핵심 수단은 Odoo 모델 상속입니다.
모델 상속
모델을 확장하려면 _inherit = 'account.move'를 사용합니다. 새로운 필드를 추가하거나 메서드를 오버라이드하고 제약을 넣을 수 있습니다. 별도 모듈로 변경을 유지하면 향후 업그레이드가 쉬워집니다.
필드 추가
상속 모델에서 새로운 필드를 정의하세요. Char, Many2one, Boolean, Integer, Text, Selection 등 적절한 타입을 선택하고 멀티컴퍼니 환경에서는 회사별 필드를 고려하세요. 송장 전용 필드는 move_type으로 도메인을 제한하면 안전합니다.
파이썬 확장
create, write, _post, button_draft 등을 오버라이드해 비즈니스 로직을 추가할 수 있습니다. 항상 super()로 원래 동작을 호출하고, 계산 필드의 의존성(@api.depends 등)을 신중히 설계하세요.
Odoo Studio
Odoo Studio를 사용하면 코드 없이 필드를 추가할 수 있어 빠른 커스터마이징에 유용합니다. 다만 복잡한 검증이나 자동화 로직은 커스텀 모듈로 구현하는 것이 유지보수성에 더 유리합니다.
참고: account.move는 일반 모델로 데이터베이스 테이블을 가집니다. 추상 모델(템플릿)이나 transient 모델(임시 마법사)과는 다릅니다. account.move는 영속적인 회계 데이터를 저장합니다.
권장 실무 가이드
- 리포트나 연동을 만들 때는 항상 move_type으로 필터링하세요. 타입에 따라 필수 필드와 동작이 다릅니다.
- 각 move_type에 맞는 저널을 사용하세요. 저널을 섞어 쓰면 시퀀스나 보고서가 깨질 수 있습니다.
- API로 분개를 생성할 때는 게시 이전에 line_ids의 차변·대변 합계가 일치하는지 확인하세요. 불균형 분개는 검증에서 실패합니다.
- 외부 시스템에서 송장 정보를 가져올 때는 문서 유형을 move_type에 정확히 매핑하세요. 판매 문서는 out_invoice, 구매 문서는 in_invoice로 처리합니다.
- 커스텀 필드는 x_ 접두사를 사용해 향후 Odoo 버전과 충돌을 피하세요.
흔한 실수와 주의사항
- 균형이 맞지 않는 상태로 분개를 게시하려는 시도는 거부됩니다. 항상 차변=대변을 확인하세요.
- 게시된 분개를 직접 수정하지 마세요. 게시된 문서는 잠기므로 수정할 때는 반대 분개를 생성하거나 정정 분개를 만드세요.
- 고객·공급업체 문서에 partner_id를 설정하지 않으면 많은 보고서와 워크플로우가 정상적으로 동작하지 않습니다.
- move_type을 잘못 사용하는 실수에 주의하세요. 예를 들어 out_refund는 단순히 음수 금액의 out_invoice와 동일하지 않습니다. 환불은 적절한 타입으로 처리해야 합니다.
- 핵심 메서드를 오버라이드할 때 super()를 호출하지 않으면 다른 모듈이나 향후 업그레이드에 문제를 일으킬 수 있습니다.
마무리
account.move는 Odoo 회계의 중심입니다. 송장, 청구서, 분개를 통합된 구조로 표현하며, 필드와 확장 방식을 이해하면 설정·커스터마이징·연동 작업을 효과적으로 수행할 수 있습니다.
업무 프로세스를 설계하는 기능 컨설턴트든 맞춤 모듈을 개발하는 엔지니어든 account.move를 잘 이해하면 시간과 비용을 절감하고 오류를 줄일 수 있습니다.
Odoo 도입을 도와드릴까요?
Dasolo는 기업의 Odoo 도입, 커스터마이징, 최적화를 지원합니다. 특히 API 연동과 개발에 강점을 가지고 있으며 account.move 같은 핵심 모델에 대한 깊은 경험을 보유하고 있습니다.
Odoo 도입, 맞춤 모듈 개발, 연동이 필요하시면 저희가 도와드리겠습니다. 데모 요청하기 프로젝트에 대해 이야기해 보겠습니다.