Files
xk-api-yii/common/handlers/orderHandler/BaseOrderSalesHandler.php
2024-09-19 11:32:39 +08:00

352 lines
13 KiB
PHP

<?php
namespace common\handlers\orderHandler;
use common\events\OrderEvent;
use common\forms\order\CommonLog;
use common\helpers\FuncHelper;
use common\jobs\OrderAutoComments;
use common\jobs\WechatShareingQueryJob;
use common\models\ClerkIntegralGive;
use common\models\IntegralLog;
use common\models\Mall;
use common\models\MallSubAmount;
use common\models\Order;
use common\models\OrderDetail;
use common\models\OrderRefund;
use common\models\OrderSubAmount;
use common\models\OrderWechatSubAmount;
use common\models\PaymentOrder;
use common\models\RelationAgentMallClerk;
use common\models\RelationClerkUser;
use common\models\SupplierDrugMall;
use common\models\User;
use common\services\BankService;
use common\services\WechatService;
use yii\base\Exception;
/**
* @property User $user
*/
abstract class BaseOrderSalesHandler extends BaseOrderHandler
{
/* @var Order $order */
public $order;
/* @var User $user */
public $user;
/* @var OrderDetail[] $orderDetailList */
public $orderDetailList;
public function handle()
{
$this->sales();
}
protected function sales()
{
/**@var OrderEvent $event */
$event = $this->event;
CommonLog::saveLog($event->order->id,'过售后sales事件start');
try {
$this->order = $event->order;
$this->user = User::find()->where(['id' => $this->order->user_id])->one();
$orderRefundList = OrderRefund::find()->where([
'order_id' => $this->order->id,
'is_delete' => 0,
])->all();
// 已退款的订单详情id列表
$notOrderDetailIdList = [];
if ($orderRefundList) {
/* @var OrderRefund[] $orderRefundList */
foreach ($orderRefundList as $orderRefund) {
//退货退款,为拒绝,并且未实际退款,退款进行中不进行
if ($orderRefund->status != 3 && in_array($orderRefund->type, [1, 3]) && $orderRefund->is_refund == 0) {
return false;
} else if ($orderRefund->status != 3 && $orderRefund->type == 2 && $orderRefund->is_confirm == 0) {
return false;
}
}
}
$query = OrderDetail::find()->where(['order_id' => $this->order->id, 'is_delete' => 0])->with('goods', 'refund','goods.supplierDrugMall');
if(!empty($notOrderDetailIdList)){
$query->andWhere(['not in', 'id', $notOrderDetailIdList]);
};
$this->orderDetailList = $query->all();
$this->action();
CommonLog::saveLog($event->order->id,'过售后sales事件end');
} catch (\Exception $e) {
\Yii::error($e);
}
}
protected function action()
{
// 发放佣金
// $res = $this->giveShareMoney();
// 过售后成为分销商
// $this->becomeShare();
// 发放积分
$this->giveClerkIntegral();
$this->giveIntegral();
//如果是微信支付,添加分账方并请求分账
$this->wechatSub();
//确认分账 - 没有异步也就没有确认
// $this->confirmSubAmount();
// 发放余额
// $this->giveBalance();
// 入驻商订单金额转到商户余额
// $this->transferToMch($res);
// 消费升级会员等级
// $this->level();
//自动评价
$this->autoOrderCommon();
}
public function wechatSub()
{
try {
$order = $this->event->order;
if(!$order->is_shareing){
return true;
}
$payment = PaymentOrder::find()->where([
'order_no' => $order->order_no,
'is_pay' => 1,
'pay_type' => 1
])->one();
if(!$payment){
throw new Exception('未找到支付订单');
}
CommonLog::saveLog($this->event->order->id,'微信请求分账start');
//添加分账方
$data = [
'receiver' => [
'type' => 'MERCHANT_ID',
'account' => \Yii::$app->params['huiliao_wechat']['merchant_id'],
'name'=>\Yii::$app->params['huiliao_wechat']['full_name'],
'relation_type' => 'DISTRIBUTOR',
]
];
$wechat = new WechatService();
$res = $wechat->profitSharingAddReceiver($data);
if(!$res){
throw new Exception('添加分账接收方失败');
}
$shareing_percent = \Yii::$app->params['company']['shareing_percent'];
//请求分账 - 分账金额低于0.01的不再分账,直接完结分账
$sub_amount = bcmul($order->total_pay_price,bcdiv($shareing_percent,100,2),2);
$sub = new OrderWechatSubAmount();
$sub->order_no = $order->order_no;
$sub->total_amount = $order->total_pay_price;
$sub->sub_order_no = FuncHelper::generate_order_no('SH');
$sub->sub_id = \Yii::$app->params['huiliao_wechat']['merchant_id'];
$sub->sub_percent = $shareing_percent;
$sub->sub_amount = $sub_amount;
if(bccomp($sub_amount,0,2) == 1){
//单次分账
$data = [
'transaction_id' => $payment->transaction_id,
'out_order_no' => $sub->sub_order_no,
'receivers' => [
[
"type" => "MERCHANT_ID",
"account" => \Yii::$app->params['huiliao_wechat']['merchant_id'],
"amount" => intval(bcmul($sub->sub_amount,100,0)),
"description" => '订单单次分账,分账来源商户号:'.\Yii::$app->params['wechat']['merchant_id']
]
]
];
$sub->data = json_encode($data);
$sub->saveOrFail();
$wechat = new WechatService();
$wechat->profitSharing($data);
}else{
//完结分账
$data = [
'transaction_id' => $payment->transaction_id,
'out_order_no' => $sub->sub_order_no,
'description' => '订单完成分账'
];
$sub->data = json_encode($data);
$sub->saveOrFail();
$wechat = new WechatService();
$wechat->profitSharingFinish($data);
}
//添加分账查询队列
//定时查询
\Yii::$app->queue->delay(30)->push(new WechatShareingQueryJob([
'shareing' => $sub,
'key' => 0
]));
}catch (\Exception $exception){
CommonLog::saveLog($this->event->order->id,'微信请求分账异常:'.$exception->getMessage());
}
}
// public function confirmSubAmount()
// {
// try {
// CommonLog::saveLog($this->event->order->id,'分账确认start');
//
// $order = $this->event->order;
// if($order->pay_type==4)
// {
// $orderSubAmount = OrderSubAmount::find()->where([
// 'mall_id' => $order->mall_id,
// 'order_id' => $order->id,
// 'status' => 1,
// ])->orderBy('id desc')->one();
// if($orderSubAmount)
// {
// $data = json_decode($orderSubAmount['data'],true);
//
// $param = [];
// $param['merOrderId'] = $data['merOrderId'];
// $param['platformAmount'] = $data['platformAmount'];
// $param['subOrders'] = $data['subOrders'];
// $re = (new BankService())->orderComplete($data);
// if($re){
// OrderSubAmount::updateAll(['status'=>2],[
// 'mall_id' => $order->mall_id,
// 'order_id' => $order->id,
// 'status' => 1,
// ]);
// }else{
// OrderSubAmount::updateAll(['status'=>-1],[
// 'mall_id' => $order->mall_id,
// 'order_id' => $order->id,
// 'status' => 1,
// ]);
// }
// $orderSubAmount->save();
// }
// }
// CommonLog::saveLog($this->event->order->id,'分账确认end');
// }catch (\Exception $exception){
// CommonLog::saveLog($this->event->order->id,'分账确认异常:'.$exception->getMessage());
// }
// }
private function autoOrderCommon()
{
$mallSetting = (new Mall())->getMallSetting(['has_order_evaluate', 'order_evaluate_day']);
if ($mallSetting['has_order_evaluate']) {
foreach ($this->orderDetailList as $orderDetail) {
if ($orderDetail instanceof OrderDetail) {
CommonLog::saveLog($this->event->order->id,'添加自动评价队列');
\Yii::$app->queue->delay(60 * 60 * 24 * (int)$mallSetting['order_evaluate_day'])->push(new OrderAutoComments([
'orderDetail' => $orderDetail,
]));
}
}
}
}
//用户积分发放
protected function giveIntegral()
{
$transaction = \Yii::$app->db->beginTransaction();
try {
CommonLog::saveLog($this->event->order->id,'用户积分发放start');
foreach ($this->orderDetailList as $orderDetail) {
if ($orderDetail->goods->give_integral_type == 1) {
$sendIntegral = bcmul($orderDetail->goods->give_integral,$orderDetail->num,4);
} else {
$sendIntegral = bcmul($orderDetail->total_price,bcdiv($orderDetail->goods->give_integral,100,2),4);
}
if(bccomp($sendIntegral,0,4) <=0){
continue;
}
$user = User::findOne($this->order->user_id);
if(!$user->updateCounters(['current_integral_common' => $sendIntegral,'total_integral_common'=>$sendIntegral])){
throw new Exception('更新账户失败');
};
$integralLog = new IntegralLog();
$integralLog->mall_id = \Yii::$app->mall->id;
$integralLog->user_id = $this->order->user_id;
$integralLog->type = 1;
$integralLog->integral = $sendIntegral;
$integralLog->desc = "订单购买赠送积分";
$integralLog->custom_desc = json_encode(['msg' => '用户积分变动说明']);
$integralLog->order_id = $this->order->id;
$integralLog->order_detail_id = $orderDetail->id;
if (!$integralLog->save()) {
throw new \Exception($this->getErrorMsg($integralLog));
}
}
$transaction->commit();
CommonLog::saveLog($this->event->order->id,'用户积分发放end');
return true;
} catch (\Exception $e) {
$transaction->rollBack();
CommonLog::saveLog($this->event->order->id,'用户积分发货异常:'.$e->getMessage());
return false;
}
}
// 店员积分发放
protected function giveClerkIntegral()
{
$transaction = \Yii::$app->db->beginTransaction();
try {
CommonLog::saveLog($this->event->order->id,'店员积分发放start');
foreach ($this->orderDetailList as $orderDetail) {
if(!$this->order->clerk_id){
continue;//如果没有对应店员不处理
}
if(!$orderDetail->supplier_id || !$orderDetail->agent_id){
continue;//没有积分关系
}
$sendIntegral = bcmul($orderDetail->total_price,$orderDetail->dy_integral,4);
if(bccomp($sendIntegral,0,4) <= 0){
continue;
}
$model = new ClerkIntegralGive();
$model->agent_id = $orderDetail->agent_id;
$model->supplier_id = $orderDetail->supplier_id;
$model->mall_id = \Yii::$app->mall->id;
$model->user_id = $this->order->clerk_id;
$model->order_id = $this->order->id;
$model->order_detail_id = $orderDetail->id;
$model->integral = $sendIntegral;
$model->saveOrFail();
$user = User::findOne($this->order->clerk_id);
if(!$user->updateCounters(['current_integral' => $sendIntegral,'total_integral'=>$sendIntegral])){
throw new Exception('更新账户失败');
};
}
$transaction->commit();
CommonLog::saveLog($this->event->order->id,'店员积分发放end');
return true;
} catch (\Exception $e) {
$transaction->rollBack();
CommonLog::saveLog($this->event->order->id,'店员积分发放异常:'.$e->getMessage());
return false;
}
}
}