#운영 #프로덕트
재고가 있는데 왜 발주가 나갔을까 — 숫자가 어긋나는 자리 4곳

현장에서 제일 자주 듣는 말 중 하나가 "우리 재고 숫자는 못 믿는다"입니다. 그러면 대개 원인을 사람에게서 찾습니다. 입고 등록을 늦게 했다거나, 출고를 안 찍었다거나, 재고 실사를 제때 안 했다는 쪽입니다.

그런데 저희가 생산관리 소프트웨어를 만들면서 같은 증상을 저희 손으로 재현해 보니, 사람이 잘못 넣은 자리는 하나도 없었습니다. 넣은 값은 전부 맞았고, 그 값을 누가 어느 표에서 읽었는가가 갈라져 있었습니다.

아래는 개발 중인 소프트웨어의 시험 데이터에서 나온 실측입니다. 고객사 데이터가 아니라 저희가 만들어 둔 시험용 장부이고, 그래서 마음 놓고 숫자를 그대로 공개합니다. 다만 어긋난 모양은 실제 공장에서 그대로 나타나는 것이라, 도입을 검토하시는 분들이 그대로 점검 목록으로 쓰실 수 있습니다.

있는 재고를 없다고 보고, 발주가 두 건 나갔습니다

소요량 계산을 돌렸더니 자재 43품목의 현재고가 전부 0으로 잡혔습니다. 창고에 물건이 있는데도 0이었습니다. 계산은 그 0을 근거로 부족분을 채우는 발주를 만들었고, 그중 두 건은 이미 있는 재고를 다시 사는 발주였습니다.

원인을 찾아보니 계산식이 틀린 게 아니었습니다. 계산이 읽는 표를 바꿨더니 숫자가 이렇게 달라졌습니다.

· 재고가 잡힌 품목 — 바꾸기 전: 0 · 바꾼 뒤: 28 · 차이: +28
· 발주 수량 — 바꾸기 전: 47,614 · 바꾼 뒤: 45,516 · 차이: −2,098
· 계획오더 — 바꾸기 전: 40건 · 바꾼 뒤: 38건 · 차이: −2건

같은 코드, 같은 공장, 같은 순간입니다. 읽는 표만 바꿨습니다.

원인은 계산이 아니라 어느 표를 읽었는가였습니다

공장에는 재고를 적는 자리가 보통 둘 이상 있습니다. 하나는 창고가 실물을 관리하는 원장이고, 다른 하나는 회계가 자산으로 인식하는 장부입니다. 이름이 둘 다 "재고"라서 같은 것처럼 보이지만, 두 표는 서로 다른 질문에 답합니다.

· 창고 원장 — "지금 이 물건이 어느 선반에 몇 개 있는가." 그래서 여기에는 보류·검역·불량 상태의 물건도 그대로 들어 있습니다. 실물이 있으니까요.
· 회계 장부 — "지금 이 회사가 쓸 수 있는 자산이 얼마인가." 그래서 검사에 걸려 있거나 불량 판정을 받은 물건은 여기서 빠집니다.

소요량 계산이 읽어야 하는 것은 쓸 수 있는 재고이므로 회계 장부 쪽입니다. 그런데 코드는 창고 원장을 읽고 있었고, 그 결과 보류·검역·불량 재고까지 "쓸 수 있다"고 세고 있었습니다. 게다가 같은 계산 안에서 입고 예정 수량만은 다른 표에서 읽어 오고 있어서, 한 계산 안에 두 층이 섞여 있었습니다.

이게 왜 위험하냐면, 틀리는 방향이 한쪽으로 쏠리기 때문입니다. 못 쓰는 물건을 쓸 수 있다고 세면 발주가 줄고, 그러면 라인이 섭니다. 반대로 있는 물건을 못 봤을 때는 돈만 나갑니다. 어느 쪽이든 숫자가 나오기는 나오기 때문에 아무도 이상하다고 말하지 않습니다.

여기서 더 중요한 것은 마지막입니다. 어느 표를 원본으로 삼을지가 어디에도 적혀 있지 않았습니다. 설계 문서에도, 규격에도 없었습니다. 코드가 스스로 하나를 골랐고, 고른 순간에는 아무도 그것이 선택이었다는 사실을 몰랐습니다.

같은 출하인데 화면에 따라 재고가 빠지기도 하고 안 빠지기도 했습니다

두 번째는 더 곤란했습니다. 똑같은 출하를 두 가지 화면으로 넣어 봤습니다.

· 문서 화면 — 출하 뒤 재고: 22,132 · 결과: 안 빠짐
· 라인 표 화면 — 출하 뒤 재고: 22,127 · 결과: 빠짐

같은 회사, 같은 품목, 같은 수량입니다. 그런데 담당자가 어느 화면으로 입력했느냐에 따라 재고가 빠지기도 하고 안 빠지기도 했습니다.

원인은 화면 하나가 재고 차감을 부르는 함수를 호출하지 않은 것이었습니다. 한 줄짜리 누락입니다. 문제는 그다음입니다.

두 화면 모두 정상으로 보였습니다. 저장은 성공했고, 오류 메시지도 없었고, 출하 기록도 정상으로 남았습니다. 화면만 봐서는 어느 쪽이 맞는지 알 방법이 없었습니다. 두 화면을 나란히 놓고 같은 값을 넣어 재고를 대조하기 전까지는요.

공장에서 이런 일이 나면 재고 정확도가 서서히 무너지는데, 원인이 사람에게 씌워집니다. "저 반장님 라인만 이상하게 안 맞네"가 되는 겁니다. 실제로는 그 반장님이 남들과 다른 화면을 쓰고 있었을 뿐입니다.

문서번호 하나가 두 가지를 뜻하고 있었습니다

세 번째는 재고 자체가 아니라 재고를 부르는 이름 쪽입니다.

문서번호에 접두어를 붙여 종류를 나누는 방식은 어디서나 사용합니다. 그런데 접두어를 나눠 쓰는 무리 20개를 전수 대조해 보니, 같은 번호가 실제로 두 곳에서 발행된 무리가 4개, 건수로 11건 있었습니다. 예를 들어 하나의 부적합 보고서 번호가 사내 부적합이면서 동시에 공급사 부적합을 가리키고, 하나의 구매 관련 번호가 지급 기록이면서 구매 요청이었습니다.

처음에는 이것을 급하지 않다고 봤습니다. 대상이 서로 다르니 실무에서 헷갈릴 일이 없다고 생각한 겁니다. 그런데 우선순위를 다시 잡을 기준이 하나 나왔고, 그 기준이 판단을 뒤집었습니다.

그 번호가 회사 밖으로 나가는가.

부적합 보고서 번호는 협력업체에 발행되고, 회신도 그 번호로 받습니다. 사내에서만 도는 번호라면 나중에 정리해도 되지만, 밖으로 나간 번호가 어긋나면 어긋났다는 사실을 우리가 먼저 알 수 없습니다. 상대가 그 번호로 물건을 보내거나 대금을 청구하고 나서야 드러납니다.

번호 체계를 점검하실 때는 중복 여부만 보지 마시고, 어느 번호가 회사 밖으로 나가는지를 먼저 표시해 보시기 바랍니다. 그 목록이 곧 우선순위입니다.

통제계정과 보조부가 80만 원 어긋나 있었습니다

네 번째는 회계 쪽입니다. 총계정원장의 통제계정 잔액과 보조부 합계가 맞아야 하는데, 실측해 보니 14,050,000원 대 14,850,000원으로 80만 원이 어긋나 있었습니다.

이 대사는 원래 매달 돌립니다. 그런데 대사를 자동으로 돌리는 자리가 없으면, 어긋난 채로 몇 달이 지나갑니다. 나중에 발견하면 어느 달에 무엇 때문에 벌어진 차이인지 되짚기가 훨씬 어려워집니다.

앞의 세 가지와 원인이 같습니다. 두 표가 같은 것을 적고 있다고 믿고, 같은지 확인하는 자리를 안 만든 것입니다.

이걸 못 잡은 검사에도 이유가 있었습니다

여기까지 읽으시면 자연스럽게 드는 질문이 있습니다. 그러면 검사는 뭘 하고 있었느냐입니다. 저희도 자동 판정을 40건 넘게 돌리고 있었고, 전부 통과였습니다.

세 가지가 나왔습니다.

첫째, 판정하는 도구가 둘이면 둘이 다른 말을 합니다. 표 사이 연결 규칙을 검사하는 자리가 연결 대상을 엉뚱한 표에서 찾고 있었습니다. 실제로는 양쪽 다 있는 항목인데 "없다"고 판정하고 그 규칙을 꺼 버렸습니다. 검사가 자기 판단으로 검사를 끈 겁니다.

둘째, 값을 바꾸는 자리와 설명하는 자리에 같은 요구를 걸지 않았습니다. 선언 파일에 적어 넣은 설정 3건이 실제 등재는 0건이었습니다. 반영하는 쪽은 그 항목을 요구했는데 승인하는 쪽은 요구하지 않아서, 값은 조용히 바뀌고 설명은 조용히 사라졌습니다.

셋째, 빈칸을 기본값이 채우면 검사가 통과합니다. 설비 보전 기록을 넣는 표에서 실제로 확인한 것인데, 보전 일자는 비워 두면 오늘 날짜가 자동으로 들어가고 비용은 비워 두면 0원이 들어갑니다. 그래서 내용을 거의 채우지 않은 요청 하나가 막히지 않고 그대로 통과하면서, 비용 0원에 정지 시간 0시간짜리 "완료된 보전" 한 건이 조용히 남았습니다. 필수 항목이 비어 있으면 막아야 하는데, 기본값이 대신 채워 주면서 막을 이유가 사라진 겁니다.

이런 기록은 나중에 설비별 보전 비용을 집계할 때 분모에 들어갑니다. 실제로는 하지 않은 보전이 한 건 잡히고, 비용은 0원이니 평균 보전비가 내려갑니다. 아무도 거짓말을 하지 않았는데 집계가 실제보다 좋게 나옵니다.

검사를 늘린다고 해결되지 않습니다. 저희가 넣은 판정 40여 건은 전부 초록이었으니까요. 필요한 것은 개수가 아니라, 검사가 실제로 대상에 닿고 있는지를 한 번 의심해 보는 자리입니다.

그래서 확인하실 4가지

시스템을 새로 들이시거나, 지금 쓰는 것이 미덥지 않으실 때 그대로 쓰실 수 있는 질문으로 정리했습니다. 개발자가 아니어도 물어보실 수 있는 문장으로 적었습니다.

· 원본 표 — 물어볼 문장: "가용 재고는 어느 표에서 읽습니까" · 위험 신호: 답이 바로 안 나옴
· 상태 제외 — 물어볼 문장: "보류·불량도 세고 있습니까" · 위험 신호: "그건 안 세죠"만
· 경로 일치 — 물어볼 문장: "화면마다 결과가 같습니까" · 위험 신호: 시험해 본 적 없음
· 대사 주기 — 물어볼 문장: "장부 대사는 언제 돌립니까" · 위험 신호: 필요할 때만

각각 왜 이 질문인지 한 줄씩 붙입니다.

· 원본 표 — 답이 문서에 적혀 있어야 합니다. 담당자의 기억에 있으면 그 담당자가 바뀔 때 같이 사라집니다.
· 상태 제외 — "당연히 안 세죠"가 아니라, 어느 상태를 빼는지 목록으로 보여 달라고 하시면 됩니다. 목록이 없으면 확인이 안 된 겁니다.
· 경로 일치 — 같은 거래를 두 화면으로 넣어 결과를 대조해 본 적이 있는지 물어보시는 게 가장 빠릅니다. 30분이면 끝나는 시험인데 안 해 본 곳이 많습니다.
· 대사 주기 — "필요할 때"라는 답은 사실상 안 한다는 뜻입니다. 매달 자동으로 돌고 결과가 남는지를 보셔야 합니다.

남는 이야기

이 네 가지를 저희 손으로 겪으면서 배운 것은, 재고 숫자가 안 맞는 문제가 대체로 정확도 문제가 아니라 정의 문제라는 점입니다. 어느 표가 원본인지, 그 표는 무엇을 세고 무엇을 빼는지, 같은 사건이 어느 경로로 들어와도 같게 기록되는지. 이 셋이 문서에 적혀 있지 않으면 숫자는 언제든 다시 어긋납니다.

그리고 어긋난 숫자는 틀렸다고 말해 주지 않습니다. 계산은 끝까지 돌고, 화면은 값을 보여 주고, 발주는 나갑니다. 사람이 눈치채는 것은 대개 물건이 없거나, 돈이 두 번 나간 다음입니다.

이 네 자리를 저희가 어떻게 막았는지, 그리고 규칙으로 만들면서 저희가 새로 틀린 것들은 이어지는 글에 적었습니다.

(이 글은 웨이스 기술블로그에 먼저 실린 글입니다. 원문: https://blog.vexplor.com/post/why-inventory-numbers-disagree)

링크 복사

댓글 0
댓글이 없습니다.
추천 아티클
0