Skip to content
isdnetworks
Go back

배송비 규칙이 너무 많았다

배송비 계산에 조건이 계속 붙었다.

if ($total >= 50000) { $fee = 0; }
else if ($isIsland) { $fee = 5000; }
else if ($category == '대형') { $fee = 8000; }
else { $fee = 2500; }

볼 때마다 조건이 늘어 있었다.

Table of contents

Open Table of contents

원인 — 순서에 따라 결과가 달라졌다

if 를 위에서부터 검사하니 순서가 결과를 정했다. 무료 조건을 먼저 보면 섬이어도 무료가 되고 섬 조건을 먼저 보면 금액과 무관하게 5,000원이 붙는다.

$total 을 먼저 보느냐 $isIsland 를 먼저 보느냐로 답이 갈리는데 이건 코드를 짜는 내가 정할 문제가 아니었다. 물어보니 경우마다 달랐다.

섬 + 5만원 이상  →  섬 배송비만
대형 + 5만원 이상 →  대형 배송비만

무료가 조건부였다. 그런 조합이 실제로 생기는 것을 생각해 본 적이 없다고 했는데 정해지지 않은 조합이 코드에는 이미 어떤 결과로 정해져 있었다.

표로 만들었다

말로 정리가 안 돼서 표로 만들었다.

금액       지역     분류     배송비
5만 미만   일반     일반     2,500
5만 이상   일반     일반     0
5만 미만   섬       일반     5,000
5만 이상   섬       일반     5,000
...

PHP 코드에서는 있는 조건만 보이는데 표를 만드니 안 정해진 조합이 보였다.

5만 이상 + 섬 + 대형  →  ?

물어보니 정해져 있지 않았다. 코드에서는 있는 조건만 보이는데 표에서는 빠진 조합이 보인다.

표를 들고 다시 물어보니 이번에는 답이 나왔다. 어떤 조합인지 눈앞에 있으니 판단할 수 있었고 조합이 열몇 개였다. 표가 무엇을 물어야 할지 알려 준 셈이었다.

자료로 뺀 규칙

표가 채워지고 나니 코드가 아니라 자료로 둘 수 있었다.

shipping_rule
  min_amount
  region_type
  category_type
  fee
  priority

MySQL 에 조건과 결과를 행으로 담고 코드는 SELECT 로 찾아 쓰기만 한다.

$rules = $model->get_rules_ordered();
foreach ($rules as $r) {
    if (matches($r, $order)) { return $r->fee; }
}

priority 순으로 읽어 먼저 맞는 것을 쓴다. 순서를 코드 수정과 배포 없이 값만 바꿔 조정할 수 있게 된 것이다.

아무것도 안 맞을 때를 위해 기본 규칙도 하나 뒀다. 우선순위가 가장 낮고 조건이 없는 행이라 항상 하나는 맞는다. 이게 없으면 조합이 늘었을 때 아무것도 안 맞아 오류가 난다.

어느 규칙이 적용됐는지 남겼다

계산 결과에 어느 규칙인지도 남겼다.

order
  shipping_fee
  shipping_rule_id

배송비가 이상하다는 문의가 오면 shipping_rule_id 로 어느 규칙이 걸렸는지 바로 본다. 안 남기면 다시 계산해 봐야 하는데 그 사이 규칙이 바뀌었으면 그때 값이 안 나온다.

규칙 자체도 고칠 때 이력을 남겼다.

shipping_rule_history

shipping_rule_history 에 옛 규칙이 남으니 지난 주문의 계산 근거를 찾을 수 있다.

자료로 빼고 나니 AdminLTE 로 관리 화면도 만들 수 있었다. 개발자가 코드를 고치던 것을 운영이 값으로 고치게 된 것이다. 다만 아무 값이나 들어가면 안 돼서 저장할 때 priority 가 같은 규칙이 겹치는지 검사했다.

금액과 지역과 분류를 넣으면 어느 규칙이 맞고 얼마인지 보여 주는 시험 기능도 넣었다. 저장 전에 확인할 수 있으니 틀린 규칙이 운영에 나가는 것이 줄었고 이것이 가장 많이 쓰였다.

정리


Share this post on:

Previous Post
화면대로 테이블을 만들었다
Next Post
지우려던 것이 비상용 통로였다