은행 현장의 언어 · 원장과 복식부기 · 실습
원장에서 차대변 불일치 찾아내기
목표
복식부기 원장에서 시작해, 차대변이 맞지 않는 전표 1건을 분개행 한 줄까지 좁혀 내고, 원 기록을 지우지 않는 방식으로 바로잡은 뒤, 잔액 표까지 원장에 맞춰 놓을 수 있게 됩니다.
왜 중요한가
은행 시스템에서 잔액은 저장된 값이 아니라 원장에서 계산해 내는 값입니다. 성능 때문에 계정마다 잔액 컬럼을 함께 들고 있지만, 그것은 원장의 사본이지 원본이 아닙니다.
이 구분이 조사에서 결정적인 이유는 이렇습니다. 잔액 하나는 그냥 숫자라서, 그 숫자만 보고는 맞는지 틀린지 알 방법이 없습니다. 반면 복식부기 원장은 자기 자신을 검증합니다 — 모든 거래가 차변과 대변 양쪽에 기록되므로 원장 전체의 차변 합과 대변 합은 반드시 같아야 하고, 이 항등식이 깨지면 그 자체가 사고 신호입니다. 그리고 그 신호는 전표 단위로 한 번 더 좁혀집니다.
이번 사건은 이렇습니다. 고객사 운영 담당자가 "결산 잔액이 안 맞는다" 고 연락해 왔습니다. 사흘치 원장에 어긋남이 두 군데 있는데, 성질이 서로 정반대입니다. 한쪽은 원장이 틀렸고 잔액 표가 맞으며, 다른 한쪽은 원장이 맞고 잔액 표가 틀렸습니다. 이 둘을 가르지 않고 손대면 고치는 쪽이 반대가 됩니다.
정정 방법도 일반 서비스와 다릅니다. 틀린 전표를 UPDATE 로 고치면 안 됩니다. 원 전표를 거울처럼 뒤집은 역분개를 넣어 상쇄하고, 올바른 전표를 새로 기표합니다. 원장에 세 장이 나란히 남아야 두 달 뒤 감사에서 무슨 일이 있었는지 설명할 수 있습니다.
단계
1. /root/bank/gen_ledger.py 를 만들어 실행해 /root/bank/ledger.db 를 만드세요. 계정 10개, 전표 201건, 분개행 430줄이 들어갑니다.
2. /root/bank/trial_balance.csv 에 계정별 시산표를 뽑으세요. 머리글은 code,name,debit,credit,balance 이고 balance 는 차변합 빼기 대변합입니다. 한 번도 안 움직인 계정도 남깁니다.
3. /root/bank/tb_totals.txt 에 네 줄을 적으세요. debit_total=, credit_total=, gap= 은 원장에서, cached_sum= 은 accounts.cached_balance 의 합입니다.
4. 전표별로 차변 합과 대변 합을 비교해 어긋난 전표를 찾고, /root/bank/broken_entry.txt 에 entry_id=, debit=, credit=, gap= 을 적으세요. 그 전표의 분개행은 /root/bank/broken_lines.csv 에 line_id,entry_id,account_code,dc,amount 머리글과 함께 그대로 뜹니다.
5. /root/bank/balance_diff.csv 에 code,cached,ledger,gap 머리글로 잔액 표와 원장 합산이 다른 계정만 남기세요. gap 은 cached 에서 ledger 를 뺀 값입니다.
6. 원 전표를 손대지 말고 정정 전표 두 장을 넣으세요. 역분개는 JE-20260826-0134-R, 재기표는 JE-20260826-0134-C 로 등록하고 journal 과 journal_line 양쪽에 넣습니다.
7. accounts.cached_balance 를 원장 합산으로 다시 계산해 덮고, /root/bank/recheck.txt 에 debit_total=, credit_total=, gap=, unbalanced_entries=, original_credit=, cached_sum=, balance_diff_rows= 일곱 줄을 적으세요.
8. /root/bank/ledger_report.md 에 ## 무엇이 틀렸나, ## 어떻게 찾았나, ## 어떻게 고쳤나, ## 잔액 표는 왜 못 잡았나, ## 재발 방지 다섯 절로 보고서를 쓰세요.
참고
sqlite3 -readonly <파일> "<쿼리>"로 읽으면 조사 중에 실수로 쓰는 일을 막을 수 있습니다.- CSV 로 뽑을 때는 표준입력으로
.headers on과.mode csv를 먼저 넘기세요:sqlite3 -readonly ledger.db > out.csv <<'SQL' ... SQL. - 부호 있는 잔액은
SUM(CASE dc WHEN 'D' THEN amount ELSE -amount END)로 한 번에 냅니다. - 흔한 실수 1: 2단계에서 움직임이 없는 계정을 표에서 빼는 것. 그러면 '움직임이 없다' 와 '계정이 없다' 가 구별되지 않습니다.
- 흔한 실수 2: 6단계에서 역분개 금액을 올바른 금액으로 쓰는 것. 기록된 금액 그대로 뒤집어야 틀림이 정확히 상쇄됩니다.
- 흔한 실수 3: 7단계에서 전표 단위 불일치가 0 이 되기를 기대하는 것. 원 전표와 역분개가 짝을 이뤄 남는 것이 정상입니다.
단계 8개
- 원장 스냅샷 만들기
- 시산표 만들기
- 원장과 잔액 표를 각각 세기
- 전표 한 건, 분개행 한 줄까지 좁히기
- 잔액 표와 원장 합산 대사하기
- 역분개와 재기표로 바로잡기
- 잔액 표를 원장에서 다시 만들기
- 원장 정합성 보고서 쓰기