multi-store/app/common/service/RefundOrderService.php

157 lines
5.8 KiB
PHP

<?php
namespace app\common\service;
use app\common\enum\OrderEnum;
use app\common\logic\CommissionnLogic;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_finance_flow\StoreFinanceFlow;
use app\common\model\store_finance_flow_product\StoreFinanceFlowProduct;
use app\common\model\store_order\StoreOrder;
use app\common\model\store_order_cart_info\StoreOrderCartInfo;
use app\common\service\pay\PayTool;
use Exception;
use support\exception\BusinessException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
class RefundOrderService
{
public function refund($userId, $params): void
{
Db::startTrans();
try {
$order = StoreOrder::where('id', $params['id'])->where('uid', $userId)->find();
if (empty($order)) {
throw new BusinessException('订单不存在');
}
if (!$order->allowRefund()) {
throw new BusinessException('订单不能退款');
}
$orderCartProducts = StoreOrderCartInfo::where('oid', $order['id'])->whereIn('id', $params['old_cart_id'])->select();
foreach ($orderCartProducts as $orderCartProduct) {
if ($orderCartProduct['is_pay'] != 1 || $orderCartProduct['status'] != StoreOrderCartInfo::StatusWait) {
throw new BusinessException('订单商品状态异常');
}
}
$refundAmount = $this->calculate($orderCartProducts);
$this->refundMoney($order, $refundAmount);
$this->updateProductStock($orderCartProducts);
$this->updateOrderProductStatus($order, $params['old_cart_id']);
$this->updateOrderStatus($order, $refundAmount, count($params['old_cart_id']));
$this->refundCommission($order, $orderCartProducts);
Db::commit();
} catch (Exception $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
/**
* 计算退款金额
* @param $orderCartProducts
* @return string
*/
public function calculate($orderCartProducts): string
{
$amount = '0.00';
foreach ($orderCartProducts as $orderCartProduct) {
if ($orderCartProduct['is_pay'] == 1 && $orderCartProduct['status'] == StoreOrderCartInfo::StatusWait) {
$amount = bcadd($amount, $orderCartProduct['total_price'], 2);
}
}
return $amount;
}
/**
* 资金原路退回
* @param $order
* @param $refundAmount
* @return void
*/
public function refundMoney($order, $refundAmount): void
{
$payTool = PayTool::getInstance($order['pay_type']);
$payTool->refund($refundAmount, $order);
}
/**
* 更新商品库存
* @param $orderCartProducts
* @throws Exception
*/
public function updateProductStock($orderCartProducts): void
{
$updateData = [];
foreach ($orderCartProducts as $product) {
$storeBranchProductId = StoreBranchProduct::where('store_id', $product['store_id'])
->where('product_id', $product['product_id'])
->withTrashed()->value('id');
if ($storeBranchProductId) {
$updateData[] = [
'id' => $storeBranchProductId,
'stock' => ['inc', $product['cart_num']],
'sales' => ['dec', $product['cart_num']],
];
}
}
(new StoreBranchProduct())->saveAll($updateData);
}
/**
* 更新订单商品状态
* @param $order
* @param $orderCartIds
* @return void
* @throws DbException
*/
public function updateOrderProductStatus($order, $orderCartIds): void
{
StoreOrderCartInfo::whereIn('id', $orderCartIds)->where('oid', $order['id'])->update(['is_pay' => -1, 'status' => OrderEnum::REFUND_STATUS_FINISH]);
}
/**
* 更新订单状态
* @param $order
* @param $refundAmount
* @param $refundNum
* @return void
* @throws DbException
*/
public function updateOrderStatus($order, $refundAmount, $refundNum): void
{
$orderProductCount = StoreOrderCartInfo::where('oid', $order['id'])->count();
if (($order['refund_num'] + $refundNum) == $orderProductCount) {
// 全部退款完成,订单状态改为已退款
$order->refund_status = OrderEnum::REFUND_STATUS_FINISH;
$order->status = OrderEnum::RECEIVED_BACK;
}
$order->refund_price = bcadd($order['refund_price'], $refundAmount, 2);
$order->refund_num += $refundNum;
$order->save();
}
/**
* 退佣金
* @param $order
* @param $storeOrderProducts
* @return void
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function refundCommission($order, $storeOrderProducts): void
{
$productIds = array_unique(array_column($storeOrderProducts->toArray(), 'product_id'));
StoreFinanceFlowProduct::where('oid', $order['id'])->whereIn('product_id', $productIds)->update(['number' => 0, 'update_time' => strtotime(time())]);
$village_uid = StoreFinanceFlow::where('order_id', $order['id'])->where('financial_type', 14)->value('other_uid');
$brigade_uid = StoreFinanceFlow::where('order_id', $order['id'])->where('financial_type', 15)->value('other_uid');
$transaction_id = StoreFinanceFlow::where('order_id', $order['id'])->value('transaction_id');
StoreFinanceFlow::where('order_id', $order['id'])->update(['delete_time' => time()]);
CommissionnLogic::setStore($order, $village_uid, $brigade_uid, $transaction_id);
}
}