瀏覽代碼

使用余额付款

shish 2 月之前
父節點
當前提交
309a3a917d

+ 12 - 4
app-ghs/controllers/OrderController.php

@@ -3079,7 +3079,6 @@ class OrderController extends BaseController
         set_time_limit(0);
 
         $connection = Yii::$app->db;
-        $transaction = $connection->beginTransaction();
         try {
 
             $get = Yii::$app->request->get();
@@ -3233,9 +3232,19 @@ class OrderController extends BaseController
                 $post['bookSn'] = $bookSn;
 
                 //多处有用到此方法,需要同步修改,搜索关键词create_new_order
-                OrderService::createNewOrder($post, $custom, $hasPay);
+                util::runWithDbConcurrencyRetry(function () use ($connection, $post, $custom, $hasPay) {
+                    $transaction = $connection->beginTransaction();
+                    try {
+                        OrderService::createNewOrder($post, $custom, $hasPay);
+                        $transaction->commit();
+                    } catch (\Exception $exception) {
+                        if ($transaction->isActive) {
+                            $transaction->rollBack();
+                        }
+                        throw $exception;
+                    }
+                });
 
-                $transaction->commit();
                 util::complete('提交成功');
 
             } else {
@@ -3243,7 +3252,6 @@ class OrderController extends BaseController
             }
 
         } catch (\Exception $e) {
-            $transaction->rollBack();
             Yii::info("导入失败了," . $e->getMessage());
             noticeUtil::push('导入失败,失败原因:' . $e->getMessage(), '15280215347');
             $msg = $e->getMessage();

+ 83 - 10
biz-ghs/custom/classes/CustomClass.php

@@ -650,30 +650,98 @@ class CustomClass extends BaseClass
     }
 
     /**
-     * 开单余额支付:扣减净 balance 并记购买流水(净余额模型,对照 hd payToChangeBalance)
+     * 调用方已 lockAccountPair 时,校验 custom/ghs 净余额一致
      */
-    public static function payToChangeBalance($order)
+    protected static function assertPairBalanceEqual($custom, $ghs)
+    {
+        if (empty($ghs)) {
+            return;
+        }
+        $customBal = bcadd((string)($custom->balance ?? '0'), '0', 2);
+        $ghsBal = bcadd((string)($ghs->balance ?? '0'), '0', 2);
+        if (bccomp($customBal, $ghsBal, 2) !== 0) {
+            util::fail('客户与供货商余额不一致,请联系管理员');
+        }
+    }
+
+    /**
+     * 开单扣减净 balance:写 custom(及成对 ghs),调用方须已 FOR UPDATE 锁行。
+     */
+    protected static function savePairBalanceAfterDeduct($custom, $ghs, $newBalance)
+    {
+        $newBalance = bcadd((string)$newBalance, '0', 2);
+        $custom->balance = $newBalance;
+        $custom->isDebt = bccomp($newBalance, '0', 2) < 0 ? CustomClass::IS_DEBT_YES : CustomClass::IS_DEBT_NO;
+        $custom->save(false, ['balance', 'isDebt']);
+        if (empty($ghs)) {
+            return;
+        }
+        AccountMoneyClass::ensureGhsMoneyReady($ghs, true);
+        $ghs->balance = $newBalance;
+        $ghs->debt = bccomp($newBalance, '0', 2) < 0 ? 2 : 1;
+        $ghs->save(false, ['balance', 'debt']);
+        self::assertPairBalanceEqual($custom, $ghs);
+    }
+
+    protected static function addGhsOrderBalanceChange($custom, $ghs, $order, $amount, $newBalance, $bookOrder = false)
+    {
+        if (empty($ghs)) {
+            return;
+        }
+        $orderSn = $order->orderSn ?? '';
+        $event = '购买花材,单号:' . $orderSn;
+        if ($bookOrder) {
+            $event = '预订单多退少补,单号:' . $orderSn;
+        }
+        $customShopId = $custom->shopId ?? 0;
+        $customShop = ShopClass::getById($customShopId, true);
+        $gbData = [
+            'ghsId' => $ghs->id ?? 0,
+            'relateId' => $order->id ?? 0,
+            'ptStyle' => dict::getDict('ptStyle', 'ghs'),
+            'capitalType' => dict::getDict('capitalType', 'xhGhsOrder', 'id'),
+            'amount' => $amount,
+            'balance' => $newBalance,
+            'io' => 0,
+            'side' => 0,
+            'onlinePay' => 1,
+            'payWay' => $order->payWay ?? 0,
+            'fromType' => dict::getDict('fromType', 'shop'),
+            'event' => $event,
+            'sjId' => $customShop->sjId ?? ($custom->sjId ?? 0),
+            'mainId' => $customShop->mainId ?? 0,
+            'shopId' => $customShopId,
+            'remark' => '',
+        ];
+        GhsBalanceChangeClass::add($gbData, true);
+    }
+
+    /**
+     * 开单余额支付:扣减净 balance 并记购买流水(须传入 payAfter 已 lockAccountPair 的 custom/ghs)。
+     */
+    public static function payToChangeBalance($order, $custom, $ghs = null)
     {
         $actPrice = bcadd((string)($order->actPrice ?? '0'), '0', 2);
         if (bccomp($actPrice, '0', 2) <= 0) {
             return;
         }
-        $customId = $order->customId ?? 0;
-        $custom = self::getLockById($customId);
         if (empty($custom)) {
             util::fail('没有找到客户');
         }
         AccountMoneyClass::ensureCustomMoneyReady($custom, true);
+        if (!empty($ghs)) {
+            AccountMoneyClass::ensureGhsMoneyReady($ghs, true);
+            self::assertPairBalanceEqual($custom, $ghs);
+        }
         $beforeBalance = bcadd((string)($custom->balance ?? '0'), '0', 2);
         if (bccomp($beforeBalance, $actPrice, 2) < 0) {
             util::fail('余额不足');
         }
         $newBalance = bcsub($beforeBalance, $actPrice, 2);
-        $custom->balance = $newBalance;
-        $custom->isDebt = bccomp($newBalance, '0', 2) < 0 ? CustomClass::IS_DEBT_YES : CustomClass::IS_DEBT_NO;
-        $custom->save(false, ['balance', 'isDebt']);
+        self::savePairBalanceAfterDeduct($custom, $ghs, $newBalance);
 
         $orderSn = $order->orderSn ?? '';
+        $customId = $custom->id ?? 0;
         $capitalType = dict::getDict('capitalType', 'xhGhsOrder', 'id');
         $change = [
             'relateId' => $order->id ?? 0,
@@ -696,6 +764,7 @@ class CustomClass extends BaseClass
             'remark' => '',
         ];
         CustomBalanceChangeClass::add($change, true);
+        self::addGhsOrderBalanceChange($custom, $ghs, $order, $actPrice, $newBalance, false);
     }
 
     /**
@@ -741,10 +810,14 @@ class CustomClass extends BaseClass
      * 挂账开单:增加客户待结(改造后 balance 减少,只记余额变动,不再记挂账变动)
      * ssh 20220306
      */
-    public static function cgDebtAmountAdd($custom, $order, $bookOrder = false)
+    public static function cgDebtAmountAdd($custom, $order, $bookOrder = false, $ghs = null)
     {
         // 挂账开单:合并后 balance 减少,不再写 CustomDebtChange
         AccountMoneyClass::ensureCustomMoneyReady($custom, true);
+        if (!empty($ghs)) {
+            AccountMoneyClass::ensureGhsMoneyReady($ghs, true);
+            self::assertPairBalanceEqual($custom, $ghs);
+        }
         $amount = bcadd((string)($order->remainDebtPrice ?? '0'), '0', 2);
         if (bccomp($amount, '0', 2) <= 0) {
             return;
@@ -788,8 +861,7 @@ class CustomClass extends BaseClass
             }
         }
 
-        $custom->balance = $newBalance;
-        $custom->save(false, ['balance', 'isDebt']);
+        self::savePairBalanceAfterDeduct($custom, $ghs, $newBalance);
 
         $relateId = $order->id ?? 0;
         $customId = $custom->id ?? 0;
@@ -822,6 +894,7 @@ class CustomClass extends BaseClass
             'remark' => '',
         ];
         CustomBalanceChangeClass::add($change, true);
+        self::addGhsOrderBalanceChange($custom, $ghs, $order, $amount, $newBalance, $bookOrder);
 
         $mainId = $order->mainId ?? 0;
         $main = MainClass::getLockById($mainId);

+ 4 - 2
biz-ghs/order/classes/OrderClass.php

@@ -771,11 +771,13 @@ class OrderClass extends BaseClass
 
                 $payWay = dict::getDict('payWay', 'debtPay');
 
-                $custom = CustomClass::getLockById($customId);
+                $pair = \bizGhs\custom\services\GhsRechargeSettleService::lockAccountPair(['id' => $customId]);
+                $custom = $pair['custom'];
+                $ghs = $pair['ghs'];
                 if (empty($custom)) {
                     util::fail('没有找到客户');
                 }
-                CustomClass::cgDebtAmountAdd($custom, $order, true);
+                CustomClass::cgDebtAmountAdd($custom, $order, true, $ghs);
 
                 //收入增加
                 StatIncomeClass::updateOrInsert($main, $shop, $currentDebt);

+ 21 - 31
biz-ghs/order/services/OrderService.php

@@ -15,6 +15,7 @@ use bizGhs\base\services\BaseService;
 use bizGhs\book\classes\BookItemClass;
 use bizGhs\custom\classes\CustomClass;
 use bizGhs\custom\classes\CustomDebtChangeClass;
+use bizGhs\custom\services\GhsRechargeSettleService;
 use bizGhs\clear\classes\OrderCgClearClass;
 use bizGhs\order\classes\OrderClass;
 use bizGhs\order\classes\OrderExpressClass;
@@ -288,34 +289,6 @@ class OrderService extends BaseService
         //欠款、已付款、余额支付的走付款后流程
         if (in_array($hasPay, [dict::getDict('hasPay', 'payed'), dict::getDict('hasPay', 'debt'), dict::getDict('hasPay', 'balance')])) {
 
-            if ($hasPay == dict::getDict('hasPay', 'debt')) {
-                $shopId = $data['shopId'] ?? 0;
-                $shop = ShopClass::getById($shopId, true);
-                if (empty($shop)) {
-                    util::fail('没有门店信息');
-                }
-                //老商家允许设置overAllowDebt,新商家已经不允许设置,默认就是 1,不能超过已经设置的授信额度
-                if (isset($shop->overAllowDebt) && $shop->overAllowDebt == 0) {
-                    $debtLimit = $custom['debtLimit'] ?? 0;
-                    $debtLimit = floatval($debtLimit);
-                    // 待结额度校验:用净余额欠款额,不再读 debtAmount
-                    $outstanding = \bizGhs\custom\classes\AccountMoneyClass::getOutstandingDebt($custom);
-                    $currentPrice = $returnOrder->actPrice ?? 0;
-                    $newDebt = bcadd($currentPrice, $outstanding, 2);
-                    if (bccomp($newDebt, $debtLimit, 2) > 0) {
-                        util::fail('待结款已超' . $debtLimit . ',请先结账');
-                    }
-                }
-            }
-            if ($hasPay == dict::getDict('hasPay', 'balance')) {
-                $actPrice = bcadd((string)($returnOrder->actPrice ?? '0'), '0', 2);
-                $customRow = is_array($custom) ? $custom : $custom->attributes;
-                $netBalance = \bizGhs\custom\classes\AccountMoneyClass::getNetBalanceFromRow($customRow);
-                if (bccomp($netBalance, $actPrice, 2) < 0) {
-                    util::fail('余额不足');
-                }
-            }
-
             // 挂账/余额:先处理销售单(含余额抵挂账),再同步采购单待结
             if (in_array($hasPay, [dict::getDict('hasPay', 'debt'), dict::getDict('hasPay', 'balance')])) {
                 self::payAfter($returnOrder, $payWay);
@@ -749,7 +722,14 @@ class OrderService extends BaseService
         $orderId = $order->id;
         $orderSn = $order->orderSn ?? '';
         $customId = $order->customId;
-        $custom = CustomClass::getLockById($customId);
+        $ghs = null;
+        if (in_array($payWay, [dict::getDict('payWay', 'balancePay'), dict::getDict('payWay', 'debtPay')], true)) {
+            $pair = GhsRechargeSettleService::lockAccountPair(['id' => $customId]);
+            $custom = $pair['custom'];
+            $ghs = $pair['ghs'];
+        } else {
+            $custom = CustomClass::getLockById($customId);
+        }
         if (empty($custom)) {
             util::fail('没有找到客户信息');
         }
@@ -763,6 +743,16 @@ class OrderService extends BaseService
         if (empty($shop)) {
             util::fail('没有找到门店5');
         }
+        if ($payWay == dict::getDict('payWay', 'debtPay') && $book != 1) {
+            if (isset($shop->overAllowDebt) && $shop->overAllowDebt == 0) {
+                $debtLimit = $custom->debtLimit ?? 0;
+                $outstanding = \bizGhs\custom\classes\AccountMoneyClass::getOutstandingDebt($custom);
+                $newDebt = bcadd((string)$realPrice, (string)$outstanding, 2);
+                if (bccomp($newDebt, (string)$debtLimit, 2) > 0) {
+                    util::fail('待结款已超' . $debtLimit . ',请先结账');
+                }
+            }
+        }
         $mainId = $shop->mainId ?? 0;
         $main = MainClass::getLockById($mainId);
         if (empty($main)) {
@@ -908,12 +898,12 @@ class OrderService extends BaseService
 
         //余额支付
         if ($payWay == dict::getDict('payWay', 'balancePay') && $isPurchase == false) {
-            CustomClass::payToChangeBalance($order);
+            CustomClass::payToChangeBalance($order, $custom, $ghs);
         }
 
         //欠款
         if ($payWay == dict::getDict('payWay', 'debtPay')) {
-            CustomClass::cgDebtAmountAdd($custom, $order);
+            CustomClass::cgDebtAmountAdd($custom, $order, false, $ghs);
         }
         $custom->buyNum += 1;
         $custom->buyAmount = bcadd($custom->buyAmount, $amount, 2);