CashierOrderCreate.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 上海牛之云网络科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace addon\store\model\cashier;
  11. use addon\store\model\goods\Goods;
  12. use addon\store\model\member\MemberOnceCard;
  13. use addon\store\model\order\OrderCommonCreate;
  14. use addon\store\model\stock\Stock;
  15. use app\model\system\Pay;
  16. /**
  17. * 挂单
  18. *
  19. * @author Administrator
  20. *
  21. */
  22. class CashierOrderCreate extends OrderCommonCreate
  23. {
  24. /**
  25. * 订单创建
  26. * @param unknown $data
  27. */
  28. public function create($calculate_data)
  29. {
  30. $calculate_data = $this->calculate($calculate_data);
  31. if ($calculate_data[ 'code' ] < 0)
  32. return $calculate_data;
  33. if (isset($calculate_data[ 'code' ]) && $calculate_data[ 'code' ] < 0)
  34. return $calculate_data;
  35. $check_error = $this->checkError();
  36. if ($check_error[ 'code' ] < 0) {
  37. return $check_error;
  38. }
  39. $calculate_data = $calculate_data[ 'data' ];
  40. model('store_cashier_order')->startTrans();
  41. try {
  42. $member_id = $calculate_data[ 'member_id' ] ?? 0;
  43. $pay = new Pay();
  44. $out_trade_no = $pay->createOutTradeNo($member_id);
  45. $site_id = $calculate_data[ 'site_id' ];
  46. $order_no = $this->createOrderNo($site_id, $member_id);
  47. $site_info = $calculate_data[ 'site_info' ];
  48. $site_type = $site_info[ 'site_type' ];
  49. $order_name = $calculate_data[ 'order_name' ] ?? '';
  50. $member_info = $calculate_data[ 'member_info' ] ?? [];
  51. $nickname = $member_info[ 'nickname' ] ?? '';//会员昵称
  52. $headimg = $member_info[ 'headimg' ] ?? '';
  53. $mobile = $member_info['mobile'] ?? '';
  54. $nickname = !empty($nickname) ? $nickname : $mobile;
  55. $goods_list = $calculate_data[ 'goods_list' ] ?? [];
  56. $pay_money = $calculate_data[ 'pay_money' ] ?? 0;
  57. $order_status = 'topay';//订单状态
  58. $store_id = $calculate_data[ 'store_id' ] ?? 0;
  59. $store_info = $calculate_data[ 'store_info' ] ?? [];
  60. $store_name = $store_info[ 'store_name' ] ?? '';
  61. $goods_id_array = array_unique(array_column($goods_list, 'goods_id'));
  62. $goods_ids = ',' . implode(',', $goods_id_array) . ',';
  63. $extend = $calculate_data[ 'extend' ] ?? [];
  64. $order_type = $calculate_data[ 'order_type' ];
  65. $cashier_type = $calculate_data[ 'cashier_type' ];
  66. $sell_time = $calculate_data[ 'create_time' ] ?? 0;
  67. if ($sell_time == 0) {
  68. $sell_time = time();
  69. } else {
  70. $sell_time = strtotime($sell_time);
  71. }
  72. $operator = $calculate_data['operator'] ?? [];
  73. $operator_id = $operator['uid'] ?? 0;
  74. $operator_name = $operator['username'] ?? '';
  75. //创建订单
  76. $data_order = [
  77. 'order_no' => $order_no,
  78. 'site_id' => $site_id,
  79. 'site_name' => $site_info[ 'site_name' ],
  80. 'order_name' => $order_name,
  81. 'out_trade_no' => $out_trade_no,
  82. 'status' => $order_status,
  83. 'member_id' => $member_id,
  84. 'nickname' => $nickname,
  85. 'headimg' => $headimg,
  86. 'mobile' => $mobile,
  87. 'pay_money' => $calculate_data[ 'pay_money' ],
  88. 'goods_money' => $calculate_data[ 'goods_money' ],
  89. 'real_goods_money' => $calculate_data[ 'real_goods_money' ],
  90. 'order_money' => $calculate_data[ 'order_money' ],
  91. 'store_id' => $store_id,
  92. 'store_name' => $store_name,
  93. 'goods_ids' => $goods_ids,
  94. 'create_time' => time(),
  95. 'sell_time' => $sell_time,
  96. 'order_type' => $order_type,
  97. 'remark' => $calculate_data[ 'remark' ] ?? '',
  98. 'cashier_type' => $cashier_type,
  99. 'site_type' => $calculate_data[ 'app_module' ] ?? '',
  100. 'operator_id' => $operator_id,
  101. 'operator_name' => $operator_name,
  102. ];
  103. switch($order_type){
  104. case 'goods':
  105. $is_can_refund = 1;
  106. break;
  107. case 'card':
  108. $is_can_refund = 1;
  109. break;
  110. case 'recharge':
  111. $is_can_refund = 0;
  112. break;
  113. }
  114. $data_order['is_can_refund'] = $is_can_refund ?? 0;
  115. //店铺优惠
  116. $discount_money = $calculate_data['coupon_money'] ?? 0;
  117. //抵扣金额
  118. $balance_money = $calculate_data['balance_money'] ?? 0;
  119. $point_money = $calculate_data['point_money'] ?? 0;
  120. $hongbao_money = $calculate_data['hongbao_money'] ?? 0;
  121. $offset_money = $calculate_data['offset_money'] ?? 0;
  122. // $offset_money = $balance_money + $point_money + $hongbao_money;
  123. $order_pay_data = array(
  124. 'total_balance' => $calculate_data['total_balance'] ?? 0,//总余额
  125. 'point' => $calculate_data['point'] ?? 0,
  126. 'point_money' => $calculate_data['point_money'] ?? 0,
  127. 'coupon_id' => $calculate_data['coupon_id'] ?? 0,
  128. 'coupon_money' => $calculate_data['coupon_money'] ?? 0,
  129. 'hongbao_money' => $calculate_data['hongbao_money'] ?? 0,
  130. 'hongbao_id' => $calculate_data['hongbao_id'] ?? '',
  131. 'discount_money' => $discount_money,
  132. 'offset_money' => $offset_money,
  133. );
  134. $data_order = array_merge($data_order, $order_pay_data);
  135. $order_id = model('store_cashier_order')->add($data_order);
  136. $calculate_data[ 'order_no' ] = $order_no;
  137. $calculate_data[ 'out_trade_no' ] = $out_trade_no;
  138. $order_goods_id_map = [];
  139. $can_refund_num = 0;
  140. $store_stock_model = new Stock();
  141. foreach ($goods_list as $goods_k => $goods_info) {
  142. $card_item_id = $goods_info[ 'card_item_id' ] ?? 0;
  143. //订单项目表
  144. $data_order_goods = [
  145. 'order_id' => $order_id,
  146. 'site_id' => $site_id,
  147. 'member_id' => $member_id,
  148. 'goods_id' => $goods_info[ 'goods_id' ],
  149. 'sku_id' => $goods_info[ 'sku_id' ],
  150. 'goods_name' => $goods_info[ 'goods_name' ],
  151. 'goods_image' => $goods_info[ 'goods_image' ],
  152. 'spec_name' => $goods_info[ 'spec_name' ],
  153. 'price' => $goods_info[ 'price' ],
  154. 'num' => $goods_info[ 'num' ],
  155. 'goods_money' => $goods_info[ 'goods_money' ],
  156. 'card_item_id' => $card_item_id,
  157. 'trade_type' => $goods_info[ 'trade_type' ],
  158. 'store_id' => $store_id,
  159. 'extend' => json_encode($extend),
  160. 'real_goods_money' => $goods_info['real_goods_money'],
  161. ];
  162. $item_is_can_refund = 0;
  163. if($is_can_refund){
  164. if($card_item_id == 0) {
  165. switch ($goods_info['trade_type']) {
  166. case '':
  167. $item_is_can_refund = 1;
  168. break;
  169. case 'oncecard':
  170. $item_is_can_refund = 1;
  171. break;
  172. case 'service':
  173. $item_is_can_refund = 1;
  174. break;
  175. }
  176. }
  177. }
  178. if($item_is_can_refund){
  179. $can_refund_num++;
  180. }
  181. $data_order_goods['is_can_refund'] = $item_is_can_refund ?? 0;
  182. //扣除销售库存
  183. if($order_type == 'goods'){
  184. if(empty($goods_info['trade_type'])){
  185. $sku_name = $goods_info[ 'goods_name' ].$goods_info[ 'spec_name' ];
  186. $stock_params = $data_order_goods;
  187. $stock_params['sku_name'] = $sku_name;
  188. $stock_result = $store_stock_model->decSaleStock($stock_params);
  189. if($stock_result['code'] < 0){
  190. model('store_cashier_order')->rollback();
  191. return $stock_result;
  192. }
  193. }
  194. }
  195. $order_goods_id = model('store_cashier_order_goods')->add($data_order_goods);
  196. $goods_list[$goods_k]['order_goods_id'] = $order_goods_id;
  197. $order_goods_id_map[$goods_k] = $order_goods_id;
  198. }
  199. //轮询订单项的退款
  200. if($can_refund_num == 0){
  201. model('store_cashier_order')->update(['is_can_refund' => 0], [['order_id', '=', $order_id]]);
  202. }
  203. $calculate_data[ 'order_id' ] = $order_id;
  204. $calculate_data['order_goods_id_map'] = $order_goods_id_map;
  205. //赠品项
  206. $reward_goods_list = $calculate_data['reward_goods_list'] ?? [];
  207. foreach($reward_goods_list as $k => $v){
  208. //订单项目表
  209. $reward_order_goods_data = [
  210. 'order_id' => $order_id,
  211. 'site_id' => $site_id,
  212. 'member_id' => $member_id,
  213. 'goods_id' => $v[ 'goods_id' ],
  214. 'sku_id' => $v[ 'sku_id' ],
  215. 'goods_name' => $v[ 'goods_name' ],
  216. 'goods_image' => $v[ 'goods_image' ],
  217. 'spec_name' => $v[ 'spec_name' ],
  218. 'price' => $v[ 'price' ],
  219. 'num' => $v[ 'num' ],
  220. 'goods_money' => $v[ 'goods_money' ],
  221. 'card_item_id' => 0,
  222. 'trade_type' => $v[ 'trade_type' ],
  223. 'store_id' => $store_id,
  224. 'extend' => json_encode([]),
  225. 'real_goods_money' => $v['real_goods_money'],
  226. 'is_can_refund' => 0,
  227. 'is_gift' => 1
  228. ];
  229. $refund_order_goods_id = model('store_cashier_order_goods')->add($reward_order_goods_data);
  230. //扣除销售库存
  231. if(empty($v['trade_type'])){
  232. $sku_name = $v[ 'goods_name' ].$v[ 'spec_name' ];
  233. $stock_params = $reward_order_goods_data;
  234. $stock_params['sku_name'] = $sku_name;
  235. $stock_result = $store_stock_model->decSaleStock($stock_params);
  236. if($stock_result['code'] < 0){
  237. //赠品库存不足也无所谓
  238. }
  239. }
  240. }
  241. //现在扣除余额
  242. $cashier_pay_model = new CashierOrderPay();
  243. $offset_result = $cashier_pay_model->deductOffset($calculate_data);
  244. if($offset_result['code'] < 0){
  245. model('store_cashier_order')->rollback();
  246. return $offset_result;
  247. }
  248. //创建奖励
  249. $reward_result = $cashier_pay_model->rewardAction($calculate_data);
  250. if ($reward_result['code'] < 0) {
  251. model('store_cashier_order')->rollback();
  252. return $reward_result;
  253. }
  254. model('store_cashier_order')->commit();
  255. $res = [
  256. 'order_id' => $order_id,
  257. 'out_trade_no' => $out_trade_no
  258. ];
  259. // 生成整体付费支付单据
  260. $pay->addPay($calculate_data[ 'site_id' ], $out_trade_no, $this->pay_type, $order_name, $order_name, $pay_money, '', 'CashierOrderPayNotify', '');
  261. return $this->success($res);
  262. } catch (\Exception $e) {
  263. model('store_cashier_order')->rollback();
  264. return $this->error('', $e->getMessage() . $e->getFile() . $e->getLine());
  265. }
  266. }
  267. /**
  268. * 订单创建
  269. * @param unknown $data
  270. */
  271. // public function create($data)
  272. // {
  273. // //查询出会员相关信息
  274. // $calculate_data = $this->calculate($data);
  275. // if ($calculate_data[ 'code' ] < 0)
  276. // return $calculate_data;
  277. //
  278. // $result = parent::create($calculate_data[ 'data' ]);
  279. // //订单创建成功
  280. // if ($result[ 'code' ] >= 0) {
  281. //
  282. // }
  283. // return $result;
  284. //
  285. // }
  286. /**
  287. * 订单计算
  288. * @param $data
  289. * @return mixed
  290. */
  291. public function calculate($data)
  292. {
  293. $type = $data[ 'type' ] ?? '';
  294. $data['site_type'] = $data['app_module'];
  295. $data = $this->initStore($data);//初始化仓库门店
  296. // $data = $this->initMemberAddress($data); //初始化地址
  297. $member_id = $data[ 'member_id' ] ?? 0;
  298. $data = $this->initSiteData($data); //初始化站点信息
  299. // $data = $this->initPointConfig($data);//初始化消费返积分倍率
  300. // $data = $this->initGrowthConfig($data);//初始化消费返成长值倍率
  301. if ($member_id > 0) {
  302. $data = $this->initMemberAccount($data); //初始化会员账户
  303. $data = $this->initMemberLevel($data);//初始化会员卡权益
  304. }
  305. //商品列表信息
  306. $calculate_result = $this->getItemList($data);
  307. if ($calculate_result[ 'code' ] < 0) {
  308. return $calculate_result;
  309. }
  310. //抵扣优惠计算
  311. $calculate = $calculate_result['data'];
  312. $cashier_calculate_model = new CashierOrderCalculate();
  313. $calculate_result = $cashier_calculate_model->promotionCalculate($calculate);
  314. if ($calculate_result[ 'code' ] < 0) {
  315. return $calculate_result;
  316. }
  317. return $calculate_result;
  318. }
  319. /**
  320. * 购买项列表
  321. * @param $data
  322. * @return mixed
  323. */
  324. public function getItemList($data)
  325. {
  326. $type = $data[ 'type' ];
  327. $order_name = '';
  328. $goods_list = [];
  329. $data_result = event('CashierCalculate', $data, true);
  330. if(empty($data_result)){
  331. switch ( $type ) {
  332. case 'level'://会员卡
  333. $data[ 'order_type' ] = 'level';
  334. $goods_money = 0;
  335. $sku_array = $data[ 'sku_array' ];
  336. $sku_ids = array_column($sku_array, 'member_level_id');
  337. $sku_data_array = array_column($sku_array, null, 'member_level_id');
  338. $member_level_condition = array (
  339. [ 'level_id', 'in', $sku_ids ]
  340. );
  341. $member_level_list = model('member_level')->getList($member_level_condition);
  342. if (!empty($member_level_list)) {
  343. foreach ($member_level_list as $k => $v) {
  344. $payment_rules = empty($v[ 'payment_rules' ]) ? [] : json_decode($v[ 'payment_rules' ], true);
  345. if (!empty($payment_rules)) {
  346. $item_sku_id = $v[ 'level_id' ];
  347. $sku_item = $sku_data_array[ $v[ 'level_id' ] ];
  348. $spec = $sku_item[ 'spec' ];
  349. $price = $payment_rules[ $spec ];
  350. $num = 1;
  351. $item_goods_money = $price * $num;
  352. $goods_money += $item_goods_money;
  353. switch ( $spec ) {
  354. case 'month':
  355. $spec_name = '月';
  356. break;
  357. case 'quarter':
  358. $spec_name = '季';
  359. break;
  360. case 'year':
  361. $spec_name = '年';
  362. break;
  363. }
  364. $order_name = string_split($order_name, ',', $v[ 'level_name' ]);
  365. $goods_list[] = array (
  366. 'goods_id' => $item_sku_id,
  367. 'sku_id' => $spec,
  368. 'price' => $price,
  369. 'num' => $num,
  370. 'goods_money' => $item_goods_money,
  371. 'goods_name' => $v[ 'level_name' ],
  372. 'goods_image' => '',
  373. 'spec_name' => $spec_name ?? '',
  374. 'trade_type' => 'level'
  375. );
  376. }
  377. }
  378. }
  379. $data[ 'goods_money' ] = $goods_money;
  380. $order_money = $goods_money;
  381. $pay_money = $goods_money;
  382. $data[ 'goods_list' ] = $goods_list;
  383. $data[ 'order_name' ] = $order_name;
  384. $data[ 'order_money' ] = $order_money;
  385. $data[ 'pay_money' ] = $pay_money;
  386. break;
  387. case 'goods':
  388. $data[ 'order_type' ] = 'goods';
  389. //处理产品数据
  390. $sku_array = $data[ 'sku_array' ] ?? [];
  391. //消费分为产品和买单(暂)
  392. $product_id_array = [];
  393. $money_array = [];//买单
  394. foreach ($sku_array as $k => $v) {
  395. $sku_id = $v[ 'sku_id' ] ?? 0;
  396. if ($sku_id > 0) {
  397. $product_id_array[] = $v;
  398. }
  399. $money = $v[ 'money' ] ?? 0;
  400. if ($money > 0) {
  401. $money_array[] = $money;
  402. }
  403. }
  404. $data[ 'product_array' ] = $product_id_array;
  405. $calculate_result = $this->toCalculate($data);
  406. if ($calculate_result[ 'code' ] < 0) {
  407. return $calculate_result;
  408. }
  409. $data = $calculate_result[ 'data' ];
  410. //money_array
  411. $data[ 'money_array' ] = $money_array;
  412. $calculate_result = $this->moneyCalculate($data);
  413. if ($calculate_result[ 'code' ] < 0) {
  414. return $calculate_result;
  415. }
  416. $goods_list = $calculate_result['data']['goods_list'] ?? [];
  417. if(empty($goods_list))
  418. return $this->error([], '缺少必填参数商品数据');
  419. $data = $calculate_result[ 'data' ];
  420. break;
  421. case 'card'://卡项
  422. $data[ 'order_type' ] = 'card';
  423. $shop_goods_list_result = $this->cardCalculate($data);
  424. if ($shop_goods_list_result[ 'code' ] < 0) {
  425. return $shop_goods_list_result;
  426. }
  427. $data = $shop_goods_list_result[ 'data' ];
  428. break;
  429. }
  430. }else{
  431. $data = $data_result['data'];
  432. }
  433. return $this->success($data);
  434. }
  435. /**
  436. * 待付款订单
  437. * @param $data
  438. * @return mixed
  439. */
  440. public function orderPayment($data)
  441. {
  442. $data[ 'is_payment' ] = true;
  443. $calculate_data = $this->calculate($data);
  444. if ($calculate_data[ 'code' ] < 0)
  445. return $calculate_data;
  446. return $calculate_data;
  447. }
  448. /**
  449. * 个性化计算
  450. * @param $data
  451. * @return mixed
  452. */
  453. public function toCalculate($data)
  454. {
  455. $product_array = $data[ 'product_array' ] ?? [];
  456. if (!empty($product_array)) {
  457. $shop_goods_list_result = $this->getShopGoodsList($data);
  458. if ($shop_goods_list_result[ 'code' ] < 0) {
  459. return $shop_goods_list_result;
  460. }
  461. $data = $shop_goods_list_result[ 'data' ];
  462. //商品部分的计算
  463. $data = $this->goodsCalculate($data);
  464. //卡项抵消
  465. $delivery_money = $data[ 'delivery_money' ] ?? 0;
  466. $real_goods_money = $data[ 'real_goods_money' ] ?? $data[ 'goods_money' ];
  467. $order_money = $real_goods_money + $delivery_money;
  468. $pay_money = $order_money;
  469. $data[ 'pay_money' ] = $pay_money;
  470. //总结计算
  471. $data[ 'order_money' ] = $order_money;
  472. }
  473. return $this->success($data);
  474. }
  475. /**
  476. * 卡项
  477. * @param $data
  478. */
  479. public function cardCalculate($data)
  480. {
  481. $store_id = $data[ 'store_id' ];
  482. $sku_array = $data[ 'sku_array' ];
  483. $sku_ids = array_column($sku_array, 'sku_id');
  484. $sku_num_array = array_column($sku_array, 'num', 'sku_id');
  485. // $sku_ids = $data['sku_ids'];//sku_id数组weight
  486. $site_id = $data[ 'site_id' ];
  487. $field = 'gs.site_id,gs.goods_id,gs.sku_id,gs.goods_name,gs.sku_name,gs.spec_name,gs.introduction,g.goods_image,gsd.stock,gs.price,gs.discount_price,gs.line_price,
  488. g.is_dec_stock,g.one_fenxiao_switch,g.one_fenxiao_way,g.one_fenxiao_commission,g.one_fenxiao_remark,g.two_fenxiao_switch,g.two_fenxiao_way,g.two_fenxiao_commission,
  489. g.two_fenxiao_remark,g.promotion_type,g.fenxiao_bind,g.fenxiao_qualification,g.fenxiao_withdraw_step,
  490. g.is_virtual,g.support_trade_type,g.action_type,g.action_link,g.delivery_type,g.delivery_unity_price,g.delivery_template_data,g.delivery_template_id,
  491. g.delivery_calc_type,g.virtual_verify_id,
  492. g.refund_mode,g.min_buy,g.max_buy,gs.weight,gs.volume,g.promotion_id,g.manjian_id,
  493. gs.is_consume_discount,gs.member_price,gs.discount_config,gs.discount_method,gs.card_discount_method,
  494. g.goods_type,g.is_need_yuyue,g.yuyue_need_pay,g.service_length,(gsd.sale_num + gsd.virtual_sale) as sale_num';
  495. $alias = 'gs';
  496. $join = [
  497. [ 'goods g', 'g.goods_id = gs.goods_id', 'inner' ],
  498. [ 'goods_sku_data gsd', 'gsd.sku_id = gs.sku_id', 'inner' ],
  499. ];
  500. $goods_condition = [
  501. [ 'gs.is_delete', '=', 0 ],
  502. // [ 'gs.goods_state', '=', 1 ],
  503. [ 'gs.sku_id', 'in', $sku_ids ],
  504. [ 'gs.site_id', '=', $site_id ]
  505. ];
  506. $goods_list = model('goods_sku')->getList($goods_condition, $field, '', $alias, $join);
  507. $order_name = '';
  508. $goods_num = 0;
  509. foreach ($goods_list as $k => $v) {
  510. $sku_id = $v[ 'sku_id' ];
  511. $order_name = string_split($order_name, ',', $v[ 'goods_name' ]);
  512. $item_num = $sku_num_array[ $sku_id ] ?? 1;
  513. $goods_num += $item_num;
  514. $goods_info = $v;
  515. $is_virtual = $is_virtual ?? $v[ 'is_virtual' ];
  516. $action_type = $v[ 'action_type' ];
  517. $goods_info[ 'trade_type' ] = $action_type;//业务类型
  518. $goods_info[ 'num' ] = $item_num;
  519. $goods_list[ $k ] = $goods_info;
  520. }
  521. $data[ 'goods_list' ] = $goods_list;
  522. $data[ 'order_name' ] = $order_name;
  523. $data[ 'goods_num' ] = $goods_num;
  524. $goods_list = $data[ 'goods_list' ];
  525. //具备某个参数(控制是否是单品活动)
  526. //计算订单总额 ,订单总优惠 ,
  527. $goods_money = 0;
  528. $real_goods_money = 0;
  529. foreach ($goods_list as $k => $v) {
  530. // 计算单价 可能情况 (折扣价 会员价)
  531. $goods_item = $v;
  532. //商品类主体中应该封装一个函数用于获取商品价格(可能还会有关联会员价 满减 折扣....)
  533. $price = moneyFormat($goods_item[ 'price' ]);// 我也不确定会用哪个价格 大概率是用销售价(字段名称不太合法)
  534. $member_price_result = $this->memberPrice($v, $data);
  535. if ($member_price_result[ 'code' ] >= 0) {
  536. $price = $member_price_result[ 'data' ];
  537. $goods_item[ 'is_member_price' ] = true;
  538. }
  539. $goods_item[ 'price' ] = $price;
  540. $num = $goods_item[ 'num' ];//购买数量
  541. $item_goods_money = $price * $num;//商品总额()
  542. $min_buy = $goods_item[ 'min_buy' ];
  543. $max_buy = $goods_item[ 'max_buy' ];
  544. if ($min_buy > 0 && $min_buy > $num) {
  545. $this->setError('GOODS_LESS_MIN_NUM');
  546. }
  547. if ($max_buy > 0 && $max_buy < $num) {
  548. $this->setError('GOODS_OUT_MAX_NUM');
  549. }
  550. $goods_money += $item_goods_money;
  551. $item_real_goods_money = $item_goods_money;
  552. $real_goods_money += $item_real_goods_money;
  553. $goods_item[ 'goods_money' ] = $item_goods_money;
  554. $goods_item[ 'real_goods_money' ] = $item_real_goods_money;
  555. $goods_list[ $k ] = $goods_item;
  556. }
  557. $data[ 'goods_list' ] = $goods_list;
  558. $data[ 'goods_money' ] = $goods_money;
  559. $data[ 'real_goods_money' ] = $real_goods_money;
  560. $delivery_money = $data[ 'delivery_money' ] ?? 0;
  561. $order_money = $real_goods_money + $delivery_money;
  562. $pay_money = $order_money;
  563. //总结计算
  564. $data[ 'order_money' ] = $order_money;
  565. $data[ 'pay_money' ] = $pay_money;
  566. return $this->success($data);
  567. }
  568. /**
  569. * 买单计算
  570. * @param $data
  571. */
  572. public function moneyCalculate($data)
  573. {
  574. $money_array = $data[ 'money_array' ];
  575. if (!empty($money_array)) {
  576. $goods_money = $data[ 'goods_money' ] ?? 0;
  577. $order_name = $data[ 'order_name' ] ?? '';
  578. $order_money = $data[ 'order_money' ] ?? 0;
  579. $pay_money = $data[ 'pay_money' ] ?? 0;
  580. $goods_list = $data['goods_list'] ?? [];
  581. $goods_image = 'upload/cashier/cashier-order-money.png';
  582. foreach ($money_array as $k => $v) {
  583. $num = 1;
  584. $item_price = $v;
  585. if($item_price > 0){
  586. $item_goods_money = $item_price * $num;
  587. $item_order_name = $item_goods_money . '元买单';
  588. $goods_list[] = array (
  589. 'goods_id' => 0,
  590. 'sku_id' => 0,
  591. 'price' => $item_price,
  592. 'num' => 1,
  593. 'goods_money' => $item_goods_money,
  594. 'goods_name' => $item_order_name,
  595. 'goods_image' => $goods_image,
  596. 'spec_name' => '',
  597. 'trade_type' => 'money',
  598. 'real_goods_money' => $item_goods_money
  599. );
  600. $goods_money += $item_goods_money;
  601. $order_money += $order_money;
  602. $pay_money += $pay_money;
  603. $order_name = string_split($order_name, ',', $item_order_name);
  604. }
  605. }
  606. $data[ 'goods_money' ] = $goods_money;
  607. $data[ 'real_goods_money' ] = $goods_money;
  608. $data[ 'goods_list' ] = $goods_list;
  609. $data[ 'order_name' ] = $order_name;
  610. $data[ 'order_money' ] = $goods_money;
  611. $data[ 'pay_money' ] = $goods_money;
  612. }
  613. return $this->success($data);
  614. }
  615. public function goodsCalculate($data)
  616. {
  617. $site_id = $data[ 'site_id' ];
  618. $goods_list = $data[ 'goods_list' ];
  619. $fans_id = $data[ 'fans_id' ] ?? 0;
  620. $sku_array = $data[ 'product_array' ];
  621. //具备某个参数(控制是否是单品活动)
  622. //计算订单总额 ,订单总优惠 ,
  623. $goods_money = 0;
  624. $real_goods_money = 0;
  625. foreach ($goods_list as $k => $v) {
  626. // 计算单价 可能情况 (折扣价 会员价)
  627. $goods_item = $v;
  628. $sku_id = $v[ 'sku_id' ];
  629. //商品类主体中应该封装一个函数用于获取商品价格(可能还会有关联会员价 满减 折扣....)
  630. $price = moneyFormat($goods_item[ 'price' ]);// 我也不确定会用哪个价格 大概率是用销售价(字段名称不太合法)
  631. $member_price_result = $this->memberPrice($v, $data);
  632. if ($member_price_result[ 'code' ] >= 0) {
  633. $price = $member_price_result[ 'data' ];
  634. $goods_item[ 'is_member_price' ] = true;
  635. }
  636. $num = $goods_item[ 'num' ];//购买数量
  637. $item_goods_money = $price * $num;//商品总额()
  638. $goods_item[ 'price' ] = $price;
  639. $goods_item[ 'goods_money' ] = $item_goods_money;
  640. $goods_item[ 'fans_id' ] = $fans_id;
  641. $goods_item[ 'site_id' ] = $site_id;
  642. $min_buy = $goods_item[ 'min_buy' ];
  643. $max_buy = $goods_item[ 'max_buy' ];
  644. if ($min_buy > 0 && $min_buy > $num)
  645. $this->setError('GOODS_LESS_MIN_NUM');
  646. if ($max_buy > 0 && $max_buy < $num)
  647. $this->setError('GOODS_OUT_MAX_NUM');
  648. $item_real_goods_money = $goods_item[ 'goods_money' ];
  649. $goods_item[ 'real_goods_money' ] = $item_real_goods_money;
  650. //卡项
  651. $goods_item = $this->itemCardCalculate($goods_item, $data);
  652. if (empty($goods_item)) {
  653. unset($goods_list[ $k ]);
  654. } else {
  655. $item_goods_money = $goods_item[ 'goods_money' ];
  656. $item_real_goods_money = $goods_item[ 'real_goods_money' ];
  657. }
  658. $goods_money += $item_goods_money;
  659. $real_goods_money += $item_real_goods_money;
  660. $goods_item[ 'real_goods_money' ] = $item_real_goods_money;
  661. $goods_list[ $k ] = $goods_item;
  662. }
  663. $data[ 'goods_list' ] = $goods_list;
  664. $data[ 'goods_money' ] = $goods_money;
  665. $data[ 'real_goods_money' ] = $real_goods_money;
  666. return $data;
  667. }
  668. /**
  669. * 商品卡项抵扣(抵扣会将商品单价视为0)
  670. * @param $goods_item
  671. * @param $card_item
  672. */
  673. public function itemCardCalculate($goods_item, $data)
  674. {
  675. $card_item_id = $goods_item[ 'card_item_id' ] ?? 0;
  676. $member_id = $data[ 'member_id' ];
  677. $sku_id = $goods_item[ 'sku_id' ];
  678. if ($card_item_id > 0) {
  679. $num = $goods_item[ 'num' ];
  680. $member_oncecard_model = new MemberOnceCard();
  681. $card_item_params = array (
  682. 'member_id' => $member_id,
  683. 'sku_id' => $sku_id,
  684. 'item_id' => $card_item_id
  685. );
  686. $item_card_result = $member_oncecard_model->getUseCardNum($card_item_params);
  687. if ($item_card_result[ 'code' ] < 0) {
  688. return [];
  689. }
  690. $item_card_data = $item_card_result[ 'data' ];
  691. $card_item_info = $item_card_data[ 'card_item_info' ];
  692. $card_info = $item_card_data[ 'card_info' ];
  693. $goods_item[ 'card_item_info' ] = $card_item_info;
  694. $goods_item[ 'card_info' ] = $card_info;
  695. $card_num = $item_card_data[ 'card_num' ];
  696. $goods_item[ 'card_num' ] = $card_num;
  697. if ($card_num > 0) {
  698. if ($num > $card_num) {
  699. $num = $card_num;
  700. }
  701. }
  702. $goods_item[ 'num' ] = $num;
  703. $price = 0;
  704. $goods_money = $price * $num;
  705. $goods_item[ 'price' ] = $price;
  706. $goods_item[ 'goods_money' ] = $goods_money;
  707. $goods_item[ 'real_goods_money' ] = $goods_money;
  708. }
  709. return $goods_item;
  710. }
  711. /**
  712. * 获取立即购买商品信息
  713. * @param $data
  714. * @return array
  715. */
  716. public function getShopGoodsList($data)
  717. {
  718. $store_id = $data[ 'store_id' ];
  719. $sku_array = $data[ 'product_array' ];
  720. // $sku_array = $data[ 'sku_array' ];
  721. $sku_ids = array_column($sku_array, 'sku_id');
  722. $sku_num_array = array_column($sku_array, 'num', 'sku_id');
  723. $sku_data = array_column($sku_array, null, 'sku_id');
  724. $data[ 'sku_data' ] = $sku_data;
  725. // $sku_ids = $data['sku_ids'];//sku_id数组weight
  726. $site_id = $data[ 'site_id' ];
  727. $field = 'gs.site_id,gs.goods_id,gs.sku_id,gs.goods_name,gs.sku_name,gs.spec_name,gs.introduction,g.goods_image,gsd.stock,gs.price,gs.discount_price,gs.line_price,
  728. g.is_dec_stock,g.one_fenxiao_switch,g.one_fenxiao_way,g.one_fenxiao_commission,g.one_fenxiao_remark,g.two_fenxiao_switch,g.two_fenxiao_way,g.two_fenxiao_commission,
  729. g.two_fenxiao_remark,g.promotion_type,g.fenxiao_bind,g.fenxiao_qualification,g.fenxiao_withdraw_step,
  730. g.is_virtual,g.support_trade_type,g.action_type,g.action_link,g.delivery_type,g.delivery_unity_price,g.delivery_template_data,g.delivery_template_id,
  731. g.delivery_calc_type,g.virtual_verify_id,
  732. g.refund_mode,g.min_buy,g.max_buy,gs.weight,gs.volume,g.promotion_id,g.manjian_id,
  733. gs.is_consume_discount,gs.member_price,gs.discount_config,gs.discount_method,gs.card_discount_method,
  734. g.goods_type,g.is_need_yuyue,g.yuyue_need_pay,g.service_length,osgs.stock,osgs.sale_stock,(gsd.sale_num + gsd.virtual_sale) as sale_num';
  735. $alias = 'gs';
  736. $join = [
  737. [ 'goods g', 'g.goods_id = gs.goods_id', 'inner' ],
  738. [ 'goods_sku_data gsd', 'gsd.sku_id = gs.sku_id', 'inner' ],
  739. [
  740. 'store_store_goods_sku_data osgs',
  741. 'osgs.sku_id = gs.sku_id and (osgs.store_id is null or osgs.store_id = ' . $store_id . ')',
  742. 'left'
  743. ]
  744. ];
  745. $goods_condition = [
  746. [ 'gs.is_delete', '=', 0 ],
  747. // [ 'gs.goods_state', '=', 1 ],
  748. [ 'gs.sku_id', 'in', $sku_ids ],
  749. [ 'gs.site_id', '=', $site_id ]
  750. ];
  751. $temp_goods_list = model('goods_sku')->getList($goods_condition, $field, '', $alias, $join);
  752. if (empty($temp_goods_list)) {
  753. return $this->error([], '不存在的商品!');
  754. }
  755. $column_goods_list = array_column($temp_goods_list, null, 'sku_id');
  756. $order_name = '';
  757. $goods_num = 0;
  758. $goods_list = [];
  759. //分配关联商品数据
  760. foreach ($sku_array as $k => $v) {
  761. $sku_id = $v[ 'sku_id' ];
  762. $goods_info = $column_goods_list[ $sku_id ];
  763. $order_name = string_split($order_name, ',', $goods_info[ 'goods_name' ]);
  764. $item_num = $v[ 'num' ] ?? 1;
  765. $goods_info[ 'card_item_id' ] = $v[ 'card_item_id' ] ?? 0;
  766. $goods_num += $item_num;
  767. // $item_stock = $v['sale_stock'] ?? 0;
  768. // $goods_info['stock'] = $item_stock;
  769. $is_virtual = $is_virtual ?? $goods_info[ 'is_virtual' ];
  770. $action_type = $goods_info[ 'action_type' ];
  771. $goods_info[ 'trade_type' ] = $action_type;//业务类型
  772. $goods_info[ 'num' ] = $item_num;
  773. $goods_list[ $k ] = $goods_info;
  774. }
  775. $data[ 'goods_list' ] = $goods_list;
  776. $data[ 'order_name' ] = $order_name;
  777. $data[ 'goods_num' ] = $goods_num;
  778. return $this->success($data);
  779. }
  780. public function memberPrice($goods_item, $calculate_data)
  781. {
  782. $member_level_info = $calculate_data[ 'member_level_info' ] ?? [];
  783. $promotion_type = $goods_item[ 'promotion_type' ] ?? '';
  784. $source = $calculate_data[ 'source' ] ?? '';
  785. //这里要判断如果准备享受活动的话这里就不要计算会员价了(不打算参与活动的话需要传递source)
  786. if ($promotion_type != 'discount') {
  787. // if (!empty($source)) {
  788. $goods_model = new Goods();
  789. $goods_member_price_result = $goods_model->memberPriceCalculate($goods_item, $member_level_info);
  790. return $goods_member_price_result;
  791. // }
  792. }
  793. return $this->error();
  794. }
  795. }