Trade.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: shenyang
  5. * Date: 2018/11/13
  6. * Time: 5:07 PM
  7. */
  8. namespace app\common\modules\trade\models;
  9. use app\common\events\order\AfterTradeCreatedEvent;
  10. use app\common\events\order\AfterTradeCreatingEvent;
  11. use app\common\models\BaseModel;
  12. use app\common\models\DispatchType;
  13. use app\common\models\order\OrderDeliver;
  14. use app\common\models\order\OrderMergeCreate;
  15. use app\common\modules\memberCart\MemberCartCollection;
  16. use app\common\modules\order\OrderCollection;
  17. use app\framework\Http\Request;
  18. use app\frontend\models\Member;
  19. use app\frontend\modules\order\models\PreOrder;
  20. use Illuminate\Support\Facades\DB;
  21. use Yunshop\PackageDelivery\models\DeliveryOrder;
  22. use Yunshop\StoreCashier\common\models\SelfDelivery;
  23. /**
  24. * Class Trade
  25. * @package app\common\modules\trade\models
  26. * @property OrderCollection orders
  27. * @property TradeDiscount discount
  28. * @property float total_deduction_price
  29. * @property float total_discount_price
  30. * @property float total_dispatch_price
  31. * @property float total_goods_price
  32. * @property float total_price
  33. */
  34. class Trade extends BaseModel
  35. {
  36. /**
  37. * @var MemberCartCollection
  38. */
  39. private $memberCartCollection;
  40. /**
  41. * @var Member
  42. */
  43. private $member;
  44. /**
  45. * @var Request
  46. */
  47. private $request;
  48. public function init(MemberCartCollection $memberCartCollection, $member = null, $request = null)
  49. {
  50. $this->request = $request ?: request();
  51. $this->memberCartCollection = $memberCartCollection;
  52. $this->member = $member;
  53. event(new AfterTradeCreatingEvent($this));
  54. $this->setRelation('orders', $this->getOrderCollection($memberCartCollection, $member, $this->request));
  55. $this->setRelation('discount', $this->getDiscount());
  56. $this->setRelation('dispatch', $this->getDispatch());
  57. $this->last_deliver_user_info = $this->getLastDeliverUserInfo();
  58. $this->amount_items = $this->getAmountItems();
  59. $this->discount_amount_items = $this->getDiscountAmountItems();
  60. $this->fee_items = $this->getFeeItems();
  61. $this->service_fee_items = $this->getServiceFeeItems();
  62. $this->tax_fee_items = $this->getTaxFeeItems();
  63. $this->total_price = $this->orders->sum('price');
  64. $this->is_diy_form_jump = \Setting::get('shop.order.is_diy_form_jump') ?: 0;
  65. $member = Member::current();
  66. $this->balance =$member->credit2 ? : 0;
  67. event(new AfterTradeCreatedEvent($this));
  68. }
  69. /**
  70. * 获取最后一次自提填写的信息
  71. * @return array
  72. */
  73. protected function getLastDeliverUserInfo()
  74. {
  75. $uid = \YunShop::app()->getMemberId();
  76. $dispatch_type_id = $this->request->dispatch_type_id;
  77. switch ($dispatch_type_id) {
  78. case DispatchType::PACKAGE_DELIVER :
  79. return $this->packageDeliverUserInfo($uid);
  80. case DispatchType::PACKAGE_DELIVERY:
  81. return $this->shopDeliverUserInfo($uid);
  82. default :
  83. return $this->storeDeliverUserInfo($uid);
  84. }
  85. }
  86. /**
  87. * 商城自提
  88. * @param $uid
  89. * @return array|null
  90. */
  91. private function shopDeliverUserInfo($uid)
  92. {
  93. $setting = \Setting::get('plugin.package_delivery');
  94. if ($setting['open_state']) {
  95. $delivery_order = DeliveryOrder::where('uid', $uid)
  96. ->orderBy('id', 'desc')
  97. ->first(['buyer_name', 'buyer_mobile']);
  98. if($delivery_order){
  99. return [
  100. "realname" => $delivery_order->buyer_name,
  101. "mobile" => $delivery_order->buyer_mobile,
  102. ];
  103. }
  104. }
  105. return null;
  106. }
  107. /**
  108. * 门店自提点用户最后的信息
  109. * @param $uid
  110. * @return array|null
  111. */
  112. private function storeDeliverUserInfo($uid)
  113. {
  114. $is_enabled = app('plugins')->isEnabled("store-cashier");
  115. //开启插件
  116. if ($is_enabled) {
  117. $order_deliver = SelfDelivery::where("uid", $uid)->orderBy('id', 'desc')->first(['member_mobile', 'member_realname']);
  118. if ($order_deliver) {
  119. return [
  120. "realname" => $order_deliver->member_realname,
  121. "mobile" => $order_deliver->member_mobile,
  122. ];
  123. }
  124. }
  125. return null;
  126. }
  127. /**
  128. * 自提点插件用户最后的信息
  129. * @param $uid
  130. * @return array|null
  131. */
  132. private function packageDeliverUserInfo($uid)
  133. {
  134. $is_enabled = app('plugins')->isEnabled("package-deliver");
  135. if ($is_enabled) {
  136. $order_deliver = OrderDeliver::where('uid', $uid)->orderBy('id', 'desc')->first(['order_id']);
  137. if ($order_deliver) {
  138. return [
  139. "realname" => $order_deliver->hasOneOrderAddress->realname,
  140. "mobile" => $order_deliver->hasOneOrderAddress->mobile,
  141. ];
  142. }
  143. }
  144. return null;
  145. }
  146. public function getMemberCartCollection()
  147. {
  148. return $this->memberCartCollection;
  149. }
  150. public function getServiceFeeItems()
  151. {
  152. // 按照code合并
  153. $orderFeesItems = [];
  154. foreach ($this->orders as $order) {
  155. foreach ($order->orderServiceFees as $orderServiceFee) {
  156. if ($orderServiceFee->checked) {
  157. if (isset($orderFeesItems[$orderServiceFee['code']])) {
  158. $orderFeesItems[$orderServiceFee['code']]['amount'] += $orderServiceFee['amount'];
  159. } else {
  160. $orderFeesItems[$orderServiceFee['code']] = [
  161. 'code' => $orderServiceFee['code'],
  162. 'name' => $orderServiceFee['name'],
  163. 'amount' => $orderServiceFee['amount'],
  164. ];
  165. }
  166. }
  167. }
  168. }
  169. return array_values($orderFeesItems);
  170. }
  171. public function getTaxFeeItems()
  172. {
  173. // 按照code合并
  174. $orderTaxFeesItems = [];
  175. foreach ($this->orders as $order) {
  176. foreach ($order->orderTaxFees as $orderTaxFee) {
  177. if ($orderTaxFee->checked) {
  178. if (isset($orderTaxFeesItems[$orderTaxFee['code']])) {
  179. $orderTaxFeesItems[$orderTaxFee['code']]['amount'] += $orderTaxFee['amount'];
  180. } else {
  181. $orderTaxFeesItems[$orderTaxFee['code']] = [
  182. 'code' => $orderTaxFee['code'],
  183. 'name' => $orderTaxFee['name'],
  184. 'amount' => $orderTaxFee['amount'],
  185. ];
  186. }
  187. }
  188. }
  189. }
  190. return array_values($orderTaxFeesItems);
  191. }
  192. public function getFeeItems()
  193. {
  194. // 按照code合并
  195. $orderFeesItems = [];
  196. foreach ($this->orders as $order) {
  197. foreach ($order->orderFees as $orderFee) {
  198. if (isset($orderFeesItems[$orderFee['fee_code']])) {
  199. $orderFeesItems[$orderFee['fee_code']]['amount'] += $orderFee['amount'];
  200. } else {
  201. $orderFeesItems[$orderFee['fee_code']] = [
  202. 'code' => $orderFee['fee_code'],
  203. 'name' => $orderFee['name'],
  204. 'amount' => $orderFee['amount'],
  205. ];
  206. }
  207. }
  208. }
  209. foreach ($orderFeesItems as &$item) {
  210. $item['amount'] = sprintf('%.2f', $item['amount']);
  211. }
  212. return array_values($orderFeesItems);
  213. }
  214. private function getAmountItems()
  215. {
  216. $items = [
  217. [
  218. 'code' => 'total_goods_price',
  219. 'name' => '订单总金额',
  220. 'amount' => $this->orders->sum('order_goods_price'),
  221. ], [
  222. 'code' => 'total_dispatch_price',
  223. 'name' => '总运费',
  224. 'amount' => $this->orders->sum('dispatch_price'),
  225. ]
  226. ];
  227. if ($this->orders->sum('deduction_price')) {
  228. $items[] = [
  229. 'code' => 'total_deduction_price',
  230. 'name' => '总' . $this->deductionLang(),
  231. 'amount' => $this->orders->sum('deduction_price'),
  232. ];
  233. }
  234. return $items;
  235. }
  236. private function getCoinExchanges()
  237. {
  238. $point = 0;
  239. $this->orders->map(function($order) use (&$point) {
  240. $order->orderCoinExchanges->map(function($coinExchange) use (&$point) {
  241. if (in_array($coinExchange->code,['point'])) {
  242. $point += $coinExchange->coin;
  243. }
  244. });
  245. });
  246. if (!$point) {
  247. return 0;
  248. }
  249. $this->orders->map(function($order) use (&$point) {
  250. $order->orderDeductions->map(function($deduction) use (&$point) {
  251. if (in_array($deduction->code,['point']) && $deduction->checked) {
  252. $point += $deduction->coin;
  253. }
  254. });
  255. });
  256. return $point;
  257. }
  258. private function coinExchangeLang()
  259. {
  260. $point_name = \Setting::get('shop.shop')['credit1'] ?: '积分';
  261. return $point_name;
  262. }
  263. private function deductionLang()
  264. {
  265. $langSetting = \Setting::get('shop.lang');
  266. return $langSetting[$langSetting['lang']]['order']['deduction_lang'] ?: "抵扣";
  267. }
  268. /**
  269. * @return mixed
  270. */
  271. private function getDiscountAmountItems()
  272. {
  273. // 按照code合并
  274. $orderDiscountsItems = [];
  275. foreach ($this->orders as $order) {
  276. foreach ($order->orderDiscounts as $orderDiscount) {
  277. if (isset($orderDiscountsItems[$orderDiscount['discount_code']])) {
  278. $orderDiscountsItems[$orderDiscount['discount_code']]['amount'] += $orderDiscount['amount'];
  279. } else {
  280. if ($orderDiscount['amount'] > 0 && !in_array($orderDiscount['discount_code'],['coinExchange'])) {
  281. $orderDiscountsItems[$orderDiscount['discount_code']] = [
  282. 'code' => $orderDiscount['discount_code'],
  283. 'name' => $orderDiscount['name'],
  284. 'amount' => $orderDiscount['amount'],
  285. 'no_show' => $orderDiscount['no_show'],
  286. ];
  287. }
  288. }
  289. }
  290. }
  291. foreach ($orderDiscountsItems as &$item) {
  292. $item['amount'] = sprintf('%.2f', $item['amount']);
  293. }
  294. if ($point = $this->getCoinExchanges()) {
  295. $orderDiscountsItems[] = [
  296. 'code' => 'pointCoinExchanges',
  297. 'name' => '总' . $this->coinExchangeLang(),
  298. 'amount' => $point,
  299. 'no_show' => 0,
  300. ];
  301. }
  302. return array_values($orderDiscountsItems);
  303. }
  304. /**
  305. * 显示订单数据
  306. * @return array
  307. */
  308. public function toArray()
  309. {
  310. $attributes = parent::toArray();
  311. $attributes = $this->formatAmountAttributes($attributes);
  312. return $attributes;
  313. }
  314. private function getOrderCollection(MemberCartCollection $memberCartCollection, $member = null, $request = null)
  315. {
  316. // 按插件分组
  317. $groups = $memberCartCollection->groupByGroupId()->values();
  318. // 分组下单
  319. $orderCollection = $groups->map(function (MemberCartCollection $memberCartCollection) use ($member, $request) {
  320. return $memberCartCollection->getOrder($memberCartCollection->getPlugin(), $member, $request);
  321. });
  322. return app('OrderManager')->make(OrderCollection::class,$orderCollection->all());
  323. }
  324. /**
  325. * @return TradeDiscount
  326. */
  327. private function getDiscount()
  328. {
  329. $tradeDiscount = new TradeDiscount();
  330. $tradeDiscount->init($this);
  331. return $tradeDiscount;
  332. }
  333. private function getDispatch()
  334. {
  335. $tradeDispatch = new TradeDispatch();
  336. $tradeDispatch->init($this);
  337. return $tradeDispatch;
  338. }
  339. public function generate()
  340. {
  341. DB::transaction(function () {
  342. $this->orders->map(function (PreOrder $order) {
  343. /**
  344. * @var $order
  345. */
  346. $order->generate();
  347. $order->fireCreatedEvent();
  348. });
  349. OrderMergeCreate::saveData($this->orders->pluck('id')->implode(','));
  350. return $this->orders;
  351. });
  352. }
  353. }