Browse Source

有余额时的解决方案

shish 2 months ago
parent
commit
a4be3e766b

+ 98 - 2
biz-ghs/custom/classes/CustomClass.php

@@ -14,6 +14,7 @@ use bizGhs\shop\classes\ShopMoneyClass;
 use bizGhs\shop\classes\TotalDebtChangeClass;
 use bizGhs\ghs\classes\GhsBalanceClass;
 use bizGhs\ghs\classes\GhsRechargeClass;
+use bizGhs\order\classes\OrderClearClass;
 use bizGhs\shop\classes\ShopClass;
 use bizHd\member\classes\MemberLevelClass;
 use bizHd\saas\classes\ApplyClass;
@@ -648,6 +649,94 @@ class CustomClass extends BaseClass
         }
     }
 
+    /**
+     * 开单余额支付:扣减净 balance 并记购买流水(净余额模型,对照 hd payToChangeBalance)。
+     */
+    public static function payToChangeBalance($order)
+    {
+        $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);
+        $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']);
+
+        $orderSn = $order->orderSn ?? '';
+        $capitalType = dict::getDict('capitalType', 'xhGhsOrder', 'id');
+        $change = [
+            'relateId' => $order->id ?? 0,
+            'customId' => $customId,
+            'customName' => $custom->name ?? '',
+            'ptStyle' => dict::getDict('ptStyle', 'ghs'),
+            'capitalType' => $capitalType,
+            'amount' => $actPrice,
+            'balance' => $newBalance,
+            'io' => 0,
+            'payWay' => dict::getDict('payWay', 'balancePay'),
+            'event' => '购买花材,单号:' . $orderSn,
+            'sjId' => $order->sjId ?? 0,
+            'shopId' => $order->shopId ?? 0,
+            'mainId' => $order->mainId ?? 0,
+            'staffId' => $order->shopAdminId ?? 0,
+            'staffName' => $order->shopAdminName ?? '',
+            'side' => 0,
+            'fromType' => dict::getDict('fromType', 'shop'),
+            'remark' => '',
+        ];
+        CustomBalanceChangeClass::add($change, true);
+    }
+
+    /**
+     * 挂账开单时若账户有正余额且不足本单:用余额先结本单一部分(只改 remainDebtPrice,不另扣 balance)。
+     */
+    protected static function inlineOrderBalancePartialClear($custom, $order, $clearAmount)
+    {
+        $clearAmount = bcadd((string)$clearAmount, '0', 2);
+        if (bccomp($clearAmount, '0', 2) <= 0) {
+            return;
+        }
+        $orderId = intval($order->id ?? 0);
+        if ($orderId <= 0) {
+            return;
+        }
+        $shopId = intval($order->shopId ?? 0);
+        $shop = ShopClass::getById($shopId, true);
+        if (empty($shop)) {
+            util::fail('没有找到门店');
+        }
+        $staffId = intval($order->shopAdminId ?? 0);
+        $staffName = $order->shopAdminName ?? '';
+        $sjId = $shop->sjId ?? 0;
+        $orderSn = $order->orderSn ?? '';
+
+        OrderClearClass::expireAwaitPayClears(intval($custom->id ?? 0));
+        $clear = OrderClearClass::clearWithAmountMap([
+            'customId' => $custom->id ?? 0,
+            'ghsShopAdminId' => $staffId,
+            'ghsShopId' => $shopId,
+            'ghsShopAdminName' => $staffName,
+            'modifyPrice' => $clearAmount,
+            'payWay' => dict::getDict('payWay', 'balancePay'),
+            'complete' => 0,
+            'remark' => '开单余额抵挂账',
+        ], [
+            ['orderId' => $orderId, 'clearAmount' => $clearAmount, 'orderSn' => $orderSn],
+        ], $sjId, $shopId);
+        OrderClearClass::applyNetBalanceClear($clear, dict::getDict('payWay', 'balancePay'), ['skipCashMoney' => true]);
+    }
+
     /**
      * 挂账开单:增加客户待结(改造后 balance 减少,只记余额变动,不再记挂账变动)
      * ssh 20220306
@@ -656,11 +745,18 @@ class CustomClass extends BaseClass
     {
         // 挂账开单:合并后 balance 减少,不再写 CustomDebtChange
         AccountMoneyClass::ensureCustomMoneyReady($custom, true);
-        $amount = $order->remainDebtPrice ?? 0;
+        $amount = bcadd((string)($order->remainDebtPrice ?? '0'), '0', 2);
         if (bccomp($amount, '0', 2) <= 0) {
             return;
         }
-        $beforeBalance = $custom->balance ?? '0.00';
+        $beforeBalance = bcadd((string)($custom->balance ?? '0'), '0', 2);
+        $positiveBalance = bccomp($beforeBalance, '0', 2) > 0 ? $beforeBalance : '0.00';
+        if (bccomp($positiveBalance, $amount, 2) >= 0) {
+            util::fail('余额充足,请用余额支付');
+        }
+        if (bccomp($positiveBalance, '0', 2) > 0) {
+            self::inlineOrderBalancePartialClear($custom, $order, $positiveBalance);
+        }
         $custom->isDebt = CustomClass::IS_DEBT_YES;
         $debtLimit = $custom->debtLimit ?? 0;
         if (!$bookOrder) {

+ 35 - 6
biz-ghs/order/services/OrderService.php

@@ -200,7 +200,10 @@ class OrderService extends BaseService
         //销售单欠款字段与采购单欠款字段转换
         $debt = $data['debt'] ?? 0;
         $purchaseDebt = $debt == 1 ? PurchaseClass::DEBT_YES : PurchaseClass::DEBT_NO;
-        if ($debt == 1) {
+        if ($hasPay == dict::getDict('hasPay', 'balance')) {
+            $payWay = dict::getDict('payWay', 'balancePay');
+            $purchaseDebt = PurchaseClass::DEBT_NO;
+        } elseif ($debt == 1) {
             $payWay = dict::getDict('payWay', 'debtPay');
         }
         //销售单的自取还是配送字段 与 采购单的转换
@@ -282,8 +285,8 @@ class OrderService extends BaseService
         $returnOrder->purchaseId = $purchaseId;
         $returnOrder->save();
 
-        //欠款和已付款的走付款后流程
-        if (in_array($hasPay, [dict::getDict('hasPay', 'payed'), dict::getDict('hasPay', 'debt')])) {
+        //欠款、已付款、余额支付的走付款后流程
+        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;
@@ -304,10 +307,31 @@ class OrderService extends BaseService
                     }
                 }
             }
+            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('余额不足');
+                }
+            }
 
-            //下面二个顺序不能换
-            PurchaseService::payAfter($purchase, $payWay);
-            self::payAfter($returnOrder, $payWay);
+            // 挂账/余额:先处理销售单(含余额抵挂账),再同步采购单待结
+            if (in_array($hasPay, [dict::getDict('hasPay', 'debt'), dict::getDict('hasPay', 'balance')])) {
+                self::payAfter($returnOrder, $payWay);
+                $purchase = PurchaseClass::getLockById($purchaseId, true);
+                if (!empty($purchase)) {
+                    $purchase->remainDebtPrice = $returnOrder->remainDebtPrice;
+                    $purchase->debtPrice = $returnOrder->debtPrice;
+                    $purchase->debt = ($returnOrder->debt ?? 0) == OrderClass::DEBT_YES
+                        ? PurchaseClass::DEBT_YES : PurchaseClass::DEBT_NO;
+                    $purchase->save(false, ['remainDebtPrice', 'debtPrice', 'debt']);
+                }
+                PurchaseService::payAfter($purchase, $payWay);
+            } else {
+                PurchaseService::payAfter($purchase, $payWay);
+                self::payAfter($returnOrder, $payWay);
+            }
 
             //不是预订单,并且供货商不是源花汇、小明鲜花、淄博花超、云漫梦金鹏、海翔,则订单直接完成掉。是预订单,则确认发货时直接完成掉。有多个地方要修改,请搜索关键词zjFinish
             if (isset($returnOrder->book) && $returnOrder->book == 0) {
@@ -882,6 +906,11 @@ class OrderService extends BaseService
             StatYjClass::addYj($main, $shop, $shopAdminId, $yjAmount);
         }
 
+        //余额支付
+        if ($payWay == dict::getDict('payWay', 'balancePay') && $isPurchase == false) {
+            CustomClass::payToChangeBalance($order);
+        }
+
         //欠款
         if ($payWay == dict::getDict('payWay', 'debtPay')) {
             CustomClass::cgDebtAmountAdd($custom, $order);

+ 5 - 1
biz-hd/ghs/classes/GhsClass.php

@@ -25,7 +25,11 @@ class GhsClass extends BaseClass
     {
         // hd 采购挂账:净 balance 减少
         AccountMoneyClass::ensureGhsMoneyReady($ghs, true);
-        $amount = $order->remainDebtPrice ?? 0;
+        // 开单余额抵挂账后 remainDebtPrice 变小,balance 仍按整单 debtPrice 扣减
+        $amount = bcadd((string)($order->debtPrice ?? '0'), '0', 2);
+        if (bccomp($amount, '0', 2) <= 0) {
+            $amount = bcadd((string)($order->remainDebtPrice ?? '0'), '0', 2);
+        }
         if (bccomp($amount, '0', 2) <= 0) {
             return;
         }

+ 14 - 6
biz-hd/purchase/services/PurchaseService.php

@@ -503,14 +503,22 @@ class PurchaseService extends BaseService
         $info->payTime = $payTime;
 
         if ($payWay == dict::getDict('payWay', 'debtPay')) {
-            //欠款支付
-            if (isset($info->actPrice) && $info->actPrice == 0) {
-                $info->debt = 0;
+            //欠款支付(批发开单若销售单已 payAfter,沿用其待结,支持开单余额抵挂账)
+            $saleId = intval($info->saleId ?? 0);
+            $saleOrder = $saleId > 0 ? \bizGhs\order\classes\OrderClass::getById($saleId, true) : null;
+            if (!empty($saleOrder) && intval($saleOrder->payStatus ?? 0) === 1) {
+                $info->debt = ($saleOrder->debt ?? 0) == 1 ? 1 : 0;
+                $info->remainDebtPrice = $saleOrder->remainDebtPrice ?? 0;
+                $info->debtPrice = $saleOrder->debtPrice ?? ($info->orderPrice ?? 0);
             } else {
-                $info->debt = 1;
+                if (isset($info->actPrice) && $info->actPrice == 0) {
+                    $info->debt = 0;
+                } else {
+                    $info->debt = 1;
+                }
+                $info->remainDebtPrice = $info->orderPrice ?? 0;
+                $info->debtPrice = $info->orderPrice ?? 0;
             }
-            $info->remainDebtPrice = $info->orderPrice ?? 0;
-            $info->debtPrice = $info->orderPrice ?? 0;
         }
         $info->save();