OrderService.php 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. <?php
  2. namespace bizGhs\order\services;
  3. use biz\ghs\classes\GhsClass;
  4. use biz\shop\classes\ShopAdminClass;
  5. use biz\shop\classes\ShopCapitalClass;
  6. use biz\shop\classes\ShopClass;
  7. use biz\stat\classes\StatKdClass;
  8. use biz\stat\classes\StatKhCgClass;
  9. use biz\stat\classes\StatSaleClass;
  10. use biz\wx\classes\WxMessageClass;
  11. use bizGhs\base\services\BaseService;
  12. use bizGhs\book\classes\BookItemClass;
  13. use bizGhs\custom\classes\CustomClass;
  14. use bizGhs\custom\classes\CustomDebtChangeClass;
  15. use bizGhs\order\classes\OrderClass;
  16. use bizGhs\order\classes\OrderExpressClass;
  17. use bizGhs\order\classes\OrderItemClass;
  18. use bizGhs\order\classes\OrderSendClass;
  19. use bizGhs\product\classes\ProductClass;
  20. use bizGhs\shop\classes\MainClass;
  21. use bizGhs\shop\classes\ShopMoneyChangeClass;
  22. use bizGhs\shop\classes\ShopMoneyClass;
  23. use bizGhs\stat\classes\StatYjClass;
  24. use bizGhs\ws\services\WsService;
  25. use bizHd\cg\services\CgRefundService;
  26. use bizHd\purchase\services\PurchaseService;
  27. use bizHd\stat\classes\StatIncomeClass;
  28. use bizHd\stat\classes\StatOrderClass;
  29. use common\components\dict;
  30. use common\components\noticeUtil;
  31. use common\components\util;
  32. use bizHd\purchase\classes\PurchaseClass;
  33. use common\components\stringUtil;
  34. use Yii;
  35. class OrderService extends BaseService
  36. {
  37. public static $baseFile = '\bizGhs\order\classes\OrderClass';
  38. public static function arrival($order, $data)
  39. {
  40. $params = ['fhType' => 0, 'fhWl' => '', 'fhWlNo' => '',];
  41. OrderClass::orderSend($order, $params);
  42. //product [{"productId":"3674","num":0,"price":1}]
  43. $product = $data['product'] ?? '';
  44. if (empty($product)) {
  45. util::fail('请填写成本价和到货数量');
  46. }
  47. $product = json_decode($product, true);
  48. if (empty($product)) {
  49. util::fail('没有填写成本价和到货数量');
  50. }
  51. $data['product'] = $product;
  52. //供货商到货
  53. $respond = OrderClass::arrival($order, $data);
  54. $cgId = $order->purchaseId ?? 0;
  55. $cg = PurchaseClass::getById($cgId, true);
  56. if (empty($cg)) {
  57. util::fail('没有找到采购单');
  58. }
  59. //供货商花材转换为零售店花材
  60. $ids = array_column($product, 'productId');
  61. $ghsProductInfo = ProductClass::getByIds($ids);
  62. if (empty($ghsProductInfo)) {
  63. util::fail('没有花材??');
  64. }
  65. $ghsPtIdRelation = [];
  66. foreach ($ghsProductInfo as $ghsProduct) {
  67. $id = $ghsProduct['id'] ?? 0;
  68. $ptItemId = $ghsProduct['itemId'] ?? 0;
  69. $ghsPtIdRelation[$ptItemId] = $id;
  70. }
  71. $ptIds = array_keys($ghsPtIdRelation);
  72. $cgMainId = $cg->mainId ?? 0;
  73. $cgSjId = $cg->sjdId ?? 0;
  74. $cgShopId = $cg->shopId ?? 0;
  75. $cgItem = ProductClass::getAllByCondition(['mainId' => $cgMainId, 'itemId' => ['in', $ptIds]], null, '*');
  76. $ghsHdIdRelate = [];
  77. foreach ($cgItem as $it) {
  78. $ptItemId = $it['itemId'] ?? 0;
  79. $ghsItemId = $ghsPtIdRelation[$ptItemId] ?? 0;
  80. $cgItemId = $it['id'] ?? 0;
  81. $ghsHdIdRelate[$ghsItemId] = $cgItemId;
  82. }
  83. $cgProduct = [];
  84. foreach ($product as $pro) {
  85. $price = $pro['price'] ?? 0;
  86. $num = $pro['num'] ?? 0;
  87. $productId = $pro['productId'] ?? 0;
  88. $currentId = $ghsHdIdRelate[$productId] ?? 0;
  89. $cgProduct[$currentId] = ['num' => $num, 'price' => $price, 'productId' => $currentId];
  90. }
  91. //零售到货
  92. $saleRefund = $respond['refund'] ?? null;
  93. $saleRefundId = 0;
  94. if (!empty($saleRefund)) {
  95. $saleRefundId = $saleRefund->id ?? 0;
  96. }
  97. $kiloFee = $respond['kiloFee'] ?? 0;
  98. $miniKilo = $respond['miniKilo'] ?? 0;
  99. $saleRefundId = $saleRefundId;
  100. $sendCost = isset($data['sendCost']) && is_numeric($data['sendCost']) ? $data['sendCost'] : 0;
  101. $packCost = isset($data['packCost']) && is_numeric($data['packCost']) ? $data['packCost'] : 0;
  102. $cgData = [
  103. 'product' => $cgProduct,
  104. 'kiloFee' => $kiloFee,
  105. 'miniKilo' => $miniKilo,
  106. 'saleRefundId' => $saleRefundId,
  107. 'sjId' => $cgSjId,
  108. 'shopId' => $cgShopId,
  109. 'mainId' => $cgMainId,
  110. 'sendCost' => $sendCost,
  111. 'packCost' => $packCost,
  112. ];
  113. $result = PurchaseClass::arrival($cg, $cgData);
  114. $cgRefund = $result['refund'] ?? null;
  115. if (!empty($cgRefund)) {
  116. $cgRefundId = $cgRefund->id ?? 0;
  117. if (!empty($saleRefund)) {
  118. $saleRefund->cgRefundId = $cgRefundId;
  119. $saleRefund->save();
  120. }
  121. }
  122. //不是预订单,并且供货商不是源花汇、小明鲜花、淄博花超、云漫梦金鹏、海翔,则订单直接完成掉。是预订单,则确认发货时直接完成掉。有多个地方要修改,请搜索关键词zjFinish
  123. if (!empty($cg) && !empty($order)) {
  124. $ghsShopId = $order->shopId ?? 0;
  125. if (getenv('YII_ENV') == 'production') {
  126. $specialList = [10649, 8042, 16454, 21319, 33668, 42345];
  127. } else {
  128. $specialList = [36523];
  129. }
  130. if (!in_array($ghsShopId, $specialList)) {
  131. $newCg = PurchaseClass::getById($cgId, true);
  132. PurchaseClass::confirmTake($newCg);
  133. }
  134. }
  135. }
  136. //添加订单
  137. public static function createNewOrder($data, $custom, $hasPay = 1)
  138. {
  139. //有unitType数据,说明是收银台传过来的数据,转换成和手机端结构一致
  140. $hasUnitType = array_column($data['product'], 'unitType');
  141. if (!empty($hasUnitType)) {
  142. $newProductData = [];
  143. foreach ($data['product'] as $productItem) {
  144. $unitType = $productItem['unitType'] ?? 0;
  145. $num = $productItem['num'] ?? 0;
  146. $productId = $productItem['productId'] ?? 0;
  147. $classId = $productItem['classId'] ?? 0;
  148. $itemId = $productItem['itemId'] ?? 0;
  149. $price = $productItem['price'] ?? 0;
  150. if ($unitType == 0) {
  151. $bigNum = $num;
  152. $smallNum = '';
  153. } else {
  154. $bigNum = '';
  155. $smallNum = $num;
  156. }
  157. $newProductData[] = [
  158. 'productId' => (int)$productId,
  159. 'bigNum' => (int)$bigNum,
  160. 'smallNum' => (int)$smallNum,
  161. 'classId' => (int)$classId,
  162. 'itemId' => (int)$itemId,
  163. 'price' => floatval($price),
  164. ];
  165. }
  166. $data['product'] = $newProductData;
  167. }
  168. //供货商销售单
  169. $returnOrder = OrderClass::addOrder($data);
  170. $saleId = $returnOrder->id ?? 0;
  171. $customSjId = $custom['sjId'] ?? 0;
  172. $customShopId = $custom['shopId'] ?? 0;
  173. $localOrder = $data['localOrder'] ?? 0;
  174. $transType = $data['transType'] ?? 0;
  175. $ghsShopAdminId = $data['shopAdminId'] ?? 0;
  176. $ghsShopAdminName = $data['shopAdminName'] ?? '';
  177. $customId = $data['customId'] ?? 0;
  178. $ghsId = $data['ghsId'] ?? 0;
  179. $ghs = GhsClass::getById($ghsId);
  180. if (empty($ghs)) {
  181. util::fail('没有找到供货商');
  182. }
  183. $ghsName = $ghs['name'] ?? '';
  184. $ghsAvatar = $ghs['avatar'] ?? '';
  185. $ghsMobile = $ghs['mobile'] ?? '';
  186. $ghsFullAddress = $ghs['fullAddress'] ?? '';
  187. $payWay = $data['payWay'] ?? dict::getDict('payWay', 'wxPay');
  188. //销售单欠款字段与采购单欠款字段转换
  189. $debt = $data['debt'] ?? 0;
  190. $purchaseDebt = $debt == 1 ? PurchaseClass::DEBT_YES : PurchaseClass::DEBT_NO;
  191. if ($debt == 1) {
  192. $payWay = dict::getDict('payWay', 'debtPay');
  193. }
  194. //销售单的自取还是配送字段 与 采购单的转换
  195. $sendType = $data['sendType'] ?? OrderClass::SEND_TYPE_CAR_GET;
  196. $getType = $sendType == OrderClass::SEND_TYPE_THIRD_SEND ? PurchaseClass::GET_TYPE_SEND : PurchaseClass::GET_TYPE_SELF_GET;
  197. //零售采购单时没有传price字段,供货商可以改价会传price字段,这里转成userPrice以便采购单识别使用改的价还是花材原价!
  198. $currentProduct = $data['product'];
  199. foreach ($currentProduct as $currentKey => $currentItem) {
  200. if (isset($currentProduct[$currentKey]['price'])) {
  201. $currentProduct[$currentKey]['userPrice'] = $currentProduct[$currentKey]['price'];
  202. unset($currentProduct[$currentKey]['price']);
  203. }
  204. }
  205. $sendTimeWant = isset($data['sendTimeWant']) && !empty($data['sendTimeWant']) ? $data['sendTimeWant'] : date("Y-m-d");
  206. $remark = $data['remark'] ?? '';
  207. $xj = $data['xj'] ?? '';
  208. $book = $data['book'] ?? 0;
  209. $wlName = $data['wlName'] ?? '';
  210. $cgMainId = $ghs['ownMainId'] ?? 0;
  211. $purchaseData = [
  212. 'book' => $book,
  213. 'product' => $currentProduct,
  214. 'sendTimeWant' => $sendTimeWant,
  215. 'sendCost' => $data['sendCost'] ?? '0',
  216. 'packCost' => $data['packCost'] ?? '0',
  217. 'ghsShopAdminId' => $ghsShopAdminId,
  218. 'ghsShopAdminName' => $ghsShopAdminName,
  219. 'sjId' => $customSjId,
  220. 'shopId' => $customShopId,
  221. 'saleId' => $saleId,
  222. 'ghsId' => $ghsId,
  223. 'ghsName' => $ghsName,
  224. 'ghsMobile' => $ghsMobile,
  225. 'ghsFullAddress' => $ghsFullAddress,
  226. 'ghsAvatar' => $ghsAvatar,
  227. 'customId' => $customId,
  228. 'payWay' => $payWay,
  229. 'status' => PurchaseClass::STATUS_UN_PAY,
  230. 'cgStyle' => dict::getDict('cgStyle', 'ghs'),
  231. 'debt' => $purchaseDebt,
  232. 'getType' => $getType,
  233. 'sendType' => $sendType,
  234. 'remark' => $remark,
  235. 'xj' => $xj,
  236. 'discount' => 1,
  237. 'mainId' => $cgMainId,
  238. 'wlName' => $wlName,
  239. 'localOrder' => $localOrder,
  240. 'transType' => $transType,
  241. ];
  242. if (isset($data['deadline']) && !empty($data['deadline'])) {
  243. $purchaseData['deadline'] = $data['deadline'];
  244. }
  245. if (isset($data['modifyPrice']) && is_numeric($data['modifyPrice'])) {
  246. $purchaseData['modifyPrice'] = $data['modifyPrice'];
  247. }
  248. $purchase = PurchaseClass::addPurchase($purchaseData, $ghs);
  249. $purchaseId = $purchase->id ?? 0;
  250. $returnOrder->purchaseId = $purchaseId;
  251. $returnOrder->save();
  252. //欠款和已付款的走付款后流程
  253. if (in_array($hasPay, [dict::getDict('hasPay', 'payed'), dict::getDict('hasPay', 'debt')])) {
  254. if ($hasPay == dict::getDict('hasPay', 'debt')) {
  255. $shopId = $data['shopId'] ?? 0;
  256. $shop = ShopClass::getById($shopId, true);
  257. if (empty($shop)) {
  258. util::fail('没有门店信息');
  259. }
  260. //老商家允许设置overAllowDebt,新商家已经不允许设置,默认就是 1,不能超过已经设置的授信额度
  261. if (isset($shop->overAllowDebt) && $shop->overAllowDebt == 0) {
  262. $debtLimit = $custom['debtLimit'] ?? 0;
  263. $debtLimit = floatval($debtLimit);
  264. $debtAmount = $custom['debtAmount'] ?? 0;
  265. $currentPrice = $returnOrder->actPrice ?? 0;
  266. $newDebt = bcadd($currentPrice, $debtAmount, 2);
  267. if ($newDebt > $debtLimit) {
  268. util::fail('欠款已超' . $debtLimit . ',请先清账');
  269. }
  270. }
  271. }
  272. //下面二个顺序不能换
  273. PurchaseService::payAfter($purchase, $payWay);
  274. self::payAfter($returnOrder, $payWay);
  275. //开历史订单
  276. $historyDate = $data['historyDate'] ?? '';
  277. if (!empty($historyDate)) {
  278. $currentPayTime = $historyDate . ' 12:00:00';
  279. $purchase->payTime = $currentPayTime;
  280. $purchase->save();
  281. $returnOrder->payTime = $currentPayTime;
  282. $returnOrder->save();
  283. //有修改账单日期需要更新到欠款变动明细,财务好对账,多个地方要同步修改,关键词to_change_custom_debt_pay_time
  284. CustomDebtChangeClass::updateByCondition(['capitalType' => 10, 'relateId' => $returnOrder->id], ['payTime' => $currentPayTime]);
  285. }
  286. //不是预订单,并且供货商不是源花汇、小明鲜花、淄博花超、云漫梦金鹏、海翔,则订单直接完成掉。是预订单,则确认发货时直接完成掉。有多个地方要修改,请搜索关键词zjFinish
  287. if (isset($returnOrder->book) && $returnOrder->book == 0) {
  288. $ghsShopId = $ghs['shopId'] ?? 0;
  289. if (getenv('YII_ENV') == 'production') {
  290. $specialList = [10649, 8042, 16454, 21319, 33668,42345];
  291. } else {
  292. $specialList = [36523];
  293. }
  294. if (!in_array($ghsShopId, $specialList)) {
  295. $returnId = $returnOrder->id;
  296. $order = OrderClass::getById($returnId, true);
  297. if (!empty($order)) {
  298. OrderClass::confirmReach($order);
  299. }
  300. }
  301. }
  302. }
  303. return $returnOrder;
  304. }
  305. //修改订单
  306. public static function updateOrder($order, $data)
  307. {
  308. $purchaseId = $order->purchaseId ?? 0;
  309. $purchase = PurchaseClass::getLockById($purchaseId);
  310. //修改供货商销售单
  311. $returnOrder = OrderClass::updateOrder($order, $data);
  312. //供货商销售单的 0未欠款 1欠款 转成零售采购单的 1欠款 2未欠款
  313. $debt = $data['debt'] ?? 0;
  314. $purchaseDebt = $debt == 1 ? PurchaseClass::DEBT_YES : PurchaseClass::DEBT_NO;
  315. $payWay = $data['payWay'] ?? dict::getDict('payWay', 'wxPay');
  316. if ($debt == 1) {
  317. $payWay = dict::getDict('payWay', 'debtPay');
  318. }
  319. //自取还是配送订单,销售单与采购单之间转换
  320. $sendType = $data['sendType'] ?? OrderClass::SEND_TYPE_MYSELF;
  321. $getType = $sendType == OrderClass::SEND_TYPE_NO ? PurchaseClass::GET_TYPE_SELF_GET : PurchaseClass::GET_TYPE_SEND;
  322. //供货商价格是可以修改的,修改的价格一起传给采购单保存
  323. $currentProduct = $data['product'];
  324. foreach ($currentProduct as $currentKey => $currentItem) {
  325. if (isset($currentProduct[$currentKey]['price'])) {
  326. $currentProduct[$currentKey]['userPrice'] = $currentProduct[$currentKey]['price'];
  327. unset($currentProduct[$currentKey]['price']);
  328. }
  329. }
  330. $remark = $data['remark'] ?? '';
  331. $purchaseData = [
  332. 'product' => $currentProduct,
  333. 'sendTime' => date("H:i:s"),
  334. 'sendCost' => $data['sendCost'] ?: '0.00',
  335. 'payWay' => $payWay,
  336. 'status' => PurchaseClass::STATUS_UN_PAY,
  337. 'cgStyle' => dict::getDict('cgStyle', 'ghs'),
  338. 'debt' => $purchaseDebt,
  339. 'getType' => $getType,
  340. 'status' => PurchaseClass::STATUS_UN_PAY,
  341. 'remark' => $remark,
  342. ];
  343. if (isset($data['deadline']) && !empty($data['deadline'])) {
  344. $purchaseData['deadline'] = $data['deadline'];
  345. }
  346. if (isset($data['modifyPrice']) && is_numeric($data['modifyPrice'])) {
  347. //优惠之后的金额
  348. if (is_numeric($data['modifyPrice']) == false || $data['modifyPrice'] <= 0) {
  349. util::fail('金额填错了哦');
  350. }
  351. $purchaseData['modifyPrice'] = $data['modifyPrice'];
  352. }
  353. //修改采购单
  354. $purchase = PurchaseClass::updatePurchase($purchase, $purchaseData);
  355. //除了自取订单直接变成已确认,其它都进入待确认流程。订单的确认以欠款或已收款方式确认。 ssh 20210809
  356. if (isset($data['sendType']) && $data['sendType'] == OrderClass::SEND_TYPE_NO) {
  357. PurchaseService::payAfter($purchase, $payWay);
  358. self::payAfter($returnOrder, $payWay);
  359. } else {
  360. //没有进入确认流程的订单也有打印需求
  361. if ($data['needPrint'] == dict::getDict('needPrint', 'need')) {
  362. OrderClass::onlinePrint($returnOrder);
  363. $returnOrder->printNum += 1;
  364. $returnOrder->save();
  365. }
  366. }
  367. return $returnOrder;
  368. }
  369. //自取免配送流程处理 ssh 2021.1.24
  370. public static function withoutSend($order)
  371. {
  372. if (isset($order->status) == false) {
  373. util::fail('没有订单状态');
  374. }
  375. if ($order->status == OrderClass::ORDER_STATUS_COMPLETE) {
  376. util::fail('订单已完成');
  377. }
  378. //自取订单,订单直接完成。【现在有三个地方有订单完成操作】
  379. $shopId = $order->shopId ?? 0;
  380. $shop = ShopClass::getLockById($shopId);
  381. if (empty($shop)) {
  382. util::fail('没有找到门店3');
  383. }
  384. $shop->unSendOrder -= 1;
  385. $shop->sendingOrder += 1;
  386. $shop->save();
  387. //自取免配送
  388. $order->sendType = OrderClass::SEND_TYPE_NO;
  389. $order->save();
  390. //这个是采购模板的withoutSend,应另外封装方法
  391. $purchaseId = $order->purchaseId ?? 0;
  392. $purchase = PurchaseClass::getById($purchaseId, true);
  393. $pShopId = $purchase->shopId;
  394. $pShop = ShopClass::getLockById($pShopId);
  395. $pShop->cgUnSend -= 1;
  396. $pShop->cgSending += 1;
  397. $pShop->save();
  398. //订单完成
  399. self::finish($order, $shop);
  400. OrderSendClass::withoutSend($order);
  401. return OrderClass::TOTAL_FLOW;
  402. }
  403. //确认送达 ssh 2021.3.4
  404. public static function reach($order)
  405. {
  406. if ($order->status != OrderClass::ORDER_STATUS_SENDING) {
  407. util::fail('订单没有在配送状态');
  408. }
  409. //第三方配送的变更第三方订单状态
  410. if (isset($order->sendType) && $order->sendType == OrderClass::SEND_TYPE_THIRD) {
  411. $express = OrderExpressClass::getByCondition(['orderSn' => $order->orderSn], true);
  412. if (!empty($express)) {
  413. $express->status = OrderExpressClass::STATUS_COMPLETE;
  414. $express->save();
  415. }
  416. }
  417. $shopId = $order->shopId ?? 0;
  418. $shop = ShopClass::getLockById($shopId);
  419. if (empty($shop)) {
  420. util::fail('没有找到门店4');
  421. }
  422. //订单完成
  423. self::finish($order, $shop);
  424. OrderSendClass::reach($order);
  425. //是否微信通知
  426. $noNeedWxNotice = isset(Yii::$app->params['noNeedWxNotice']) ? Yii::$app->params['noNeedWxNotice'] : 0;
  427. if ($noNeedWxNotice == 0) {
  428. //微信通知
  429. WxMessageClass::reachInform($shop, $order);
  430. }
  431. }
  432. //订单完成
  433. public static function finish($order, $shop)
  434. {
  435. //销售单完成
  436. $order = OrderClass::complete($order, $shop);
  437. //采购单完成
  438. $purchaseId = $order->purchaseId ?? 0;
  439. $purchase = PurchaseClass::getById($purchaseId, true);
  440. PurchaseClass::complete($purchase);
  441. }
  442. //获取订单信息 ssh 2019.11.28
  443. public static function getOrderList($where)
  444. {
  445. $data = self::getList('*', $where, 'addTime DESC');
  446. if (isset($data['list']) == false || empty($data['list'])) {
  447. return $data;
  448. }
  449. $orderSns = array_column($data['list'], 'orderSn');
  450. //获取订单的商品信息
  451. $goodsList = OrderGoodsService::getGoodsListByOrderSns($orderSns);
  452. //获取订花人的用户信息
  453. $orderUserIds = array_column($data['list'], 'userId');
  454. $orderUserIds = array_unique($orderUserIds);
  455. $userInfoList = UserService::getUserByIds($orderUserIds);
  456. $sjIdList = array_column($data['list'], 'sjId');
  457. $sjIdList = array_filter(array_unique($sjIdList));
  458. $merchantList = MerchantService::getByIds($sjIdList, null, 'id');
  459. $periodData = [0 => '上午', 1 => '下午', 2 => '晚上'];
  460. foreach ($data['list'] as $key => $val) {
  461. $id = $val['id'];
  462. $userId = $val['userId'];
  463. $data['list'][$key]['goodsInfoList'] = isset($goodsList[$id]) ? $goodsList[$id] : [];
  464. $data['list'][$key]['bookAvatar'] = isset($userInfoList[$userId]['smallAvatarUrl']) ? $userInfoList[$userId]['smallAvatarUrl'] : '';
  465. $sjId = $val['sjId'];
  466. $data['list'][$key]['name'] = isset($merchantList[$sjId]['name']) ? $merchantList[$sjId]['name'] : '';
  467. $data['list'][$key]['reachTime'] = OrderClass::getReachTime($val);
  468. $requireReachTime = '';
  469. if ($val['reachDate'] != '0000-00-00') {
  470. $reachPeriodId = $val['reachPeriod'];
  471. $reachPeriod = isset($periodData[$reachPeriodId]) ? $periodData[$reachPeriodId] : '上午';
  472. $requireReachTime = date("m-d", strtotime($val['reachDate'])) . ' ' . $reachPeriod;
  473. }
  474. $data['list'][$key]['requireReachTime'] = $requireReachTime;
  475. }
  476. return $data;
  477. }
  478. //取客户最近若干条订单 ssh 2019.11.30
  479. public static function getUserOrder($userId, $limit = 10, $order = null, $with = null)
  480. {
  481. $where = ['userId' => $userId, 'payStatus' => 1];
  482. return self::getLimitList('*', $where, $limit, $order, $with);
  483. }
  484. //支付前验证订单 ssh 2019.12.6
  485. public static function checkBeforePay($order, $userId)
  486. {
  487. $now = time();
  488. if (empty($order)) {
  489. util::fail('订单无效');
  490. }
  491. if (isset($order['userId']) && $order['userId'] != $userId) {
  492. util::fail('非法访问');
  493. }
  494. if ($order['status'] != 0) {
  495. util::fail('订单不是待付款状态');
  496. }
  497. if (isset($order['deadline']) && $now > $order['deadline']) {
  498. util::fail('订单已过期');
  499. }
  500. if (ceil($order['actPrice']) <= 0) {
  501. util::fail('订单金额有问题');
  502. }
  503. if ($order['payStatus'] == 1) {
  504. util::fail('您已经付过了');
  505. }
  506. }
  507. //商家验证是否有效 ssh 2019.12.15
  508. public static function valid($order, $shopId)
  509. {
  510. $now = date("Y-m-d H:i:s");
  511. if (empty($order)) {
  512. util::fail('订单无效');
  513. }
  514. if ($order['shopId'] != $shopId) {
  515. util::fail('不是您的订单');
  516. }
  517. if (isset($order['status']) && $order['status'] == OrderClass::ORDER_STATUS_UN_PAY) {
  518. if (isset($order['deadline']) && $now > $order['deadline']) {
  519. util::fail('订单已过期');
  520. }
  521. }
  522. }
  523. //点评 ssh 2019.12.16
  524. public static function comment($data)
  525. {
  526. return OrderClass::comment($data);
  527. }
  528. //订单归类
  529. public static function classify($id, $categoryId, $usageId)
  530. {
  531. $connection = Yii::$app->db;
  532. $transaction = $connection->beginTransaction();
  533. try {
  534. $order = OrderClass::getById($id, true);
  535. if ($order->payStatus != 1) {
  536. util::fail('订单还未付款');
  537. }
  538. if ($order->classify == 1) {
  539. util::fail('已经归类过了');
  540. }
  541. $order->categoryId = $categoryId;
  542. $order->usageId = $usageId;
  543. $order->classify = 1;
  544. $order->save();
  545. //设置流水的分类和用途并分配资金
  546. $setData = [
  547. 'sjId' => $order->sjId,
  548. 'capitalId' => $order->capitalId,
  549. 'time' => $order->payTime,
  550. 'usageId' => $order->usageId,
  551. 'categoryId' => $order->categoryId,
  552. 'amount' => $order->actPrice,
  553. 'payWay' => $order->payWay,
  554. ];
  555. SjCapitalService::orderClassify($setData);
  556. $transaction->commit();
  557. } catch (Exception $e) {
  558. $transaction->rollBack();
  559. util::fail('没有归类成功');
  560. }
  561. }
  562. //更新配送单 ssh 2019.12.17
  563. public static function updateSheet($order, $data)
  564. {
  565. $id = $order['id'];
  566. if ($order['status'] != OrderClass::ORDER_STATUS_UN_SEND) {
  567. util::fail('订单当前不是待配送状态');
  568. }
  569. $data['deliver'] = 1;
  570. OrderClass::updateById($id, $data);
  571. }
  572. //订单详情 ssh 2020.1.2
  573. public static function getOrderById($id)
  574. {
  575. return OrderClass::getOrderById($id);
  576. }
  577. //查看订单详情 ssh 2020.1.4
  578. public static function getOrderBySn($orderSn)
  579. {
  580. return OrderClass::getOrderBySn($orderSn);
  581. }
  582. //计算优惠 ssh 2020.3.9
  583. public static function getDiscountPrice($params)
  584. {
  585. $couponId = isset($params['couponId']) ? $params['couponId'] : 0;
  586. $userId = isset($params['userId']) ? $params['userId'] : 0;
  587. $price = isset($params['price']) ? $params['price'] : 0;
  588. $sourceType = isset($params['sourceType']) ? $params['sourceType'] : 0;
  589. $discountAmount = 0;
  590. $discountType = 0;
  591. $discountPrice = $price;
  592. //使用优惠券
  593. if (!empty($couponId)) {
  594. $discountAmount = CouponService::checkBeforeUse($couponId, $price, $userId);
  595. $discountPrice = stringUtil::calcSub($price, $discountAmount);
  596. $discountType = 1;
  597. } else {
  598. //使用会员
  599. // $asset = UserAssetClass::getByUserId($userId);
  600. // if (isset($asset['member']) && $asset['member'] > 0) {
  601. // $currentDiscount = $asset['discount'];
  602. // $currentPrice = $price * $currentDiscount;
  603. // $newPrice = substr(sprintf("%.3f", $currentPrice), 0, -1);
  604. // $discountType = 2;
  605. // $discountAmount = stringUtil::calcSub($price, $newPrice);
  606. // $discountPrice = $newPrice;
  607. // }
  608. }
  609. //如果没有优惠券和会员优惠,并且是朋友圈收款,则进行随机优惠 ssh 2019.9.12
  610. if ($discountPrice == $price && $sourceType == 3) {
  611. $discountAmount = OrderClass::getRandDiscount($price);
  612. //开发和测试环境直接随机优惠
  613. $env = getenv('YII_ENV');
  614. if ($env == 'local' || $env == 'test') {
  615. $discountAmount = 0.01;
  616. }
  617. $discountPrice = stringUtil::calcSub($price, $discountAmount);
  618. $discountType = 3;
  619. }
  620. $discountType = $discountAmount <= 0 ? 0 : $discountType;
  621. $discountPrice = $discountPrice <= 0 ? 0.01 : $discountPrice;
  622. return ['price' => $discountPrice, 'discountType' => $discountType, 'discountAmount' => $discountAmount];
  623. }
  624. //获取订单详情 ssh 2021.1.21
  625. public static function getOrderInfo($id, $showButton = false, $showItem = false, $showExpress = false, $isList = false)
  626. {
  627. $order = OrderClass::getById($id, true);
  628. if (empty($order)) {
  629. util::fail('没有找到订单');
  630. }
  631. $info = $order->attributes;
  632. $respond = OrderClass::groupOrder([$info], $showButton, $showItem, $showExpress, $isList);
  633. return current($respond);
  634. }
  635. //订单失效后的操作 ssh 2021.5.14
  636. public static function expire($order)
  637. {
  638. $purchaseId = $order->purchaseId ?? 0;
  639. $current = PurchaseClass::getById($purchaseId, true);
  640. if (empty($current)) {
  641. util::fail('没有找到采购单');
  642. }
  643. PurchaseService::expire($current);
  644. return true;
  645. }
  646. //支付成功后的流程 ssh 2021.5.14
  647. //$isPurchase 是否零售端采购支付,如果是会引起销售方余额变动
  648. public static function payAfter($order, $payWay, $isPurchase = false)
  649. {
  650. if (isset($order->status) == false) {
  651. util::fail('没有订单状态');
  652. }
  653. if ($order->status != OrderClass::ORDER_STATUS_UN_PAY) {
  654. util::fail('重复操作');
  655. }
  656. if (isset($order->debt) == false) {
  657. util::fail('订单有问题,没有欠款项');
  658. }
  659. $orderId = $order->id;
  660. $orderSn = $order->orderSn ?? '';
  661. $customId = $order->customId;
  662. $custom = CustomClass::getLockById($customId);
  663. if (empty($custom)) {
  664. util::fail('没有找到客户信息');
  665. }
  666. //门店资产变化
  667. $amount = $order->actPrice ?? 0.00;
  668. $realPrice = $order->realPrice ?? 0.00;
  669. $currentShopId = $order->shopId ?? 0;
  670. $book = $order->book ?? 0;
  671. $shop = ShopClass::getLockById($currentShopId);
  672. if (empty($shop)) {
  673. util::fail('没有找到门店5');
  674. }
  675. $mainId = $shop->mainId ?? 0;
  676. $main = MainClass::getLockById($mainId);
  677. if (empty($main)) {
  678. util::fail('没有main信息3');
  679. }
  680. $main->unPayOrder -= 1;
  681. //预订单的待发货订单增加
  682. if ($book == 1) {
  683. $main->unSendOrder += 1;
  684. //预订单统计数量增加
  685. $itemList = OrderItemClass::getAllByCondition(['orderSn' => $orderSn], null, '*', null, true);
  686. if (!empty($itemList)) {
  687. $bookData = [];
  688. foreach ($itemList as $currentItem) {
  689. $itemRemark = $currentItem->remark ?? 0;
  690. $hasRemark = !empty($itemRemark) ? 1 : 0;
  691. $bookData[] = [
  692. 'productId' => $currentItem->productId,
  693. 'num' => $currentItem->xhNum ?? 0,
  694. 'lastNum' => $currentItem->xhNum ?? 0,
  695. 'remark' => $itemRemark,
  696. 'hasRemark' => $hasRemark,
  697. ];
  698. }
  699. $staffId = $order->shopAdminId ?? 0;
  700. $staffName = $order->shopAdminName ?? '';
  701. $params = [
  702. 'staffId' => $staffId, 'staffName' => $staffName, 'action' => 'add'
  703. ];
  704. BookItemClass::addBatchItem($bookData, $order, $params);
  705. }
  706. } else {
  707. $main->finishOrder += 1;
  708. }
  709. $main->totalOrderNum += 1;
  710. $currentTotalIncome = bcadd($main->totalIncome, $amount, 2);
  711. $main->totalIncome = $currentTotalIncome;
  712. $totalSale = bcadd($main->totalSale, $amount, 2);
  713. $main->totalSale = $totalSale;
  714. if ($payWay == dict::getDict('payWay', 'debtPay')) {
  715. $currentGathering = bcadd($main->mayGathering, $realPrice, 2);
  716. $main->mayGathering = $currentGathering;
  717. if ($custom->debtNum == 0) {
  718. $main->mayGatheringNum += 1;
  719. }
  720. }
  721. $main->save();
  722. $capitalType = dict::getDict('capitalType', 'xhGhsOrder', 'id');
  723. $shopAdminId = $order->shopAdminId ?? 0;
  724. $shopAdminName = $order->shopAdminName ?? '';
  725. $event = '下单';
  726. if ($isPurchase) {
  727. $event = '客户采购';
  728. if (isset($custom->name) && !empty($custom->name)) {
  729. $event = $custom->name . '采购';
  730. }
  731. }
  732. $sjId = $order->sjId ?? 0;
  733. $shopId = $order->shopId ?? 0;
  734. $capital = [
  735. 'capitalType' => $capitalType,
  736. 'relateId' => $orderId,
  737. 'io' => 1,
  738. 'amount' => $amount,
  739. 'totalIncome' => $currentTotalIncome,
  740. 'payWay' => $payWay,
  741. 'event' => $event,
  742. 'mainId' => $mainId,
  743. 'sjId' => $sjId,
  744. 'shopId' => $shopId,
  745. 'shopAdminId' => $shopAdminId,
  746. 'shopAdminName' => $shopAdminName,
  747. 'mainId' => $mainId,
  748. ];
  749. ShopCapitalClass::addCapital($capital);
  750. //客户采购,会增加余额,会增加收入
  751. if ($isPurchase == true) {
  752. //余额支付和在线支付(微信支付、支付宝支付)会增加余额
  753. if ($order->onlinePay == dict::getDict('onlinePay', 'yes') || $payWay == dict::getDict('payWay', 'balancePay')) {
  754. ShopClass::customKdAddBalance($main, $shop, $realPrice, $order, $capitalType);
  755. }
  756. }
  757. //现金付款,现金余额需要增加
  758. if ($payWay == dict::getDict('payWay', 'cash')) {
  759. $moneyBalance = bcadd($main->money, $realPrice, 2);
  760. $main->money = $moneyBalance;
  761. $main->save();
  762. $moneyEvent = $custom->name . "现金下单" . floatval($realPrice) . "元(单号 {$orderSn})";
  763. $moneyRemark = '';
  764. $change = [
  765. 'relateId' => $orderId,
  766. 'amount' => $realPrice,
  767. 'balance' => $moneyBalance,
  768. 'io' => 1,
  769. 'mainId' => $mainId,
  770. 'capitalType' => $capitalType,
  771. 'ptStyle' => dict::getDict('ptStyle', 'ghs'),
  772. 'event' => $moneyEvent,
  773. 'remark' => $moneyRemark,
  774. ];
  775. ShopMoneyChangeClass::addData($change);
  776. }
  777. //更新订单基础状态和支付状态
  778. $order->payWay = $payWay;
  779. if ($book == 1) {
  780. $order->status = OrderClass::ORDER_STATUS_UN_SEND;
  781. } else {
  782. $order->status = OrderClass::ORDER_STATUS_UN_SEND;
  783. }
  784. if ($payWay == dict::getDict('payWay', 'debtPay')) {
  785. if (isset($order->actPrice) && $order->actPrice == 0) {
  786. $order->debt = OrderClass::DEBT_NO;
  787. } else {
  788. $order->debt = OrderClass::DEBT_YES;
  789. }
  790. $order->remainDebtPrice = $order->orderPrice ?? 0;
  791. $order->debtPrice = $order->orderPrice ?? 0;
  792. }
  793. $order->payStatus = 1;
  794. $order->payTime = date("Y-m-d H:i:s");
  795. $order->save();
  796. //新订单进入队列,用于花材的销量统计
  797. OrderClass::newOrderAddQueue($order);
  798. //员工业绩、总业绩增加
  799. $shopAdminId = $order->shopAdminId ?? 0;
  800. if (!empty($shopAdminId)) {
  801. $shopAdmin = ShopAdminClass::getById($shopAdminId, true);
  802. $shopAdmin->kdAmount = bcadd($shopAdmin->kdAmount, $amount, 2);
  803. $shopAdmin->save();
  804. $yjAmount = $order->orderPrice ?? 0;
  805. StatYjClass::addYj($main, $shop, $shopAdminId, $yjAmount);
  806. }
  807. //欠款
  808. if ($payWay == dict::getDict('payWay', 'debtPay')) {
  809. CustomClass::cgDebtAmountAdd($custom, $order);
  810. }
  811. $custom->buyNum += 1;
  812. $custom->buyAmount = bcadd($custom->buyAmount, $amount, 2);
  813. $custom->visitTime = date("Y-m-d H:i:s");
  814. $custom->save();
  815. //收入统计
  816. StatIncomeClass::updateOrInsert($main, $shop, $amount);
  817. //各渠道收入金额统计
  818. StatKdClass::replace($shop, $amount, $payWay);
  819. //今日订单+1
  820. StatOrderClass::updateOrInsert($main, $shop);
  821. //销售统计
  822. StatSaleClass::replace($main, $shop, $amount);
  823. //客户采购统计
  824. StatKhCgClass::replace($order, $amount);
  825. //当天同个人同地址的订单汇总
  826. $sameDate = date("Y_m_d");
  827. $sameAddress = $order->showAddress ?? '';
  828. $addressMd5 = md5($sameAddress);
  829. $sameKey = $customId . '_' . $addressMd5 . '_' . $sameDate;
  830. $sameString = Yii::$app->redis->executeCommand('GET', [$sameKey]);
  831. if (!empty($sameString)) {
  832. $newString = $sameString . ',' . $orderId;
  833. $newIdsArray = explode(',', $newString);
  834. if (count($newIdsArray) <= 90) {
  835. Yii::$app->redis->executeCommand('SETEX', [$sameKey, 186400, $newString]);
  836. foreach ($newIdsArray as $currentOrderId) {
  837. OrderClass::updateById($currentOrderId, ['sameTimeIds' => $newString]);
  838. }
  839. //noticeUtil::push($sameKey . '' . $sameAddress . " 当天汇总ids:" . $newString, '15280215347');
  840. }
  841. } else {
  842. Yii::$app->redis->executeCommand('SETEX', [$sameKey, 186400, $orderId]);
  843. $order->sameTimeIds = $orderId;
  844. $order->save();
  845. //noticeUtil::push($sameKey . '' . $sameAddress . " 当天汇总ids:" . $orderId, '15280215347');
  846. }
  847. }
  848. //发起退款
  849. public static function refund($id, $post)
  850. {
  851. $order = OrderClass::getLockById($id);
  852. if (empty($order)) {
  853. util::fail('没有找到订单');
  854. }
  855. if (isset($order->clearId) && !empty($order->clearId)) {
  856. util::fail('已经结账,不能再售后');
  857. }
  858. if ($order->debt != 1 && $order->addTime < '2023-10-17 00:00:00') {
  859. util::fail('10月17日前订单无法申请退款');
  860. }
  861. //供货商销售单退款
  862. $saleRefund = RefundOrderService::addRefund($post, $order);
  863. $saleRefundId = $saleRefund->id;
  864. $purchaseId = $order->purchaseId;
  865. $cg = PurchaseClass::getLockById($purchaseId);
  866. if (empty($cg)) {
  867. util::fail('没有找到采购订单');
  868. }
  869. $mainId = $cg->mainId ?? 0;
  870. //花材列表结构
  871. // [{productId:0,num:1,unitType:0,unitPrice:12,unitName:'扎'}] productId 花材id num 退货数 unitType 大小单位0大1小 unitPrice 售价 unitName单位名称
  872. //供货商的花材信息转换成零售店的花材信息
  873. $ghsProduct = $post['product'] ?? '';
  874. $ghsProductIndex = array_column($ghsProduct, null, 'productId');
  875. $ids = array_column($ghsProduct, 'productId');
  876. $ghsProductInfo = ProductClass::getByIds($ids, null, 'itemId');
  877. $ptItemIds = array_keys($ghsProductInfo);
  878. $ptItemIds = array_unique(array_filter($ptItemIds));
  879. $hdProductInfo = ProductClass::getAllByCondition(['mainId' => $mainId, 'itemId' => ['in', $ptItemIds]], null, '*', 'itemId');
  880. $newProduct = [];
  881. foreach ($hdProductInfo as $ptItemId => $hdInfo) {
  882. $ghsItemId = $ghsProductInfo[$ptItemId]['id'] ?? 0;
  883. $current = $ghsProductIndex[$ghsItemId] ?? [];
  884. $hdItemId = $hdInfo['id'] ?? 0;
  885. $cost = $hdInfo['cost'] ?? 0;
  886. $name = $hdInfo['name'] ?? '';
  887. $cover = $hdInfo['cover'] ?? '';
  888. $ratio = $hdInfo['ratio'] ?? 20;
  889. if (empty($current)) {
  890. util::fail('没有找到花材');
  891. }
  892. $current['productId'] = $hdItemId;
  893. $current['ptItemId'] = $ptItemId;
  894. $current['cost'] = $cost;
  895. $current['name'] = $name;
  896. $current['cover'] = $cover;
  897. $current['ratio'] = $ratio;
  898. $newProduct[] = $current;
  899. }
  900. $refundType = $post['refundType'] ?? 0;
  901. $price = $post['price'] ?? 0;
  902. $remark = $post['remark'] ?? '';
  903. $cause = $post['cause'] ?? 0;
  904. $refundSendCost = isset($post['refundSendCost']) && is_numeric($post['refundSendCost']) ? $post['refundSendCost'] : 0;
  905. $refundPackCost = isset($post['refundPackCost']) && is_numeric($post['refundPackCost']) ? $post['refundPackCost'] : 0;
  906. $cgData = [
  907. 'product' => $newProduct,
  908. 'refundType' => $refundType,
  909. 'price' => $price,
  910. 'remark' => $remark,
  911. 'cause' => $cause,
  912. 'refundSendCost' => $refundSendCost,
  913. 'refundPackCost' => $refundPackCost,
  914. ];
  915. $cgRefund = CgRefundService::addRefund($cgData, $cg);
  916. $cgRefundId = $cgRefund->id;
  917. $saleRefund->cgRefundId = $cgRefundId;
  918. $saleRefund->save();
  919. $cgRefund->saleRefundId = $saleRefundId;
  920. $cgRefund->save();
  921. return $saleRefund;
  922. }
  923. }