|
@@ -54,11 +54,14 @@ class HdRefundMallClass
|
|
|
} else {
|
|
} else {
|
|
|
$refundPrice = $post['price'] ?? 0;
|
|
$refundPrice = $post['price'] ?? 0;
|
|
|
}
|
|
}
|
|
|
- if (!is_numeric($refundPrice) || bccomp((string)$refundPrice, '0', 2) <= 0) {
|
|
|
|
|
|
|
+ $couldRefund = self::remainRefundCash($order);
|
|
|
|
|
+ // 红包全额抵扣后实付为 0:允许提交 0 元申请,审核通过后退回红包;其它 0 元仍拦截
|
|
|
|
|
+ if (!is_numeric($refundPrice) || bccomp((string)$refundPrice, '0', 2) < 0) {
|
|
|
|
|
+ util::fail('退款金额不正确');
|
|
|
|
|
+ }
|
|
|
|
|
+ if (bccomp((string)$refundPrice, '0', 2) === 0 && !self::allowZeroCashRefundByHb($order)) {
|
|
|
util::fail('退款金额必须大于0');
|
|
util::fail('退款金额必须大于0');
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- $couldRefund = bcsub((string)($order->orderPrice ?? 0), (string)($order->tkPrice ?? 0), 2);
|
|
|
|
|
if (bccomp((string)$refundPrice, $couldRefund, 2) === 1) {
|
|
if (bccomp((string)$refundPrice, $couldRefund, 2) === 1) {
|
|
|
util::fail('退款金额超过可退金额');
|
|
util::fail('退款金额超过可退金额');
|
|
|
}
|
|
}
|
|
@@ -276,10 +279,7 @@ class HdRefundMallClass
|
|
|
$price = '0.00';
|
|
$price = '0.00';
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- $couldRefund = bcsub(self::toMoney($order->orderPrice ?? 0), self::toMoney($order->tkPrice ?? 0), 2);
|
|
|
|
|
- if (bccomp($couldRefund, '0', 2) < 0) {
|
|
|
|
|
- $couldRefund = '0.00';
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ $couldRefund = self::remainRefundCash($order);
|
|
|
if (bccomp($price, $couldRefund, 2) === 1) {
|
|
if (bccomp($price, $couldRefund, 2) === 1) {
|
|
|
$price = $couldRefund;
|
|
$price = $couldRefund;
|
|
|
}
|
|
}
|
|
@@ -333,6 +333,114 @@ class HdRefundMallClass
|
|
|
return number_format((float)$value, 2, '.', '');
|
|
return number_format((float)$value, 2, '.', '');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从订单数组或对象取字段;详情接口和申请页传入形态不同
|
|
|
|
|
+ * @param array|object $order
|
|
|
|
|
+ * @param string $key
|
|
|
|
|
+ * @param mixed $default
|
|
|
|
|
+ * @return mixed
|
|
|
|
|
+ */
|
|
|
|
|
+ protected static function orderField($order, $key, $default = 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (is_object($order)) {
|
|
|
|
|
+ return $order->$key ?? $default;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (is_array($order)) {
|
|
|
|
|
+ return $order[$key] ?? $default;
|
|
|
|
|
+ }
|
|
|
|
|
+ return $default;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 剩余可退现金:实付合计 orderPrice 减已退 tkPrice
|
|
|
|
|
+ * 红包抵扣已计入 orderPrice,所以红包全额单这里为 0
|
|
|
|
|
+ * @param array|object $order
|
|
|
|
|
+ * @return string 两位小数字符串,不会为负
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function remainRefundCash($order)
|
|
|
|
|
+ {
|
|
|
|
|
+ $could = bcsub(
|
|
|
|
|
+ self::toMoney(self::orderField($order, 'orderPrice', 0)),
|
|
|
|
|
+ self::toMoney(self::orderField($order, 'tkPrice', 0)),
|
|
|
|
|
+ 2
|
|
|
|
|
+ );
|
|
|
|
|
+ if (bccomp($could, '0', 2) < 0) {
|
|
|
|
|
+ return '0.00';
|
|
|
|
|
+ }
|
|
|
|
|
+ return $could;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 红包是否仍占用本单未退回:下单写正数 hbId,退回后改成负数
|
|
|
|
|
+ * @param array|object $order
|
|
|
|
|
+ * @return bool
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function hasUnreturnedHb($order)
|
|
|
|
|
+ {
|
|
|
|
|
+ return (int)self::orderField($order, 'hbId', 0) > 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 订单实付现金:优先 mainPay(详情「订单合计」),否则 actPrice / orderPrice
|
|
|
|
|
+ * @param array|object $order
|
|
|
|
|
+ * @return string 两位小数字符串
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function orderPayAmount($order)
|
|
|
|
|
+ {
|
|
|
|
|
+ foreach (['mainPay', 'actPrice', 'orderPrice'] as $key) {
|
|
|
|
|
+ if (self::orderFieldExists($order, $key)) {
|
|
|
|
|
+ return self::toMoney(self::orderField($order, $key, 0));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return '0.00';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 字段是否存在于订单数组或对象上;mainPay=0 也算有值,不能当缺失
|
|
|
|
|
+ * @param array|object $order
|
|
|
|
|
+ * @param string $key
|
|
|
|
|
+ * @return bool
|
|
|
|
|
+ */
|
|
|
|
|
+ protected static function orderFieldExists($order, $key)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (is_object($order)) {
|
|
|
|
|
+ return isset($order->$key);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (is_array($order)) {
|
|
|
|
|
+ return array_key_exists($key, $order);
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 现金为 0 时是否仍可申请:红包未退回,且红包金额大于订单实付
|
|
|
|
|
+ * 红包把合计抵成 0 时 hbAmount > mainPay;红包已退回或金额不足以覆盖实付则不允许
|
|
|
|
|
+ * @param array|object $order
|
|
|
|
|
+ * @return bool
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function allowZeroCashRefundByHb($order)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!self::hasUnreturnedHb($order)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ $hbAmount = self::toMoney(self::orderField($order, 'hbAmount', 0));
|
|
|
|
|
+ $payAmount = self::orderPayAmount($order);
|
|
|
|
|
+ return bccomp($hbAmount, $payAmount, 2) === 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 是否还有可售后标的:剩余现金>0,或现金为 0 但红包未退回且红包金额大于实付
|
|
|
|
|
+ * @param array|object $order
|
|
|
|
|
+ * @return bool
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function hasRefundableAmount($order)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (bccomp(self::remainRefundCash($order), '0', 2) > 0) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return self::allowZeroCashRefundByHb($order);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 商家审核通过:复用已有待审核行执行真实退款 + 红包按过期退回 + 消费回退
|
|
* 商家审核通过:复用已有待审核行执行真实退款 + 红包按过期退回 + 消费回退
|
|
|
* @param object $refund xhHdRefund 待审核对象
|
|
* @param object $refund xhHdRefund 待审核对象
|