OrderSubmitForm.php 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\alliance\models\order;
  8. use app\models\Address;
  9. use app\models\Admin;
  10. use app\models\Cart;
  11. use app\models\BusinessCart;
  12. use app\models\common\CommonOrder;
  13. use app\models\DeliveryInfo;
  14. use app\models\FoodCart;
  15. use app\models\FoodFlag;
  16. use app\models\Goods;
  17. use app\models\GoodsBook;
  18. use app\models\Md;
  19. use app\models\MdProfit;
  20. use app\models\Option;
  21. use app\constants\OptionSetting;
  22. use app\models\Order;
  23. use app\models\OrderDetail;
  24. use app\models\Register;
  25. use app\models\SaasUser;
  26. use app\models\SeckillActivity;
  27. use app\models\SeckillActivityGoods;
  28. use app\models\SeckillActivityOrderLog;
  29. use app\models\Store;
  30. use app\models\User;
  31. use app\models\UserCoupon;
  32. use app\models\VerifyCard;
  33. use app\models\VerifyCardSale;
  34. use app\models\VerifyCardLog;
  35. use app\modules\admin\models\ActivityCutPriceForm;
  36. use app\utils\CloudPrint;
  37. use app\utils\Delivery\Delivery;
  38. use app\utils\Delivery\Alipay\ADelivery;
  39. use app\utils\Notice\NoticeSend;
  40. use app\utils\OrderNo;
  41. use app\utils\PrintOrder;
  42. use app\utils\Tools;
  43. use yii\helpers\Json;
  44. use app\models\SaasCoupon;
  45. use app\modules\admin\models\maiyatian\MaiyatianForm;
  46. use app\modules\admin\models\keloop\KeloopForm;
  47. use app\models\LocalDeliveryFreight;
  48. use app\models\OfferPrice;
  49. use yii\helpers\VarDumper;
  50. class OrderSubmitForm extends OrderForm
  51. {
  52. public $user;
  53. public $payment;
  54. public $use_integral;
  55. public function rules()
  56. {
  57. $rules = [
  58. [['payment', 'use_integral'], 'integer']
  59. ];
  60. return array_merge(parent::rules(), $rules);
  61. }
  62. public function preOrder()
  63. {
  64. if (!$this->validate())
  65. return [
  66. 'code' => 1,
  67. 'msg' => $this->getErrorSummary(false)[0],
  68. ];
  69. try {
  70. if(!$this->address['id']){
  71. return [
  72. 'code' => 1,
  73. 'msg' => '请先选择收货地址',
  74. ];
  75. }
  76. $mch_list = $this->getStoreListData(true);
  77. $goods_list = [];
  78. foreach ($mch_list as $mch) {
  79. foreach ($mch['goods_list'] as $goods) {
  80. $goods_list[] = [
  81. 'name' => $goods['goods_name'],
  82. 'price' => $goods['price'],
  83. 'pic' => $goods['goods_pic'],
  84. 'num' => $goods['num'],
  85. ];
  86. }
  87. $delivery_time = $mch['delivery_time'];//送出时间
  88. }
  89. if($this->order_no){
  90. $existOrder = Order::findOne(['order_no' => $this->order_no]);
  91. if($existOrder){
  92. return [
  93. 'code' => 1,
  94. 'msg' => '单号错误0,请后退到商品页重新下单',
  95. ];
  96. }
  97. $order_no = $this->order_no;
  98. }else{
  99. $order_no = cache()->get('delivery_order_no_' . get_saas_user_id());
  100. }
  101. $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, $this->store_id, 'store')['value'];
  102. $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, $this->store_id, 'pay', $local_type);
  103. if($local_type['value'] == 'keloop') {
  104. if(KeloopForm::isSaasOpen()){
  105. $preAddOrder = KeloopForm::preAddOrder($this->store_id, $order_no, $this->address['longitude'], $this->address['latitude']);
  106. if ($preAddOrder['code']) {
  107. return $preAddOrder;
  108. }
  109. return [
  110. 'code' => 0,
  111. 'msg' => 'ok',
  112. 'data' => [
  113. "resultcode" => 0,
  114. 'fee' => (float)$preAddOrder['data']['fee'],
  115. 'fee_data' => $preAddOrder['data']['fee_data'],
  116. ],
  117. 'order_no' => $order_no,
  118. ];
  119. }
  120. return [
  121. 'code' => 1,
  122. 'msg' => '快跑者配送没有配置',
  123. ];
  124. }
  125. if($local_type['value'] == 'maiyatian') {//麦芽田
  126. if(MaiyatianForm::isopen($this->store_id)){
  127. $getFreight = LocalDeliveryFreight::getFreight($this->store_id, $this->address, $delivery_time, LocalDeliveryFreight::TYPE_MAIYATIAN, $goods_list);
  128. if($getFreight['code'] != 0){
  129. return $getFreight;
  130. }
  131. $freight = $getFreight['data'];
  132. $preAddOrder = MaiyatianForm::preAddOrder($this->store_id, $order_no, $freight);
  133. return [
  134. 'code' => 0,
  135. 'msg' => 'ok',
  136. 'data' => [
  137. "resultcode" => 0,
  138. // 'fee' => (float)MaiyatianForm::getConf($this->store_id, 'cyy_delivery_fee'),
  139. 'fee' => (float)$freight,
  140. ],
  141. 'order_no' => $order_no,
  142. ];
  143. return $preAddOrder;
  144. }
  145. return [
  146. 'code' => 1,
  147. 'msg' => '麦芽田没有配置',
  148. ];
  149. } elseif($local_type['value'] == 'aggregate') {//聚合配送
  150. if(is_alipay_platform()){
  151. $this->address_id || $this->address_id = 220;
  152. $res = ADelivery::createOrder(1, $this->store_id, get_mini_id(), get_saas_user()->ali_user_id, $goods_list, $order_no, $this->address_id);;
  153. return array_merge($res, ['order_no' => $order_no]);
  154. }
  155. return array_merge(Delivery::preAddOrder($goods_list, $order_no), ['order_no' => $order_no]);
  156. } elseif(in_array($local_type['value'], ['self', 'self_store'])) {//平台自配
  157. $type = LocalDeliveryFreight::TYPE_LOCAL;
  158. if ($local_type['value'] === 'self_store') {
  159. $type = LocalDeliveryFreight::TYPE_STORE_LOCAL;
  160. }
  161. $getFreight = LocalDeliveryFreight::getFreight($this->store_id, $this->address, $delivery_time, $type, $goods_list);
  162. if($getFreight['code'] != 0){
  163. return $getFreight;
  164. }
  165. $freight = $getFreight['data'];
  166. DeliveryInfo::deleteAll(['order_no' => $order_no, 'store_id' => get_store_id(), 'status' => 0]);
  167. // 存预下单表
  168. $delivery_info = new DeliveryInfo();
  169. $delivery_info->store_id = get_store_id();
  170. $delivery_info->order_no = $order_no;
  171. $delivery_info->fee = $freight;
  172. $delivery_info->delivery_type = 0;
  173. $delivery_info->created_at = time();
  174. $delivery_info->is_local = DeliveryInfo::IS_LOCAL_YSE;
  175. $delivery_info->is_store_delivery_type = intval($local_type['value'] === 'self_store');
  176. $serial_num = DeliveryInfo::find()->where(['>','created_at',strtotime(date('Y-m-d'))])->orderBy('serial_num desc')->asArray()->one()['serial_num'];
  177. $delivery_info->serial_num = $serial_num > 0 ? $serial_num + 1 : 1;
  178. $delivery_info->save();
  179. return [
  180. 'code' => 0,
  181. 'msg' => 'success',
  182. 'order_no' => $order_no,
  183. 'data' => $getFreight['info'],
  184. ];
  185. /* end */
  186. // return [
  187. // 'code' => 0,
  188. // 'data' => [
  189. // 'goods_list' => $goods_list,
  190. // 'order_no' => $order_no,
  191. // 'test' => [
  192. // 'address' => $address,
  193. // 'store' => $store,
  194. // 'distance' => $distance,
  195. // 'delivery_time' => $delivery_time,
  196. // 'delivery_time_stamp' => $delivery_time_stamp,
  197. // 'LocalDeliveryFreight' => $data,
  198. // 'freight_detail' => $freight_detail,
  199. // 'freight' => $freight,
  200. // ]
  201. // ],
  202. // 'msg' => '平台自配'
  203. // ];
  204. }
  205. } catch (\Exception $e) {
  206. return [
  207. 'code' => 1,
  208. 'msg' => $e->getMessage()
  209. ];
  210. }
  211. }
  212. public function save()
  213. {
  214. if (!$this->validate())
  215. return [
  216. 'code' => 1,
  217. 'msg' => $this->getErrorSummary(false)[0],
  218. ];
  219. try {
  220. $mchListData = $this->getStoreListData(true);
  221. } catch (\Exception $e) {
  222. return [
  223. 'code' => 1,
  224. 'msg' => $e->getMessage()
  225. ];
  226. }
  227. $order_id_list = [];
  228. //$level = $this->level;
  229. /**
  230. * @var $address Address
  231. */
  232. $saas_user = get_saas_user();
  233. $this->user = User::findOne(['binding' => $saas_user->mobile,'store_id' => get_store_id(),'is_delete'=>0]);
  234. if (intval(get_store_id()) <= 0) {
  235. $this->user = $saas_user;
  236. }
  237. $address = (object)($this->address);
  238. $t = \Yii::$app->db->beginTransaction();
  239. foreach ($mchListData as &$mch) {
  240. if (isset($mch['use_integral']) && !$mch['use_integral']) {
  241. $mch['integral'] = ['forehead' => 0, 'forehead_integral' => 0];
  242. $mch['give'] = 0;
  243. }
  244. $mch_goods = $mch['goods_list'];
  245. if ($mch_goods) {
  246. $checkMchData = $this->checkMchData($mch);
  247. if ($checkMchData['code'] == 1) {
  248. $t->rollBack();
  249. return $checkMchData;
  250. }
  251. $level_price = 0;
  252. $total_price = 0;
  253. $is_have_express = false;
  254. $is_have_shop = false;
  255. $order_type = 0;
  256. $is_have_delivery = 0;
  257. $total_integral = 0;
  258. if ($mch['send'] == 'express') {
  259. $is_have_express = true;
  260. }
  261. if ($mch['send'] == 'shop') {
  262. $is_have_shop = true;
  263. }
  264. $is_delivery = OfferPrice::findOne([
  265. 'store_id' => get_store_id(),
  266. 'is_delete' => 0
  267. ]);
  268. $store_data = Store::findOne(get_store_id());
  269. $delivery_rules = [];
  270. if ($mch['send'] == 'delivery') {
  271. $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, get_store_id(), 'store')['value'];
  272. $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, get_store_id(), 'pay', $local_type);
  273. $is_have_express = true;
  274. $delivery_rules = json_decode($is_delivery->delivery_rules, true);
  275. if ($is_delivery->delivery_type == 1 && !empty($delivery_rules)) {
  276. $conf = [
  277. 'shop_tag' => $store_data->coordinate,
  278. 'deliveryRules' => $delivery_rules
  279. ];
  280. $deliveryRules = $this->canDeliver($address, $conf);
  281. if (!$deliveryRules['can_deliver']) {
  282. return [
  283. 'code' => 1,
  284. 'msg' => '当前订单超出配送距离'
  285. ];
  286. }
  287. }
  288. if ($local_type['value'] == 'keloop') { //快跑者配送
  289. if (!KeloopForm::isSaasOpen()) {
  290. $t->rollBack();
  291. return [
  292. 'code' => 1,
  293. 'msg' => '商城未设置有效配送方式'
  294. ];
  295. }
  296. }
  297. if($local_type['value'] == 'maiyatian') {//麦芽田
  298. $maiyatian = MaiyatianForm::isopen($this->store_id);
  299. if (!$maiyatian) {
  300. $t->rollBack();
  301. return [
  302. 'code' => 1,
  303. 'msg' => '商城未设置有效配送方式'
  304. ];
  305. }
  306. } elseif($local_type['value'] == 'aggregate') {//聚合配送
  307. $store = Store::findOne($this->store_id);
  308. if ($store->delivery_type == 0) {
  309. $t->rollBack();
  310. return [
  311. 'code' => 1,
  312. 'msg' => '商城未设置有效配送方式'
  313. ];
  314. }
  315. $res = Delivery::getBindAccount();
  316. // 下单时判断是否可以同城配送
  317. if (empty($res['data']['shop_list'])) {
  318. $t->rollBack();
  319. return [
  320. 'code' => 1,
  321. 'msg' => '当前未绑定运力账号,暂不能保存选择同城配送方式'
  322. ];
  323. }
  324. $shop_list = $res['data']['shop_list'];
  325. $delivery_arr = array_column($shop_list, 'delivery_id');
  326. $delivery_arr[] = 'TEST';
  327. $delivery_arr_id = array_column($shop_list, null, 'delivery_id');
  328. if (!in_array(Delivery::$deliveryIdArr[$store->delivery_type], $delivery_arr) || $delivery_arr_id[Delivery::$deliveryIdArr[$store->delivery_type]]['audit_result'] != 0) {
  329. $t->rollBack();
  330. return [
  331. 'code' => 1,
  332. 'msg' => '当前账号未在微信后台绑定或者并未审核通过'
  333. ];
  334. }
  335. } elseif(in_array($local_type['value'], ['self', 'self_store'])) {//平台自配
  336. if(empty($mch['delivery_time'])){
  337. $store_id = $local_type['value'] === 'self_store' ? $this->store_id : 0;
  338. $setting = json_decode(Option::get(OptionSetting::LOCAL_DELIVERY_SETTING, $store_id, '', '{}')['value'], true);
  339. $mch['delivery_time'] = date('Y-m-d H:i:s', time() + 90 * 60);
  340. if(!empty($setting['default_time']) && !empty($setting['default_time']['value'])){
  341. $mch['delivery_time'] = date('Y-m-d H:i:s', time() + ($setting['default_time']['value'] * 60));
  342. }
  343. }
  344. }
  345. $is_have_delivery = true;
  346. }
  347. $take_price = 0;
  348. $send_price = 0;
  349. foreach ($mch_goods as $v) {
  350. if ($v['product_type'] == 1) {
  351. $order_type = 1;
  352. }
  353. if ($v['product_type'] == 2) {
  354. $order_type = 2;
  355. }
  356. if ($v['product_type'] == 3) {
  357. $order_type = 4;
  358. }
  359. if ($v['product_type'] == Goods::GOODS_TYPE_INTEGRAL) {
  360. $order_type = 7;
  361. $total_integral += isset($v['integral_price']) ? $v['integral_price'] : 0;
  362. }
  363. // if ($v['send'] == 'shop' && empty($v['shop_id']) && empty($v['shop'])) {
  364. // return [
  365. // 'code' => 1,
  366. // 'msg' => '自提商品请选择自提点'
  367. // ];
  368. // }
  369. $level_price += $v['level_price'];
  370. $total_price += isset($v['total_price']) ? $v['total_price'] : $v['price'];
  371. $send_price += $v['send_price'] ?? 0;
  372. $take_price += $v['take_price'] ?? 0;
  373. }
  374. $mch['level_price'] = $level_price;
  375. $mch['total_price'] = $total_price;
  376. $mch['total_integral'] = $total_integral;
  377. // 是否开启配送范围设置
  378. if ($is_have_delivery) {
  379. if (get_md_id() > 0) {
  380. $md_info = Md::findOne(get_md_id());
  381. $lat = $md_info->latitude;
  382. $long = $md_info->longitude;
  383. $is_set_distance = $md_info->is_set_distance;
  384. $distance = $md_info->distance;
  385. } else {
  386. $store_info = Store::findOne(get_store_id());
  387. $is_set_distance = $store_info->is_set_distance;
  388. $distance = $store_info->distance;
  389. $coordinate = explode(',', $store_info->coordinate);
  390. $lat = $coordinate[0];
  391. $long = $coordinate[1];
  392. }
  393. if ($is_set_distance) {
  394. $distance_str = Tools::getDistance($lat, $long, $address->latitude, $address->longitude);
  395. if ($distance_str != '未知距离') {
  396. if (false !== strpos($distance_str, 'km')) {
  397. if (floatval($distance_str) > $distance) {
  398. $t->rollBack();
  399. return [
  400. 'code' => 1,
  401. 'msg' => '当前订单超出配送距离'
  402. ];
  403. }
  404. } else {
  405. if (floatval($distance_str) > $distance * 1000) {
  406. $t->rollBack();
  407. return [
  408. 'code' => 1,
  409. 'msg' => '当前订单超出配送距离'
  410. ];
  411. }
  412. }
  413. }
  414. }
  415. }
  416. // 开启使用积分抵扣
  417. if (isset($mch['use_integral']) && $mch['use_integral'] == 1 && isset($this->user->integral)) {
  418. if ($this->user->integral < $mch['integral']['forehead'] || $this->user->integral < $mch['total_integral']) {
  419. return [
  420. 'code' => 1,
  421. 'msg' => '积分可抵扣支付数量不足'
  422. ];
  423. }
  424. }
  425. $resultPrice = $this->getPayPrice($mch);
  426. $payPrice = $resultPrice['pay_price'];
  427. $payPrice = $this->getBookPrice($payPrice, $mch_goods);
  428. if ($is_have_express && $is_delivery->delivery_type == 1 && !empty($delivery_rules)) {
  429. if ($resultPrice['goods_price'] < $deliveryRules['delivery_price']) {
  430. return [
  431. 'code' => 1,
  432. 'msg' => '同城配送订单满 ¥' . $deliveryRules['delivery_price'] . ' 起送'
  433. ];
  434. }
  435. }
  436. if ($order_type == 1) {
  437. // $bookCount = count($mch_goods[0]['book']);
  438. $mch['level_price'] = $payPrice;
  439. $mch['total_price'] = $payPrice;
  440. }
  441. $order = new Order();
  442. // $verifylog = new VerifyCardLog();
  443. // $verifycardsale = new VerifyCardSale();
  444. if($mch['delivery_time']){
  445. $order->delivery_time = strtotime($mch['delivery_time']);
  446. }
  447. $order->store_id = $this->store_id;
  448. $order->user_id = 0;
  449. //saas订单记录use用户信息
  450. if ($this->store_id > 0) {
  451. if(isset($this->user->id) && $this->user->id > 0){
  452. $order->user_id = $this->user->id;
  453. }
  454. } else {
  455. $order->store_id = 0;
  456. }
  457. if (is_app_platform()) {
  458. $order->order_origin = Order::ORDER_SOURCE_APP;
  459. }
  460. $order->saas_id = get_saas_user_id();
  461. if (!empty($this->verify_card_id)) {
  462. $order->type = 1;
  463. }
  464. if ($is_have_delivery) {
  465. $order->order_no = cache()->get('delivery_order_no_' . get_saas_user_id());
  466. } else {
  467. $order->order_no = OrderNo::getOrderNo(OrderNo::ORDER_ALLIANCE);
  468. }
  469. $order->pay_price = !empty($this->verify_card_id) ? 0 : $payPrice;
  470. if (isset($mch['picker_coupon']) && !empty($mch['picker_coupon'])) {
  471. $order->user_coupon_id = $mch['picker_coupon']['user_coupon_id'];
  472. $order->coupon_sub_price = $mch['picker_coupon']['sub_price'];
  473. // 查找优惠券优惠的商品
  474. $this->pickerGoods($mch);
  475. }
  476. // 订单类型
  477. $order->order_type = $order_type;
  478. // 积分兑换商品
  479. if (isset($mch['total_integral']) && $mch['total_integral'] > 0 ) {
  480. if ($this->user->integral < $mch['total_integral']) {
  481. return [
  482. 'code' => 1,
  483. 'msg' => '积分数量不足'
  484. ];
  485. }else{
  486. $order->integral_price = $mch['total_integral'] ?? 0;
  487. $order->integral_difference_price = 0;
  488. $mch['integral_type'] = 1; //全部使用积分
  489. $mch['integral_difference_price'] = 0; //补的差额
  490. }
  491. //当用户有积分时
  492. // if(get_user()->integral > 0){
  493. // $upIntegral = get_user()->integral - $order->integral_price;
  494. // //减用户积分
  495. // if(! User::updateAll(['integral'=>$upIntegral],['id'=> get_user_id()]) ){
  496. // $t->rollBack();
  497. // return [
  498. // 'code' => 1,
  499. // 'msg' => '积分抵扣失败,稍后重试!'
  500. // ];
  501. // }
  502. // }
  503. }
  504. // 是否是平台小程序订单
  505. //if (is_platform()) {
  506. $order->is_platform = 1;
  507. //}
  508. if (get_md_id()) {
  509. $order->md_id = get_md_id();
  510. }
  511. // if($this->send_price){
  512. $order->send_price = $send_price;
  513. // }
  514. // if($this->take_price){
  515. $order->take_price = $take_price;
  516. // }
  517. $order->created_at = time();
  518. $order->first_price = 0;
  519. $order->second_price = 0;
  520. $order->third_price = 0;
  521. $order->content = isset($mch['content']) ? $mch['content'] : '';
  522. $order->is_offline = $is_have_shop ? 1 : 0;
  523. $order->is_delivery = $is_have_delivery ? 1 : 0;
  524. if (isset($mch['use_integral']) && $mch['use_integral'] == 1) {
  525. $order->integral = json_encode($mch['integral'], JSON_UNESCAPED_UNICODE);
  526. } else {
  527. $order->integral = json_encode(['forehead' => 0, 'forehead_integral' => 0], JSON_UNESCAPED_UNICODE);
  528. }
  529. $order->version = cyy_version();
  530. $order->mch_id = $mch['mch_id'] ?: 0;
  531. $order->discount = isset($level['discount']) ? $level['discount'] : 10;
  532. $order->remark = $mch['remark'] ?: '';
  533. if ($this->payment == 2) {
  534. $order->pay_type = 2;
  535. $order->is_pay = 0;
  536. }
  537. if ($this->payment == 3) {
  538. $order->pay_type = 3;
  539. $order->is_pay = 0;
  540. }
  541. // 线下支付
  542. if ($this->payment == 6) {
  543. $order->pay_type = 6;
  544. $order->is_pay = 0;
  545. }
  546. $flag_id = input_params('flag_id');
  547. $table_num = input_params('table_num');
  548. if(empty($flag_id) && !empty($mch_goods[0]['food_cart_id'])){
  549. $food_cart_id = $mch_goods[0]['food_cart_id'];
  550. $foodCart = FoodCart::findOne($food_cart_id);
  551. $flag_id = $foodCart->flag_id;
  552. }
  553. if ((!empty($flag_id) || !empty($table_num))) {
  554. if (get_md_id() < 0) {
  555. $store = Store::findOne(get_store_id());
  556. if ($store->open_status == 0) {
  557. $t->rollBack();
  558. return [
  559. 'code' => 1,
  560. 'msg' => '已打烊'
  561. ];
  562. }
  563. if ($store->is_time_forbid == 0 && !$this->checkTimeBeginEnd($store->s_time, $store->e_time) && $store->shop_time_type == 1) {
  564. $t->rollBack();
  565. return [
  566. 'code' => 1,
  567. 'msg' => '非营业时间禁止下单'
  568. ];
  569. }
  570. }
  571. if (!empty($flag_id)) {
  572. $order->food_flag_id = $flag_id;
  573. } else {
  574. $order->food_flag_id = FoodFlag::findOne(['store_id' => get_store_id(), 'md_id' => get_md_id(), 'status' => 0, 'table_num' => $table_num])->id;
  575. }
  576. $order->order_type = 3;
  577. $order->food_book_ext = $mch['food_book_ext'];
  578. }
  579. if ($is_have_express || get_md_id()) {
  580. $order->address = $address->province . $address->city . $address->district . $address->detail;
  581. $order->mobile = $address->mobile;
  582. $order->name = $address->name;
  583. $order->province_id = $address->province_id;
  584. $order->city_id = $address->city_id;
  585. $order->district_id = $address->district_id;
  586. $order->address_data = json_encode([
  587. 'province' => trim($address->province),
  588. 'city' => trim($address->city),
  589. 'district' => trim($address->district),
  590. 'detail' => trim($address->detail),
  591. 'latitude' => $address->latitude,
  592. 'longitude' => $address->longitude,
  593. ], JSON_UNESCAPED_UNICODE);
  594. if ($is_have_delivery) {
  595. $order->total_price = !empty($this->verify_card_id) ? 0 : $mch['total_price'];
  596. } else {
  597. $order->express_price = $mch['express_price'];
  598. $order->total_price = !empty($this->verify_card_id) ? 0 : $mch['total_price'] + $mch['express_price'];
  599. }
  600. }
  601. if ($is_have_shop) {
  602. $order->total_price = !empty($this->verify_card_id) ? 0 : $mch['total_price'];
  603. $order->express_price = 0;
  604. }
  605. if ($order->order_type == 1 || $order->order_type == 2) {
  606. $order->book_info = Json::encode($mch['book_info']);
  607. }
  608. if ($order->order_type == 2) {
  609. $order->total_price = $payPrice;
  610. }
  611. if ($order->order_type == 1) {
  612. $order->total_price = $mch['total_price'];
  613. }
  614. // // 礼品卡订单
  615. // if (!empty(post_params('verify_card_id'))) {
  616. // $order->verify_card_id = post_params('verify_card_id');
  617. // }
  618. //获取代理配置信息
  619. $store = Store::findOne($this->store_id);
  620. $option = Option::get('agency_price_config', 0, 'saas', [])['value'];
  621. if ($option) {
  622. $option = json_decode($option, true);
  623. }
  624. $province_percent = $option['province_percent'] ?? 0;
  625. $city_percent = $option['city_percent'] ?? 0;
  626. $district_percent = $option['district_percent'] ?? 0;
  627. $ag_rebate = $payPrice * ($store->transfer_profit / 100);
  628. $order->ag_rebate = $ag_rebate;
  629. // 配送订单预存数据
  630. // if ($is_have_delivery) {
  631. // $delivery_info = new DeliveryInfo();
  632. // $delivery_info->store_id = get_store_id();
  633. // $delivery_info->order_no = $order->order_no;
  634. // $delivery_info->status = 0;
  635. // $delivery_info->created_at = time();
  636. // $delivery_info->updated_at = time();
  637. // $delivery_info->save();
  638. // }
  639. $order->integral_difference_price = 0;
  640. if($this->activity_cut_price_order_id){
  641. $order->activity_cut_price_order_id = $this->activity_cut_price_order_id;
  642. }
  643. if ($is_have_delivery) {
  644. $cacheK = 'is_have_delivery_' . $order->order_no;
  645. $cacheV = cache()->get($cacheK);
  646. $deliveryInfo = DeliveryInfo::find()->where(['order_no' => $order->order_no])->one();
  647. if(!$deliveryInfo){
  648. $t->rollBack();
  649. if($cacheV){
  650. return [
  651. 'code' => 1,
  652. 'msg' => '配送单不存在,请返回商品详情页重新下单。' . $cacheV . $cacheK
  653. ];
  654. }
  655. cache()->set($cacheK, 1, 180);
  656. $this->order_no = '';
  657. $preOrder = $this->preOrder();
  658. if($preOrder['code'] != 0){
  659. return $preOrder;
  660. }else{
  661. $this->order_no = '';
  662. return $this->save();
  663. }
  664. }
  665. $order->total_price += $deliveryInfo->fee;
  666. $order->pay_price += $deliveryInfo->fee;
  667. }
  668. if ($order->save()) {
  669. //砍价订单
  670. if($this->activity_cut_price_order_id){
  671. $orderUsed = ActivityCutPriceForm::orderUsed($this->activity_cut_price_order_id, $order);
  672. if ($orderUsed['code'] != 0) {
  673. $t->rollBack();
  674. return $orderUsed;
  675. }
  676. }
  677. // 绑定上下级
  678. // $user = User::findOne($this->user_id);
  679. // if ($user && $user->parent_user_id) {
  680. // CommonOrder::saveParentId($user->parent_user_id);
  681. // }
  682. // VerifyCard::updateAll(['send_times' => $send_times], 'id='.$VerifyCardSale['verify_card_id']);
  683. // VerifyCardSale::updateAll(['left_num' => $left_num, 'status' => 1],'id='.$this->verify_card_id);
  684. // $verifylog->save();
  685. // 更改点餐flag_id状态
  686. // if (get_md_id() && !empty(input_params('flag_id'))) {
  687. // FoodFlag::updateAll(['status' => 1], ['id' => input_params('flag_id')]);
  688. // }
  689. // 处理订单生成之后其他相关数据
  690. $orderRes = $this->insertData($mch, $order);
  691. if ($orderRes['code'] == 1) {
  692. $t->rollBack();
  693. return $orderRes;
  694. }
  695. $printer_order = new PrintOrder($order->store_id, $order->id, 'order', 0, 0, 0, $order['mch_id']);
  696. $printer_order->print_order();
  697. // 订单提交完成发送消息
  698. //NoticeSend::OrderSubmit($this->user_id, $order->mobile, $order->order_no, $order->pay_price, $mch_goods[0]['goods_name']);
  699. $order_id_list[] = $order->id;
  700. } else {
  701. $t->rollBack();
  702. return [
  703. 'code' => 1,
  704. 'msg' => array_shift($order->getFirstErrors()),
  705. 'data' => $order,
  706. ];
  707. }
  708. }
  709. }
  710. if (count($order_id_list) > 0) {
  711. $t->commit();
  712. if (count($order_id_list) > 1) {//多个订单合并
  713. return [
  714. 'code' => 0,
  715. 'msg' => '订单提交成功',
  716. 'data' => (object)[
  717. 'order_id_list' => $order_id_list,
  718. 'add_time' => $order->created_at
  719. ],
  720. ];
  721. } else {//单个订单
  722. $order_id = $order_id_list[0];
  723. $order = Order::findOne($order_id);
  724. if($order->take_price > 0){
  725. if (($order->pay_price - $order->take_price) >= 0) {
  726. $order->pay_price -= $order->take_price;
  727. $order->total_price -= $order->take_price;
  728. } else {
  729. $order->take_price -= $order->pay_price;
  730. $order->total_price = $order->pay_price = 0;
  731. }
  732. $order->save();
  733. }
  734. CloudPrint::doPrint($order_id, 0, $this->store_id);
  735. return [
  736. 'code' => 0,
  737. 'msg' => '订单提交成功',
  738. 'data' => (object)[
  739. 'order_id' => $order_id_list[0],
  740. 'add_time' => $order->created_at,
  741. 'order_price' => $order->pay_price
  742. ],
  743. ];
  744. }
  745. } else {
  746. $t->rollBack();
  747. return [
  748. 'order_list' => $order_id_list
  749. ];
  750. }
  751. }
  752. /**
  753. * 判断是否可以配送并计算费用
  754. */
  755. private function canDeliver($address, $conf)
  756. {
  757. // 解析商家地址的经纬度
  758. list($shopLon, $shopLat) = explode(',', $conf['shop_tag']);
  759. // 计算距离
  760. $distance = Tools::getDistance((float)$shopLat, (float)$shopLon, $address->latitude ?: $address['latitude'], $address->longitude ?: $address['longitude']);
  761. if (strpos($distance, 'km') !== false) {
  762. $distance = floatval(explode('km', $distance)[0]);
  763. } elseif (strpos($distance, 'm') !== false) {
  764. $distance = floatval(explode('m', $distance)[0]) / 1000;
  765. }
  766. foreach ($conf['deliveryRules'] as $rule) {
  767. if ($rule['start'] <= $distance && $distance <= $rule['end']) {
  768. return [
  769. 'can_deliver' => true,
  770. 'distance' => $distance,
  771. 'delivery_price' => $rule['price'],
  772. 'delivery_range' => [$rule['start'], $rule['end']]
  773. ];
  774. }
  775. }
  776. return ['can_deliver' => false, 'distance' => $distance, 'delivery_price' => null, 'delivery_range' => null];
  777. }
  778. public function getNo($attrStr, $searchAttrIds)
  779. {
  780. $attr = json_decode($attrStr, true);
  781. foreach ($attr as $item) {
  782. $attrIds = array_column($item['attr_list'], 'attr_id');
  783. if ($attrIds == $searchAttrIds) {
  784. return $item['no'];
  785. }
  786. }
  787. }
  788. // 获得实际支付金额
  789. private function getPayPrice($mch)
  790. {
  791. $goods_list = $mch['goods_list'];
  792. $payPrice = $mch['level_price'];
  793. $goodsPrice = $mch['level_price'];
  794. if (isset($mch['use_integral']) && $mch['use_integral']) {
  795. $payPrice -= $mch['integral']['forehead'];
  796. }
  797. if (isset($mch['picker_coupon'])) {
  798. $pickerCoupon = $mch['picker_coupon'];
  799. if ($pickerCoupon['sub_price'] > 0) {
  800. $coupon_price = 0;
  801. if ($pickerCoupon['appoint_type'] == 1 && $pickerCoupon['cat_id_list'] != null) {
  802. foreach ($goods_list as $goods) {
  803. foreach ($goods['cat_id'] as $v1) {
  804. if (in_array($v1, $pickerCoupon['cat_id_list'])) {
  805. $coupon_price += floatval($goods['level_price']);
  806. break;
  807. };
  808. };
  809. }
  810. } else if ($pickerCoupon['appoint_type'] == 2 && $pickerCoupon['goods_id_list'] != null) {
  811. foreach ($goods_list as $goods) {
  812. if (in_array($goods['goods_id'], $pickerCoupon['goods_id_list'])) {
  813. $coupon_price += floatval($goods['level_price']);
  814. };
  815. }
  816. };
  817. if ($pickerCoupon['sub_price'] > $coupon_price && $coupon_price > 0) {
  818. $payPrice -= $coupon_price;
  819. } else {
  820. $payPrice -= $pickerCoupon['sub_price'];
  821. }
  822. }
  823. }
  824. // Todo 此处有待确认算法是否正确 by Syan
  825. // $payPrice = $payPrice > 0 ? $payPrice : 0.01;
  826. if ($mch['express_price'] > 0) {
  827. if (isset($mch['send']) && $mch['send'] == 'express') {
  828. $payPrice += $mch['express_price'];
  829. } else {
  830. foreach ($goods_list as $goods) {
  831. if (isset($goods['send']) && $goods['send'] == 'express') {
  832. $payPrice += $mch['express_price'];
  833. break;
  834. }
  835. }
  836. }
  837. }
  838. return ['pay_price'=>$payPrice > 0 ? $payPrice : 0,'goods_price' => $goodsPrice];
  839. }
  840. // 检查数据
  841. private function checkMchData($mch)
  842. {
  843. if (empty($mch['goods_list'])) {
  844. return [
  845. 'code' => 1,
  846. 'msg' => '商品不存在或已删除'
  847. ];
  848. }
  849. $checkFormData = $this->checkFormData($mch);
  850. if ($checkFormData['code'] == 1) {
  851. return $checkFormData;
  852. }
  853. $checkSendType = $this->checkSendType($mch);
  854. if ($checkSendType['code'] == 1) {
  855. return $checkSendType;
  856. }
  857. $checkCoupon = $this->checkCoupon($mch);
  858. if ($checkCoupon['code'] == 1) {
  859. return $checkCoupon;
  860. }
  861. $checkGoods = $this->checkGoods($mch);
  862. if ($checkGoods['code'] == 1) {
  863. return $checkGoods;
  864. }
  865. return ['code' => 0, 'msg' => 'success'];
  866. }
  867. // 检测优惠券是否可使用
  868. private function checkCoupon($mch)
  869. {
  870. if (empty($mch['picker_coupon'])) {
  871. return [
  872. 'code' => 0,
  873. 'msg' => ''
  874. ];
  875. }
  876. $ok = false;
  877. foreach ($mch['coupon_list'] as $item) {
  878. if ($item['user_coupon_id'] == $mch['picker_coupon']['user_coupon_id']) {
  879. $ok = true;
  880. }
  881. }
  882. if (!$ok) {
  883. return [
  884. 'code' => 1,
  885. 'msg' => '该优惠券已过期'
  886. ];
  887. } else {
  888. return [
  889. 'code' => 0,
  890. 'msg' => ''
  891. ];
  892. }
  893. }
  894. // 检测发货方式
  895. private function checkSendType($mch)
  896. {
  897. if ($mch['mch_id'] == 0) {
  898. if (isset($mch['is_offline']) && $mch['is_offline'] == 1) {
  899. if (isset($mch['shop']) == false) {
  900. return [
  901. 'code' => 1,
  902. 'msg' => '请选择自提门店'
  903. ];
  904. }
  905. if (!(isset($mch['offline_name']) && $mch['offline_name']) || !(isset($mch['offline_mobile']) && $mch['offline_mobile'])) {
  906. return [
  907. 'code' => 1,
  908. 'msg' => '请输入自提信息'
  909. ];
  910. }
  911. if (!preg_match("/^1\d{10}$/", $mch['offline_mobile'])) {
  912. return [
  913. 'code' => 1,
  914. 'msg' => '请输入正确的手机号'
  915. ];
  916. }
  917. } else {
  918. if (!$this->address) {
  919. return [
  920. 'coe' => 1,
  921. 'msg' => '收货地址不存在'
  922. ];
  923. }
  924. if ($mch['offer_rule'] && $mch['offer_rule']['is_allowed'] == 1) {
  925. return [
  926. 'code' => 1,
  927. 'msg' => $mch['offer_rule']['msg']
  928. ];
  929. }
  930. if ($mch['is_area'] == 1 && $mch['send'] == 'express') {
  931. return [
  932. 'code' => 1,
  933. 'msg' => '所选地区自营商品暂时无货'
  934. ];
  935. }
  936. }
  937. } else {
  938. if (!$this->address) {
  939. return [
  940. 'coe' => 1,
  941. 'msg' => '收货地址不存在'
  942. ];
  943. }
  944. }
  945. return ['code' => 0, 'msg' => ''];
  946. }
  947. // 检测自定义表单
  948. private function checkFormData($mch)
  949. {
  950. foreach ($mch['goods_list'] as $goods) {
  951. if (isset($goods['form']['code'])) {
  952. return $goods['form'];
  953. }
  954. if (!isset($goods['form'])) {
  955. continue;
  956. }
  957. $form = $goods['form'];
  958. if ($form['is_form'] == 1) {
  959. $form_list = $form['list'];
  960. foreach ($form_list as $index => $value) {
  961. if ($value['required'] == 1) {
  962. if (in_array($value['type'], ['radio', 'checkbox'])) {
  963. $is_true = false;
  964. foreach ($value['default_list'] as $k => $v) {
  965. if ($v['checked'] == true) {
  966. $is_true = true;
  967. }
  968. }
  969. if (!$is_true) {
  970. return [
  971. 'code' => 1,
  972. 'msg' => '请填写' . $form['name'] . ',加“*”为必填项',
  973. 'name' => $value['name']
  974. ];
  975. }
  976. } else {
  977. if (empty($value['default']) && strlen($value['default']) == 0) {
  978. return [
  979. 'code' => 1,
  980. 'msg' => '请填写' . $form['name'] . ',加“*”为必填项',
  981. 'name' => $value['name']
  982. ];
  983. }
  984. }
  985. }
  986. }
  987. }
  988. }
  989. return [
  990. 'code' => 0,
  991. 'msg' => ''
  992. ];
  993. }
  994. // 检测商品相关
  995. private function checkGoods($mch)
  996. {
  997. \Yii::warning($mch);
  998. foreach ($mch['goods_list'] as $goods) {
  999. $attr_id_list = [];
  1000. foreach ($goods['attr_list'] as $item) {
  1001. array_push($attr_id_list, $item['attr_id']);
  1002. }
  1003. $_goods = Goods::findOne($goods['goods_id']);
  1004. //2砍价商品6当面付
  1005. if ($_goods->type != 2 && $_goods->type != 6 && $_goods->product_type == Goods::GOODS_TYPE_NORMAL) {
  1006. if (!$_goods->numSub($attr_id_list, $goods['num'])) {
  1007. return [
  1008. 'code' => 1,
  1009. 'msg' => '订单提交失败,商品“' . $_goods->name . '”库存不足',
  1010. 'attr_id_list' => $attr_id_list,
  1011. 'attr_list' => $goods['attr_list'],
  1012. ];
  1013. }
  1014. }
  1015. if($_goods->product_type == Goods::GOODS_TYPE_DATE){
  1016. $num = Goods::getGoodsNum($_goods)['data'];
  1017. $attr = $goods['book'];
  1018. \Yii::error(['$num$num$num$num$num', $num]);
  1019. \Yii::error(['$attr$attr$attr$attr', $attr]);
  1020. foreach ($attr as $iattr) {
  1021. $idate = $iattr['date'];
  1022. foreach ($num as $inum) {
  1023. $indate = $inum['date'];
  1024. if(($idate == $indate) && ($inum['num'] < $goods['num'])){
  1025. return ['code' => 1, 'msg' => $idate.'库存不足'];
  1026. }
  1027. }
  1028. }
  1029. }
  1030. }
  1031. return ['code' => 0, 'msg' => ''];
  1032. }
  1033. public function getOrderNo()
  1034. {
  1035. $order_no = null;
  1036. while (true) {
  1037. $order_no = date('YmdHis') . mt_rand(100000, 999999);
  1038. $exist_order_no = Order::find()->where(['order_no' => $order_no])->exists();
  1039. if (!$exist_order_no) {
  1040. break;
  1041. }
  1042. }
  1043. return $order_no;
  1044. }
  1045. // 优惠券可优惠的商品总额计算
  1046. private function pickerGoods(&$mch)
  1047. {
  1048. $totalPrice = 0;
  1049. $pickerCoupon = $mch['picker_coupon'];
  1050. if (empty($pickerCoupon)) {
  1051. return;
  1052. }
  1053. foreach ($mch['goods_list'] as $item) {
  1054. if ($pickerCoupon['appoint_type'] == 1) {
  1055. if ($pickerCoupon['cat_id_list'] !== null) {
  1056. $catIdList = $pickerCoupon['cat_id_list'];
  1057. if (array_intersect($item['cat_id'], $catIdList)) {
  1058. $totalPrice += $item['price'];
  1059. $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
  1060. }
  1061. } else {
  1062. $totalPrice += $item['price'];
  1063. $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
  1064. }
  1065. } else if ($pickerCoupon['appoint_type'] == 2) {
  1066. if ($pickerCoupon['goods_id_list'] !== null) {
  1067. $goodsIdList = $pickerCoupon['goods_id_list'];
  1068. if (in_array($item['goods_id'], $goodsIdList)) {
  1069. $totalPrice += $item['price'];
  1070. $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
  1071. }
  1072. } else {
  1073. $totalPrice += $item['price'];
  1074. $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
  1075. }
  1076. } else {
  1077. $totalPrice += $item['price'];
  1078. $mch['picker_coupon']['goods_id'][] = $item['goods_id'];
  1079. }
  1080. }
  1081. $mch['picker_coupon']['total_price'] = $totalPrice;
  1082. }
  1083. /**
  1084. * @param $mch
  1085. * @param $order Order
  1086. * @return array
  1087. */
  1088. private function insertData($mch, $order)
  1089. {
  1090. // 计算商品相关
  1091. $goods_list = $mch['goods_list'];
  1092. $goodsPrice = 0;
  1093. // 计算商品分润
  1094. $goods_profit = 0;
  1095. $chain_goods_profit = 0;
  1096. $chainGoodsList = [];
  1097. foreach ($goods_list as $goods) {
  1098. // 存入下单表单
  1099. if ($goods['form'] && $goods['form']['is_form'] == 1) {
  1100. foreach ($goods['form']['list'] as $index => $value) {
  1101. $order_form = new \app\models\OrderForm();
  1102. $order_form->store_id = $this->store_id;
  1103. $order_form->order_id = $order->id;
  1104. $order_form->goods_id = $goods['id'];
  1105. $order_form->key = $value['name'];
  1106. $order_form->value = $value['default'];
  1107. $order_form->type = $value['type'];
  1108. $order_form->is_delete = 0;
  1109. $order_form->save();
  1110. }
  1111. }
  1112. // 删除购物车
  1113. if (isset($goods['cart_id'])) {
  1114. BusinessCart::updateAll(['is_delete' => 1], ['id' => $goods['cart_id']]);
  1115. }
  1116. $order_detail = new OrderDetail();
  1117. $order_detail->order_id = $order->id;
  1118. $order_detail->goods_id = $goods['goods_id'];
  1119. $order_detail->num = $goods['num'];
  1120. if (isset($goods['cost_price'])) {
  1121. $order_detail->cost_price = $goods['cost_price'];
  1122. }
  1123. // if ($goods['is_level'] && $goods['is_level'] == 1) {
  1124. // $order_detail->is_level = (int)$goods['is_level'];
  1125. // } else {
  1126. $order_detail->is_level = 1;
  1127. //}
  1128. $payPrice = $goods['level_price'];
  1129. if (isset($mch['picker_coupon']) && $mch['picker_coupon'] && !empty($mch['picker_coupon'])) {
  1130. if (!empty($mch['picker_coupon']['goods_id_list']) && in_array($goods['goods_id'], $mch['picker_coupon']['goods_id_list']) && $mch['picker_coupon']['total_price'] > 0) {
  1131. $pickerCouponSubPrice = doubleval($mch['picker_coupon']['sub_price'] * doubleval($goods['price']) / $mch['picker_coupon']['total_price']);
  1132. $payPrice -= $pickerCouponSubPrice;
  1133. }
  1134. // 删除优惠券
  1135. SaasCoupon::updateAll(['is_use' => 1], ['id' => $mch['picker_coupon']['user_coupon_id']]);
  1136. }
  1137. // if (isset($mch['use_integral']) && $mch['use_integral']) {
  1138. // if ($goods['resIntegral'] && $goods['resIntegral']['forehead'] > 0) {
  1139. // $payPrice -= $goods['resIntegral']['forehead'];
  1140. // }
  1141. // }
  1142. $payPrice = $payPrice >= 0 ? sprintf('%.2f', $payPrice) : 0;
  1143. $goodsPrice += $payPrice;
  1144. $orderPrice = floatval($order->pay_price) - floatval($order->express_price);
  1145. if ($goodsPrice > $orderPrice) {
  1146. $payPrice = $payPrice - ($goodsPrice - $orderPrice);
  1147. $goodsPrice = $orderPrice;
  1148. }
  1149. $payPrice = $this->getBookPrice($payPrice, $goods_list);
  1150. // $order_detail->supplier_price = $goods['supplier_price'];
  1151. $order_detail->total_price = $payPrice;
  1152. // 计算单个商品可分红金额
  1153. $profit = $goods['rate_type'] == 0 ? floatval($payPrice * $goods['rate'] / 100) : floatval($goods['rate'] * $goods['num']);
  1154. $goods_profit += $profit;
  1155. $order_detail->profit = $profit;
  1156. // 链动
  1157. $chain_profit = $goods['chain_rate_type'] == 0 ? floatval($payPrice * $goods['chain_rate'] / 100) : floatval($goods['chain_rate'] * $goods['num']);
  1158. $chain_goods_profit += $chain_profit;
  1159. $order_detail->chain_profit = $chain_profit;
  1160. $order_detail->is_delete = 0;
  1161. $chainGoodsList[] = [
  1162. 'id' => $goods['id'],
  1163. 'num' => $goods['num'],
  1164. 'pay_price' => $payPrice,
  1165. ];
  1166. if ($goods['product_type'] == 1) {
  1167. $order_detail->attr = json_encode($goods['book'], JSON_UNESCAPED_UNICODE);
  1168. } elseif ($goods['product_type'] == 2) {
  1169. //$order_detail->attr = json_encode($goods['service'], JSON_UNESCAPED_UNICODE);
  1170. $service = $goods['service'];
  1171. $time = explode('-', $service['time']);
  1172. $order_detail->attr = json_encode([
  1173. 'start_date' => $service['date'] . ' ' . $time[0],
  1174. 'end_date' => $service['date'] . ' ' . $time[1],
  1175. 'time' => $service['time'],
  1176. 'date' => $service['date'],
  1177. 'price' => $service['price'],
  1178. ], JSON_UNESCAPED_UNICODE);
  1179. // $order_detail->attr = json_encode($goods['service'], JSON_UNESCAPED_UNICODE);
  1180. } else {
  1181. $order_detail->attr = json_encode($goods['attr_list'], JSON_UNESCAPED_UNICODE);
  1182. }
  1183. $goods_info = Goods::findOne($goods['goods_id']);
  1184. $order_detail->pic = $goods['goods_pic'] ? $goods['goods_pic'] : $goods_info->cover_pic;
  1185. $order_detail->goods_name = $goods_info ? $goods_info->name : $goods['goods_name'];
  1186. $order_detail->goods_info = $goods_info ? Json::encode($goods_info->toArray()) : json::encode([]);
  1187. $order_detail->delivery_type = $mch['send'] == 'express' ? OrderDetail::GOODS_DELIVERY_EXPRESS : ($mch['send'] == 'delivery' ? OrderDetail::GOODS_DELIVERY_IM : OrderDetail::GOODS_DELIVERY_SHOP);
  1188. if ($mch['send'] == 'shop' && empty(input_params('flag_id'))) {
  1189. $order_detail->shop_id = $goods['shop_id'];
  1190. }
  1191. if (isset($goods['give']) && $goods['give'] > 0) {
  1192. $order_detail->integral = $goods['give'];
  1193. } else {
  1194. $order_detail->integral = 0;
  1195. }
  1196. $order_detail->integral_price = $goods['integral_price'];
  1197. $attr_id_list = [];
  1198. foreach ($goods['attr_list'] as $item) {
  1199. array_push($attr_id_list, $item['attr_id']);
  1200. }
  1201. //满减价格提示
  1202. //$order_detail->batch_price_tips = $goods['current_batch_price_tips'];
  1203. // 存入点餐的user_id
  1204. if (!empty($goods['user_id'])) {
  1205. $order_detail->user_id = $goods['user_id'];
  1206. }
  1207. if (!$order_detail->save()) {
  1208. return [
  1209. 'code' => 1,
  1210. 'msg' => '订单提交失败,请稍后再重试',
  1211. 'error' => $order_detail->errors[0]
  1212. ];
  1213. }
  1214. if ($this->is_seckill) {
  1215. $seckill_activity_goods = SeckillActivityGoods::find()->alias('sag')->where(['sag.goods_id' => $goods['goods_id']])
  1216. ->leftJoin(['sg' => SeckillActivity::tableName()], 'sg.id = sag.activity_id')
  1217. ->andWhere(['AND', ['>', 'sg.end_time', time()], ['<', 'sg.start_time', time()], ['sg.is_delete' => 0, 'sag.is_delete' => 0, 'sg.store_id' => get_store_id()]])
  1218. ->select('sag.id sag_id, sg.id, sg.end_time, sag.attr, sag.use_attr, sag.seckill_num, sag.seckill_price, sag.sale_num, sg.order_limit_num, sg.self_limit_num')->asArray()->one();
  1219. if ($seckill_activity_goods) {
  1220. $activity_order_log = new SeckillActivityOrderLog();
  1221. $activity_order_log->order_id = $order->id;
  1222. $activity_order_log->order_detail_id = $order_detail->id;
  1223. $activity_order_log->user_id = get_user_id();
  1224. $activity_order_log->sale_price = $goods['level_price'];
  1225. $activity_order_log->activity_id = $seckill_activity_goods['id'];
  1226. $activity_order_log->activity_goods_id = $seckill_activity_goods['sag_id'];
  1227. $activity_order_log->goods_id = $goods['goods_id'];
  1228. $activity_order_log->num = $goods['num'];
  1229. $activity_order_log->store_id = get_store_id();
  1230. if (!$activity_order_log->save()) {
  1231. debug_log("秒杀信息保存" . json_encode($activity_order_log->errors));
  1232. }
  1233. $order->seckill_order_id = $activity_order_log->id;
  1234. }
  1235. }
  1236. }
  1237. // goods_profit 计算之后存入订单表中
  1238. $order->profit = $goods_profit;
  1239. $order->chain_profit = $chain_goods_profit;
  1240. $orderChainLevelProfit = \app\utils\Share\BonusPool::getOrderLevelProfit(get_store_id(), $chainGoodsList);
  1241. $order->chain_level_value = json_encode($orderChainLevelProfit);
  1242. $order->save();
  1243. // // 计算门店收益
  1244. // if (get_md_id() > 0) {
  1245. $result = OrderForm::findPrice($order->id);
  1246. MdProfit::handleProfit($order->id, $result['original_price'], $result['md_price']);
  1247. if (!empty(input_params('flag_id'))) {
  1248. FoodCart::updateAll(['is_delete' => 1], ['flag_id' => input_params('flag_id')]);
  1249. FoodFlag::updateAll(['status' => 1], ['id' => input_params('flag_id')]);
  1250. }
  1251. // }
  1252. return [
  1253. 'code' => 0,
  1254. 'msg' => ''
  1255. ];
  1256. }
  1257. public function getBookPrice($payPrice, $mch_goods)
  1258. {
  1259. $price = $payPrice;
  1260. foreach ($mch_goods as $goods) {
  1261. if ($goods['product_type'] == 1) {
  1262. $price = 0;
  1263. $goods_id = $goods['goods_id'];
  1264. $goodsInfoObj = Goods::findOne($goods_id);
  1265. if ($goodsInfoObj) {
  1266. $service_book_desc = json_decode($goodsInfoObj->service_book_desc ?: '', true);
  1267. }
  1268. if (!empty($service_book_desc)) {
  1269. if (empty($goods['book'])) {
  1270. return [
  1271. 'code' => 1,
  1272. 'msg' => '预约日期数据为空'
  1273. ];
  1274. }
  1275. foreach ($goods['book'] as $value) {
  1276. $book_date = strtotime($value['date']);
  1277. foreach ($service_book_desc as $service_book_item) {
  1278. $service_book_date = strtotime($service_book_item['date']);
  1279. if ($book_date === $service_book_date) {
  1280. $price += $service_book_item['price'];
  1281. }
  1282. }
  1283. // if ($num_config[$value['date']] < $goods['num']) {
  1284. // return [
  1285. // 'code' => 1,
  1286. // 'msg' => '选中日期' . $value['date'] . '内暂无房源'
  1287. // ];
  1288. // }
  1289. // $price += $data_config[$value['date']];
  1290. }
  1291. $price = $price * $goods['num'];
  1292. }
  1293. }
  1294. if ($goods['product_type'] == 2) {
  1295. $price = 0;
  1296. $goods_book = GoodsBook::findOne(['goods_id' => $goods['id']]);
  1297. $service_book = Json::decode($goods_book->service_book);
  1298. //$service_book = $service_book['data'];
  1299. $date_data = $this->getDateByInterval(7);
  1300. $new_arr = [
  1301. 'data' => []
  1302. ];
  1303. foreach ($date_data as $index => $datum) {
  1304. $new_arr['data'][$index]['date'] = $datum;
  1305. $new_arr['data'][$index]['time'] = $service_book['data'][0]['time'];
  1306. }
  1307. if (!$new_arr) {
  1308. return [
  1309. 'code' => 1,
  1310. 'msg' => '数据异常'
  1311. ];
  1312. }
  1313. $price = 0;
  1314. $service_book = $new_arr['data'];
  1315. $service_book_date = array_column($service_book, NULL, 'date');
  1316. $service_book_time = $service_book_date[$goods['service']['date']]['time'];
  1317. foreach ($service_book_time as $m) {
  1318. foreach ($m['times'] as $n) {
  1319. if ($n['time'] == $goods['service']['time']) {
  1320. $price = $goods['service']['price'] * $goods['num'];
  1321. break;
  1322. }
  1323. }
  1324. if ($price > 0) {
  1325. break;
  1326. }
  1327. }
  1328. }
  1329. }
  1330. \Yii::error($price);
  1331. return $price;
  1332. }
  1333. /**
  1334. * 检查当前时间是否为指定时间范围内
  1335. * @param $begin 20:00:00
  1336. * @param $end 08:00:00
  1337. * @param $date
  1338. * @return bool true 时间范围内
  1339. */
  1340. private function checkTimeBeginEnd ($begin, $end, $date = null)
  1341. {
  1342. if (empty($begin) && empty($end)) {
  1343. return true;//
  1344. }
  1345. $date = is_null ($date) ? date ('H:i:s') : $date;
  1346. $curTime = strtotime ($date); // 当前时分
  1347. $assignTime1 = strtotime ($begin); // 获得指定分钟时间戳,00:00
  1348. $assignTime2 = strtotime ($end); // 获得指定分钟时间戳,01:00
  1349. $result = false;
  1350. if ($assignTime1 > $assignTime2) {
  1351. //跨24点
  1352. if ($curTime > $assignTime1 || $curTime < $assignTime2) {
  1353. $result = true;
  1354. }
  1355. }
  1356. if ($curTime > $assignTime1 && $curTime < $assignTime2) {
  1357. $result = true;
  1358. }
  1359. if ($assignTime1 == $assignTime2) {
  1360. $result = true;
  1361. }
  1362. return $result;
  1363. }
  1364. }