You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

219 lines
7.8 KiB

<?php
namespace backend\modules\shop\logic\delivery;
use backend\modules\shop\models\ars\Delivery;
use backend\modules\shop\models\ars\DeliveryGoods;
use backend\modules\shop\models\ars\ExpressTemplate;
use backend\modules\shop\models\ars\Order;
use backend\modules\shop\models\ars\OrderGoods;
use Yii;
use yii\db\Exception;
use yii\helpers\ArrayHelper;
class DeliveryManager
{
/**
* @param $order
* @param $delivery
* @return array
* 订单发货
*/
public static function orderDelivery($order, $delivery)
{
$transaction = Yii::$app->db->beginTransaction();
try {
$data = Yii::$app->request->post();
if (empty($data['deliveryGoods'])) {
throw new Exception('缺少发货商品信息');
}
$delivery->load($data);
$delivery->order_id = $order->id;
if (!$delivery->save()) {
throw new Exception('保存物流信息失败');
}
/*发货商品数据*/
$orderStatus = self::saveDeliveryGoods($data['deliveryGoods'], $delivery->id);
$order->status = $orderStatus;
if (!$order->save()) {
throw new Exception('order shipping_status update false');
}
if ($orderStatus == Order::STATUS_SHIPMENT_PORTION || Delivery::findOne(['!=', 'id', $delivery->id])) {
$delivery->type = Delivery::TYPE_SHIPMENT_PORTION;
} else {
$delivery->type = Delivery::TYPE_SHIPMENT_ALL;
}
if (!$delivery->save()) {
throw new Exception('保存物流信息失败');
}
$transaction->commit();
return ['status' => true];
} catch (Exception $e) {
$transaction->rollBack();
return ['status' => false, 'info' => $e->getMessage()];
}
}
/**
* @param $deliveryGoods
* @param $delivery_id
* @return int
* @throws Exception
* 保存发货商品信息
*/
private static function saveDeliveryGoods($deliveryGoods, $delivery_id)
{
$status = Order::STATUS_SHIPMENT_ALL;
foreach ($deliveryGoods as $id => $goodsCount) {
if ($goodsCount < 0) {
throw new Exception('操作异常,发货数量不能小于0');
} elseif ($goodsCount == 0) {
continue;
}
$orderGoods = OrderGoods::findOne($id);
/*如果是发货数量不是全部,订单状态为部分发货*/
$deliveryGoodsCount = DeliveryGoods::find()->where(['order_goods_id' => $id])->sum('goods_count');
if (($deliveryGoodsCount + $goodsCount) < $orderGoods->goods_count) { //如果已发货数量未达到order_goods里的数量
$status = Order::STATUS_SHIPMENT_PORTION;
} elseif (($deliveryGoodsCount + $goodsCount) > $orderGoods->goods_count) {
throw new Exception('操作异常,现发货数量超过之前缺少的发货数量');
}
$model = new DeliveryGoods();
$model->delivery_id = $delivery_id;
$model->order_goods_id = $orderGoods->id;
$model->goods_id = $orderGoods->goods_id;
$model->goods_name = $orderGoods->goods_name;
$model->goods_count = $goodsCount;
if (!$model->save()) {
throw new Exception('delivery_goods save false');
}
}
return $status;
}
/**
* @param $order_id
* @return array
* @throws Exception
* 获取发货全部商品信息
*/
public static function deliveryGoodsInfo($order_id)
{
$delivery = Delivery::find()->select('id')->where(['order_id' => $order_id])->all();
/*如果该订单是首次发货*/
if (!$delivery) {
$unShippedGoods = OrderGoods::find()->where(['order_id' => $order_id])->asArray()->all();
return ['unShipped' => $unShippedGoods];
}
$filter = [];
$deliveryIds = [];
foreach ($delivery as $value) {
$deliveryIds[] = $value->id;
}
$deliveryGoods = DeliveryGoods::find()->where(['delivery_id' => $deliveryIds])->all();
for ($i = 0; $i < count($deliveryGoods); $i++) {
$orderGoodsId = $deliveryGoods[$i]['order_goods_id'];
//以orderGoods的id为键名,以orderGoods的数量为键值,先保存到filter数组中
$filter[$orderGoodsId] = $deliveryGoods[$i]['goods_count'];
for ($j = 0; $j < count($deliveryGoods); $j++) {
//如果发货商品中有其他相同orderGoods的商品
if ($orderGoodsId == $deliveryGoods[$j]['order_goods_id'] && $i != $j) {
//商品数量叠加起来并保存
$filter[$orderGoodsId] += $deliveryGoods[$j]['goods_count'];
}
}
}
/*获取订单已发的商品和未发的商品*/
return self::getDeliveryGoodsInfo($filter, $order_id);
}
/**
* @param $filter
* @param $order_id
* @return array
* @throws Exception
* 获取订单已发的商品和未发的商品
*/
public static function getDeliveryGoodsInfo($filter, $order_id)
{
$unShipped = []; //未发货商品
foreach ($filter as $k => $value) { //键名为order_goods_id,键值为对应的已发货数量
$goodsData = self::getOrderGoodsInfo($k);
if ($value < $goodsData['goods_count']) { //如果已发货数量未达到order_goods里的数量
$lack_number = $goodsData['goods_count'] - $value;
$goodsData['lack_number'] = $lack_number;
$goodsData['goods_count'] = $lack_number;
$unShipped[] = $goodsData;
}
}
$shipped = [];
$delivery = Delivery::findAll(['order_id' => $order_id]);
foreach ($delivery as $k => $value) {
$shipped[$k]['logisticInfo'] = [
'exp_name' => '',
'invoice_no' => '',
'created_at' => '',
]; //物流公司和运单号
$shipped[$k]['goodsInfo'] = self::getDeliverGoodsInfo($value->id); //获取商品信息
}
return ['shipped' => $shipped, 'unShipped' => $unShipped];
}
/**
* @param $delivery_id
* @return array
* @throws Exception
* 通过获取订单已发货的商品信息
*/
public static function getDeliverGoodsInfo($delivery_id)
{
$goodsInfo = [];
$deliveryGoods = DeliveryGoods::find()
->where(['delivery_id' => $delivery_id])
->andWhere(['>', 'goods_count', 0])
->all();
foreach ($deliveryGoods as $value) {
$goodsData = self::getOrderGoodsInfo($value->order_goods_id);
$goodsData['delivery_number'] = $value->goods_count;
$goodsInfo[] = $goodsData;
}
return $goodsInfo;
}
/**
* @param $order_goods_id
* @return array
* @throws Exception
* 获取订单商品信息
*/
private static function getOrderGoodsInfo($order_goods_id)
{
$orderGoods = OrderGoods::findOne($order_goods_id); //通过orderGoods_id找到订单商品
if ($orderGoods) {
$goodsData = [
'id' => $orderGoods->id,
'goods_id' => $orderGoods->goods_id,
'goods_name' => $orderGoods->goods_name,
'goods_count' => $orderGoods->goods_count,
'goods_img' => $orderGoods->goods_img,
'sku_value' => $orderGoods->sku_value,
];
return $goodsData;
} else {
throw new Exception('order_goods not found');
}
}
}