calculate($calculate_data); if($calculate_data['code'] < 0) return $calculate_data; if(isset($calculate_data['code']) && $calculate_data['code'] < 0) return $calculate_data; $check_error = $this->checkError(); if($check_error['code'] < 0) return $check_error; $calculate_data = $calculate_data['data']; model('order')->startTrans(); try{ $member_id = $calculate_data['member_id'] ?? 0; $pay_model = new Pay(); $out_trade_no = $pay_model->createOutTradeNo($member_id); $site_id = $calculate_data['site_id']; $order_no = $this->createOrderNo($site_id,$member_id); $site_info = $calculate_data['site_info']; $order_type = 5;//收银订单 $order_name = $calculate_data['order_name'] ?? ''; $member_info = $calculate_data['member_info'] ?? []; $nickname = $member_info['nickname'] ?? '';//会员昵称 $headimg = $member_info['headimg'] ?? ''; $mobile = $member_info['mobile'] ?? ''; $nickname = !empty($nickname) ? $nickname : $mobile; $goods_list = $calculate_data['goods_list'] ?? []; $pay_money = $calculate_data['pay_money'] ?? 0; $order_status = '0';//订单状态 $store_id = $calculate_data['store_id'] ?? 0; $store_info = $calculate_data['store_info'] ?? []; $store_name = $store_info['store_name'] ?? ''; $extend = $calculate_data['extend'] ?? []; $sell_time = $calculate_data['create_time'] ?? 0; if($sell_time == 0) $sell_time = time(); else $sell_time = strtotime($sell_time); $cashier_order_type = $calculate_data['cashier_order_type']; $operator = $calculate_data['operator'] ?? []; $operator_id = $operator['uid'] ?? 0; $operator_name = $operator['username'] ?? ''; $order_from = 'cashier'; $order_from_name = (new CashierOrder)->order_from_list[$order_from]['name'] ?? ''; $cashier_order_model = new CashierOrder(); //创建订单 $data_order = [ 'order_no' => $order_no, 'site_id' => $site_id, 'site_name' => $site_info['name'], 'order_name' => $order_name, 'out_trade_no' => $out_trade_no, 'member_id' => $member_id, 'nickname' => $nickname, 'headimg' => $headimg, 'mobile' => $mobile, 'pay_money' => $calculate_data['pay_money'], 'goods_money' => $calculate_data['goods_money'], 'real_goods_money' => $calculate_data['real_goods_money'], 'order_money' => $calculate_data['order_money'], 'store_id' => $store_id, 'create_time' => time(), 'order_from' => $order_from, 'order_from_name' => $order_from_name, 'order_type' => $order_type, 'order_type_name' => '收银订单', 'order_status' => 0, 'order_status_name' => '待支付', 'order_status_action' => json_encode($cashier_order_model->order_status[0],JSON_UNESCAPED_UNICODE), 'cashier_sell_time' => $sell_time, 'cashier_order_type' => $cashier_order_type, 'cashier_operator_id' => $operator_id, 'cashier_operator_name' => $operator_name, 'order_scene' => 'cashier', 'goods_num' => $calculate_data['goods_num'] ?? 1, 'remark' => $calculate_data['remark'] ?? '', 'legumes_integral_use' => $calculate_data['legumes_integral_use'] ?? 0, 'legumes_integral_money' => $calculate_data['legumes_integral_money'] ?? 0, ]; $order_id = model('order')->add($data_order); $calculate_data['order_no'] = $order_no; $calculate_data['out_trade_no'] = $out_trade_no; $order_goods_id_map = []; foreach($goods_list as $goods_k => $goods_info){ $card_item_id = $goods_info['card_item_id'] ?? 0; //订单项目表 $data_order_goods = [ 'order_id' => $order_id, 'site_id' => $site_id, 'member_id' => $member_id, 'goods_id' => $goods_info['goods_id'], 'sku_id' => $goods_info['sku_id'], 'goods_name' => $goods_info['goods_name'], 'sku_name' => $goods_info['sku_name'], 'sku_no' => $goods_info['sku_no'] ?? '', 'sku_image' => $goods_info['goods_image'] ?? '', 'spec_name' => $goods_info['spec_name'] ?? '', 'price' => $goods_info['price'], 'num' => $goods_info['num'], 'goods_money' => $goods_info['goods_money'], 'is_virtual' => $goods_info['is_virtual'] ?? 1, 'goods_class' => $goods_info['goods_class'], 'goods_class_name' => $goods_info['goods_class_name'], 'store_id' => $store_id, 'extend' => json_encode($extend), 'real_goods_money' => $goods_info['real_goods_money'], 'card_item_id' => $card_item_id, 'card_promotion_money' => $goods_info['card_promotion_money'] ?? 0,//次卡抵扣优惠 'legumes_integral_use' => $goods_info['legumes_integral_use'] ?? 0, 'legumes_integral_money' => $goods_info['legumes_integral_money'] ?? 0, ]; //扣除库存 if(in_array($cashier_order_type,['goods','card'])){ $stock_result = $this->skuDecStock($goods_info,$site_id,$store_id); if($stock_result['code'] < 0){ model('order')->rollback(); return $stock_result; } } $order_goods_id = model('order_goods')->add($data_order_goods); $goods_list[$goods_k]['order_goods_id'] = $order_goods_id; $order_goods_id_map[$goods_k] = $order_goods_id; } $calculate_data['order_id'] = $order_id; model('order')->commit(); $log_data = [ 'order_id' => $order_id, 'action' => 'create', 'site_id' => $site_id, 'member_id' => $member_id ]; (new OrderLog())->addLog($log_data); $res = [ 'order_id' => $order_id, 'out_trade_no' => $out_trade_no ]; // 生成整体付费支付单据 $pay_model->addPay($site_id,$out_trade_no,$this->pay_type,$order_name,$order_name,$pay_money,'','CashierOrderPayNotify',''); //执行自动关闭 $this->addOrderCronClose($order_id,$site_id); //增加关闭订单自动事件 return $this->success($res); } catch(\Exception $e){ model('order')->rollback(); return $this->error('',$e->getMessage().$e->getFile().$e->getLine()); } } /** * 计算 * @param $data * @return mixed */ public function calculate($data){ $data = $this->initStore($data);//初始化仓库门店 $member_id = $data['member_id'] ?? 0; $data = $this->initSiteData($data); //初始化站点信息 //商品列表信息 $calculate_result = $this->getItemList($data); if($calculate_result['code'] < 0) return $calculate_result; return $calculate_result; } /** * 购买项列表 * @param $data * @return mixed */ public function getItemList($data){ $type = $data['type']; $data_result = event('CashierCalculate',$data,TRUE); if(empty($data_result)){ switch($type){ case 'goods': $data['cashier_order_type'] = 'goods'; //处理产品数据 $sku_array = $data['sku_array'] ?? []; //消费分为产品和买单(暂) $product_id_array = []; $money_array = [];//买单 foreach($sku_array as $k => $v){ $money = $v['money'] ?? 0; $sku_id = $v['sku_id'] ?? 0; $num = $v['num'] ?? 1; if($money > 0){ $money_array[] = ['money' => $money,'sku_id' => $sku_id,'num' => $num]; } else{ if($sku_id > 0){ $product_id_array[] = $v; } } } $data['product_array'] = $product_id_array; $calculate_result = $this->toCalculate($data); if($calculate_result['code'] < 0){ return $calculate_result; } $data = $calculate_result['data']; //money_array $data['money_array'] = $money_array; $calculate_result = $this->moneyCalculate($data); if($calculate_result['code'] < 0){ return $calculate_result; } $goods_list = $calculate_result['data']['goods_list'] ?? []; if(empty($goods_list)) return $this->error([],'缺少必填参数商品数据'); $data = $calculate_result['data']; break; case 'card'://卡项 $data['cashier_order_type'] = 'card'; $shop_goods_list_result = $this->cardCalculate($data); if($shop_goods_list_result['code'] < 0){ return $shop_goods_list_result; } $data = $shop_goods_list_result['data']; break; } } else{ $data = $data_result['data']; } return $this->success($data); } /** * 个性化(主要用于商品)计算 * @param $data * @return mixed */ public function toCalculate($data){ $product_array = $data['product_array'] ?? []; if(!empty($product_array)){ $shop_goods_list_result = $this->getShopGoodsList($data); if($shop_goods_list_result['code'] < 0){ return $shop_goods_list_result; } $data = $shop_goods_list_result['data']; //商品部分的计算 $data = $this->goodsCalculate($data); //卡项抵消 $delivery_money = $data['delivery_money'] ?? 0; $real_goods_money = $data['real_goods_money'] ?? $data['goods_money']; $order_money = moneyFormat($real_goods_money + $delivery_money); $pay_money = $order_money; $data['pay_money'] = $pay_money; //总结计算 $data['order_money'] = $order_money; } return $this->success($data); } /** * 买单计算 * @param $data */ public function moneyCalculate($data){ $money_array = $data['money_array']; if(!empty($money_array)){ $goods_money = $data['goods_money'] ?? 0; $order_name = $data['order_name'] ?? ''; $order_money = $data['order_money'] ?? 0; $pay_money = $data['pay_money'] ?? 0; $goods_list = $data['goods_list'] ?? []; // 收银订单默认图片 $defaultImg = (new ConfigModel())->getDefaultImg($data['site_id'])['data']['value']; $goods_image = $defaultImg['cashier'] ?? 'upload/cashier/cashier-order-money.png'; // $goods_image = 'public/resource/cashier/cashier-order-money.png'; $goods_num = 0; foreach($money_array as $k => $v){ $num = $v['num'] ?? 1; $item_price = $v['money']; if($item_price > 0){ $sku_id = $v['sku_id']; $item_goods_money = moneyFormat($item_price * $num); $item_order_name = $item_goods_money.'元买单'; $sku_name = '在线买单'; $goods_list[] = [ 'goods_id' => 0, 'sku_id' => $sku_id, 'price' => $item_price, 'num' => $num, 'goods_money' => $item_goods_money, 'goods_name' => $item_order_name, 'sku_name' => $sku_name, 'goods_image' => $goods_image, 'spec_name' => '', 'goods_class' => 'money', 'goods_class_name' => '在线买单', 'real_goods_money' => $item_goods_money ]; $goods_money += $item_goods_money; $order_money += $item_goods_money; $pay_money += $item_goods_money; $order_name = string_split($order_name, ",", $item_order_name); $goods_num += $num; } } // 豆豆积分抵扣处理 $useIntegral = $data['legumes_integral_use'] ?? 0; if((float)$useIntegral > 0){ // 获取剩余可用积分 $legumesInfo = (new Legumes())->getAllSiteHoldInfo((int)$data['member_id']); $integralSurplus = $legumesInfo['surplus_use_integral'] ?? 0; // 判断:积分是否充足 if($useIntegral > $integralSurplus) return $this->error('','积分不足'); // $useIntegral = $useIntegral > $integralSurplus ? $integralSurplus : $useIntegral; // 积分抵扣 $data['legumes_integral_use'] = (float)$useIntegral; $data['legumes_integral_money'] = (float)$useIntegral; $pay_money -= (float)$data['legumes_integral_use']; // 根据商品金额比例 分配使用的豆豆积分 $totalGoodsPrice = array_sum(array_column($goods_list, 'real_goods_money')); foreach($goods_list as &$goodsInfo){ $rate = sprintf("%.2f", $goodsInfo['real_goods_money'] / $totalGoodsPrice); $reduceAmount = sprintf("%.2f", $data['legumes_integral_use'] * $rate); $goodsInfo['legumes_integral_use'] = $goodsInfo['legumes_integral_money'] = $reduceAmount; $goodsInfo['real_goods_money'] -= $reduceAmount; } } $data['goods_money'] = $goods_money; $data['real_goods_money'] = $pay_money; $data['goods_list'] = $goods_list; $data['order_name'] = $order_name; $data['order_money'] = $order_money; $data['goods_num'] = $goods_num; $data['pay_money'] = $pay_money; } return $this->success($data); } public function goodsCalculate($data){ $site_id = $data['site_id']; $goods_list = $data['goods_list']; $sku_array = $data['product_array']; //具备某个参数(控制是否是单品活动) //计算订单总额 ,订单总优惠 , $goods_money = 0; $real_goods_money = 0; foreach($goods_list as $k => $v){ // 计算单价 可能情况 (折扣价 会员价) $goods_item = $v; $sku_id = $v['sku_id']; //商品类主体中应该封装一个函数用于获取商品价格(可能还会有关联会员价 满减 折扣....) if($v['is_unify_pirce'] == 1){ $price = moneyFormat($v['sku_price']); } else{ $price = moneyFormat($v['price']); } $v['price'] = $price; $member_price_result = $this->getGoodsMemberPrice($v,$data); if($member_price_result['code'] >= 0){ $price = $member_price_result['data']; $goods_item['is_member_price'] = TRUE; } $num = $goods_item['num'];//购买数量 $item_goods_money = moneyFormat($price * $num);//商品总额() $goods_item['price'] = $price; $goods_item['goods_money'] = $item_goods_money; $goods_item['site_id'] = $site_id; // $min_buy = $goods_item[ 'min_buy' ]; // $max_buy = $goods_item[ 'max_buy' ]; // if ($min_buy > 0 && $min_buy > $num) // $this->setError('GOODS_LESS_MIN_NUM'); // // if ($max_buy > 0 && $max_buy < $num) // $this->setError('GOODS_OUT_MAX_NUM'); $item_real_goods_money = $goods_item['goods_money']; $goods_item['real_goods_money'] = $item_real_goods_money; //卡项 $goods_item = $this->itemCardCalculate($goods_item,$data); if(empty($goods_item)){ unset($goods_list[$k]); continue; } else{ $item_goods_money = $goods_item['goods_money']; $item_real_goods_money = $goods_item['real_goods_money']; } $goods_money += $item_goods_money; $real_goods_money += $item_real_goods_money; $goods_item['real_goods_money'] = $item_real_goods_money; $goods_list[$k] = $goods_item; } $data['goods_list'] = $goods_list; $data['goods_money'] = $goods_money; $data['real_goods_money'] = $real_goods_money; return $data; } /** * 商品卡项抵扣(抵扣会将商品单价视为0) * @param $goods_item * @param $card_item */ public function itemCardCalculate($goods_item,$data){ $card_item_id = $goods_item['card_item_id'] ?? 0; $member_id = $data['member_id']; $sku_id = $goods_item['sku_id']; if($card_item_id > 0){ $num = $goods_item['num']; $member_card_model = new MemberCard(); $card_item_params = [ 'member_id' => $member_id, 'sku_id' => $sku_id, 'item_id' => $card_item_id ]; $item_card_result = $member_card_model->getUseCardNum($card_item_params); if($item_card_result['code'] < 0){ return []; } $item_card_data = $item_card_result['data']; $card_item_info = $item_card_data['card_item_info']; $card_info = $item_card_data['card_info']; $goods_item['card_item_info'] = $card_item_info; $goods_item['card_info'] = $card_info; $card_num = $item_card_data['card_num']; $goods_item['card_num'] = $card_num; if($card_num > 0){ if($num > $card_num){ $num = $card_num; } } $goods_item['num'] = $num; $price = $goods_item['price']; $card_promotion_money = moneyFormat($price * $num); $goods_money = moneyFormat($price * $num); $goods_item['price'] = $price; $goods_item['goods_money'] = $goods_money; $real_goods_money = moneyFormat($goods_money - $card_promotion_money); $real_goods_money = $real_goods_money < 0 ? 0 : $real_goods_money; $goods_item['card_promotion_money'] = $card_promotion_money; $goods_item['real_goods_money'] = $real_goods_money; } return $goods_item; } /** * 获取立即购买商品信息 * @param $data * @return array */ public function getShopGoodsList($data){ $store_id = $data['store_id']; $sku_array = $data['product_array']; $sku_ids = array_column($sku_array,'sku_id'); $sku_data = array_column($sku_array,NULL,'sku_id'); $data['sku_data'] = $sku_data; $site_id = $data['site_id']; $field = 'gs.site_id,gs.goods_id,gs.sku_id,gs.goods_name,gs.sku_name,gs.spec_name,gs.sku_image,g.goods_image,gs.price as sku_price,gs.sku_no, g.is_virtual,g.min_buy,g.max_buy,g.unit,sgs.stock, g.goods_class,g.goods_class_name,sgs.price,(sgs.sale_num + g.virtual_sale) as sale_num,g.is_unify_pirce'; $alias = 'gs'; $join = [ ['goods g','g.goods_id = gs.goods_id','inner'], [ 'store_goods_sku sgs', 'sgs.sku_id = gs.sku_id and sgs.store_id = '.$store_id, 'left' ] ]; $goods_condition = [ ['gs.is_delete','=',0], ['sgs.status','=',1], // [ 'gs.goods_state', '=', 1 ], ['gs.sku_id','in',$sku_ids], ['gs.site_id','=',$site_id] ]; $temp_goods_list = model('goods_sku')->getList($goods_condition,$field,'',$alias,$join); if(empty($temp_goods_list)){ return $this->error([],'商品不存在!'); } foreach($temp_goods_list as $k => $v){ $temp_goods_list[$k]['sale_num'] = numberFormat($temp_goods_list[$k]['sale_num']); $temp_goods_list[$k]['stock'] = numberFormat($temp_goods_list[$k]['stock']); } $column_goods_list = array_column($temp_goods_list,NULL,'sku_id'); $order_name = ''; $goods_num = 0; $goods_list = []; //分配关联商品数据 foreach($sku_array as $k => $v){ $sku_id = $v['sku_id']; $goods_info = $column_goods_list[$sku_id] ?? 0; if(empty($goods_info)){ return $this->error([],'商品不存在!'); } $order_name = string_split($order_name,",",$goods_info['goods_name']); $item_num = $v['num'] ?? 1; if($goods_info['goods_class'] != 6){ if($item_num < 1){ return $this->error([],'商品数量不能小于1!'); } } else{ if($item_num < 0){ return $this->error([],'称重重量不能小于0!'); } } $goods_info['card_item_id'] = $v['card_item_id'] ?? 0; $goods_num += $item_num; $is_virtual = $is_virtual ?? $goods_info['is_virtual']; // $goods_info[ 'trade_type' ] = $goods_info['goods_class'];//业务类型 $goods_info['num'] = $item_num; $goods_info['sku_image'] = explode(',',$goods_info['sku_image'])[0] ?? ''; $goods_info['goods_image'] = explode(',',$goods_info['goods_image'])[0] ?? ''; $goods_list[$k] = $goods_info; } $data['goods_list'] = $goods_list; $data['order_name'] = $order_name; $data['goods_num'] = $goods_num; return $this->success($data); } /** * 卡项的计算 * @param $data */ public function cardCalculate($data){ $store_id = $data['store_id']; $sku_array = $data['sku_array']; $sku_ids = array_column($sku_array,'sku_id'); $sku_num_array = array_column($sku_array,'num','sku_id'); // $sku_ids = $data['sku_ids'];//sku_id数组weight $site_id = $data['site_id']; $field = 'gs.site_id,gs.goods_id,gs.sku_id,gs.goods_name,gs.sku_name,gs.spec_name,gs.sku_image,g.goods_image,sgs.price,gs.price as sku_price,gs.sku_no, g.is_virtual,g.unit,sgs.stock, g.min_buy,g.max_buy, g.goods_class,g.goods_class_name,(sgs.sale_num + g.virtual_sale) as sale_num,g.is_unify_pirce'; $alias = 'gs'; $join = [ ['goods g','g.goods_id = gs.goods_id','inner'], [ 'store_goods_sku sgs', 'sgs.sku_id = gs.sku_id and sgs.store_id = '.$store_id, 'left' ] ]; $goods_condition = [ ['gs.is_delete','=',0], ['sgs.status','=',1], ['gs.sku_id','in',$sku_ids], ['gs.site_id','=',$site_id], ]; $goods_list = model('goods_sku')->getList($goods_condition,$field,'',$alias,$join); $order_name = ''; $goods_num = 0; foreach($goods_list as $k => $v){ $sku_id = $v['sku_id']; $order_name = string_split($order_name,",",$v['goods_name']); $item_num = $sku_num_array[$sku_id] ?? 1; $goods_num += $item_num; $goods_info = $v; $is_virtual = $is_virtual ?? $v['is_virtual']; $goods_info['num'] = $item_num; $goods_info['sale_num'] = numberFormat($goods_info['sale_num']); $goods_info['stock'] = numberFormat($goods_info['stock']); $goods_list[$k] = $goods_info; } $data['goods_list'] = $goods_list; $data['order_name'] = $order_name; $data['goods_num'] = $goods_num; $goods_list = $data['goods_list']; //具备某个参数(控制是否是单品活动) //计算订单总额 ,订单总优惠 , $goods_money = 0; $real_goods_money = 0; foreach($goods_list as $k => $v){ // 计算单价 可能情况 (折扣价 会员价) $goods_item = $v; //商品类主体中应该封装一个函数用于获取商品价格(可能还会有关联会员价 满减 折扣....) if($v['is_unify_pirce'] == 1){ $price = moneyFormat($v['sku_price']); } else{ $price = moneyFormat($v['price']); } $v['price'] = $price; $member_price_result = $this->getGoodsMemberPrice($v,$data); if($member_price_result['code'] >= 0){ $price = $member_price_result['data']; $goods_item['is_member_price'] = TRUE; } $goods_item['price'] = $price; $num = $goods_item['num'];//购买数量 $item_goods_money = moneyFormat($price * $num);//商品总额() // $min_buy = $goods_item[ 'min_buy' ]; // $max_buy = $goods_item[ 'max_buy' ]; // if ($min_buy > 0 && $min_buy > $num) { // $this->setError('GOODS_LESS_MIN_NUM'); // } // if ($max_buy > 0 && $max_buy < $num) { // $this->setError('GOODS_OUT_MAX_NUM'); // } $goods_money += $item_goods_money; $item_real_goods_money = $item_goods_money; $real_goods_money += $item_real_goods_money; $goods_item['goods_money'] = $item_goods_money; $goods_item['real_goods_money'] = $item_real_goods_money; $goods_item['sku_image'] = explode(',',$goods_item['sku_image'])[0] ?? ''; $goods_item['goods_image'] = explode(',',$goods_item['goods_image'])[0] ?? ''; $goods_list[$k] = $goods_item; } $data['goods_list'] = $goods_list; $data['goods_money'] = moneyFormat($goods_money); $data['real_goods_money'] = moneyFormat($real_goods_money); $delivery_money = $data['delivery_money'] ?? 0; $order_money = moneyFormat($real_goods_money + $delivery_money); $pay_money = $order_money; //总结计算 $data['order_money'] = $order_money; $data['pay_money'] = $pay_money; return $this->success($data); } /** * 设置错误 * @param $error_code */ protected function setError($error_code,$error_printf = []){ $this->error = $error_code; $this->error_printf = $error_printf; } /** * 校验错误 * @return bool */ public function checkError(){ if(!empty($this->error)){ $error_msg = $this->getError(); return $this->error(['error_code' => $this->error,'error_msg' => $error_msg],$error_msg); } else{ return $this->success(); } } /** * 获取错误 * @return mixed */ protected function getError(){ $error_list = [ 'GOODS_STOCK_EMPTY' => '%s库存不足%s', 'ADDRESS_EMPTY' => '%s收货地址必须选择!%s', 'TRADE_TYPE_EMPTY' => '%s配送方式必须选择!%s', 'GOODS_LESS_MIN_NUM' => '%s商品数量不能小于最小购买量%s', 'GOODS_OUT_MAX_NUM' => '%s商品数量不能超出最大购买量%s', 'MOBILE_EMPTY' => '%s联系人手机号不能为空%s', 'NAME_EMPTY' => '%s联系人名称不能为空%s', 'YUEYUE_ERROR' => '%s %s', ]; $error_msg = $error_list[$this->error] ?? ''; return sprintf($error_msg,$this->error_printf[0] ?? '',$this->error_printf[1] ?? ''); } }