fix(after-sale): 售后工单已完结即不可再申请,不看订单是否另标已退款
原来的重复申请闸门只看「进行中」的工单(find_active = pending/processing), 于是工单已 completed、但订单没被另标「已退款」时,订单还能再发起一次售后。 已退款订单之所以不能再申请,是因为 status_group 变了导致 enabled 为 false, 属于间接效果;工单层面的规则一直是漏的。 - create() 改为以 latest_for_order() 为准:completed 直接挡掉;待审核/处理中 仍走同人同因幂等(返回原工单),rejected / cancelled 放行再次发起 - after_sale_state() 的 can_apply 同步收紧,与 can_reapply 同一口径: 有工单时只有 rejected / cancelled 才放行,completed 不再漏过去 - 界面上售后详细弹窗的「再次申请」本就只对 rejected / cancelled 渲染, 这条改动把服务端与 API 口径补齐,堵住绕过前端直接打 REST 的口子 harness 补两个场景:completed 挡住而 rejected / cancelled 放行;待审核工单 同因幂等返回原单、换因挡住。 验证:tests/widget-system/ 462 项、tests/admin/ 76 项通过;after-sale-log-harness 7/7(新增两场景);dev harness 渲染两个后台页面与 unchecked 处理场景均正常。 未做浏览器视觉验收。
This commit is contained in:
@@ -62,7 +62,16 @@ test('after-sale submissions are order-locked and admins set status directly', (
|
||||
const column = block.slice(0, block.indexOf('ENGINE=InnoDB'))
|
||||
assert.ok(!column.includes(dead), `${dead} column must be removed from aksrt_order_aftersale`)
|
||||
}
|
||||
assert.match(afterSale, /GET_LOCK\(%s, 5\)[\s\S]*?get_user_order\(\$user_id, \$order_number\)[\s\S]*?find_active\(\$order_number\)/)
|
||||
// create() 的重复申请闸门看「最新一条工单」而不是只看进行中的:已完结同样要挡
|
||||
assert.match(afterSale, /GET_LOCK\(%s, 5\)[\s\S]*?get_user_order\(\$user_id, \$order_number\)[\s\S]*?latest_for_order\(\$order_number\)/)
|
||||
assert.ok(afterSale.includes("return new \\WP_Error('aksrt_after_sale_exists', __('该订单的售后申请已完结,不能再次申请', 'aksrt'), ['status' => 409]);"),
|
||||
'completed ticket must block a new application')
|
||||
// 待审核 / 处理中仍走同人同因幂等,rejected / cancelled 放行再次发起
|
||||
assert.match(afterSale, /in_array\(\$latest_status, \[self::STATUS_PENDING, self::STATUS_PROCESSING\], true\)/)
|
||||
assert.match(afterSale, /hash_equals\(\(string\) \(\$latest\['reason'\] \?\? ''\), \$reason\)/)
|
||||
// 只看 create() 方法体,避免跨方法匹配到 cancel_for_user() 里的 find_active
|
||||
const createBody = afterSale.slice(afterSale.indexOf('public function create('), afterSale.indexOf('private function sanitize_images('))
|
||||
assert.ok(!createBody.includes('find_active'), 'create must not gate on find_active alone')
|
||||
assert.match(afterSale, /Order::STATUS_PAID/)
|
||||
assert.match(afterSale, /public function set_status\(int \$id, string \$status, string \$note = ''\)/)
|
||||
assert.match(afterSale, /in_array\(\$status, \[self::STATUS_PENDING, self::STATUS_PROCESSING, self::STATUS_COMPLETED, self::STATUS_REJECTED, self::STATUS_CANCELLED\], true\)/)
|
||||
|
||||
Reference in New Issue
Block a user