Jelajahi Sumber

fix unique price

stanley-king 1 bulan lalu
induk
melakukan
c425a5e0cf

+ 2 - 1
composer.json

@@ -4,6 +4,7 @@
       "ext-json": "*",
       "ext-redis": "*",
       "ext-mysqli": "*",
-      "ext-openssl": "*"
+      "ext-openssl": "*",
+      "ext-bcmath": "*"
     }
 }

+ 58 - 1
helper/refill/CalcMerchantPrice.php

@@ -13,8 +13,12 @@ use Log;
 class CalcMerchantPrice implements ICalc
 {
     private $mPrice;
-    public function __construct($mchid,$spec,$card_type,$quality,$policy,$other = [])
+    public function __construct(order $order,$quality,$policy,$other = [])
     {
+        $mchid = $order->mchid();
+        $spec = $order->spec();
+        $card_type = $order->card_type();
+
         if(empty($other) || empty($other['product_code'])) {
             $pcode = '';
         }
@@ -48,6 +52,59 @@ class CalcMerchantPrice implements ICalc
     }
 }
 
+
+class CalcMerchantMixedPrice implements ICalc
+{
+    private $mPrice;
+    public function __construct(order $order,$quality,$policy,$other = [])
+    {
+        $mchid = $order->mchid();
+        $spec = $order->spec();
+        $card_type = $order->card_type();
+
+        $mch_amount = $order->mch_amount();
+        $quantity = $order->quantity();
+
+        Log::record("CalcMerchantMixedPrice mch_amount=$mch_amount quantity=$quantity",Log::DEBUG);
+        if (bccomp("$mch_amount", '0', 5) === 0)
+        {
+            if(empty($other) || empty($other['product_code'])) {
+                $pcode = '';
+            }
+            else {
+                $pcode = $other['product_code'];
+            }
+
+            $price = $policy->price($mchid, $spec, $card_type, $quality, $pcode);
+            if ($price === false or $price <= 0.01) {
+                throw new Exception("没有协商商品购买价格.");
+            } else {
+                $this->mPrice = $price;
+            }
+        }
+        else {
+            $this->mPrice = round($mch_amount / $quantity, 4);
+        }
+    }
+
+    public function calc_vgoods_price($goods_info)
+    {
+        return $this->mPrice;
+    }
+
+    public function calc_vorder_amount($order_info)
+    {
+        $num = $order_info['quantity'];
+        return round($this->mPrice * $num,4);
+    }
+
+    public function calc_tips()
+    {
+        Log::record("没有实现该接口" . __FUNCTION__, Log::ERR);
+        return [];
+    }
+}
+
 class ZeroMerchantPrice implements ICalc
 {
     public function __construct($mchid,$amount,$card_type,$quality)

+ 35 - 21
helper/refill/RefillBase.php

@@ -317,13 +317,9 @@ class RefillBase
         try
         {
             $minfo = new member_info($order->buyer_id());
-            $org_quality = $order->org_quality();
-            if(PolicyUtil::mixed_quality($org_quality)) {
-                $calc = new CalcMerchantPrice($mchid, $order->spec(), $order->card_type(),$org_quality,$this->mPolicy,$order->thrid_params());
-            }
-            else {
-                $calc = new CalcMerchantPrice($mchid, $order->spec(), $order->card_type(),$order->cur_quality(),$this->mPolicy,$order->thrid_params());
-            }
+
+            $calc = $this->getMerchantPriceCalc($order);
+
             $mch_price = $calc->calc_vgoods_price([]);
             $mch_amount = $mch_price * $order->quantity();
         }
@@ -364,9 +360,18 @@ class RefillBase
     public function zero_order(order $order,$errmsg='')
     {
         $buyer_id = $order->buyer_id();
-        $minfo = new member_info($buyer_id);
-        $calc = new ZeroMerchantPrice($order->mchid(), $order->spec(), $order->card_type(),$order->cur_quality());
-        $mch_amount = $calc->calc_vgoods_price([]);
+
+        try
+        {
+            $minfo = new member_info($order->buyer_id());
+            $calc = $this->getMerchantPriceCalc($order);
+            $mch_price = $calc->calc_vgoods_price([]);
+            $mch_amount = $mch_price * $order->quantity();
+        }
+        catch (Exception $ex) {
+            $mch_price = 0.00;
+            $mch_amount = 0.00;
+        }
 
         $input['goods_id'] = ZERO_GOODS_ID;
         $input['quantity'] = 1; //数量
@@ -428,11 +433,7 @@ class RefillBase
 
         try
         {
-            if (PolicyUtil::mixed_quality($org_quality)) {
-                $calc = new CalcMerchantPrice($mchid, $order->spec(), $order->card_type(), $org_quality, $this->mPolicy, $order->thrid_params());
-            } else {
-                $calc = new CalcMerchantPrice($mchid, $order->spec(), $order->card_type(), $order->cur_quality(), $this->mPolicy, $order->thrid_params());
-            }
+            $calc = $this->getMerchantPriceCalc($order);
             $mch_price = $calc->calc_vgoods_price([]);
             $mch_amount = $mch_price * $order->quantity();
 
@@ -475,12 +476,8 @@ class RefillBase
         {
             $minfo = new member_info($order->buyer_id());
             $org_quality = $order->org_quality();
-            if(PolicyUtil::mixed_quality($org_quality)) {
-                $calc = new CalcMerchantPrice($mchid, $order->spec(), $order->card_type(),$org_quality,$this->mPolicy,$order->thrid_params());
-            }
-            else {
-                $calc = new CalcMerchantPrice($mchid, $order->spec(), $order->card_type(),$order->cur_quality(),$this->mPolicy,$order->thrid_params());
-            }
+            $calc = $this->getMerchantPriceCalc($order);
+
             $mch_price = $calc->calc_vgoods_price([]);
             $mch_amount = $mch_price * $order->quantity();
         }
@@ -1233,4 +1230,21 @@ class RefillBase
     {
         return $this->mPolicy->is_over_chspeed($chname);
     }
+
+    /**
+     * @param order $order
+     * @param $mchid
+     * @return CalcMerchantPrice
+     * @throws Exception
+     */
+    public function getMerchantPriceCalc(order $order): CalcMerchantPrice
+    {
+        $org_quality = $order->org_quality();
+        if (PolicyUtil::mixed_quality($org_quality)) {
+            $calc = new CalcMerchantMixedPrice($order, $org_quality, $this->mPolicy, $order->thrid_params());
+        } else {
+            $calc = new CalcMerchantPrice($order, $order->cur_quality(), $this->mPolicy, $order->thrid_params());
+        }
+        return $calc;
+    }
 }

+ 21 - 4
helper/refill/order.php

@@ -10,7 +10,7 @@ class order
     private $mMchid;
     private $mBuyerId;
     private $mAmount;
-//    private $mMchAmount;
+    private $mMchAmount;
     private $mCardNo;
     private $mMchOrder;
     private $mNotifyUrl;
@@ -51,7 +51,7 @@ class order
         $this->mMchCardTypes = [];
         $this->mFirstQuality = 0;
         $this->mOverPriceFlag = 0;
-//        $this->mMchAmount = 0.0001;
+        $this->mMchAmount = 0;
     }
 
     public function finish()
@@ -106,6 +106,11 @@ class order
         return $this->mAmount;
     }
 
+    public function mch_amount()
+    {
+        return $this->mMchAmount;
+    }
+
     public function card_no()
     {
         return $this->mCardNo;
@@ -298,8 +303,14 @@ class order
         $this->mIsTransfer = $refill_info['is_transfer'] == 1;
         $this->mIsValidate = mtopcard\is_validate($this->mCardState);
 
-//        $this->mQuantity = intval($order_info['goods_num']);
+        $this->mQuantity = intval($order_info['goods_num'] ?? 1);
 
+        $mch_amount = $refill_info['mch_amount'];
+        if (bccomp("$mch_amount", '0', 5) === 0) {
+            $this->mMchAmount = 0;
+        } else {
+            $this->mMchAmount = $mch_amount;
+        }
 
         if (!empty($third_info) && $this->is_third()) {
             $this->mProductCode = $third_info['product_code'];
@@ -356,6 +367,8 @@ class order
         $this->mBuyerId = intval($params['buyer_id']);
         $this->mAmount = intval($params['amount']);
 
+        $this->mMchAmount = $params['mch_amount'] ?? 0;
+
         $this->mCardNo = $params['card_no'];
         $this->mMchOrder = $params['mch_order'] ?? '';
         $this->mNotifyUrl = $params['notify_url'] ?? '';
@@ -525,7 +538,9 @@ class order
     {
         $params = ['mchid' => $this->mMchid,
             'buyer_id' => $this->mBuyerId,
-            'amount' => $this->mAmount,
+            'amount' => $this->mAmount, //spec
+            'mch_amount' => $this->mMchAmount,
+            'quantity' => $this->mQuantity,
             'card_no' => $this->mCardNo,
             'card_type' => $this->mCardType,
             'regin_no' => $this->mRegionNo,
@@ -550,6 +565,8 @@ class order
     {
         $params = ['mchid' => $this->mMchid,
             'buyer_id' => $this->mBuyerId,
+            'mch_amount' => $this->mMchAmount,
+            'quantity' => $this->mQuantity,
             'card_no' => $this->mCardNo,
             'org_quality' => $this->mOriginQuality,
             'quality' => $this->mCurQuality,

+ 38 - 0
test/refill/TestCalcPrice.php

@@ -0,0 +1,38 @@
+<?php
+/**
+ *   TestCalcPrice.php
+ *   stanley-king
+ *   2025/3/8
+ *   PhpStorm
+ *   PHPProject
+ */
+
+use PHPUnit\Framework\TestCase;
+
+define('APP_ID', 'test');
+define('BASE_ROOT_PATH', str_replace('/test/refill', '', dirname(__FILE__)));
+require_once(BASE_ROOT_PATH . '/global.php');
+require_once(BASE_CORE_PATH . '/lrlz.php');
+require_once(BASE_ROOT_PATH . '/fooder.php');
+
+require_once(BASE_HELPER_PATH . '/refill/XYZRefillFactory.php');
+require_once(BASE_HELPER_PATH . '/refill_proxy.php');
+
+class TestCalcPrice extends TestCase
+{
+    public static function setUpBeforeClass(): void
+    {
+        Base::run_util();
+    }
+
+    public function testMerchantPrice()
+    {
+        $mch_amount = 0.00001;
+        $ret = bccomp("$mch_amount", '0', 5);
+        if ($ret === 0) {
+            Log::record("True", Log::DEBUG);
+        } else {
+            Log::record("False", Log::DEBUG);
+        }
+    }
+}