PurchaseClearClass.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. namespace bizHd\purchase\classes;
  3. use biz\ghs\classes\GhsClass;
  4. use biz\shop\classes\ShopClass;
  5. use biz\shop\classes\ShopYeChangeClass;
  6. use biz\wx\classes\WxMessageClass;
  7. use bizGhs\clear\classes\ClearClass;
  8. use bizGhs\custom\classes\CustomClass;
  9. use bizGhs\order\classes\OrderClass;
  10. use bizHd\base\classes\BaseClass;
  11. use bizHd\shop\classes\MainClass;
  12. use common\components\dict;
  13. use common\components\noticeUtil;
  14. use common\components\orderSn;
  15. use common\components\util;
  16. use Yii;
  17. class PurchaseClearClass extends BaseClass
  18. {
  19. public static $baseFile = '\bizHd\purchase\models\PurchaseClear';
  20. const STATUS_AWAIT_PAY = 1;
  21. const STATUS_HAS_PAY = 2;
  22. const STATUS_EXPIRE = 3;
  23. public static function addOrder($data, $ghs)
  24. {
  25. $ghsId = $ghs->id;
  26. $customId = $ghs->customId;
  27. $custom = CustomClass::getById($customId, true);
  28. if (empty($custom)) {
  29. util::fail('没有找到客户');
  30. }
  31. $ghsShopId = $ghs->shopId ?? 0;
  32. $ghsShop = ShopClass::getById($ghsShopId, true);
  33. $ghsShopName = $ghsShop->shopName ?? '';
  34. $ghsShopName = $ghsShopName == '首店' ? '总店' : $ghsShopName;
  35. $orderSn = orderSn::getPurchaseClearSn();
  36. $purchaseIdStr = $data['purchaseIds'] ?? '';
  37. $arr = explode(',', $purchaseIdStr);
  38. if (empty($arr)) {
  39. util::fail('请选择采购单');
  40. }
  41. //订单太多数据库会报错
  42. if (count($arr) > 100) {
  43. util::fail('订单太多,请选月份再结');
  44. }
  45. $purchaseList = PurchaseClass::getAllByCondition(['id' => ['in', $arr]], null, '*', null, true);
  46. if (empty($purchaseList)) {
  47. util::fail('请选择采购单');
  48. }
  49. $totalPrice = 0;
  50. $currentGhsId = $data['ghsId'] ?? 0;
  51. foreach ($purchaseList as $purchase) {
  52. if ($purchase->debt != PurchaseClass::DEBT_YES) {
  53. util::fail('请选择有欠款的采购单');
  54. }
  55. if ($purchase->ghsId != $currentGhsId) {
  56. util::fail('请选择同个供货商的订单');
  57. }
  58. $totalPrice = bcadd($totalPrice, $purchase->remainDebtPrice, 2);
  59. }
  60. $data['prePrice'] = $totalPrice;
  61. $data['actPrice'] = $totalPrice;
  62. $data['realPrice'] = $totalPrice;
  63. $data['orderSn'] = $orderSn;
  64. // 生成并保存 salt 字段,用于结账单的验签和防篡改分享链接
  65. $data['salt'] = $data['salt'] ?? \common\components\stringUtil::charsShuffleLowerCase(10);
  66. //10个小时
  67. $deadTime = time() + 36000;
  68. $data['deadline'] = date("Y-m-d H:i:s", $deadTime);
  69. $params = [
  70. 'ghsId' => $ghsId,
  71. 'ghsName' => $ghs['name'] ?? '',
  72. 'ghsMobile' => $ghs['mobile'] ?? '',
  73. 'ghsAvatar' => $ghs['avatar'] ?? '',
  74. 'ghsAddress' => $ghs['address'] ?? '',
  75. 'customId' => $customId,
  76. 'customName' => $custom['name'] ?? '',
  77. 'customAvatar' => $custom['avatar'] ?? '',
  78. 'customMobile' => $custom['mobile'] ?? '',
  79. 'customAddress' => $custom['address'] ?? '',
  80. 'num' => count($arr),
  81. 'ghsShopName' => $ghsShopName,
  82. ];
  83. $data = array_merge($data, $params);
  84. $clear = self::add($data);
  85. $pairs = OrderCgClearClass::buildPairsFromPurchases($purchaseList);
  86. OrderCgClearClass::bindRelations($clear, $pairs);
  87. return $clear;
  88. }
  89. //第三方支付回调 ssh 2021.4.28
  90. public static function thirdPay($payWay, $orderSn, $totalFee, $attach, $transactionId)
  91. {
  92. $info = self::getByCondition(['orderSn' => $orderSn], true);
  93. $isOldSnPay = false; // 标记是否使用了老单号支付
  94. if (empty($info)) {
  95. // 尝试从 Redis 读取老单号映射,防止用户支付了已失效的旧单号导致回调找不到订单
  96. $redisKey = 'hd_clear_old_sn_map_' . $orderSn;
  97. $orderId = Yii::$app->redis->executeCommand('GET', [$redisKey]);
  98. if (!empty($orderId)) {
  99. $info = self::getById($orderId);
  100. $isOldSnPay = true; // 确认为老单号支付
  101. }
  102. }
  103. if (empty($info)) {
  104. $msg = "没有找到清算订单 orderSn:{$orderSn} {$attach}";
  105. noticeUtil::push($msg, '15280215347');
  106. Yii::info($msg);
  107. util::fail($msg);
  108. }
  109. if ($info->actPrice != $totalFee) {
  110. $msg = "清算订单金额与回调通知金额不一致 orderSn:{$orderSn} {$info->actPrice} {$totalFee} {$attach}";
  111. noticeUtil::push($msg, '15280215347');
  112. Yii::info($msg);
  113. util::fail($msg);
  114. }
  115. //临时解决微信一秒内通知二次问题
  116. $id = $info->id;
  117. $info = self::getLockById($id);
  118. // 如果是老单号支付,将数据库中的 orderSn 修正为实际支付的老单号,并同步更新关联表的 clearSn
  119. if ($isOldSnPay) {
  120. $info->orderSn = $orderSn;
  121. OrderCgClearClass::updateClearSnByClearId($id, $orderSn);
  122. }
  123. $info->payWay = $payWay;
  124. $info->onlinePay = dict::getDict('onlinePay', 'yes');
  125. $info->thirdNo = $transactionId;
  126. $info->save();
  127. self::complete($info, $payWay);
  128. }
  129. //支付成功后的流程 ssh 2021.4.28
  130. public static function complete($order, $payWay)
  131. {
  132. if (empty($order)) {
  133. util::fail('没有找到订单');
  134. }
  135. if (isset($order->status) && $order->status == self::STATUS_EXPIRE) {
  136. if ($order->onlinePay == dict::getDict('onlinePay', 'yes')) {
  137. $ghsName = $order->ghsName ?? '';
  138. $customName = $order->customName ?? '';
  139. $orderSn = $order->orderSn ?? '';
  140. noticeUtil::push("花店线上付款结账,但结账单是取消状态。供货商:{$ghsName},客户:{$customName},订单编号:{$orderSn}", '15280215347');
  141. $ghsShopId = $order->ghsShopId;
  142. $shop = ShopClass::getById($ghsShopId, true);
  143. if (!empty($shop)) {
  144. //原路退回给客户
  145. ClearClass::refundMoney($shop, $order);
  146. }
  147. util::stop("SUCCESS");
  148. }
  149. }
  150. if (!isset($order->status) || $order->status != self::STATUS_AWAIT_PAY) {
  151. $ghsName = $order->ghsName ?? '';
  152. $customName = $order->customName ?? '';
  153. $orderSn = $order->orderSn ?? '';
  154. if($order->status == self::STATUS_HAS_PAY){
  155. echo "SUCCESS";
  156. noticeUtil::push("花店线上付款结账,但结账单不是待付款状态。已经返回 success 。供货商:{$ghsName},客户:{$customName},订单编号:{$orderSn}", '15280215347');
  157. exit();
  158. }
  159. noticeUtil::push("花店线上付款结账,但结账单不是待付款状态。供货商:{$ghsName},客户:{$customName},订单编号:{$orderSn}", '15280215347');
  160. util::fail('订单不是待付款状态');
  161. }
  162. $order->status = self::STATUS_HAS_PAY;
  163. $order->payTime = date("Y-m-d H:i:s");
  164. $order->save();
  165. $clearId = $order->id;
  166. $orderSn = $order->orderSn;
  167. $arr = OrderCgClearClass::getCgIdsByClearId($clearId);
  168. //供货商欠款变更
  169. $ghsId = $order->ghsId;
  170. $ghs = GhsClass::getLockById($ghsId);
  171. if (empty($ghs)) {
  172. util::fail('没有找到供货商信息');
  173. }
  174. $customId = $ghs->customId;
  175. $custom = CustomClass::getLockById($customId);
  176. if (empty($custom)) {
  177. util::fail('没有找到客户信息');
  178. }
  179. \bizHd\ghs\classes\GhsClass::clearDebtAmountReduce($ghs, $custom, $order->actPrice, $order);
  180. $shopId = $ghs->shopId;
  181. $shop = ShopClass::getLockById($shopId);
  182. if (empty($shop)) {
  183. util::fail('没有找到供货商门店');
  184. }
  185. $mainId = $shop->mainId ?? 0;
  186. $main = MainClass::getLockById($mainId);
  187. if (empty($main)) {
  188. util::fail('没有main数据呢');
  189. }
  190. if ($order->onlinePay == dict::getDict('onlinePay', 'yes')) {
  191. //供货商门店余额增加
  192. ShopClass::customClearAddBalance($main, $shop, $order);
  193. }
  194. //供货商的门店应收客户款减少
  195. $currentGathering = bcsub($main->mayGathering, $order->actPrice, 2);
  196. $main->mayGathering = $currentGathering;
  197. $main->save();
  198. if (empty($arr)) {
  199. $msg = "结算订单 orderSn:{$orderSn} 支付成功,回调处理,没有找到采购订单";
  200. util::fail($msg);
  201. }
  202. $list = PurchaseClass::getAllByCondition(['id' => ['in', $arr]], null, '*', null, true);
  203. if (empty($list)) {
  204. $msg = "结算订单 orderSn:{$orderSn} 支付成功,回调处理,没有找到采购订单!";
  205. util::fail($msg);
  206. }
  207. $clearTime = date("Y-m-d H:i:s");
  208. //采购单状态变更
  209. $saleIds = OrderCgClearClass::getOrderIdsByClearId($clearId);
  210. foreach ($list as $purchase) {
  211. $purchase->debt = PurchaseClass::DEBT_NO;
  212. $purchase->payWay = $payWay;
  213. $purchase->clearId = $clearId;
  214. $purchase->remainDebtPrice = 0;
  215. $purchase->clearTime = $clearTime;
  216. $purchase->save();
  217. }
  218. //销售单状态变化
  219. if (!empty($saleIds)) {
  220. OrderClass::updateByIds($saleIds, ['debt' => OrderClass::DEBT_NO, 'clearId' => $clearId, 'remainDebtPrice' => 0, 'clearTime' => $clearTime]);
  221. }
  222. //客户付供货商款减少
  223. CustomClass::clearDebtAmountReduce($custom, $ghs, $order->actPrice, $order);
  224. OrderCgClearClass::markDoneByClearId($clearId);
  225. }
  226. }