初始上传
This commit is contained in:
444
app/model/order/ordercreate/DeliveryTool.php
Executable file
444
app/model/order/ordercreate/DeliveryTool.php
Executable file
@@ -0,0 +1,444 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 上海牛之云网络科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace app\model\order\ordercreate;
|
||||
|
||||
use app\model\express\Express;
|
||||
use app\model\express\Local;
|
||||
use app\model\store\Store;
|
||||
|
||||
/**
|
||||
* 订单创建 可调用的工具类
|
||||
*/
|
||||
trait DeliveryTool
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取配送配置数据
|
||||
* @return true
|
||||
*/
|
||||
public function getDeliveryData()
|
||||
{
|
||||
$curr_store_id = $this->param['store_id'] ?? 0;
|
||||
$jielong_id = $this->param['jielong_id'] ?? 0;
|
||||
$express_type = [];
|
||||
if ($this->is_virtual == 0) {
|
||||
//todo 没有活动才会参与计算
|
||||
if (empty($this->promotion_type)) $trade_result = event('OrderCreateCommonData', ['type' => 'trade', 'order_object' => $this], true);
|
||||
if (!empty($trade_result)) {
|
||||
if ($trade_result['code'] >= 0) {
|
||||
$express_type = $trade_result['data'];
|
||||
}
|
||||
} else {
|
||||
$deliver_type_sort = $this->config('delivery_type_sort');
|
||||
$deliver_sort_list = explode(',', $deliver_type_sort['value']['deliver_type']);
|
||||
//根据当前的定位查询本地配送门店或自提门店
|
||||
$latitude = $this->param['latitude'] ?? 0;
|
||||
$longitude = $this->param['longitude'] ?? 0;
|
||||
foreach ($deliver_sort_list as $type) {
|
||||
// 物流
|
||||
if ($type == 'express') {
|
||||
$express_config = $this->config('express');
|
||||
if ($express_config['is_use'] == 1) {
|
||||
$title = $express_config['value']['express_name'];
|
||||
if ($title == '') {
|
||||
$title = Express::express_type['express']['title'];
|
||||
}
|
||||
|
||||
$express_type[] = ['title' => $title, 'name' => 'express'];
|
||||
}
|
||||
|
||||
}
|
||||
// 自提
|
||||
if ($type == 'store') {
|
||||
$store_config = $this->config('store');
|
||||
if ($store_config['is_use'] == 1) {
|
||||
//根据坐标查询门店
|
||||
$store_model = new Store();
|
||||
$store_condition = [
|
||||
['site_id', '=', $this->site_id],
|
||||
//['is_pickup', '=', 1],
|
||||
//['status', '=', 1],
|
||||
['', 'exp', \think\facade\Db::raw('(is_pickup = 1 && status = 1) or store_id = '.$curr_store_id)],
|
||||
['is_frozen', '=', 0],
|
||||
];
|
||||
//考虑门店库存和上下架,进一步过滤可以选择的门店
|
||||
$this->getAvailableStoreIds();
|
||||
if($this->available_store_ids != 'all'){
|
||||
$store_condition[] = ['store_id', 'in', $this->available_store_ids];
|
||||
}
|
||||
$latlng = [
|
||||
'lat' => $latitude,
|
||||
'lng' => $longitude,
|
||||
];
|
||||
$store_list = $store_model->getLocationStoreList($store_condition, '*', $latlng)['data'] ?? [];
|
||||
$store_list = $this->currStoreToFirstData($store_list);
|
||||
$title = $store_config['value']['store_name'];
|
||||
if ($title == '') {
|
||||
$title = Express::express_type['store']['title'];
|
||||
}
|
||||
$express_type[] = ['title' => $title, 'name' => 'store', 'store_list' => $store_list];
|
||||
}
|
||||
|
||||
}
|
||||
// 外卖
|
||||
if ($type == 'local') {
|
||||
$local_config = $this->config('local');
|
||||
if ($local_config['is_use'] == 1) {
|
||||
//查询本店的通讯地址
|
||||
$title = $local_config['value']['local_name'];
|
||||
if ($title == '') {
|
||||
$title = '外卖配送';
|
||||
}
|
||||
$store_model = new Store();
|
||||
$store_condition = [
|
||||
['site_id', '=', $this->site_id],
|
||||
];
|
||||
if (addon_is_exit('store', $this->site_id)) {
|
||||
//$store_condition[] = ['is_o2o', '=', 1];
|
||||
//$store_condition[] = ['status', '=', 1];
|
||||
$store_condition[] = ['', 'exp', \think\facade\Db::raw('(is_o2o = 1 && status = 1) or store_id = '.$curr_store_id)];
|
||||
$store_condition[] = ['is_frozen', '=', 0];
|
||||
} else {
|
||||
$store_condition[] = ['is_default', '=', 1];
|
||||
}
|
||||
//考虑门店库存和上下架,进一步过滤可以选择的门店
|
||||
$this->getAvailableStoreIds();
|
||||
if($this->available_store_ids != 'all'){
|
||||
$store_condition[] = ['store_id', 'in', $this->available_store_ids];
|
||||
}
|
||||
$latlng = [
|
||||
'lat' => $latitude,
|
||||
'lng' => $longitude,
|
||||
];
|
||||
$store_list_result = $store_model->getLocationStoreList($store_condition, '*', $latlng);
|
||||
$store_list = $store_list_result['data'];
|
||||
$store_list = $this->currStoreToFirstData($store_list);
|
||||
$express_type[] = ['title' => $title, 'name' => 'local', 'store_list' => $store_list];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($jielong_id)){
|
||||
//社群接龙只保留门店自提
|
||||
foreach ($express_type as $key => $value){
|
||||
if($value['name'] != 'store'){
|
||||
unset($express_type[$key]);
|
||||
continue;
|
||||
}
|
||||
$store_list = $value['store_list'] ?? [];
|
||||
if(empty($store_list)){
|
||||
$this->setError(1, '没有可以自提的门店!');
|
||||
}
|
||||
}
|
||||
$this->jielong_info = model('promotion_jielong')->getInfo([ [ 'jielong_id', '=', $jielong_id ] ], '*');
|
||||
$express_type = array_values($express_type);
|
||||
}
|
||||
$this->delivery['express_type'] = $express_type;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送计算
|
||||
* @return true
|
||||
*/
|
||||
public function calculateDelivery()
|
||||
{
|
||||
//整理配送时间格式
|
||||
$this->getDeliveryTime();
|
||||
//计算邮费
|
||||
if ($this->is_virtual == 1) {
|
||||
//虚拟订单 运费为0
|
||||
$delivery_money = 0;
|
||||
$this->delivery['delivery_type'] = '';
|
||||
} else {
|
||||
$deliver_type_sort = $this->config('delivery_type_sort');
|
||||
$deliver_sort_list = explode(',', $deliver_type_sort['value']['deliver_type']);
|
||||
//查询店铺是否开启快递配送
|
||||
$express_config = $this->config('express');
|
||||
|
||||
//查询店铺是否开启门店自提
|
||||
$store_config = $this->config('store');
|
||||
|
||||
//查询店铺是否开启外卖配送
|
||||
$local_config = $this->config('local');
|
||||
//todo 没有活动才会参与计算
|
||||
if (empty($this->promotion_type)) {
|
||||
$trade_calc_result = event('OrderCreateCommonData', ['type' => 'trade_calc', 'order_object' => $this, 'deliver_sort_list' => $deliver_sort_list], true);
|
||||
}
|
||||
if (empty($trade_calc_result)) {
|
||||
//如果本地配送开启, 则查询出本地配送的配置
|
||||
if ($local_config['is_use'] == 1 && isset($this->param['delivery']['store_id'])) {
|
||||
$local_model = new Local();
|
||||
$local_info = $local_model->getLocalInfo([['site_id', '=', $this->site_id], ['store_id', '=', $this->param['delivery']['store_id']]])['data'];
|
||||
$this->delivery['local']['info'] = $local_info;
|
||||
} else {
|
||||
$this->delivery['local']['info'] = [];
|
||||
}
|
||||
$delivery_array = $this->param['delivery'] ?? [];
|
||||
$delivery_type = $delivery_array['delivery_type'] ?? 'express';
|
||||
if ($delivery_type == 'store') {
|
||||
//门店自提
|
||||
$delivery_money = 0;
|
||||
$this->delivery['delivery_type'] = 'store';
|
||||
if ($store_config['is_use'] == 0) {
|
||||
$this->setError(1, '门店自提方式未开启!');
|
||||
}
|
||||
if (empty($this->param['delivery']['store_id'])) {
|
||||
$this->setError(1, '门店未选择!');
|
||||
}
|
||||
$this->delivery['store_id'] = $this->param['delivery']['store_id'] ?? 0;
|
||||
$this->storeOrderData();
|
||||
$this->store_id = $this->param['delivery']['store_id'] ?? 0;
|
||||
|
||||
} else {
|
||||
if (empty($this->delivery['member_address'])) {
|
||||
$delivery_money = 0;
|
||||
$this->delivery['delivery_type'] = 'express';
|
||||
$this->setError(1, '未配置默认收货地址!');
|
||||
} else {
|
||||
if ($delivery_type == 'express') {
|
||||
if ($express_config['is_use'] == 1) {
|
||||
//物流配送
|
||||
$express = new Express();
|
||||
$express_fee_result = $express->calculate(['order_object' => $this]);
|
||||
if ($express_fee_result['code'] < 0) {
|
||||
$this->setError(1, $express_fee_result['message']);
|
||||
$delivery_fee = 0;
|
||||
} else {
|
||||
$delivery_fee = $express_fee_result['data']['delivery_fee'];
|
||||
}
|
||||
} else {
|
||||
$this->setError(1, '物流配送方式未开启!');
|
||||
$delivery_fee = 0;
|
||||
}
|
||||
$this->delivery_money = $delivery_fee;
|
||||
$this->delivery['delivery_type'] = 'express';
|
||||
} else if ($delivery_type == 'local') {
|
||||
//外卖配送
|
||||
$delivery_money = 0;
|
||||
$this->delivery['delivery_type'] = 'local';
|
||||
if ($local_config['is_use'] == 0) {
|
||||
$this->setError(1, '外卖配送方式未开启!');
|
||||
} else {
|
||||
if (empty($this->param['delivery']['store_id'])) {
|
||||
$this->setError(1, '门店未选择!');
|
||||
}
|
||||
|
||||
$this->store_id = $this->param['delivery']['store_id'] ?? 0;
|
||||
|
||||
$local_model = new Local();
|
||||
$local_result = $local_model->calculate(['order_object' => $this]);
|
||||
|
||||
$this->delivery['start_money'] = 0;
|
||||
if ($local_result['code'] < 0) {
|
||||
$this->delivery['start_money'] = $local_result['data']['start_money_array'][0] ?? 0;
|
||||
$this->setError($local_result['data']['code'], $local_result['message'], 1);
|
||||
} else {
|
||||
$this->delivery_money = $local_result['data']['delivery_money'];
|
||||
if (!empty($local_result['data']['code'])) {
|
||||
$this->setError($local_result['data']['code'], $local_result['data']['error'], 1);
|
||||
}
|
||||
}
|
||||
|
||||
$this->delivery['error'] = $this->error;
|
||||
$this->delivery['error_msg'] = $this->error_msg;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//检测门店是否可用
|
||||
if($this->available_store_ids != 'all' && !empty($this->store_id)){
|
||||
$available_store_ids = $this->available_store_ids ? explode(',', trim($this->available_store_ids, ',')) : [];
|
||||
if(!in_array($this->store_id,$available_store_ids)){
|
||||
$this->setError(1, '所选门店不可用!');
|
||||
}
|
||||
}
|
||||
|
||||
//是否符合免邮
|
||||
if ($this->is_free_delivery) {
|
||||
$this->delivery_money = 0;
|
||||
}
|
||||
//重新计算订单总额
|
||||
$this->getOrderMoney();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验商品项的配送方式支持方式
|
||||
* @param $goods
|
||||
* @return true
|
||||
*/
|
||||
public function checkDeliveryType($goods)
|
||||
{
|
||||
$delivery_type = $this->param['delivery']['delivery_type'] ?? '';
|
||||
if ($delivery_type && strpos($goods['support_trade_type'], $delivery_type) === false) {
|
||||
$express_type_list = $this->config('delivery_type');
|
||||
$delivery_type_name = $express_type_list[$delivery_type] ?? '';
|
||||
$this->error = 1;
|
||||
$this->error_msg = '有商品不支持' . $delivery_type_name;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量校验配送方式
|
||||
* @return true
|
||||
*/
|
||||
public function batchCheckDeliveryType()
|
||||
{
|
||||
$delivery_type = $this->param['delivery']['delivery_type'] ?? '';
|
||||
if (!$this->is_virtual) {
|
||||
if (!$delivery_type) {
|
||||
$this->error = 1;
|
||||
$this->error_msg = '请选择有效的配送方式';
|
||||
} else {
|
||||
$express_type_list = $this->config('delivery_type');
|
||||
$delivery_type_name = $express_type_list[$delivery_type] ?? '';
|
||||
foreach ($this->goods_list as $v) {
|
||||
if (strpos($v['support_trade_type'], $delivery_type) === false) {
|
||||
$this->error = 1;
|
||||
//$this->error_msg = '商品' . $v['goods_name'] . '不支持' . $delivery_type_name;
|
||||
$this->error_msg = '部分商品不支持' . $delivery_type_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配送时间格式
|
||||
* @return true
|
||||
*/
|
||||
public function getDeliveryTime(){
|
||||
$delivery_time = $this->param['delivery']['buyer_ask_delivery_time'] ?? [];
|
||||
$remark = '';
|
||||
$start_date = $delivery_time['start_date'] ?? '';
|
||||
$end_date = $delivery_time['end_date'] ?? '';
|
||||
if($start_date && $end_date){
|
||||
$start_time = strtotime($start_date);
|
||||
$end_time = strtotime($end_date);
|
||||
$start_ymd = date('Y-m-d', $start_time);
|
||||
$end_ymd = date('Y-m-d', $end_time);
|
||||
if($start_ymd == $end_ymd){
|
||||
$remark = $start_ymd.' '.date('H:i:s', $start_time).' ~ '.date('H:i:s', $end_time);
|
||||
}else{
|
||||
$remark = $start_date .' ~ '. $end_date;
|
||||
}
|
||||
|
||||
}else if($start_date && !$end_date){
|
||||
$remark = $start_date;
|
||||
$start_time = strtotime($start_date);
|
||||
}else if(!$start_date && $end_date){
|
||||
$remark = $end_date;
|
||||
$end_time = strtotime($end_date);
|
||||
}
|
||||
|
||||
if(!empty($this->jielong_id)){
|
||||
$jielong_info = model('promotion_jielong')->getInfo([ [ 'jielong_id', '=', $this->jielong_id ] ], '*');
|
||||
if(!empty($jielong_info)){
|
||||
$start_time = $jielong_info['take_start_time'];
|
||||
$start_date = date("Y-m-d",$jielong_info['take_start_time']);
|
||||
$end_time = $jielong_info['take_end_time'];
|
||||
$end_date = date("Y-m-d",$jielong_info['take_end_time']);
|
||||
$remark = $start_date.' ~ '.$end_date;
|
||||
}
|
||||
}
|
||||
|
||||
$this->delivery['buyer_ask_delivery_time'] = [
|
||||
'start_date' => $start_date,
|
||||
'start_time' => $start_time ?? '',
|
||||
'end_date' => $end_date,
|
||||
'end_time' => $end_time ?? '',
|
||||
'remark' => $remark
|
||||
];
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可以购买的门店数据
|
||||
* @return int[]|string[]
|
||||
*/
|
||||
protected function getAvailableStoreIds()
|
||||
{
|
||||
if(addon_is_exit('store')){
|
||||
//要注意是独立库存还是总部库存
|
||||
$alias = 'sgs';
|
||||
$join = [
|
||||
['store s', 'sgs.store_id = s.store_id', 'inner'],
|
||||
['goods_sku gs', 'sgs.sku_id = gs.sku_id', 'inner'],
|
||||
];
|
||||
$condition = [
|
||||
['sgs.sku_id', 'in', array_column($this->goods_list, 'sku_id')],
|
||||
['sgs.status', '=', 1],
|
||||
];
|
||||
if($this->available_store_ids != 'all'){
|
||||
$condition[] = ['sgs.store_id', 'in', $this->available_store_ids];
|
||||
}
|
||||
$field = "sgs.sku_id,sgs.store_id,IF(s.stock_type = 'store', sgs.stock, gs.stock) as stock";
|
||||
$store_sku_list = model('store_goods_sku')->getList($condition, $field, '', $alias, $join);
|
||||
|
||||
$store_id_data = [];
|
||||
$sku_num_data = array_column($this->goods_list, 'num','sku_id');
|
||||
$goods_model = new \app\model\goods\Goods();
|
||||
foreach($store_sku_list as $store_sku_info){
|
||||
//如果库存不足尝试库存转换
|
||||
if($store_sku_info['stock'] < $sku_num_data[$store_sku_info['sku_id']]){
|
||||
$store_sku_info = $goods_model->goodsStockTransform([$store_sku_info], $store_sku_info['store_id'], 'store')[0];
|
||||
}
|
||||
if($store_sku_info['stock'] >= $sku_num_data[$store_sku_info['sku_id']]){
|
||||
$store_id_data[$store_sku_info['store_id']][$store_sku_info['sku_id']] = $store_sku_info['sku_id'];
|
||||
}
|
||||
}
|
||||
foreach($store_id_data as $store_id=>$data){
|
||||
if(count($data) < count($sku_num_data)){
|
||||
unset($store_id_data[$store_id]);
|
||||
}
|
||||
}
|
||||
$this->available_store_ids = array_keys($store_id_data);
|
||||
$curr_store_id = $this->param['store_id'] ?? 0;
|
||||
if(!in_array($curr_store_id, $this->available_store_ids)){
|
||||
$this->available_store_ids[] = $curr_store_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前门店排到首位
|
||||
* @param $store_list
|
||||
* @return array
|
||||
*/
|
||||
protected function currStoreToFirstData($store_list)
|
||||
{
|
||||
$curr_store_id = $this->param['store_id'] ?? 0;
|
||||
$curr_store = null;
|
||||
foreach($store_list as $key=>$store_info){
|
||||
if($store_info['store_id'] == $curr_store_id){
|
||||
$curr_store = $store_info;
|
||||
unset($store_list[$key]);
|
||||
}
|
||||
}
|
||||
if(!is_null($curr_store)){
|
||||
array_unshift($store_list, $curr_store);
|
||||
}
|
||||
return array_values($store_list);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user