소개
Odoo에서 ‘모델’은 데이터베이스에 정보를 어떻게 저장하고 구조화할지 정의하는 설계도입니다. 영업 주문, 인보이스, 재고 이동처럼 업무에서 다루는 모든 항목은 각기 다른 모델에 저장되어 시스템이 일관되게 처리합니다.
모델을 이해하는 것은 개발자와 컨설턴트 모두에게 필수적입니다. 모델은 필드 정의, 관계 설정, 비즈니스 로직을 담는 근간으로서 Odoo 데이터 구조의 토대 역할을 합니다.
이 글은 Odoo에서 핵심적인 모델 중 하나인 stock.move를 집중적으로 다룹니다. 창고 관련 커스터마이징, 외부 시스템 연동, 재고 흐름 설정 등 재고 작업을 다룰 때 반드시 만나는 모델입니다.
stock.move 모델이란 무엇인가
stock.move는 단일 재고 이동을 표현하는 레코드입니다. 제품이 한 위치에서 다른 위치로 옮겨질 때마다 이 모델의 레코드가 만들어집니다. 선반에서 출고되거나 창고 간 이동, 고객에게 인도되는 모든 경우에 해당합니다.
Inventory(재고) 모듈이 이 모델을 기본으로 사용합니다. 판매, 구매, 제조, 전자상거래 등 재고 변동을 발생시키는 기능은 모두 stock.move를 생성하거나 갱신합니다. 배송 확인, 입고 처리, 제조 완료 시 관련 이동 기록이 생성됩니다.
모델 정의는 stock 모듈 안에 위치하며, 다른 모듈들은 Odoo의 모델 상속을 통해 필요한 필드를 추가합니다. 예를 들어 Sale은 sale_line_id를, Purchase는 purchase_line_id를, Manufacturing은 production_id를 추가해 핵심 구조를 중복하지 않고 확장합니다.
모델의 핵심 필드
다음은 stock.move에서 자주 사용되는 주요 필드들입니다. 각 필드의 의미를 알면 재고 이동을 정확히 이해하고 처리할 수 있습니다.
1. name
형식: Char. 이동의 식별명이나 설명을 담는 필드입니다. 보통 제품명과 수량을 결합해 표시하며, 목록과 여러 뷰에서 식별자로 사용됩니다.
2. product_id
형식: Many2one (product.product). 이동 대상 제품을 가리키는 필수 필드입니다. 재고 수량 추적과 재고 규칙 적용에 핵심적으로 사용됩니다.
3. product_uom
형식: Many2one (uom.uom). 수량 단위(UoM)를 지정하는 필드로, 보통 제품의 기본 단위와 일치합니다. 수량 입력과 검증 시 기준 단위로 사용됩니다.
4. product_uom_qty
형식: Float. 이동을 요청한 수량(요구 수량)입니다. 실제 처리된 양은 quantity_done으로 기록됩니다.
5. quantity
형식: Float. 화면 표시용으로 계산되거나 변환된 수량을 보여주는 필드입니다. product_uom_qty와 같거나 단위 변환 값일 수 있습니다.
6. location_id
형식: Many2one (stock.location). 출발 위치를 가리킵니다. 필수 필드이며, 출고의 경우 재고 위치, 입고의 경우 공급자나 생산 위치일 수 있습니다.
7. location_dest_id
형식: Many2one (stock.location). 도착 위치를 가리킵니다. 필수이며, 입고 시 재고 위치, 출고 시 고객이나 폐기 위치가 됩니다.
8. picking_id
형식: Many2one (stock.picking). 이 이동이 속한 전표(픽킹)를 연결합니다. 배송서, 입고서, 내부이동 전표 등 사용자 작업은 보통 이 단위로 묶입니다.
9. picking_type_id
형식: Many2one (stock.picking.type). 작업 유형을 정의합니다. 출고, 입고, 내부이동 중 어느 작업인지에 따라 기본 위치와 워크플로가 결정됩니다.
10. state
형식: Selection. 이동의 현재 상태를 나타냅니다. draft, waiting, confirmed, assigned, done, cancelled 같은 값으로 예약·확정·완료 등 흐름을 관리합니다.
11. date
형식: Datetime. 작업 예정 일시를 나타내며, 우선순위 및 작업 스케줄링에 활용됩니다.
12. date_deadline
형식: Datetime. 마감 기한으로, 고객 약속 배송일 등 긴급도 판단에 사용됩니다.
13. origin
형식: Char. 이동을 발생시킨 원본 문서의 참조(예: SO 번호, PO 번호, MO 번호)를 저장해 추적성을 제공합니다.
14. move_dest_id
형식: Many2one (stock.move). 이동 체인에서 다음 단계의 이동을 가리킵니다. 제조 산출물이 배송으로 연결되는 경우처럼 흐름을 잇는 용도입니다.
15. move_orig_ids
형식: One2many (stock.move). 반대로 이 이동으로 이어진 이전 이동들을 목록으로 가집니다. 추적성과 연쇄 처리를 돕습니다.
16. move_line_ids
형식: One2many (stock.move.line). 로트, 시리얼, 상세 위치 정보를 담은 개별 이동 라인입니다. 예약과 처리 시에 구체적인 move line이 생성됩니다.
17. partner_id
형식: Many2one (res.partner). 이동과 연관된 상대(고객/공급사)를 지정합니다. 주소나 보고서 작성 시 사용됩니다.
18. company_id
형식: Many2one (res.company). 다중 회사 환경에서 어느 회사 소속인지 표시해 가시성과 인터컴퍼니 규칙에 영향을 줍니다.
19. quantity_done
형식: Float. 실제로 처리된 수량을 기록합니다. 피킹 시 작업자가 처리한 양을 업데이트하며, quantity_done이 product_uom_qty와 같아지면 이동이 완료됩니다.
20. reserved_availability
형식: Float. 해당 이동을 위해 예약된 수량을 보여줍니다. 할당(assigned) 상태가 되면 재고가 예약되어 이 필드에 반영됩니다.
21. create_date
형식: Datetime. 레코드 생성 일시를 자동으로 저장하며 보고·감사에 유용합니다.
22. write_date
형식: Datetime. 마지막 변경 시점을 자동으로 기록해 데이터 변경 이력을 추적합니다.
23. sequence
형식: Integer. 동일 픽킹 내에서 표시 순서를 제어합니다. 작은 숫자가 우선 표시됩니다.
24. priority
형식: Selection. 작업 긴급도를 나타내며 일반적으로 0(보통), 1(긴급)처럼 우선순위 계산에 쓰입니다.
25. description_picking
형식: Char. 픽킹 문서에 표시되는 설명이나 특이사항을 적는 필드로, 취급 지침 등을 남길 때 유용합니다.
26. reference
형식: Char. 내부 참조나 외부 시스템 맵핑용 코드로 활용할 수 있습니다.
27. group_id
형식: Many2one (procurement.group). 동일 조달 흐름에 속한 이동들을 그룹화해 계획 및 연결성 확보에 사용합니다.
28. procure_method
형식: Selection. 재고에서 출고할지(MTS) 주문 시 생산/구매할지(MTO)를 결정하는 필드로, 조달 전략에 영향을 줍니다.
29. sale_line_id
형식: Many2one (sale.order.line). Sale 모듈에서 추가하며, 어떤 판매 주문 라인에서 유발된 이동인지 연결해 추적·보고에 도움을 줍니다.
30. purchase_line_id
형식: Many2one (purchase.order.line). Purchase 모듈에서 추가되며, 입고가 어떤 구매 주문 라인에서 왔는지 연결합니다.
31. production_id
형식: Many2one (mrp.production). 제조 모듈에서 추가된 필드로, 원자재 소비와 완제품 이동을 해당 제조오더와 연결합니다.
32. active
형식: Boolean. 소위 소프트 삭제 플래그로, False로 설정하면 기본 뷰에서 숨겨져 보관 처리됩니다(물리적 삭제 아님).
업무 프로세스에서의 활용 예시
1. 고객 배송
판매 주문이 확정되면 각 제품 라인별로 stock.move가 생성됩니다. 출발지는 재고 위치(location_id), 도착지는 고객 위치(location_dest_id)가 되며, 해당 이동들은 하나의 픽킹(배송 전표)으로 묶입니다. 창고에서 피킹·출고 처리하면 quantity_done이 갱신되고 상태는 done으로 바뀝니다.
2. 공급자 입고
구매 주문 확정 시 입고용 stock.move가 생성됩니다. 출발지는 공급자 위치, 도착지는 재고 위치로 설정되고, 입고 전표로 묶인 뒤 실제 물품 도착 시 사용자 검증을 통해 quantity_done이 기록됩니다.
3. 내부 이동
창고 간 또는 로케이션 간 재고 이동은 stock.move로 처리됩니다. 보충, 재분배, 다중 창고 운영 등을 위해 소스와 목적지를 지정해 전표화합니다.
4. 제조
제조 오더는 원자재 투입을 위한 입고 이동과 완제품 출력의 출고 이동, 두 종류의 이동을 생성합니다. production_id로 제조오더와 연결되며 move_dest_id 같은 연쇄 연결을 통해 제조 산출물이 이후 배송으로 자연스럽게 이어집니다.
5. 반품과 폐기
고객 반품은 역방향 이동을 만들고, 폐기는 스크랩 위치로 이동을 생성합니다. 모든 흐름은 동일한 stock.move 모델로 처리되며, picking_type_id가 작업 성격과 워크플로를 결정합니다.
개발자가 이 모델을 확장하는 방법
개발자는 여러 패턴으로 stock.move를 확장합니다. 그 중심에는 Odoo의 모델 상속이 있습니다.
모델 상속
모델을 확장하려면 _inherit = 'stock.move'를 사용합니다. 필드를 추가하거나 메서드를 오버라이드하고 제약을 걸 수 있습니다. 상속 방식으로 변경을 별도 모듈에 두면 향후 업그레이드 관리가 쉬워집니다.
필드 추가
상속 모델 안에 새로운 Odoo 필드를 정의하세요. Char, Many2one, Boolean, Integer, Text, Selection 등 적절한 타입을 사용합니다. 다중 회사 환경이면 회사 종속 필드를 고려하십시오. 재고 이동에서 자주 추가되는 항목은 커스텀 추적번호, 운송사 참조, 배치 속성 등입니다.
파이썬 확장
_action_done, _action_assign, _action_cancel 같은 핵심 메서드를 오버라이드해 로직을 집어넣을 수 있습니다. 기존 동작은 반드시 super()로 호출해 재고 처리나 체인 연결이 깨지지 않게 유의하세요. Odoo API는 이러한 확장을 염두에 둔 설계를 제공합니다.
Odoo Studio
코드 없이 필드를 추가하려면 Odoo Studio가 편리합니다. 간단한 필드 추가나 폼 커스터마이징에 적합하지만, 복잡한 워크플로 변경이나 고급 로직은 모듈 개발로 관리하는 편이 장기적으로 유지보수에 유리합니다.
권장 관행
- location_id와 location_dest_id를 정확히 설정하세요. 잘못된 위치 지정은 재고 수량 오류로 이어집니다.
- 관련 이동들은 picking_id로 묶어 관리하세요. 하나의 전표에 속하는 이동을 전표 없이 개별적으로 생성하면 흐름이 깨질 수 있습니다.
- API 연동 시에는 XML-RPC나 JSON-RPC를 사용하세요. stock.move는 외부 연동을 위해 완전히 노출되어 있으므로 외부 ID 매핑을 신중히 처리해야 합니다.
- 커스텀 필드는 충돌을 피하려면
x_프리픽스 또는 모듈 접두사를 사용하세요. 향후 Odoo 핵심 업데이트와 충돌을 예방합니다. - 프로그램으로 연쇄 이동을 생성할 때는 move_dest_id와 move_orig_ids 링크를 올바르게 설정해 추적성을 유지하세요.
- 검증 시에는 product_uom_qty와 quantity_done을 구분해 처리하세요. 부분 인도(Partial delivery)를 허용하는 시나리오가 자주 발생합니다.
자주 범하는 실수
- 잘못된 위치 유형으로 이동을 생성하는 실수. 예를 들어 출발지와 도착지를 모두 고객 위치로 지정하는 등 호환성 없는 조합은 피하세요.
- move line이 이미 존재하는데 product_uom_qty를 임의로 변경하면 재고 불일치가 생길 수 있습니다. 수정이 필요하면 해당 이동을 취소 후 재생성하는 편이 안전합니다.
- origin을 비워 두는 것. 원본 문서 없이 이동만 남으면 나중에 추적하기 어렵습니다.
- _action_done을 오버라이드하면서
super()를 호출하지 않는 실수. 이로 인해 재고 차감이나 다른 모듈 연동이 깨질 수 있습니다. - stock.picking 같은 정상 워크플로를 거치지 않고 직접 move만 생성하는 행위는 예약·할당 로직을 우회해 시스템 불일치를 초래할 수 있습니다.
- 이동을 분할하거나 병합할 때 move_dest_id를 무시하면 연쇄 연결이 끊겨 고아 레코드가 생길 수 있습니다.
맺음말
stock.move는 Odoo 재고의 핵심입니다. 제품이 한 장소에서 다른 장소로 이동하는 모든 사건을 기록하며, 필드 구조와 모듈 확장 방식을 이해하면 시스템 구성·커스터마이징·연동 작업을 훨씬 안정적으로 수행할 수 있습니다.
현업의 입고·출고 프로세스를 설계하는 컨설턴트든, 커스텀 모듈을 만드는 개발자든 stock.move 개념을 확실히 알고 있으면 시간과 오류를 크게 줄일 수 있습니다.
Odoo 도입 지원이 필요하신가요?
Dasolo는 기업의 Odoo 도입, 커스터마이징, 최적화를 지원합니다. 특히 API 연동과 모듈 개발에 전문성이 있으며, Odoo의 데이터 구조와 stock.move 같은 핵심 모델 경험이 풍부합니다.
Odoo 도입, 커스텀 모듈 제작, 시스템 연동에 도움이 필요하시면 저희가 도와드리겠습니다. 데모 신청 프로젝트 상담을 예약하세요.