PurchaseService.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. <?php
  2. namespace bizHd\purchase\services;
  3. use biz\ghs\classes\GhsClass;
  4. use biz\ghs\models\Ghs;
  5. use biz\shop\classes\ShopCapitalClass;
  6. use biz\shop\classes\ShopClass;
  7. use biz\shop\classes\ShopCouponClass;
  8. use biz\shop\models\Shop;
  9. use biz\stat\classes\StatCgClass;
  10. use biz\stat\classes\StatCgGhsClass;
  11. use biz\stat\classes\StatOutClass;
  12. use biz\wx\classes\WxMessageClass;
  13. use bizGhs\custom\classes\CustomClass;
  14. use bizGhs\order\classes\OrderClass;
  15. use bizGhs\order\services\OrderService;
  16. use bizGhs\product\classes\ProductClass;
  17. use bizGhs\stock\classes\StockRecordClass;
  18. use bizGhs\ws\services\WsService;
  19. use bizHd\admin\classes\ShopAdminClass;
  20. use bizHd\base\services\BaseService;
  21. use bizHd\purchase\classes\PurchaseClass;
  22. use bizHd\purchase\classes\PurchaseItemClass;
  23. use bizHd\shop\classes\MainClass;
  24. use common\components\dict;
  25. use common\components\imgUtil;
  26. use common\components\noticeUtil;
  27. use common\components\util;
  28. use Yii;
  29. class PurchaseService extends BaseService
  30. {
  31. public static $baseFile = '\bizHd\purchase\classes\PurchaseClass';
  32. public static function createPurchase($data, $ghs)
  33. {
  34. //零售采购单
  35. $respond = PurchaseClass::addPurchase($data, $ghs);
  36. //供货商销售单
  37. $ghsId = $data['ghsId'] ?? 0;
  38. $currentShopId = $ghs['shopId'] ?? 0;
  39. $currentSjId = $ghs['sjId'] ?? 0;
  40. $product = $data['product'] ?? [];
  41. $sendCost = $data['sendCost'] ?? 0;
  42. $customId = $ghs['customId'] ?? 0;
  43. $custom = CustomClass::getById($customId);
  44. if (empty($custom)) {
  45. util::fail('没有找到客户');
  46. }
  47. $customName = $custom['name'] ?? '';
  48. $customNamePy = $custom['py'] ?? '';
  49. $customMobile = $custom['mobile'] ?? '';
  50. $purchaseId = $respond->id ?? 0;
  51. $shopAdminId = $data['shopAdminId'] ?? 0;
  52. $shopAdminName = $data['shopAdminName'] ?? '';
  53. //客户采购时选了自取,则供货商的销售单就是自取
  54. $sendType = OrderClass::SEND_TYPE_UNKNOWN;
  55. $getType = $data['getType'] ?? PurchaseClass::GET_TYPE_SELF_GET;
  56. if ($getType == PurchaseClass::GET_TYPE_SELF_GET) {
  57. $sendType = OrderClass::SEND_TYPE_NO;
  58. }
  59. $couponId = $data['couponId'] ?? 0;
  60. $discountType = $respond->discountType ?? dict::getDict('discountType', 'noDiscount');
  61. $discountAmount = $respond->discountAmount ?? 0;
  62. $discount = $respond->discount ?? 0;
  63. $remark = $data['remark'] ?? '';
  64. $xj = $data['xj'] ?? '';
  65. $sendTimeWant = isset($data['sendTimeWant']) && !empty($data['sendTimeWant']) ? $data['sendTimeWant'] : date("Y-m-d");
  66. $orderType = 2;
  67. $book = $data['book'] ?? 0;
  68. $mainId = $custom['ownMainId'] ?? 0;
  69. $fromType = dict::getDict('fromType', 'mall');
  70. $arr = [
  71. 'mainId' => $mainId,
  72. 'book' => $book,
  73. 'product' => $product,
  74. 'sjId' => $currentSjId,
  75. 'shopId' => $currentShopId,
  76. 'sendCost' => $sendCost,
  77. 'customId' => $customId,
  78. 'customName' => $customName,
  79. 'customNamePy' => $customNamePy,
  80. 'customMobile' => $customMobile,
  81. 'province' => $custom['province'] ?? '',
  82. 'city' => $custom['city'] ?? '',
  83. 'dist' => $custom['dist'] ?? '',
  84. 'address' => $custom['address'] ?? '',
  85. 'floor' => $custom['floor'] ?? '',
  86. 'fullAddress' => $custom['fullAddress'] ?? '',
  87. 'showAddress' => $custom['showAddress'] ?? '',
  88. 'long' => $custom['long'] ?? '',
  89. 'lat' => $custom['lat'] ?? '',
  90. 'purchaseId' => $purchaseId,
  91. 'sendType' => $sendType,
  92. 'customShopAdminId' => $shopAdminId,
  93. 'customShopAdminName' => $shopAdminName,
  94. 'ghsId' => $ghsId,
  95. 'cgStyle' => dict::getDict('cgStyle', 'hd'),
  96. 'couponId' => $couponId,
  97. 'discountType' => $discountType,
  98. 'discountAmount' => $discountAmount,
  99. 'remark' => $remark,
  100. 'xj' => $xj,
  101. 'sendTimeWant' => $sendTimeWant,
  102. 'discount' => $discount,
  103. 'orderType' => $orderType,
  104. 'fromType' => $fromType,
  105. ];
  106. $result = OrderClass::addOrder($arr);
  107. $saleId = $result['id'] ?? 0;
  108. $respond->saleId = $saleId;
  109. $respond->save();
  110. return $respond;
  111. }
  112. //获取采购单信息 ssh 2021.1.24
  113. public static function getInfo($id, $showButton = false, $showProduct = false)
  114. {
  115. $purchase = PurchaseClass::getById($id, true);
  116. if (empty($purchase)) {
  117. util::fail('没有找到采购单');
  118. }
  119. $info = $purchase->attributes;
  120. $respond = PurchaseClass::groupPurchase([$info], $showButton, $showProduct);
  121. return current($respond);
  122. }
  123. //检查采购单
  124. public static function valid($info, $shopId)
  125. {
  126. if (empty($info)) {
  127. util::fail('没有找到采购单');
  128. }
  129. if (isset($info->shopId) && $info->shopId == $shopId) {
  130. return true;
  131. }
  132. util::fail('没有权限操作');
  133. }
  134. //采购记录 ssh 2021.1.24
  135. public static function getPurchaseList($where)
  136. {
  137. $data = PurchaseClass::getList('*', $where, 'addTime DESC');
  138. $data['list'] = self::groupInfo($data['list']);
  139. return $data;
  140. }
  141. //组合信息 ssh 2021.1.25
  142. public static function groupInfo($list)
  143. {
  144. if (empty($list)) {
  145. return $list;
  146. }
  147. foreach ($list as $key => $val) {
  148. $list[$key]['ghsAvatar'] = imgUtil::groupImg($val['ghsAvatar']);
  149. }
  150. return $list;
  151. }
  152. //所有的欠款采购单 ssh 2021.1.26
  153. public static function getDebtList($where)
  154. {
  155. $list = PurchaseClass::getAllList('*', $where, 'addTime DESC');
  156. $count = PurchaseClass::getCount($where);
  157. return ['list' => $list, 'debtNum' => $count];
  158. }
  159. //采购单失效 ssh 2021.5.14
  160. public static function expire($purchase)
  161. {
  162. if ($purchase->status != PurchaseClass::STATUS_UN_PAY) {
  163. util::fail('不是待付款订单哦');
  164. }
  165. //采购单失效
  166. $id = $purchase->id;
  167. $purchase = PurchaseClass::cancel($id);
  168. $saleId = $purchase->saleId;
  169. //销售单失效
  170. OrderClass::cancel($saleId);
  171. $couponId = $purchase->hbId;
  172. if (!empty($couponId)) {
  173. $coupon = ShopCouponClass::getLockById($couponId);
  174. ShopCouponClass::rollback($coupon);
  175. }
  176. return $purchase;
  177. }
  178. //订单延期支付 ssh 2021.1.24
  179. public static function debt($info)
  180. {
  181. $payWay = dict::getDict('payWay', 'debtPay');
  182. $saleId = $info->saleId ?? 0;
  183. $order = OrderClass::getById($saleId, true);
  184. //批发店开的单,客户付款了,不需要打印也不需要微信通知
  185. if ($info->cgStyle == dict::getDict('cgStyle', 'ghs')) {
  186. $order->needPrint = dict::getDict('needPrint', 'noNeed');
  187. $order->save();
  188. Yii::$app->params['noNeedWxNotice'] = 1;
  189. }
  190. self::payAfter($info, $payWay);
  191. OrderService::payAfter($order, $payWay, true);
  192. }
  193. //余额支付 ssh 2021.1.24
  194. public static function balancePay($info)
  195. {
  196. $payWay = dict::getDict('payWay', 'balancePay');
  197. self::payAfter($info, $payWay);
  198. $saleId = $info->saleId ?? 0;
  199. $order = OrderClass::getById($saleId, true);
  200. OrderService::payAfter($order, $payWay, true);
  201. }
  202. //付款码支付处理流程 ssh 20211231
  203. public static function codePay($payWay, $orderSn, $transactionId = '', $openId = '', $aliUserId = '')
  204. {
  205. //4秒内同个订单不允许重复请求
  206. $cacheKey = 'code_pay_f2f_' . $orderSn;
  207. $has = Yii::$app->redis->executeCommand('GET', [$cacheKey]);
  208. if (!empty($has)) {
  209. Yii::info("付款码支付,重复查询支付结果:orderSn:{$orderSn}");
  210. noticeUtil::push("付款码支付,重复查询支付结果:orderSn:{$orderSn}", '15280215347');
  211. util::fail('请稍等...');
  212. }
  213. Yii::$app->redis->executeCommand('SETEX', [$cacheKey, 4, 'has']);
  214. $info = self::getByCondition(['orderSn' => $orderSn], true);
  215. if (empty($info)) {
  216. $msg = "没有找到订单 orderSn:{$orderSn}";
  217. Yii::info($msg);
  218. util::fail($msg);
  219. }
  220. //解决并发问题
  221. $id = $info->id;
  222. $info = PurchaseClass::getLockById($id);
  223. $info->onlinePay = dict::getDict('onlinePay', 'yes');
  224. $info->codePay = 1;
  225. $info->thirdNo = $transactionId;
  226. $info->payOpenId = $openId;
  227. $info->aliUserId = $aliUserId;
  228. //自取订单
  229. $info->getType = PurchaseClass::GET_TYPE_SELF_GET;
  230. $info->save();
  231. self::payAfter($info, $payWay);
  232. $saleId = $info->saleId ?? 0;
  233. $order = OrderClass::getById($saleId, true);
  234. $order->onlinePay = dict::getDict('onlinePay', 'yes');
  235. $order->codePay = 1;
  236. //自取订单
  237. $order->sendType = OrderClass::SEND_TYPE_NO;
  238. //不需要小票
  239. $order->needPrint = dict::getDict('needPrint', 'noNeed');
  240. $order->save();
  241. OrderService::payAfter($order, $payWay, true);
  242. }
  243. //采购订单支付成功后回调处理流程
  244. public static function thirdPay($payWay, $orderSn, $totalFee, $attach, $transactionId = '')
  245. {
  246. $info = self::getByCondition(['orderSn' => $orderSn], true);
  247. if (empty($info)) {
  248. $msg = "没有找到订单 orderSn:{$orderSn}";
  249. Yii::info($msg);
  250. util::fail($msg);
  251. }
  252. if ($info->actPrice != $totalFee) {
  253. $msg = "订单金额与回调通知金额不一致 orderSn:{$orderSn} {$info->actPrice} {$totalFee}";
  254. Yii::info($msg);
  255. util::fail($msg);
  256. }
  257. //临时解决微信一秒内通知二次问题
  258. $id = $info->id;
  259. $info = PurchaseClass::getLockById($id);
  260. //由批发店发起的采购单,零售付款时不需要微信通知
  261. if ($info->cgStyle == dict::getDict('cgStyle', 'ghs')) {
  262. Yii::$app->params['noNeedWxNotice'] = 1;
  263. }
  264. $info->onlinePay = dict::getDict('onlinePay', 'yes');
  265. $info->thirdNo = $transactionId;
  266. $info->save();
  267. self::payAfter($info, $payWay);
  268. $saleId = $info->saleId ?? 0;
  269. $order = OrderClass::getById($saleId, true);
  270. $order->onlinePay = dict::getDict('onlinePay', 'yes');
  271. $order->save();
  272. OrderService::payAfter($order, $payWay, true);
  273. }
  274. //第三方支付、余额支付和欠款支付后调用的流程 ssh 2021.4.27
  275. public static function payAfter($info, $payWay)
  276. {
  277. if (empty($info)) {
  278. util::fail('没有找到订单');
  279. }
  280. $deadline = $info->deadline;
  281. $book = $info->book ?? 0;
  282. $current = date("Y-m-d H:i:s");
  283. if ($deadline <= $current) {
  284. Yii::info($deadline . ' ' . $current);
  285. util::fail('订单已失效..');
  286. }
  287. if (isset($info->status) == false || $info->status != PurchaseClass::STATUS_UN_PAY) {
  288. util::fail('订单不是待付款状态');
  289. }
  290. //零售采购单状态变化
  291. $info->payWay = $payWay;
  292. $info->status = $book == 1 ? PurchaseClass::STATUS_UN_SEND : PurchaseClass::STATUS_COMPLETE;
  293. $info->payStatus = 1;
  294. $info->payTime = date("Y-m-d H:i:s");
  295. if ($payWay == dict::getDict('payWay', 'debtPay')) {
  296. //欠款支付
  297. $info->debt = 1;
  298. $info->remainDebtPrice = $info->orderPrice ?? 0;
  299. $info->debtPrice = $info->orderPrice ?? 0;
  300. }
  301. $info->save();
  302. //零售门店资产变化
  303. $shopId = $info['shopId'] ?? 0;
  304. $shop = ShopClass::getLockById($shopId);
  305. if (empty($shop)) {
  306. util::fail('没有找到门店');
  307. }
  308. $mainId = $shop->mainId ?? 0;
  309. $main = MainClass::getLockById($mainId);
  310. if (empty($main)) {
  311. util::fail('没有main信息');
  312. }
  313. $realPrice = $info->realPrice;
  314. $actPrice = $info->actPrice;
  315. //余额支付引起余额减少
  316. if ($payWay == dict::getDict('payWay', 'balancePay')) {
  317. ShopClass::purchaseReduceBalance($main, $shop, $realPrice, $info);
  318. }
  319. $main->totalPurchase = bcadd($main->totalPurchase, $actPrice, 2);
  320. $currentExpend = bcadd($main->totalExpend, $actPrice, 2);
  321. $main->totalExpend = $currentExpend;
  322. $main->cgUnPay -= 1;
  323. if ($book == 1) {
  324. $main->cgUnSend += 1;
  325. } else {
  326. $main->cgFinish += 1;
  327. //加库存 lqh 2021-05-10
  328. $orderSn = $info->orderSn;
  329. $purchaseItem = PurchaseItemClass::getAllByCondition(['orderSn' => $orderSn], null, "*");
  330. foreach ($purchaseItem as $v) {
  331. $stockInfo = ProductClass::addStockByItemNum($v['productId'], $v['itemNum']);
  332. //记录库存流水
  333. $recordData = [];
  334. $recordData['sjId'] = $info->sjId;
  335. $recordData['shopId'] = $info->shopId;
  336. $recordData['mainId'] = $info->mainId;
  337. $recordData['itemId'] = $v['itemId'] ?? 0;
  338. $recordData['itemNum'] = $v['itemNum'];
  339. $recordData['oldStock'] = $stockInfo['oldStock'];
  340. $recordData['newStock'] = $stockInfo['newStock'];
  341. $recordData['productId'] = $v['productId'];
  342. $recordData['orderSn'] = $orderSn;
  343. $recordData['relateName'] = $info->ghsName ?? '';
  344. StockRecordClass::addPurchaseOrderRecord($recordData);
  345. }
  346. $info->stockChange = 1;
  347. $info->save();
  348. }
  349. if ($payWay == dict::getDict('payWay', 'debtPay')) {
  350. //应付供货商款增加
  351. $currentMayPay = bcadd($main->mayPay, $realPrice, 2);
  352. $main->mayPay = $currentMayPay;
  353. }
  354. $main->save();
  355. //支出统计
  356. StatOutClass::updateOrInsert($main, $shop, $info->orderPrice);
  357. //支出流水
  358. $capitalType = dict::getDict('capitalType', 'xhPurchase', 'id');
  359. $sjId = $info->sjId ?? 0;
  360. $shopId = $info->shopId ?? 0;
  361. $event = '采购';
  362. $capitalData = [
  363. 'capitalType' => $capitalType,
  364. 'io' => 0,
  365. 'totalExpend' => $currentExpend,
  366. 'payWay' => $payWay,
  367. 'amount' => $actPrice,
  368. 'sjId' => $sjId,
  369. 'shopId' => $shopId,
  370. 'event' => $event,
  371. 'mainId' => $mainId,
  372. ];
  373. ShopCapitalClass::addCapital($capitalData);
  374. //采购总量统计
  375. $cgNum = $info->bigNum ?? 0;
  376. StatCgClass::replace($main, $shop, $info->orderPrice, $cgNum);
  377. //按供货商分别统计采购量
  378. $num = $info->bigNum ?? 0;
  379. $amount = $info->orderPrice ?? 0;
  380. StatCgGhsClass::hdCgGhsReplace(true, $info, $amount, $num);
  381. //供货商资产变化
  382. $ghsId = $info->ghsId ?? 0;
  383. $ghs = GhsClass::getLockById($ghsId);
  384. if (empty($ghs)) {
  385. util::fail('没有找到供货商');
  386. }
  387. if ($payWay == dict::getDict('payWay', 'debtPay')) {
  388. \bizHd\ghs\classes\GhsClass::cgDebtAmountAdd($ghs, $info);
  389. }
  390. $ghs->expendAmount = bcadd($ghs->expendAmount, $actPrice, 2);
  391. $ghs->expendNum += 1;
  392. $ghs->save();
  393. //商家给开的采购单通知客户
  394. if (isset($info->ghsShopAdminId) && !empty($info->ghsShopAdminId)) {
  395. $noNeedWxNotice = isset(Yii::$app->params['noNeedWxNotice']) ? Yii::$app->params['noNeedWxNotice'] : 0;
  396. if ($noNeedWxNotice == 0) {
  397. WxMessageClass::generateCgOrder($shop, $info);
  398. }
  399. }
  400. }
  401. }