PurchaseService.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. <?php
  2. namespace bizHd\purchase\services;
  3. use biz\ghs\classes\GhsClass;
  4. use biz\shop\classes\ShopCapitalClass;
  5. use biz\shop\classes\ShopClass;
  6. use biz\shop\classes\ShopCouponClass;
  7. use biz\stat\classes\StatCgClass;
  8. use biz\stat\classes\StatCgGhsClass;
  9. use biz\stat\classes\StatOutClass;
  10. use bizGhs\custom\classes\AccountMoneyClass;
  11. use bizGhs\custom\classes\CustomClass;
  12. use bizGhs\custom\services\GhsRechargeSettleService;
  13. use bizGhs\order\classes\OrderClass;
  14. use bizGhs\order\services\OrderService;
  15. use bizHd\base\services\BaseService;
  16. use bizHd\cg\classes\CgRefundClass;
  17. use bizGhs\clear\classes\OrderCgClearClass;
  18. use bizHd\purchase\classes\PurchaseClass;
  19. use bizHd\purchase\classes\PurchaseItemClass;
  20. use bizHd\purchase\classes\PurchaseSnClass;
  21. use Yii;
  22. use bizHd\shop\classes\MainClass;
  23. use common\components\dict;
  24. use common\components\imgUtil;
  25. use common\components\noticeUtil;
  26. use common\components\util;
  27. class PurchaseService extends BaseService
  28. {
  29. public static $baseFile = '\bizHd\purchase\classes\PurchaseClass';
  30. public static function createPurchase($data, $ghs)
  31. {
  32. //零售采购单
  33. $respond = PurchaseClass::addPurchase($data, $ghs);
  34. //供货商销售单
  35. $ghsId = $data['ghsId'] ?? 0;
  36. $currentShopId = $ghs['shopId'] ?? 0;
  37. $currentSjId = $ghs['sjId'] ?? 0;
  38. $product = $data['product'] ?? [];
  39. $sendCost = $data['sendCost'] ?? 0;
  40. $packCost = $data['packCost'] ?? 0;
  41. $localOrder = $data['localOrder'] ?? 0;
  42. $customId = $ghs['customId'] ?? 0;
  43. $live = isset($ghs['live']) ? $ghs['live'] : 1;
  44. $custom = CustomClass::getById($customId);
  45. if (empty($custom)) {
  46. util::fail('没有找到客户');
  47. }
  48. //欠款超额,是否允许使用现金下单
  49. if ($custom['debtLimitPay'] == 1) {
  50. //欠款超额,不允许使用现金下单
  51. $debtLimit = $custom['debtLimit'] ?? 0;
  52. $debtAmount = $custom['debtAmount'] ?? 0;
  53. $actPrice = $respond->actPrice ?? 0;
  54. $finalDebtAmount = bcadd($debtAmount, $actPrice, 2);
  55. if ($finalDebtAmount > $debtLimit && $debtLimit > 0) {
  56. util::fail('请结清欠款再下单');
  57. }
  58. }
  59. $customName = $custom['name'] ?? '';
  60. $customNamePy = $custom['py'] ?? '';
  61. $customMobile = $custom['mobile'] ?? '';
  62. $purchaseId = $respond->id ?? 0;
  63. $shopAdminId = $data['shopAdminId'] ?? 0;
  64. $shopAdminName = $data['shopAdminName'] ?? '';
  65. $sendType = $data['sendType'] ?? 1;
  66. $transType = $data['transType'] ?? 0;
  67. $couponId = $data['couponId'] ?? 0;
  68. $wlName = $data['wlName'] ?? '';
  69. $discountType = $respond->discountType ?? dict::getDict('discountType', 'noDiscount');
  70. $discountAmount = $respond->discountAmount ?? 0;
  71. $discount = $respond->discount ?? 0;
  72. $remark = $data['remark'] ?? '';
  73. $xj = $data['xj'] ?? '';
  74. $sendTimeWant = isset($data['sendTimeWant']) && !empty($data['sendTimeWant']) ? $data['sendTimeWant'] : date("Y-m-d");
  75. $orderType = 2;
  76. $book = $data['book'] ?? 0;
  77. $preSell = $data['presell'] ?? 0;
  78. $sendDistance = $data['sendDistance'] ?? 0;
  79. $mainId = $custom['ownMainId'] ?? 0;
  80. $fromType = dict::getDict('fromType', 'mall');
  81. $arr = [
  82. 'mainId' => $mainId,
  83. 'book' => $book,
  84. 'product' => $product,
  85. 'sjId' => $currentSjId,
  86. 'shopId' => $currentShopId,
  87. 'sendCost' => $sendCost,
  88. 'packCost' => $packCost,
  89. 'customId' => $customId,
  90. 'customName' => $customName,
  91. 'customNamePy' => $customNamePy,
  92. 'customMobile' => $customMobile,
  93. 'province' => $custom['province'] ?? '',
  94. 'city' => $custom['city'] ?? '',
  95. 'dist' => $custom['dist'] ?? '',
  96. 'address' => $custom['address'] ?? '',
  97. 'floor' => $custom['floor'] ?? '',
  98. 'fullAddress' => $custom['fullAddress'] ?? '',
  99. 'showAddress' => $custom['showAddress'] ?? '',
  100. 'long' => $custom['long'] ?? '',
  101. 'lat' => $custom['lat'] ?? '',
  102. 'purchaseId' => $purchaseId,
  103. 'sendType' => $sendType,
  104. 'customShopAdminId' => $shopAdminId,
  105. 'customShopAdminName' => $shopAdminName,
  106. 'ghsId' => $ghsId,
  107. 'cgStyle' => dict::getDict('cgStyle', 'hd'),
  108. 'couponId' => $couponId,
  109. 'discountType' => $discountType,
  110. 'discountAmount' => $discountAmount,
  111. 'remark' => $remark,
  112. 'xj' => $xj,
  113. 'sendTimeWant' => $sendTimeWant,
  114. 'discount' => $discount,
  115. 'orderType' => $orderType,
  116. 'fromType' => $fromType,
  117. 'presell' => $preSell,
  118. 'wlName' => $wlName,
  119. 'live' => $live,
  120. 'localOrder' => $localOrder,
  121. 'transType' => $transType,
  122. 'sendDistance' => $sendDistance,
  123. ];
  124. $result = OrderClass::addOrder($arr, $custom);
  125. $respond->saleId = $result['id'];
  126. $respond->save();
  127. return $respond;
  128. }
  129. //获取采购单信息 ssh 2021.1.24
  130. public static function getInfo($id, $showButton = false, $showProduct = false)
  131. {
  132. $purchase = PurchaseClass::getById($id, true);
  133. if (empty($purchase)) {
  134. util::fail('没有找到采购单');
  135. }
  136. $info = $purchase->attributes;
  137. $respond = PurchaseClass::groupPurchase([$info], $showButton, $showProduct);
  138. $result = current($respond);
  139. $purchaseId = intval($result['id'] ?? 0);
  140. $saleId = intval($result['saleId'] ?? 0);
  141. $result['orderClearList'] = OrderCgClearClass::listPaidClearRecordsForPurchase($purchaseId, $saleId);
  142. return $result;
  143. }
  144. //检查采购单
  145. public static function valid($info, $shopId)
  146. {
  147. if (empty($info)) {
  148. util::fail('没有找到采购单');
  149. }
  150. if (isset($info->shopId) && $info->shopId == $shopId) {
  151. return true;
  152. }
  153. util::fail('无法操作');
  154. }
  155. //采购记录 ssh 2021.1.24
  156. public static function getPurchaseList($where)
  157. {
  158. $data = PurchaseClass::getList('*', $where, 'addTime DESC');
  159. $data['list'] = self::groupInfo($data['list']);
  160. return $data;
  161. }
  162. //组合信息 ssh 2021.1.25
  163. public static function groupInfo($list)
  164. {
  165. if (empty($list)) {
  166. return $list;
  167. }
  168. foreach ($list as $key => $val) {
  169. $list[$key]['ghsAvatar'] = imgUtil::groupImg($val['ghsAvatar']);
  170. }
  171. return $list;
  172. }
  173. //所有的欠款采购单 ssh 2021.1.26
  174. public static function getDebtList($where)
  175. {
  176. $get = Yii::$app->request->get();
  177. $allowedPageSizes = [100, 200, 300];
  178. $pageSize = isset($get['pageSize']) && in_array((int)$get['pageSize'], $allowedPageSizes, true)
  179. ? (int)$get['pageSize'] : 100;
  180. $page = max(1, (int)($get['page'] ?? 1));
  181. $list = PurchaseClass::getAllList('*', $where, 'addTime DESC');
  182. $synced = [];
  183. $clearedSum = '0.00';
  184. $remainSum = '0.00';
  185. foreach ($list as $val) {
  186. $row = is_array($val) ? $val : (array)$val;
  187. $row = self::syncPurchaseDebtFromGhsOrder($row);
  188. if (intval($row['debt'] ?? 0) != PurchaseClass::DEBT_YES) {
  189. continue;
  190. }
  191. $row = self::enrichPurchaseDebtRow($row);
  192. $synced[] = $row;
  193. $clearedSum = bcadd($clearedSum, (string)($row['hasPayDebt'] ?? 0), 2);
  194. $remainSum = bcadd($remainSum, (string)($row['remainDebtPrice'] ?? 0), 2);
  195. }
  196. $totalNum = count($synced);
  197. $totalPage = max(1, (int)ceil($totalNum / $pageSize));
  198. if ($page > $totalPage) {
  199. $page = $totalPage;
  200. }
  201. $offset = ($page - 1) * $pageSize;
  202. return [
  203. 'list' => array_slice($synced, $offset, $pageSize),
  204. 'debtNum' => $totalNum,
  205. 'totalNum' => $totalNum,
  206. 'totalPage' => $totalPage,
  207. 'moreData' => $page < $totalPage ? 1 : 0,
  208. 'clearedAmount' => floatval($clearedSum),
  209. 'remainDebtAmount' => floatval($remainSum),
  210. ];
  211. }
  212. /** 列表展示:与 ghs order/debt-list 一致,按 debtPrice - remainDebtPrice 算已清 */
  213. public static function enrichPurchaseDebtRow(array $row)
  214. {
  215. $debtPrice = bcadd((string)($row['debtPrice'] ?? '0'), '0', 2);
  216. $remain = bcadd((string)($row['remainDebtPrice'] ?? '0'), '0', 2);
  217. $hasPayDebt = '0.00';
  218. if (bccomp($debtPrice, $remain, 2) > 0) {
  219. $hasPayDebt = bcsub($debtPrice, $remain, 2);
  220. }
  221. $row['hasPayDebt'] = floatval($hasPayDebt);
  222. return $row;
  223. }
  224. /**
  225. * 充值销账后批发订单已更新,采购单可能滞后:按 saleId 对齐 remainDebtPrice / debt。
  226. */
  227. public static function syncPurchaseDebtFromGhsOrder(array $row)
  228. {
  229. $saleId = intval($row['saleId'] ?? 0);
  230. if ($saleId <= 0) {
  231. return $row;
  232. }
  233. $order = OrderClass::getById($saleId, true);
  234. if (empty($order)) {
  235. return $row;
  236. }
  237. $purchaseId = intval($row['id'] ?? 0);
  238. if ($purchaseId <= 0) {
  239. return $row;
  240. }
  241. $purchase = PurchaseClass::getById($purchaseId, true);
  242. if (empty($purchase)) {
  243. return $row;
  244. }
  245. $orderRemain = bcadd((string)($order->remainDebtPrice ?? '0'), '0', 2);
  246. $orderDebt = bcadd((string)($order->debtPrice ?? $order->orderPrice ?? '0'), '0', 2);
  247. $needSave = false;
  248. if (bccomp((string)($purchase->remainDebtPrice ?? '0'), $orderRemain, 2) !== 0) {
  249. $purchase->remainDebtPrice = bccomp($orderRemain, '0', 2) > 0 ? $orderRemain : '0.00';
  250. $needSave = true;
  251. }
  252. if (intval($order->debt ?? 0) === 0 && intval($purchase->debt) === PurchaseClass::DEBT_YES) {
  253. $purchase->debt = PurchaseClass::DEBT_NO;
  254. if (!empty($order->clearId)) {
  255. $purchase->clearId = $order->clearId;
  256. }
  257. $needSave = true;
  258. }
  259. if (bccomp((string)($purchase->debtPrice ?? '0'), '0', 2) <= 0 && bccomp($orderDebt, '0', 2) > 0) {
  260. $purchase->debtPrice = $orderDebt;
  261. $needSave = true;
  262. }
  263. if ($needSave) {
  264. $purchase->save(false);
  265. }
  266. $row['remainDebtPrice'] = $purchase->remainDebtPrice;
  267. $row['debtPrice'] = $purchase->debtPrice;
  268. $row['debt'] = $purchase->debt;
  269. return $row;
  270. }
  271. //采购单失效 ssh 2021.5.14
  272. public static function expire($purchase)
  273. {
  274. if ($purchase->status != PurchaseClass::STATUS_UN_PAY) {
  275. util::fail('不能取消');
  276. }
  277. //采购单失效
  278. $id = $purchase->id;
  279. $purchase = PurchaseClass::cancel($id);
  280. $saleId = $purchase->saleId;
  281. //销售单失效
  282. OrderClass::cancel($saleId);
  283. $couponId = $purchase->hbId;
  284. if (!empty($couponId)) {
  285. $coupon = ShopCouponClass::getLockById($couponId);
  286. ShopCouponClass::rollback($coupon);
  287. }
  288. // OrderClass::cancel($saleId) 中已经清理了
  289. //清空限购缓存
  290. // $order = OrderClass::getById($saleId, true);
  291. // if (!empty($order)) {
  292. // $customId = $order->customId ?? 0;
  293. // $orderSn = $order->orderSn;
  294. // if (!empty($customId)) {
  295. // $orderItemList = OrderItemClass::getOrderItem($orderSn);
  296. // if (!empty($orderItemList)) {
  297. // foreach ($orderItemList as $item) {
  298. // $productId = $item['productId'] ?? 0;
  299. // $num = floor($item['num'] ?? 0);
  300. // if (!empty($productId) && $num > 0) {
  301. // ProductClass::baseClearLimitBuy($productId, $customId, $num);
  302. // }
  303. // }
  304. // }
  305. // }
  306. // }
  307. return $purchase;
  308. }
  309. //订单延期支付 ssh 2021.1.24
  310. public static function debt($info)
  311. {
  312. $payWay = dict::getDict('payWay', 'debtPay');
  313. $saleId = $info->saleId ?? 0;
  314. $order = OrderClass::getById($saleId, true);
  315. //批发店开的单,客户付款了,不需要打印也不需要微信通知
  316. if ($info->cgStyle == dict::getDict('cgStyle', 'ghs')) {
  317. $order->needPrint = dict::getDict('needPrint', 'noNeed');
  318. $order->save();
  319. Yii::$app->params['noNeedWxNotice'] = 1;
  320. }
  321. // 成对账户预检:两个 payAfter 顺序不变,先确认 xhGhsCustom/xhGhs 净余额一致再动单
  322. $customId = intval($order->customId ?? 0);
  323. if ($customId > 0) {
  324. GhsRechargeSettleService::lockAccountPair(['id' => $customId]);
  325. }
  326. self::payAfter($info, $payWay);
  327. OrderService::payAfter($order, $payWay, true);
  328. }
  329. /**
  330. * 采购单余额支付(超管密码入口等)。
  331. * 批发-客户资金只在 xhGhs / xhGhsCustom,不扣 xhShop / xhMain.balance。
  332. */
  333. public static function balancePay($info)
  334. {
  335. $result = self::payByGhsCustomBalance($info);
  336. return $result['purchase'] ?? $info;
  337. }
  338. /**
  339. * 花店采购余额付:批发商-客户资金只在 xhGhs/xhGhsCustom,先销售单 payAfter 扣净余额,再采购单 payAfter 改状态。
  340. * xhShop/xhMain 仅为花店门店属性,不参与本关系余额扣减。须在事务内调用;并发由外层重试 + 行锁保证。
  341. */
  342. public static function payByGhsCustomBalance($purchase)
  343. {
  344. if (empty($purchase)) {
  345. util::fail('没有找到采购单');
  346. }
  347. if (intval($purchase->status ?? 0) == PurchaseClass::STATUS_CANCEL) {
  348. util::fail('订单已取消');
  349. }
  350. if (intval($purchase->status ?? 0) != PurchaseClass::STATUS_UN_PAY) {
  351. util::fail('订单不是待付款状态');
  352. }
  353. if (intval($purchase->payStatus ?? 0) === 1) {
  354. util::fail('订单已经付过款了');
  355. }
  356. $saleId = intval($purchase->saleId ?? 0);
  357. if ($saleId <= 0) {
  358. util::fail('订单无法余额支付');
  359. }
  360. $purchaseId = intval($purchase->id ?? 0);
  361. $purchase = PurchaseClass::getLockById($purchaseId);
  362. $order = OrderClass::getLockById($saleId);
  363. if (empty($order)) {
  364. util::fail('没有找到销售单');
  365. }
  366. if (intval($order->status ?? 0) != OrderClass::ORDER_STATUS_UN_PAY) {
  367. util::fail('重复操作');
  368. }
  369. $customId = intval($order->customId ?? 0);
  370. $pair = GhsRechargeSettleService::lockAccountPair(['id' => $customId]);
  371. $custom = $pair['custom'];
  372. if (empty($custom)) {
  373. util::fail('没有找到客户信息');
  374. }
  375. AccountMoneyClass::ensureCustomMoneyReady($custom, true);
  376. // 与待支付页 realPrice 一致,避免 actPrice 与 realPrice 不一致时误报余额不足
  377. $payAmount = bcadd((string)($purchase->realPrice ?? $order->realPrice ?? $order->actPrice ?? '0'), '0', 2);
  378. $beforeBalance = bcadd((string)($custom->balance ?? '0'), '0', 2);
  379. if (bccomp($beforeBalance, $payAmount, 2) < 0) {
  380. util::fail('余额不足');
  381. }
  382. $payWay = dict::getDict('payWay', 'balancePay');
  383. OrderService::payAfter($order, $payWay, false);
  384. $purchase = PurchaseClass::getLockById($purchaseId);
  385. $saleOrder = OrderClass::getById($saleId, true);
  386. if (!empty($purchase) && !empty($saleOrder) && intval($saleOrder->payStatus ?? 0) === 1) {
  387. $purchase->remainDebtPrice = $saleOrder->remainDebtPrice ?? '0.00';
  388. $purchase->debtPrice = $saleOrder->debtPrice ?? '0.00';
  389. $purchase->debt = ($saleOrder->debt ?? 0) == OrderClass::DEBT_YES
  390. ? PurchaseClass::DEBT_YES : PurchaseClass::DEBT_NO;
  391. $purchase->save(false, ['remainDebtPrice', 'debtPrice', 'debt']);
  392. }
  393. self::payAfter($purchase, $payWay);
  394. return [
  395. 'purchase' => $purchase,
  396. 'saleOrder' => OrderClass::getById($saleId, true),
  397. ];
  398. }
  399. //付款码支付处理流程 ssh 20211231
  400. public static function codePay($payWay, $orderSn, $transactionId = '', $openId = '', $aliUserId = '')
  401. {
  402. //4秒内同个订单不允许重复请求
  403. $cacheKey = 'code_pay_f2f_' . $orderSn;
  404. $has = Yii::$app->redis->executeCommand('GET', [$cacheKey]);
  405. if (!empty($has)) {
  406. Yii::info("付款码支付,重复查询支付结果:orderSn:{$orderSn}");
  407. noticeUtil::push("付款码支付,重复查询支付结果:orderSn:{$orderSn}", '15280215347');
  408. util::fail('请稍等...');
  409. }
  410. Yii::$app->redis->executeCommand('SETEX', [$cacheKey, 4, 'has']);
  411. $info = self::getByCondition(['orderSn' => $orderSn], true);
  412. if (empty($info)) {
  413. $msg = "没有找到订单 orderSn:{$orderSn}";
  414. Yii::info($msg);
  415. util::fail($msg);
  416. }
  417. //解决并发问题
  418. $id = $info->id;
  419. $info = PurchaseClass::getLockById($id);
  420. $info->onlinePay = dict::getDict('onlinePay', 'yes');
  421. $info->codePay = 1;
  422. $info->thirdNo = $transactionId;
  423. $info->payOpenId = $openId;
  424. $info->aliUserId = $aliUserId;
  425. //自取订单
  426. $info->getType = PurchaseClass::GET_TYPE_SELF_GET;
  427. $info->save();
  428. self::payAfter($info, $payWay);
  429. $saleId = $info->saleId ?? 0;
  430. $order = OrderClass::getById($saleId, true);
  431. $order->onlinePay = dict::getDict('onlinePay', 'yes');
  432. $order->codePay = 1;
  433. //自取订单
  434. $order->sendType = OrderClass::SEND_TYPE_NO;
  435. //不需要小票
  436. $order->needPrint = dict::getDict('needPrint', 'noNeed');
  437. $order->save();
  438. OrderService::payAfter($order, $payWay, true);
  439. }
  440. //采购订单支付成功后回调处理流程
  441. public static function thirdPay($payWay, $orderSn, $totalFee, $attach, $transactionId = '')
  442. {
  443. $info = self::getByCondition(['orderSn' => $orderSn], true);
  444. if (empty($info)) {
  445. $ghsName = '无供货商';
  446. preg_match('/\d+/', $orderSn, $m);
  447. if ($m[0]) {
  448. $cgSnId = $m[0];
  449. $snData = PurchaseSnClass::getById($cgSnId, true);
  450. $ghsId = $snData->ghsId ?? 0;
  451. if (!empty($ghsId)) {
  452. $ghs = \bizHd\ghs\classes\GhsClass::getById($ghsId, true);
  453. $ghsName = $ghs->name;
  454. }
  455. }
  456. noticeUtil::push('花店采购,付款成功,支付回调,单号:' . $orderSn . ',没有找到订单 ' . $ghsName . ',' . $attach, '15280215347');
  457. $msg = "没有找到订单 orderSn:{$orderSn}";
  458. util::fail($msg);
  459. }
  460. if ($info->actPrice != $totalFee) {
  461. noticeUtil::push("花店采购,付款成功,支付回调,单号:{$orderSn},订单金额与回调通知金额不一致{$info->actPrice} {$totalFee} {$attach}", '15280215347');
  462. $msg = "订单金额与回调通知金额不一致 orderSn:{$orderSn} {$info->actPrice} {$totalFee}";
  463. Yii::info($msg);
  464. util::fail($msg);
  465. }
  466. //临时解决微信一秒内通知二次问题
  467. $id = $info->id;
  468. $info = PurchaseClass::getLockById($id);
  469. //由批发店发起的采购单,零售付款时不需要微信通知
  470. if ($info->cgStyle == dict::getDict('cgStyle', 'ghs')) {
  471. Yii::$app->params['noNeedWxNotice'] = 1;
  472. }
  473. $info->onlinePay = dict::getDict('onlinePay', 'yes');
  474. $info->thirdNo = $transactionId;
  475. $info->save();
  476. self::payAfter($info, $payWay);
  477. $saleId = $info->saleId ?? 0;
  478. $order = OrderClass::getById($saleId, true);
  479. $order->onlinePay = dict::getDict('onlinePay', 'yes');
  480. $order->save();
  481. OrderService::payAfter($order, $payWay, true);
  482. }
  483. //第三方支付、余额支付和欠款支付后调用的流程 ssh 2021.4.27
  484. public static function payAfter($info, $payWay)
  485. {
  486. if (empty($info)) {
  487. util::fail('没有找到订单');
  488. }
  489. $deadline = $info->deadline;
  490. $book = $info->book ?? 0;
  491. $orderSn = $info->orderSn ?? '';
  492. $current = date("Y-m-d H:i:s");
  493. if (isset($info->status) == false) {
  494. noticeUtil::push('重点注意,采购单:' . $orderSn . ',客户付钱了但没有找到订单的状态', '15280215347');
  495. util::fail('没有找到订单状态');
  496. }
  497. if ($info->status == PurchaseClass::STATUS_CANCEL) {
  498. noticeUtil::push('注意花店采购单:' . $orderSn . ',客户付款了但订单已取消,关键词 cancel_get_money', '15280215347');
  499. $saleId = $info->saleId;
  500. $sale = OrderClass::getById($saleId, true);
  501. if (!empty($sale)) {
  502. $ghsShopId = $sale->shopId;
  503. $ghsShop = ShopClass::getById($ghsShopId, true);
  504. if (!empty($ghsShop)) {
  505. CgRefundClass::onlyRefundMoney($ghsShop, $info);
  506. }
  507. }
  508. util::stop("SUCCESS");
  509. }
  510. if (isset($info->payStatus) && $info->payStatus == 1) {
  511. util::fail('订单已经付过款了');
  512. }
  513. if ($deadline <= $current) {
  514. util::fail('订单已过期了哦');
  515. }
  516. //零售采购单状态变化
  517. $info->payWay = $payWay;
  518. $info->status = PurchaseClass::STATUS_UN_SEND;
  519. $info->payStatus = 1;
  520. $payTime = date("Y-m-d H:i:s");
  521. if (empty($info->payTime) || $info->payTime == '0000-00-00 00:00:00') {
  522. //如果外面没有设置支付时间,即账单时间,则赋值支付时间
  523. $info->payTime = $payTime;
  524. }
  525. if ($payWay == dict::getDict('payWay', 'debtPay')) {
  526. //欠款支付(批发开单若销售单已 payAfter,沿用其待结,支持开单余额抵挂账)
  527. $saleId = intval($info->saleId ?? 0);
  528. $saleOrder = $saleId > 0 ? \bizGhs\order\classes\OrderClass::getById($saleId, true) : null;
  529. if (!empty($saleOrder) && intval($saleOrder->payStatus ?? 0) === 1) {
  530. $info->debt = ($saleOrder->debt ?? 0) == 1 ? 1 : 0;
  531. $info->remainDebtPrice = $saleOrder->remainDebtPrice ?? 0;
  532. $info->debtPrice = $saleOrder->debtPrice ?? ($info->orderPrice ?? 0);
  533. } else {
  534. if (isset($info->actPrice) && $info->actPrice == 0) {
  535. $info->debt = 0;
  536. } else {
  537. $info->debt = 1;
  538. }
  539. $info->remainDebtPrice = $info->orderPrice ?? 0;
  540. $info->debtPrice = $info->orderPrice ?? 0;
  541. }
  542. }
  543. $info->save();
  544. $orderSn = $info->orderSn ?? '';
  545. PurchaseItemClass::updateByCondition(['orderSn' => $orderSn], ['payTime' => $payTime]);
  546. //零售门店资产变化
  547. $shopId = $info['shopId'] ?? 0;
  548. $shop = ShopClass::getLockById($shopId);
  549. if (empty($shop)) {
  550. util::fail('没有找到门店63');
  551. }
  552. $mainId = $shop->mainId ?? 0;
  553. $main = MainClass::getLockById($mainId);
  554. if (empty($main)) {
  555. util::fail('没有main信息16');
  556. }
  557. $realPrice = $info->realPrice;
  558. $actPrice = $info->actPrice;
  559. // 余额支付:批发商-客户资金在 xhGhs/xhGhsCustom(销售单 payAfter 扣款),不扣 xhMain.balance
  560. $main->totalPurchase = bcadd($main->totalPurchase, $actPrice, 2);
  561. $currentExpend = bcadd($main->totalExpend, $actPrice, 2);
  562. $main->totalExpend = $currentExpend;
  563. $main->cgUnPay -= 1;
  564. if ($book == 1) {
  565. $main->cgUnSend += 1;
  566. } else {
  567. $main->cgUnSend += 1;
  568. }
  569. if ($payWay == dict::getDict('payWay', 'debtPay')) {
  570. //应付供货商款增加
  571. $currentMayPay = bcadd($main->mayPay, $realPrice, 2);
  572. $main->mayPay = $currentMayPay;
  573. }
  574. $main->save();
  575. //支出统计
  576. StatOutClass::updateOrInsert($main, $shop, $info->orderPrice);
  577. //支出流水
  578. $capitalType = dict::getDict('capitalType', 'xhPurchase', 'id');
  579. $sjId = $info->sjId ?? 0;
  580. $shopId = $info->shopId ?? 0;
  581. $event = '采购';
  582. $capitalData = [
  583. 'capitalType' => $capitalType,
  584. 'io' => 0,
  585. 'totalExpend' => $currentExpend,
  586. 'payWay' => $payWay,
  587. 'amount' => $actPrice,
  588. 'sjId' => $sjId,
  589. 'shopId' => $shopId,
  590. 'event' => $event,
  591. 'mainId' => $mainId,
  592. ];
  593. ShopCapitalClass::addCapital($capitalData);
  594. //采购总量统计
  595. $cgNum = $info->bigNum ?? 0;
  596. StatCgClass::replace($main, $shop, $info->orderPrice, $cgNum);
  597. //按供货商分别统计采购量
  598. $num = $info->bigNum ?? 0;
  599. $amount = $info->orderPrice ?? 0;
  600. StatCgGhsClass::hdCgGhsReplace(true, $info, $amount, $num);
  601. //供货商资产变化
  602. $ghsId = $info->ghsId ?? 0;
  603. $ghs = GhsClass::getLockById($ghsId);
  604. if (empty($ghs)) {
  605. util::fail('没有找到供货商');
  606. }
  607. // 挂账净余额:有联动销售单时由 OrderService::payAfter 成对扣,hd 侧不再扣 xhGhs.balance(同余额支付)
  608. if ($payWay == dict::getDict('payWay', 'debtPay')) {
  609. $saleId = intval($info->saleId ?? 0);
  610. if ($saleId <= 0) {
  611. \bizHd\ghs\classes\GhsClass::cgDebtAmountAdd($ghs, $info);
  612. }
  613. }
  614. $ghs->expendAmount = bcadd($ghs->expendAmount, $actPrice, 2);
  615. $ghs->expendNum += 1;
  616. $ghs->save();
  617. PurchaseClass::updateMergeCg($info, 0);
  618. }
  619. }