| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- <?php
- /**
- * Created by PhpStorm.
- * Name: 芸众商城系统
- * Author: 广州市芸众信息科技有限公司
- * Profile: 广州市芸众信息科技有限公司位于国际商贸中心的广州,专注于移动电子商务生态系统打造,拥有芸众社交电商系统、区块链数字资产管理系统、供应链管理系统、电子合同等产品/服务。官网 :www.yunzmall.com www.yunzshop.com
- * Date: 2021/12/23
- * Time: 15:39
- */
- namespace app\frontend\modules\refund\services\operation;
- use app\backend\modules\refund\services\operation\RefundOperation;
- use app\common\exceptions\AppException;
- use app\common\models\OrderGoods;
- use app\common\models\refund\RefundGoodsLog;
- use app\common\models\refund\RefundProcessLog;
- use app\common\modules\refund\RefundOrderFactory;
- use app\frontend\modules\member\listeners\Order;
- use app\frontend\modules\refund\services\RefundMessageService;
- use app\common\events\order\OrderRefundApplyEvent;
- use app\common\services\SystemMsgService;
- use app\frontend\modules\refund\services\RefundService;
- class RefundApply extends RefundOperation
- {
- protected $statusAfterChanged = self::WAIT_CHECK;
- protected $name = '申请退款';
- protected $timeField = 'create_time'; //操作时间
- protected $refundGoods;
- public function __construct(array $attributes = [])
- {
- parent::__construct($attributes);
- if (!isset($this->uid) && \YunShop::app()->getMemberId()) {
- $this->uid = \YunShop::app()->getMemberId();
- }
- }
- protected function updateBefore()
- {
- //售后记录必须是这笔订单所属会员的
- if (!isset($this->uid) || $this->uid != $this->order->uid) {
- $this->uid = $this->order->uid;
- }
- $refundApplyData = $this->getRequest()->only([
- 'reason', 'content', 'refund_type', 'order_id','receive_status','refund_way_type',
- ]);
- if (is_array($this->getRequest()->input('images'))) {
- $refundApplyData['images'] = $this->getRequest()->input('images');
- } else {
- $refundApplyData['images'] = $this->getRequest()->input('images') ? json_decode($this->getRequest()->input('images'), true):[];
- }
- //退款总金额,换货售后退款金额为0
- if ($refundApplyData['refund_type'] == static::REFUND_TYPE_EXCHANGE_GOODS) {
- $refundApplyData['price'] = 0;
- } else {
- //申请退款金额
- $refundApplyData['apply_price'] = $this->getRefundApplyPrice();
- //退款运费金额
- $refundApplyData['freight_price'] = $this->getFreightPrice();
- //退款其他金额
- $refundApplyData['other_price'] = $this->getOtherPrice();
- //售后金额不能大于订单实付金额
- $price = bcadd($refundApplyData['apply_price'], ($refundApplyData['freight_price'] + $refundApplyData['other_price']),2);
- $refundApplyData['price'] = $this->finalAmount($price);
- }
- $this->fill($this->finalFillAttribute($refundApplyData));
- $this->relatedPluginOrder()->handleAfterSales($this);//交给对应的订单做最后的业务处理
- $this->backWay()->init($this); //走退货方式验证
- }
- protected function updateAfter()
- {
- $this->order->refund_id = $this->id;
- if (!$this->order->save()) {
- throw new AppException('订单退款状态更变失败');
- }
- if ($this->getRefundGoods()) {
- $this->createOrderGoodsRefundLog($this->getRefundGoods());
- }
- $this->setBackWay(); //保存退货方式内容
- }
- //订单商品申请退款金额和
- protected function getRefundApplyPrice()
- {
- $refund_price = collect($this->getRefundGoods())->sum('refund_price');
- return min($this->order->price, $refund_price);
- }
- protected function getFreightPrice()
- {
- return $this->getRequest()->input('freight_price',0);
- }
- protected function getOtherPrice()
- {
- return $this->getRequest()->input('other_price',0);
- }
- //最终退款金额,插件订单可以修改最终退款金额
- protected function finalAmount($price)
- {
- return min($this->order->price, $price);
- }
- protected function finalFillAttribute($data)
- {
- if (!isset($data['part_refund'])) {
- $data['part_refund'] = $this->getPartRefund();
- }
- if (!isset($data['refund_sn'])) {
- $data['refund_sn'] = RefundService::createOrderRN();
- }
- return $data;
- }
- public function getPartRefund()
- {
- return $this->relatedPluginOrder()->applyPratRefundStatus($this->getRefundGoods(), $this->getRequest());
- // if ($this->getRequest()->input('refund_type') == RefundApply::REFUND_TYPE_EXCHANGE_GOODS) {
- // return 0;
- // }
- //
- // //订单商品总数量
- // $orderGoodsNum = $this->order->orderGoods->sum('total');
- //
- // $currentApplyNum = array_sum(array_column($this->getRefundGoods(), 'total'));
- //
- //
- // //一次性申请全部商品退款
- // if ($orderGoodsNum == $currentApplyNum) {
- // return 3; //申请全额退款
- // }
- //
- // //todo 问题:已经换过一次货的商品,是否需要过滤掉换货售后记录的退款数量?
- // //订单已售后总数量,这里要不要过滤换货售后
- // $refundedNum = RefundGoodsLog::where('order_id',$this->order->id)
- // //->where('refund_type', '!=', self::REFUND_TYPE_EXCHANGE_GOODS)
- // ->sum('refund_total');
- //
- // if ($orderGoodsNum == ($currentApplyNum + $refundedNum)) {
- // return 2; //最后一次退款
- // }
- //
- // return 1; //部分退款
- }
- public function requestRefundGoods()
- {
- if (is_array($this->getRequest()->input('order_goods'))) {
- $refundGoods = $this->getRequest()->input('order_goods');
- } else {
- $refundGoods = json_decode($this->getRequest()->input('order_goods'), true);
- }
- return $refundGoods;
- }
- /**
- * @return array
- * @throws AppException
- */
- protected function getRefundGoods()
- {
- if (isset($refundGoods)) {
- return $this->refundGoods;
- }
- $refundGoods = $this->requestRefundGoods();
- if (!$refundGoods) {
- $refundGoods = $this->order->orderGoods->map(function (OrderGoods $orderGoods) {
- //已退款金额
- $refundedAmount = $orderGoods->manyRefundedGoodsLog->sum('refund_price');
- //已退款数量
- $refundedTotal = $orderGoods->getRefundTotal();
- return [
- 'id'=> $orderGoods->id,
- 'total'=> max($orderGoods->total - $refundedTotal,0),
- 'refund_price'=> max($orderGoods->payment_amount - $refundedAmount,0),
- ];
- })->values()->all();
- } else {
- $totalArrays = array_column($refundGoods,'total','id');
- $refundGoods = $this->order->orderGoods->whereIn('id',array_keys($totalArrays))->map(function ($orderGoods) use ($totalArrays) {
- $refund_price = ($orderGoods->payment_amount / $orderGoods->total) * $totalArrays[$orderGoods->id];
- return ['id'=> $orderGoods->id, 'total'=>$totalArrays[$orderGoods->id],'refund_price'=> $refund_price];
- })->values()->all();
- }
- if (!$refundGoods) {
- throw new AppException('无商品可售后');
- }
- return $this->refundGoods = $refundGoods;
- }
- //售后申请监听
- protected function afterEventClass()
- {
- return new OrderRefundApplyEvent($this);
- }
- protected function writeLog()
- {
- $detail = [
- '售后类型:'. $this->getRefundTypeName()[$this->refund_type],
- $this->refund_type == static::REFUND_TYPE_EXCHANGE_GOODS ? '': '退款金额:'.$this->price,
- $this->freight_price?'运费:'. $this->freight_price :'',
- $this->other_price?'其他费用:'. $this->other_price :'',
- '售后原因:'.$this->reason,
- '说明:'.$this->content,
- ];
- $processLog = RefundProcessLog::logInstance($this, RefundProcessLog::OPERATOR_MEMBER);
- $processLog->setAttribute('operate_type', RefundProcessLog::OPERATE_APPLY);
- $processLog->saveLog($detail,request()->input());
- }
- protected function sendMessage()
- {
- //通知买家
- RefundMessageService::applyRefundNotice($this);
- RefundMessageService::applyRefundNoticeBuyer($this);
- //【系統消息通知】
- (new SystemMsgService())->applyRefundNotice($this);
- if (app('plugins')->isEnabled('instation-message')) {
- //开启了站内消息插件
- event(new \Yunshop\InstationMessage\event\OrderRefundApplyEvent($this));
- }
- }
- }
|