|
|
@@ -15,17 +15,24 @@ use bizHd\purchase\classes\PurchaseClearClass;
|
|
|
use common\components\util;
|
|
|
|
|
|
/**
|
|
|
- * 批发客户来款分配销挂账(对齐零售 RechargeClass::complete + SettleClass::clearSettle)
|
|
|
+ * 批发来款与销挂账(对齐 hd RechargeClass::complete,非照搬 ghs 旧三件套)
|
|
|
*
|
|
|
- * 【背景】挂账已并入净 balance 后,不能再走「clearDebtAmountReduce + 整单 remainDebtPrice=0」旧销账,
|
|
|
- * 也不能「充值后 balance 必须 >0 才 useBalanceClear」。
|
|
|
- * 【原则】
|
|
|
- * 1. 写账前:ensureCustomMoneyReady + ensureGhsMoneyReady(见 AccountMoneyClass)
|
|
|
- * 2. 来款先入账:balance += 本次金额(rechargeBalance / thirdPay)
|
|
|
- * 3. 仅用「本次来款」作资金池 FIFO 销 debt=1 订单(末单可部分销,见 buildNeedClearMap)
|
|
|
- * 4. confirmClear(['paymentSettleOnly'=>true]) 只改订单欠款
|
|
|
- * 5. clearConsumeBalance(实销合计) 扣减净余额,避免余额与订单状态不一致
|
|
|
- * 6. 回写充值单/流水 clearId、clearSn、clearAmount;列表 becomeBalance = amount - clearAmount
|
|
|
+ * ── 账户模型(合并后)──
|
|
|
+ * 净 balance:正=有余额,负=待结。订单 remainDebtPrice 仍逐单记录待结。
|
|
|
+ * 合并式:balance 已含历史挂账,勿再 clearDebtAmountReduce。
|
|
|
+ *
|
|
|
+ * ── hd 零售(对照)──
|
|
|
+ * balance / balancePay 与订单欠款分开记;充值 balance += 来款;
|
|
|
+ * 销单只改订单 remainDebtPrice,不再减 balance;
|
|
|
+ * 流水一条:amount=来款,settleAmount=用于销单,balance=充值+销单后的最终值。
|
|
|
+ *
|
|
|
+ * ── ghs 应对齐的行为 ──
|
|
|
+ * A. 来款充值销账(rechargeClear / 线上 thirdPay+allocate):
|
|
|
+ * 来款已 rechargeBalance 入账 → FIFO 销单(仅改订单)→ 不再 clearConsumeBalance(否则 +1 又 -1)。
|
|
|
+ * B. 用已有正余额销账(allocateFromExistingBalance):
|
|
|
+ * 无新来款 → 销单后须 clearConsumeBalance 扣减 balance → 可记一条「结账」流水。
|
|
|
+ * C. 待付结账单确认(linkedClearAfterRecharge):
|
|
|
+ * 来款入账 + 按结账单销单 → 同 A,不二次扣 balance。
|
|
|
*
|
|
|
* 搜索关键词:ensure_before_recharge_clear、custom_ghs_recharge、custom_recharge_ghs_clear_action
|
|
|
*/
|
|
|
@@ -55,14 +62,15 @@ class CustomPaymentAllocateService
|
|
|
|
|
|
self::syncDebtFlags($custom, $ghs);
|
|
|
|
|
|
- // 3. 仅用「本次充值额」作资金池 FIFO 销单,再扣余额(见 applyPoolToDebtOrders)
|
|
|
+ // 3. 仅用「本次充值额」FIFO 销单(只改订单,不二次扣 balance,对照 hd)
|
|
|
$allocate = self::applyPoolToDebtOrders($custom, $ghs, $shop, $staff, $amount, [
|
|
|
'remark' => $params['remark'] ?? '充值销账',
|
|
|
+ 'funding' => 'recharge',
|
|
|
]);
|
|
|
|
|
|
// 4. 回写充值单、余额流水上的 clearId/clearAmount(供 becomeBalance 展示)
|
|
|
if (!empty($customRecharge) && !empty($allocate['clear'])) {
|
|
|
- self::patchRechargeAudit($customRecharge, $respond['ghsRecharge'] ?? null, $allocate);
|
|
|
+ self::patchRechargeAudit($customRecharge, $respond['ghsRecharge'] ?? null, $allocate, $custom, $ghs);
|
|
|
}
|
|
|
|
|
|
return $respond;
|
|
|
@@ -85,10 +93,11 @@ class CustomPaymentAllocateService
|
|
|
// thirdPay 已入账,此处只按「本次支付金额」销挂账,勿在 NoticeController 再调 useBalanceClear
|
|
|
$allocate = self::applyPoolToDebtOrders($custom, $ghs, $shop, null, $amount, [
|
|
|
'remark' => '线上充值销账',
|
|
|
+ 'funding' => 'recharge',
|
|
|
]);
|
|
|
|
|
|
if (!empty($customRecharge) && !empty($allocate['clear'])) {
|
|
|
- self::patchRechargeAudit($customRecharge, $ghsRecharge, $allocate);
|
|
|
+ self::patchRechargeAudit($customRecharge, $ghsRecharge, $allocate, $custom, $ghs);
|
|
|
}
|
|
|
|
|
|
return $allocate;
|
|
|
@@ -96,8 +105,7 @@ class CustomPaymentAllocateService
|
|
|
|
|
|
/**
|
|
|
* 【用途】待付结账单 — 供货商确认「客户已转账」(OrderClearController::actionConfirmClear)。
|
|
|
- * 【流程】rechargeBalance(结账单 actPrice) → confirmClear(paymentSettleOnly) → clearConsumeBalance(实销)
|
|
|
- * 【替代】旧逻辑「充值 + confirmClear(clearDebt) + clearConsumeBalance(整单 actPrice)」会在合并后双计挂账。
|
|
|
+ * 【流程】rechargeBalance(来款) → confirmClear(paymentSettleOnly)(不 clearConsumeBalance,对照 hd)
|
|
|
*/
|
|
|
public static function linkedClearAfterRecharge($custom, $ghs, $shop, $staff, $clear, $payWay, $customRecharge = null)
|
|
|
{
|
|
|
@@ -136,13 +144,7 @@ class CustomPaymentAllocateService
|
|
|
if (bccomp($realClearAmount, $payCap, 2) > 0) {
|
|
|
$realClearAmount = $payCap;
|
|
|
}
|
|
|
- // 从净余额扣掉实销金额(不超过结账单 actPrice,兼容手工抹零结账单)
|
|
|
- if (bccomp($realClearAmount, '0', 2) > 0) {
|
|
|
- $custom = CustomClass::getLockById($custom->id ?? 0);
|
|
|
- $ghs = BizGhsClass::getLockById($ghs->id ?? 0);
|
|
|
- CustomClass::clearConsumeBalance($realClearAmount, $custom, $ghs, $shop, $staff, $clear);
|
|
|
- self::syncDebtFlags($custom, $ghs);
|
|
|
- }
|
|
|
+ self::syncDebtFlags($custom, $ghs);
|
|
|
$allocate = [
|
|
|
'clear' => $clear,
|
|
|
'realClearAmount' => $realClearAmount,
|
|
|
@@ -152,7 +154,7 @@ class CustomPaymentAllocateService
|
|
|
];
|
|
|
|
|
|
if (!empty($customRecharge)) {
|
|
|
- self::patchRechargeAudit($customRecharge, $ghsRecharge ?? null, $allocate);
|
|
|
+ self::patchRechargeAudit($customRecharge, $ghsRecharge ?? null, $allocate, $custom, $ghs);
|
|
|
} else {
|
|
|
self::patchRechargeAuditByClear($custom, $ghs, $clear, $realClearAmount);
|
|
|
}
|
|
|
@@ -182,10 +184,12 @@ class CustomPaymentAllocateService
|
|
|
|
|
|
$allocate = self::applyPoolToDebtOrders($custom, $ghs, $shop, $staff, $pool, [
|
|
|
'remark' => '余额结账',
|
|
|
+ 'funding' => 'existing_balance',
|
|
|
]);
|
|
|
|
|
|
$realClearAmount = $allocate['realClearAmount'] ?? '0.00';
|
|
|
if (bccomp($realClearAmount, '0', 2) > 0 && !empty($allocate['clear'])) {
|
|
|
+ // 用已有正余额销账:无充值流水,仍记一条「结账」变动
|
|
|
CustomClass::clearConsumeBalance($realClearAmount, $custom, $ghs, $shop, $staff, $allocate['clear']);
|
|
|
self::syncDebtFlags($custom, $ghs);
|
|
|
}
|
|
|
@@ -290,8 +294,9 @@ class CustomPaymentAllocateService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 【用途】用指定来款池金额销挂账:建结账单 → paymentSettleOnly 确认 → clearConsumeBalance。
|
|
|
- * 【参数】$poolAmount 本次来款(充值额或正余额),不是账户历史累计余额。
|
|
|
+ * 用资金池 FIFO 销挂账。
|
|
|
+ * funding=recharge:来款已入账,只改订单,不 clearConsumeBalance(对照 hd)。
|
|
|
+ * funding=existing_balance:用账面正余额,销单后 clearConsumeBalance 扣减。
|
|
|
*/
|
|
|
protected static function applyPoolToDebtOrders($custom, $ghs, $shop, $staff, $poolAmount, $options = [])
|
|
|
{
|
|
|
@@ -344,12 +349,15 @@ class CustomPaymentAllocateService
|
|
|
util::fail('销账金额超过本次来款' . floatval($poolAmount) . '元,请检查订单待结或联系技术员');
|
|
|
}
|
|
|
|
|
|
- // 入账后须把「用于销单」的部分从 balance 扣回,净余额才与订单状态一致
|
|
|
- if (bccomp($realClearAmount, '0', 2) > 0) {
|
|
|
+ $funding = $options['funding'] ?? 'recharge';
|
|
|
+ // 仅「用已有正余额」销账时才扣 balance;来款充值销账的来款已在 rechargeBalance 记入 balance
|
|
|
+ if ($funding === 'existing_balance' && bccomp($realClearAmount, '0', 2) > 0) {
|
|
|
$custom = CustomClass::getLockById($custom->id ?? 0);
|
|
|
$ghs = BizGhsClass::getLockById($ghs->id ?? 0);
|
|
|
CustomClass::clearConsumeBalance($realClearAmount, $custom, $ghs, $shop, $staff, $clear);
|
|
|
self::syncDebtFlags($custom, $ghs);
|
|
|
+ } else {
|
|
|
+ self::syncDebtFlags($custom, $ghs);
|
|
|
}
|
|
|
|
|
|
return [
|
|
|
@@ -377,27 +385,36 @@ class CustomPaymentAllocateService
|
|
|
}
|
|
|
|
|
|
/** 回写 xhCustomRecharge、xhCustomBalanceChange 的 clearId/clearSn/clearAmount(需先执行 add_clear_audit_fields.sql) */
|
|
|
- protected static function patchRechargeAudit($customRecharge, $ghsRecharge, $allocate)
|
|
|
+ protected static function patchRechargeAudit($customRecharge, $ghsRecharge, $allocate, $custom = null, $ghs = null)
|
|
|
{
|
|
|
$clearId = $allocate['clearId'] ?? 0;
|
|
|
$clearSn = $allocate['clearSn'] ?? '';
|
|
|
$clearAmount = $allocate['clearAmount'] ?? '0.00';
|
|
|
+ $finalCustomBalance = is_object($custom) ? ($custom->balance ?? null) : null;
|
|
|
+ $finalGhsBalance = is_object($ghs) ? ($ghs->balance ?? null) : null;
|
|
|
|
|
|
if (!empty($customRecharge)) {
|
|
|
if (self::modelHasAttr($customRecharge, 'clearId')) {
|
|
|
$customRecharge->clearId = $clearId;
|
|
|
$customRecharge->clearSn = $clearSn;
|
|
|
$customRecharge->clearAmount = $clearAmount;
|
|
|
- $customRecharge->save(false, ['clearId', 'clearSn', 'clearAmount']);
|
|
|
+ if ($finalCustomBalance !== null) {
|
|
|
+ $customRecharge->balance = $finalCustomBalance;
|
|
|
+ }
|
|
|
+ $customRecharge->save(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$relateId = $customRecharge->id ?? 0;
|
|
|
- self::patchBalanceChangeRow(CustomBalanceChangeClass::class, $relateId, $clearId, $clearSn, $clearAmount);
|
|
|
+ self::patchBalanceChangeRow(CustomBalanceChangeClass::class, $relateId, $clearId, $clearSn, $clearAmount, [], $finalCustomBalance);
|
|
|
|
|
|
if (!empty($ghsRecharge)) {
|
|
|
$gRelateId = $ghsRecharge->id ?? 0;
|
|
|
- self::patchBalanceChangeRow(GhsBalanceChangeClass::class, $gRelateId, $clearId, $clearSn, $clearAmount);
|
|
|
+ self::patchBalanceChangeRow(GhsBalanceChangeClass::class, $gRelateId, $clearId, $clearSn, $clearAmount, [], $finalGhsBalance);
|
|
|
+ if ($finalGhsBalance !== null) {
|
|
|
+ $ghsRecharge->balance = $finalGhsBalance;
|
|
|
+ $ghsRecharge->save(false, ['balance']);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -417,7 +434,7 @@ class CustomPaymentAllocateService
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
- protected static function patchBalanceChangeRow($class, $relateId, $clearId, $clearSn, $clearAmount, $extraWhere = [])
|
|
|
+ protected static function patchBalanceChangeRow($class, $relateId, $clearId, $clearSn, $clearAmount, $extraWhere = [], $finalBalance = null)
|
|
|
{
|
|
|
$where = array_merge(['io' => 1], $extraWhere);
|
|
|
if ($relateId > 0) {
|
|
|
@@ -433,6 +450,10 @@ class CustomPaymentAllocateService
|
|
|
if (self::modelHasAttr($row, 'giveAmount')) {
|
|
|
$row->giveAmount = '0.00';
|
|
|
}
|
|
|
+ // 流水余额列展示充值+销账后的净余额(与 hd 单条充值流水一致)
|
|
|
+ if ($finalBalance !== null && self::modelHasAttr($row, 'balance')) {
|
|
|
+ $row->balance = $finalBalance;
|
|
|
+ }
|
|
|
$row->save(false);
|
|
|
}
|
|
|
|