정산 파일을 올려서 주문과 맞추는 기능이 있다. 매칭이 안 되면 실패 목록에 담기는데 한 달치를 올리니 실패가 수백 건이었다. 목록에는 order_code 만 있었다.
Table of contents
Open Table of contents
무엇을 해야 할지 알 수 없었다
수백 건을 하나씩 눈으로 보니 몇 가지 유형이 섞여 있었다. order_code 가 우리 쪽에 아예 없는 것과 주문은 있는데 금액이 다른 것과 settle_yn 이 이미 Y 인 것과 파일 형식이 달라 못 읽은 것과 그 칸이 빈 것이다.
손볼 곳이 유형마다 달랐다. F2 는 상대 쪽에 문의할 일이고 F4 는 확인이 필요하다. F3 은 무시해도 되고 F5 는 우리 코드 문제다. 한 덩어리로 두면 수백 건 전부를 사람이 봐야 한다.
구분 코드를 붙였다
match_order 가 실패할 때 이유를 함께 돌려주게 바꿨다.
function match_order($row)
{
if (empty($row['order_code'])) {
return ['ok' => false, 'code' => 'F1', 'msg' => '주문번호 없음'];
}
$order = $this->order_model->get_by_code($row['order_code']);
if (!$order) {
return ['ok' => false, 'code' => 'F2', 'msg' => '주문 없음'];
}
if ($order->settle_yn === 'Y') {
return ['ok' => false, 'code' => 'F3', 'msg' => '이미 정산됨'];
}
if (abs($order->amount - $row['amount']) > 1) {
return ['ok' => false, 'code' => 'F4', 'msg' => '금액 불일치',
'detail' => "우리 {$order->amount} / 파일 {$row['amount']}"];
}
return ['ok' => true];
}
code 와 msg 를 같이 돌려준다. code 는 GROUP BY 에 쓰고 msg 는 사람이 읽는다.
세어 보니 그림이 달라졌다
GROUP BY code 로 세어 보니 대부분이 F3 이었다. 지난달 파일을 다시 올린 것이다.
F1 3
F2 18
F3 295
F4 24
수백 건 중 실제로 확인이 필요한 것은 F2 와 F4 를 합친 수십 건이고 나머지는 정상 동작이었다. 세어 보기 전에는 전부가 문제로 보였다.
화면도 유형별로 나눴다. 정상인 것과 확인이 필요한 것을 갈라 두니 담당자가 볼 곳이 수십 건으로 줄었다.
성공 1,842
이미 정산 295 (정상)
주문 없음 18 ← 확인 필요
금액 불일치 24 ← 확인 필요
주문번호 없음 3 ← 파일 확인
숫자와 재업로드
F4 는 얼마가 다른지가 중요해서 abs 로 잰 차이를 detail 에 함께 남겼다. 판정 자체는 abs(...) > 1 이라 1 원까지는 같은 것으로 본다.
F4 주문 20150112-0341 우리 128,000 / 파일 126,800 차이 1,200
차이가 일정하면 무언가 한 항목이 빠진 것이고 제각각이면 다른 문제다. F4 의 대부분이 정확히 같은 차이였고 쿠폰 할인을 반영하는 방식이 서로 달랐다. 숫자를 같이 남기지 않았으면 규칙이 안 보였을 것이다.
같은 파일을 두 번 올리는 것도 막아야 했다. 파일 이름은 바뀔 수 있으니 md5_file 로 내용을 봤다. 이 함수는 파일을 읽어 가며 해시하므로 file_get_contents 로 통째로 올린 뒤 md5 하는 것과 달리 큰 파일에서도 메모리를 안 먹는다.
$hash = md5_file($tmpPath);
$prev = $this->db->where('file_hash', $hash)->get('settle_upload')->row();
if ($prev) {
return "이 파일은 {$prev->reg_date}에 이미 올렸습니다. 계속하시겠습니까?";
}
settle_upload 의 file_hash 에는 인덱스를 걸었다. 올릴 때마다 그 컬럼으로 조회하니 안 걸면 파일이 쌓일수록 느려진다.
쓰다 보니 F5 와 F6 이 더 늘어서 목록도 만들었다. 각 코드에 무엇을 해야 하는지를 같이 적었는데 코드만 있으면 담당자가 다시 물어보기 때문이다.
F1 주문번호 없음 파일 확인
F2 주문 없음 상대 문의
F3 이미 정산됨 정상 (재업로드)
F4 금액 불일치 확인 필요
F5 날짜 형식 오류 파일 확인
F6 중복 행 파일 확인
정리
- 실패를 한 덩어리로 두면 전부를 사람이 봐야 한다
- 이유를
code로 남기면GROUP BY code와COUNT(*)로 유형별 집계가 된다 - 세어 보면 대부분이 정상 동작인 경우가 있다 — 수백 건 중 대부분이
F3이었다 - 화면에서 정상인 것과 확인이 필요한 것을 나눠 보여 준다
abs로 잰 차이를 같이 남기면 일정한지 제각각인지가 원인을 가른다md5_file로 중복 업로드를 잡는다. 이름은 바뀔 수 있다file_hash컬럼에는 인덱스를 건다. 올릴 때마다 조회한다- 구분 코드마다 무엇을 해야 하는지를 같이 적는다