상품 옵션 가격이 왜 바뀌었는지 물어보는 문의가 왔다. MySQL 의 옵션 이력을 봤더니 그 시각에 변경 기록이 없다. 그런데 값은 바뀌어 있다.
Table of contents
Open Table of contents
원인 — 상위에서 바뀐 것이었다
상품 가격을 바꾸면 옵션 가격도 같이 바뀌게 돼 있었다.
public function update_price($productNo, $price)
{
$this->db->update('product', ['price' => $price], ['product_no' => $productNo]);
$this->history_model->add('product', $productNo, 'price', $old, $price);
// 옵션 가격도 비율대로 조정
$this->db->query(
"UPDATE product_option SET price = ROUND(price * ?) WHERE product_no = ?",
[$price / $oldPrice, $productNo]
);
}
history_model->add 는 product 에만 부른다. product_option 쪽에는 안 남는다.
product_option 화면에서 이력을 보면 아무것도 없고 값만 바뀌어 있다. 조사하는 사람은 바뀐 쪽부터 열어 보는데 거기에 아무것도 없으면 엉뚱한 곳에서 원인을 찾기 시작한다.
하위에도 남기게 했다
옵션 변경도 기록하게 했다.
$options = $this->db->where('product_no', $productNo)->get('product_option')->result();
$this->db->query("UPDATE product_option SET price = ROUND(price * ?) WHERE product_no = ?",
[$rate, $productNo]);
foreach ($options as $o) {
$this->history_model->add(
'product_option', $o->option_no, 'price',
$o->price, round($o->price * $rate),
"상품 가격 변경에 따른 자동 조정 (상품 {$productNo})"
);
}
바꾸기 전 값을 먼저 읽어 두고 바꾼 뒤에 option_no 별로 이력을 넣는다. 사유를 같이 넣으니 사람이 직접 고친 것과 자동으로 조정된 것이 구분됐다.
이력 화면에서도 둘을 다르게 보여 줬다.
2014-07-09 14:20 가격 12,000 → 13,200
상품 가격 변경에 따른 자동 조정 (상품 1023)
2014-07-05 09:11 가격 11,000 → 12,000
admin2
위는 자동이고 아래는 admin2 가 고친 것이다. 문의가 오면 이 화면만 보여 주면 되는데 이전에는 코드를 따라가며 설명해야 했다.
몇 건이 바뀌는지 먼저 알렸다
옵션이 많은 상품은 한 번에 수십 개가 바뀐다. 관리자가 그걸 모르고 가격을 고치고 있었다.
이 상품의 옵션 12개 가격도 같이 조정됩니다. 계속하시겠습니까?
product_option 을 COUNT(*) 로 세어 저장 전에 알렸다. 몇 개인지가 중요했는데 12개면 그러려니 하지만 200개면 다시 생각한다.
저장한 뒤에는 affected_rows() 가 그 수와 맞는지도 봤다. 같은 동작인데 규모를 알려 주는 것만으로 사고가 줄었다.
끄는 선택과 없던 기간
옵션 가격을 개별로 정해 둔 상품이 있었다. 그런 상품은 상품 가격을 바꿔도 옵션이 그대로 남아야 맞았다.
if ($request->post('adjust_options') === 'Y') {
// 비율대로 조정
} else {
// 옵션은 그대로
}
adjust_options 의 기본값을 무엇으로 할지가 판단이었다. 조정하는 쪽을 기본으로 두면 안 바꿔야 할 것이 바뀌고 안 하는 쪽을 기본으로 두면 바꿔야 할 것이 안 바뀐다.
안 하는 쪽을 기본으로 했다. 자동으로 바뀌는 것보다 안 바뀌는 것이 알아채기 쉽기 때문이다. 값이 안 맞으면 눈에 띄지만 잘못 바뀐 price 는 한참 뒤에 발견된다.
history 테이블에 남기기 시작한 시점이 있으니 그 전 변경은 기록이 없다. 화면 아래에 적었다.
2014-07-10 이전 변경 내역은 기록되지 않았습니다.
이게 없으면 변경 없음으로 읽힌다. 기록이 없는 것과 변경이 없는 것은 다르다.
정리
- 상위 변경이 하위를 바꾸면 하위에도 그 사실을 남긴다
- 바뀐 쪽에 기록이 없으면 다른 원인을 찾게 된다
- 사유를 같이 넣으면 사람이 고친 것과 자동 조정이 구분된다
- 몇 건이 같이 바뀌는지 저장 전에 알린다. 개수가 판단을 바꾼다
- 저장한 뒤에는
affected_rows()가 그 수와 맞는지 본다 - 자동 조정을 끌 수 있게 하고 기본값은 안 하는 쪽으로 둔다
- 안 바뀐 것이 잘못 바뀐 것보다 알아채기 쉽다
- 이력을 남기기 시작한 시점을 화면에 표시한다. 기록 없음과 변경 없음은 다르다