OrderService.php 40 KB

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