|
@@ -7,6 +7,7 @@ use biz\shop\classes\ShopClass;
|
|
|
use bizGhs\base\classes\BaseClass;
|
|
use bizGhs\base\classes\BaseClass;
|
|
|
use bizGhs\custom\classes\CustomClass;
|
|
use bizGhs\custom\classes\CustomClass;
|
|
|
use bizGhs\clear\classes\OrderCgClearClass;
|
|
use bizGhs\clear\classes\OrderCgClearClass;
|
|
|
|
|
+use bizGhs\ghs\classes\GhsBalanceChangeClass;
|
|
|
use bizGhs\order\classes\OrderClass;
|
|
use bizGhs\order\classes\OrderClass;
|
|
|
use bizGhs\order\classes\PurchaseOrderClass;
|
|
use bizGhs\order\classes\PurchaseOrderClass;
|
|
|
use bizGhs\shop\classes\MainClass;
|
|
use bizGhs\shop\classes\MainClass;
|
|
@@ -150,6 +151,221 @@ class ClearClass extends BaseClass
|
|
|
return $order;
|
|
return $order;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 【用途】作废该供货商下待付的 gys2KmGys 采购结账单(新建自动销欠前调用)
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function expireAwaitPayPurchaseClears($ghsId, $shopId = 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ $ghsId = intval($ghsId);
|
|
|
|
|
+ if ($ghsId <= 0) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ $where = [
|
|
|
|
|
+ 'ghsId' => $ghsId,
|
|
|
|
|
+ 'clearStyle' => dict::getDict('clearStyle', 'gys2KmGys'),
|
|
|
|
|
+ 'status' => self::STATUS_AWAIT_PAY,
|
|
|
|
|
+ ];
|
|
|
|
|
+ if (intval($shopId) > 0) {
|
|
|
|
|
+ $where['shopId'] = intval($shopId);
|
|
|
|
|
+ }
|
|
|
|
|
+ $list = self::getAllByCondition($where, null, '*', null, true);
|
|
|
|
|
+ if (empty($list)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ foreach ($list as $item) {
|
|
|
|
|
+ $item->status = self::STATUS_EXPIRE;
|
|
|
|
|
+ $item->remark = ($item->remark ?? '') . ';售后返充自动销欠前作废待付结账单';
|
|
|
|
|
+ $item->save(false, ['status', 'remark']);
|
|
|
|
|
+ OrderCgClearClass::markExpireByClearId($item->id ?? 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 【用途】采购售后返充余额后 FIFO 销欠:建结账单并减 remain,不再加余额(钱已入账)。
|
|
|
|
|
+ * 【为什么】对齐销售侧 afterCreditFifoClear,余额流水可挂 clearId/clearSn/clearAmount。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param object $ghs 买方供货商(已锁)
|
|
|
|
|
+ * @param array $plan [['cgId'=>int,'clearAmount'=>string,'orderSn'=>string], ...]
|
|
|
|
|
+ * @param array $meta shopId/sjId/staffId/staffName/payWay/remark
|
|
|
|
|
+ * @return object|null 结账单;无计划时 null
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function settlePurchaseFifoAfterCredit($ghs, array $plan, array $meta = [])
|
|
|
|
|
+ {
|
|
|
|
|
+ if (empty($ghs) || empty($plan)) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ $planTotal = '0.00';
|
|
|
|
|
+ $pairs = [];
|
|
|
|
|
+ foreach ($plan as $row) {
|
|
|
|
|
+ $cgId = intval($row['cgId'] ?? 0);
|
|
|
|
|
+ $cut = bcadd((string)($row['clearAmount'] ?? '0'), '0', 2);
|
|
|
|
|
+ if ($cgId <= 0 || bccomp($cut, '0', 2) <= 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $planTotal = bcadd($planTotal, $cut, 2);
|
|
|
|
|
+ $pairs[] = [
|
|
|
|
|
+ 'orderId' => 0,
|
|
|
|
|
+ 'orderSn' => '',
|
|
|
|
|
+ 'cgId' => $cgId,
|
|
|
|
|
+ 'cgSn' => (string)($row['orderSn'] ?? ''),
|
|
|
|
|
+ 'amount' => $cut,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (empty($pairs) || bccomp($planTotal, '0', 2) <= 0) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $ghsId = intval($ghs->id ?? 0);
|
|
|
|
|
+ $shopId = intval($meta['shopId'] ?? ($ghs->shopId ?? 0));
|
|
|
|
|
+ $sjId = intval($meta['sjId'] ?? 0);
|
|
|
|
|
+ self::expireAwaitPayPurchaseClears($ghsId, $shopId);
|
|
|
|
|
+
|
|
|
|
|
+ $customId = intval($ghs->customId ?? 0);
|
|
|
|
|
+ $custom = $customId > 0 ? CustomClass::getById($customId, true) : null;
|
|
|
|
|
+ $payWay = isset($meta['payWay']) && is_numeric($meta['payWay'])
|
|
|
|
|
+ ? intval($meta['payWay'])
|
|
|
|
|
+ : intval(dict::getDict('payWay', 'balancePay'));
|
|
|
|
|
+
|
|
|
|
|
+ $orderSn = orderSn::getPurchaseClearSn();
|
|
|
|
|
+ $data = [
|
|
|
|
|
+ 'ghsId' => $ghsId,
|
|
|
|
|
+ 'ghsName' => $ghs->name ?? '',
|
|
|
|
|
+ 'ghsAvatar' => $ghs->avatar ?? '',
|
|
|
|
|
+ 'ghsMobile' => $ghs->mobile ?? '',
|
|
|
|
|
+ 'customId' => $customId,
|
|
|
|
|
+ 'customName' => $custom->name ?? '',
|
|
|
|
|
+ 'customAvatar' => $custom->avatar ?? '',
|
|
|
|
|
+ 'customMobile' => $custom->mobile ?? '',
|
|
|
|
|
+ 'sjId' => $sjId,
|
|
|
|
|
+ 'shopId' => $shopId,
|
|
|
|
|
+ 'clearStyle' => dict::getDict('clearStyle', 'gys2KmGys'),
|
|
|
|
|
+ 'customShopAdminId' => intval($meta['staffId'] ?? 0),
|
|
|
|
|
+ 'customShopId' => $shopId,
|
|
|
|
|
+ 'customShopAdminName' => (string)($meta['staffName'] ?? ''),
|
|
|
|
|
+ 'payWay' => $payWay,
|
|
|
|
|
+ 'prePrice' => $planTotal,
|
|
|
|
|
+ 'actPrice' => $planTotal,
|
|
|
|
|
+ 'realPrice' => $planTotal,
|
|
|
|
|
+ 'orderSn' => $orderSn,
|
|
|
|
|
+ 'salt' => \common\components\stringUtil::charsShuffleLowerCase(10),
|
|
|
|
|
+ 'deadline' => date('Y-m-d H:i:s', time() + 120),
|
|
|
|
|
+ 'status' => self::STATUS_AWAIT_PAY,
|
|
|
|
|
+ 'remark' => (string)($meta['remark'] ?? '采购售后返充余额自动销欠'),
|
|
|
|
|
+ ];
|
|
|
|
|
+ $clear = self::add($data, true);
|
|
|
|
|
+ OrderCgClearClass::bindRelations($clear, $pairs, OrderCgClearClass::STATUS_HAS_PAY);
|
|
|
|
|
+
|
|
|
|
|
+ // 只减采购单待结 / 更新 debtNum,不再加余额
|
|
|
|
|
+ self::applyPurchasePaymentSettleOnly($clear, $pairs, $payWay);
|
|
|
|
|
+
|
|
|
|
|
+ return $clear;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 【用途】结账单已建好后:按明细减采购 remain,足额写真实 clearId;不加 xhGhs 余额。
|
|
|
|
|
+ */
|
|
|
|
|
+ protected static function applyPurchasePaymentSettleOnly($clear, array $pairs, $payWay)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (empty($clear)) {
|
|
|
|
|
+ util::fail('没有结账单');
|
|
|
|
|
+ }
|
|
|
|
|
+ if (intval($clear->status ?? 0) === self::STATUS_HAS_PAY) {
|
|
|
|
|
+ // bind 时可能已标 HAS_PAY,仍允许走减 remain
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $clear->status = self::STATUS_HAS_PAY;
|
|
|
|
|
+ }
|
|
|
|
|
+ $clear->payWay = $payWay;
|
|
|
|
|
+ $clear->payTime = date('Y-m-d H:i:s');
|
|
|
|
|
+ $clear->save(false);
|
|
|
|
|
+
|
|
|
|
|
+ $clearId = intval($clear->id ?? 0);
|
|
|
|
|
+ $clearedCount = 0;
|
|
|
|
|
+ foreach ($pairs as $pair) {
|
|
|
|
|
+ $cgId = intval($pair['cgId'] ?? 0);
|
|
|
|
|
+ $cut = bcadd((string)($pair['amount'] ?? '0'), '0', 2);
|
|
|
|
|
+ if ($cgId <= 0 || bccomp($cut, '0', 2) <= 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $purchase = PurchaseOrderClass::getById($cgId, true);
|
|
|
|
|
+ if (empty($purchase) || intval($purchase->debt ?? 0) !== PurchaseOrderClass::DEBT_YES) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $remain = bcadd((string)($purchase->remainDebtPrice ?? '0'), '0', 2);
|
|
|
|
|
+ if (bccomp($remain, '0', 2) <= 0) {
|
|
|
|
|
+ $remain = bcadd((string)($purchase->actPrice ?? '0'), '0', 2);
|
|
|
|
|
+ }
|
|
|
|
|
+ $newRemain = bcsub($remain, $cut, 2);
|
|
|
|
|
+ if (bccomp($newRemain, '0', 2) < 0) {
|
|
|
|
|
+ $newRemain = '0.00';
|
|
|
|
|
+ }
|
|
|
|
|
+ $purchase->remainDebtPrice = $newRemain;
|
|
|
|
|
+ $saveAttrs = ['remainDebtPrice', 'debt', 'clearId'];
|
|
|
|
|
+ if (bccomp($newRemain, '0', 2) <= 0) {
|
|
|
|
|
+ $purchase->debt = PurchaseOrderClass::DEBT_NO;
|
|
|
|
|
+ $purchase->clearId = $clearId;
|
|
|
|
|
+ $clearedCount++;
|
|
|
|
|
+ } elseif (intval($purchase->clearId ?? 0) === 0) {
|
|
|
|
|
+ $purchase->clearId = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ $purchase->save(false, $saveAttrs);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($clearedCount > 0) {
|
|
|
|
|
+ $ghsId = intval($clear->ghsId ?? 0);
|
|
|
|
|
+ $ghs = GhsClass::getLockById($ghsId);
|
|
|
|
|
+ if (!empty($ghs)) {
|
|
|
|
|
+ $ghs->debtNum = max(0, intval($ghs->debtNum ?? 0) - $clearedCount);
|
|
|
|
|
+ $ghs->debt = bccomp((string)($ghs->balance ?? '0'), '0', 2) < 0
|
|
|
|
|
+ ? GhsClass::DEBT_YES
|
|
|
|
|
+ : (intval($ghs->debtNum) > 0 ? GhsClass::DEBT_YES : GhsClass::DEBT_NO);
|
|
|
|
|
+ $ghs->save(false, ['debtNum', 'debt']);
|
|
|
|
|
+ $customId = intval($ghs->customId ?? 0);
|
|
|
|
|
+ if ($customId > 0) {
|
|
|
|
|
+ $custom = CustomClass::getLockById($customId);
|
|
|
|
|
+ if (!empty($custom)) {
|
|
|
|
|
+ $custom->debtNum = max(0, intval($custom->debtNum ?? 0) - $clearedCount);
|
|
|
|
|
+ $custom->isDebt = bccomp((string)($custom->balance ?? '0'), '0', 2) < 0
|
|
|
|
|
+ ? CustomClass::IS_DEBT_YES
|
|
|
|
|
+ : (intval($custom->debtNum) > 0 ? CustomClass::IS_DEBT_YES : CustomClass::IS_DEBT_NO);
|
|
|
|
|
+ $custom->save(false, ['debtNum', 'isDebt']);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 【用途】售后返充流水回写结账审计字段(供 ghs 余额变动展示「本单销」)
|
|
|
|
|
+ * 【注意】getByCondition 签名为 (condition, returnObject, order, field),
|
|
|
|
|
+ * 勿把「id DESC」传到第 4 参,否则会当成 SELECT 字段导致查不到 clearId。
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function patchGhsBalanceChangeClearAudit($ghsId, $relateId, $clear, $clearAmount = null)
|
|
|
|
|
+ {
|
|
|
|
|
+ $ghsId = intval($ghsId);
|
|
|
|
|
+ $relateId = intval($relateId);
|
|
|
|
|
+ $clearId = intval(is_object($clear) ? ($clear->id ?? 0) : 0);
|
|
|
|
|
+ if ($ghsId <= 0 || $relateId <= 0 || $clearId <= 0) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 第 3 参 order、第 4 参 field;取最新一条入账流水挂结账单
|
|
|
|
|
+ $row = GhsBalanceChangeClass::getByCondition([
|
|
|
|
|
+ 'ghsId' => $ghsId,
|
|
|
|
|
+ 'relateId' => $relateId,
|
|
|
|
|
+ 'io' => 1,
|
|
|
|
|
+ ], true, 'id DESC', '*');
|
|
|
|
|
+ if (empty($row) || !method_exists($row, 'hasAttribute') || !$row->hasAttribute('clearId')) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ $row->clearId = $clearId;
|
|
|
|
|
+ $row->clearSn = (string)(is_object($clear) ? ($clear->orderSn ?? '') : '');
|
|
|
|
|
+ $row->clearAmount = bcadd(
|
|
|
|
|
+ (string)($clearAmount !== null ? $clearAmount : (is_object($clear) ? ($clear->actPrice ?? 0) : 0)),
|
|
|
|
|
+ '0',
|
|
|
|
|
+ 2
|
|
|
|
|
+ );
|
|
|
|
|
+ $row->save(false, ['clearId', 'clearSn', 'clearAmount']);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
//支付成功后的流程 ssh 2021.4.28
|
|
//支付成功后的流程 ssh 2021.4.28
|
|
|
public static function complete($order, $payWay)
|
|
public static function complete($order, $payWay)
|
|
|
{
|
|
{
|