GhsController.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. namespace console\controllers;
  3. use biz\shop\models\Shop;
  4. use bizGhs\custom\classes\AccountMoneyClass;
  5. use bizGhs\custom\classes\CustomClass;
  6. use bizGhs\ghs\classes\GhsClass;
  7. use bizGhs\order\classes\OrderClass;
  8. use bizGhs\order\classes\PurchaseOrderClass;
  9. use common\components\noticeUtil;
  10. use yii\console\Controller;
  11. /**
  12. * 批发供货商控制台任务
  13. *
  14. * adjust-debt:合并后净余额模型下的欠款一致性巡检(与线 ensure*MoneyReady 一致)
  15. * 用法:php yii ghs/adjust-debt
  16. */
  17. class GhsController extends Controller
  18. {
  19. /**
  20. * 供货商欠款跟踪:先合并挂账进余额,再比对订单待结与账户净额
  21. */
  22. public function actionAdjustDebt()
  23. {
  24. ini_set('memory_limit', '2045M');
  25. set_time_limit(0);
  26. $query = new \yii\db\Query();
  27. $query->from(Shop::tableName());
  28. $query->where(['ptStyle' => 2]);
  29. foreach ($query->batch(10) as $batch) {
  30. foreach ($batch as $shop) {
  31. $sjName = $shop['merchantName'] ?? '';
  32. $shopName = $shop['shopName'] ?? '';
  33. $name = $sjName . ' ' . $shopName;
  34. $where = ['ownShopId' => $shop['id']];
  35. $ghsList = GhsClass::getAllByCondition($where, null, '*', null, true);
  36. if (empty($ghsList)) {
  37. continue;
  38. }
  39. foreach ($ghsList as $ghs) {
  40. $this->auditGhsDebtRow($ghs, $name);
  41. }
  42. }
  43. }
  44. }
  45. /**
  46. * 单条 xhGhs:合并后校验成对净余额、销售/采购挂账待结是否一致
  47. */
  48. protected function auditGhsDebtRow($ghs, $shopLabel)
  49. {
  50. $ghsName = $ghs->name ?? '';
  51. $ghsId = intval($ghs->id ?? 0);
  52. if ($ghsId <= 0) {
  53. return;
  54. }
  55. // 巡检只读比对,不触发合并(合并请用 balance-merge / ghs-purchase-balance-merge 脚本)
  56. $ghs = GhsClass::getById($ghsId, true);
  57. if (empty($ghs)) {
  58. return;
  59. }
  60. $custom = CustomClass::getByCondition(['ghsId' => $ghsId], true);
  61. if (!empty($custom)) {
  62. $custom = CustomClass::getById($custom->id ?? 0, true);
  63. $customNet = AccountMoneyClass::getNetBalanceFromRow($custom);
  64. $ghsNet = AccountMoneyClass::getNetBalanceFromRow($ghs);
  65. if (bccomp($customNet, $ghsNet, 2) !== 0) {
  66. $customId = intval($custom->id ?? 0);
  67. noticeUtil::push(
  68. "{$shopLabel} 供货商{$ghsName}({$ghsId})与客户{$customId} 成对净余额不一致。客户:{$customNet} 关系:{$ghsNet}",
  69. '15280215347'
  70. );
  71. }
  72. }
  73. $saleDebtSum = $this->sumSaleOrderRemainDebt($custom);
  74. $purchaseDebtSum = $this->sumPurchaseOrderRemainDebt($ghsId);
  75. if (bccomp($saleDebtSum, $purchaseDebtSum, 2) !== 0) {
  76. noticeUtil::push(
  77. "{$shopLabel} 供货商{$ghsName}({$ghsId})销售单待结与采购挂账不一致。销售:{$saleDebtSum} 采购:{$purchaseDebtSum}",
  78. '15280215347'
  79. );
  80. }
  81. // 账户净余额为负时:销售单待结合计应与 |净余额| 一致(有余额抵扣时不做此项比对)
  82. $ghsNet = AccountMoneyClass::getNetBalanceFromRow($ghs);
  83. if (bccomp($ghsNet, '0', 2) < 0) {
  84. $accountDebt = AccountMoneyClass::getOutstandingDebt($ghs);
  85. if (bccomp($saleDebtSum, $accountDebt, 2) !== 0) {
  86. noticeUtil::push(
  87. "{$shopLabel} 供货商{$ghsName}({$ghsId})订单待结与账户待结不一致。订单待结:{$saleDebtSum} 账户待结:{$accountDebt} 净余额:{$ghsNet}",
  88. '15280215347'
  89. );
  90. }
  91. }
  92. }
  93. /**
  94. * 销售单挂账待结合计(FIFO 后以 remainDebtPrice 为准)
  95. */
  96. protected function sumSaleOrderRemainDebt($custom)
  97. {
  98. $customId = is_object($custom) ? intval($custom->id ?? 0) : 0;
  99. if ($customId <= 0) {
  100. return '0.00';
  101. }
  102. $orderList = OrderClass::getAllByCondition(
  103. ['customId' => $customId, 'debt' => OrderClass::DEBT_YES],
  104. null,
  105. '*',
  106. null,
  107. true
  108. );
  109. if (empty($orderList)) {
  110. return '0.00';
  111. }
  112. $total = '0.00';
  113. foreach ($orderList as $order) {
  114. $remain = $order->remainDebtPrice ?? 0;
  115. $total = bcadd($total, bcadd((string)$remain, '0', 2), 2);
  116. }
  117. return $total;
  118. }
  119. /**
  120. * 采购单(xhGhsCgOrder)挂账待结合计:有 remainDebtPrice 用之,否则 actPrice
  121. */
  122. protected function sumPurchaseOrderRemainDebt($ghsId)
  123. {
  124. $orderList = PurchaseOrderClass::getAllByCondition([
  125. 'ghsId' => $ghsId,
  126. 'status' => PurchaseOrderClass::PURCHASE_ORDER_STATUS_COMPLETE,
  127. 'debt' => PurchaseOrderClass::DEBT_YES,
  128. ], null, '*', null, true);
  129. if (empty($orderList)) {
  130. return '0.00';
  131. }
  132. $total = '0.00';
  133. foreach ($orderList as $order) {
  134. $remain = '0';
  135. if (is_object($order) && method_exists($order, 'hasAttribute') && $order->hasAttribute('remainDebtPrice')) {
  136. $remain = $order->remainDebtPrice ?? '0';
  137. }
  138. $total = bcadd($total, bcadd((string)$remain, '0', 2), 2);
  139. }
  140. return $total;
  141. }
  142. }