from(Shop::tableName()); $query->where(['ptStyle' => 2]); foreach ($query->batch(10) as $batch) { foreach ($batch as $shop) { $sjName = $shop['merchantName'] ?? ''; $shopName = $shop['shopName'] ?? ''; $name = $sjName . ' ' . $shopName; $where = ['ownShopId' => $shop['id']]; $ghsList = GhsClass::getAllByCondition($where, null, '*', null, true); if (empty($ghsList)) { continue; } foreach ($ghsList as $ghs) { $this->auditGhsDebtRow($ghs, $name); } } } } /** * 单条 xhGhs:合并后校验成对净余额、销售/采购挂账待结是否一致 */ protected function auditGhsDebtRow($ghs, $shopLabel) { $ghsName = $ghs->name ?? ''; $ghsId = intval($ghs->id ?? 0); if ($ghsId <= 0) { return; } // 巡检只读比对,不触发合并(合并请用 balance-merge / ghs-purchase-balance-merge 脚本) $ghs = GhsClass::getById($ghsId, true); if (empty($ghs)) { return; } $custom = CustomClass::getByCondition(['ghsId' => $ghsId], true); if (!empty($custom)) { $custom = CustomClass::getById($custom->id ?? 0, true); $customNet = AccountMoneyClass::getNetBalanceFromRow($custom); $ghsNet = AccountMoneyClass::getNetBalanceFromRow($ghs); if (bccomp($customNet, $ghsNet, 2) !== 0) { $customId = intval($custom->id ?? 0); noticeUtil::push( "{$shopLabel} 供货商{$ghsName}({$ghsId})与客户{$customId} 成对净余额不一致。客户:{$customNet} 关系:{$ghsNet}", '15280215347' ); } } $saleDebtSum = $this->sumSaleOrderRemainDebt($custom); $purchaseDebtSum = $this->sumPurchaseOrderRemainDebt($ghsId); if (bccomp($saleDebtSum, $purchaseDebtSum, 2) !== 0) { noticeUtil::push( "{$shopLabel} 供货商{$ghsName}({$ghsId})销售单待结与采购挂账不一致。销售:{$saleDebtSum} 采购:{$purchaseDebtSum}", '15280215347' ); } // 账户净余额为负时:销售单待结合计应与 |净余额| 一致(有余额抵扣时不做此项比对) $ghsNet = AccountMoneyClass::getNetBalanceFromRow($ghs); if (bccomp($ghsNet, '0', 2) < 0) { $accountDebt = AccountMoneyClass::getOutstandingDebt($ghs); if (bccomp($saleDebtSum, $accountDebt, 2) !== 0) { noticeUtil::push( "{$shopLabel} 供货商{$ghsName}({$ghsId})订单待结与账户待结不一致。订单待结:{$saleDebtSum} 账户待结:{$accountDebt} 净余额:{$ghsNet}", '15280215347' ); } } } /** * 销售单挂账待结合计(FIFO 后以 remainDebtPrice 为准) */ protected function sumSaleOrderRemainDebt($custom) { $customId = is_object($custom) ? intval($custom->id ?? 0) : 0; if ($customId <= 0) { return '0.00'; } $orderList = OrderClass::getAllByCondition( ['customId' => $customId, 'debt' => OrderClass::DEBT_YES], null, '*', null, true ); if (empty($orderList)) { return '0.00'; } $total = '0.00'; foreach ($orderList as $order) { $remain = $order->remainDebtPrice ?? 0; $total = bcadd($total, bcadd((string)$remain, '0', 2), 2); } return $total; } /** * 采购单(xhGhsCgOrder)挂账待结合计:有 remainDebtPrice 用之,否则 actPrice */ protected function sumPurchaseOrderRemainDebt($ghsId) { $orderList = PurchaseOrderClass::getAllByCondition([ 'ghsId' => $ghsId, 'status' => PurchaseOrderClass::PURCHASE_ORDER_STATUS_COMPLETE, 'debt' => PurchaseOrderClass::DEBT_YES, ], null, '*', null, true); if (empty($orderList)) { return '0.00'; } $total = '0.00'; foreach ($orderList as $order) { $remain = '0'; if (is_object($order) && method_exists($order, 'hasAttribute') && $order->hasAttribute('remainDebtPrice')) { $remain = $order->remainDebtPrice ?? '0'; } $total = bcadd($total, bcadd((string)$remain, '0', 2), 2); } return $total; } }