mirror of
https://gitee.com/ShopeX/OMS
synced 2026-03-23 02:45:33 +08:00
1056 lines
43 KiB
PHP
1056 lines
43 KiB
PHP
<?php
|
||
/**
|
||
* Copyright 2012-2026 ShopeX (https://www.shopex.cn)
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
*/
|
||
|
||
|
||
class ome_refund_apply
|
||
{
|
||
|
||
/**
|
||
* 显示退款申请页面
|
||
* @access public
|
||
* @param int $order_id 订单ID
|
||
* @param decimal 退款金额
|
||
* @param $addon 附加属性,用于特殊情况处理
|
||
* @param int $return_id 退款ID
|
||
* @return html
|
||
*/
|
||
public function show_refund_html($order_id,$return_id='0',$refund_money='0',$addon=null){
|
||
$render = app::get('ome')->render();
|
||
$msg = array('result'=>true, 'msg'=>'');
|
||
if(!$order_id){
|
||
$msg['result'] = false;
|
||
$msg['msg'] = '订单号传递出错';
|
||
return $msg;
|
||
}
|
||
$finder_id = $_GET['finder_id'];
|
||
$orefapply = app::get('ome')->model('orders');
|
||
$oRefund = app::get('ome')->model('refund_apply');
|
||
$refunddata = $oRefund->getList('*',array('order_id'=>$order_id),0,-1);
|
||
$amount = 0;
|
||
foreach ($refunddata as $row){
|
||
if ($row['status'] != 3 && $row['status'] != 4){
|
||
$msg['result'] = false;
|
||
$msg['msg'] = '上次申请未处理完成,请完成上次处理';
|
||
return $msg;
|
||
}
|
||
}
|
||
$render->pagedata['order'] = $orefapply->order_detail($order_id);
|
||
if ($render->pagedata['order']['pay_status'] == '5'){
|
||
$msg['result'] = false;
|
||
$msg['msg'] = '订单已全额退款,无需再处理';
|
||
return $msg;
|
||
}
|
||
$payment_cfgObj = app::get('ome')->model('payment_cfg');
|
||
$oPayment = app::get('ome')->model('payments');
|
||
$oShop = app::get('ome')->model('shop');
|
||
$shop_id = $render->pagedata['order']['shop_id'];
|
||
$shop_detail = $oShop->dump($shop_id,'node_type,node_id');
|
||
if ($shop_id){
|
||
$payment = kernel::single('ome_payment_type')->paymethod($shop_id);
|
||
}else{
|
||
$payment = $oPayment->getMethods();
|
||
}
|
||
$payment_cfg = $payment_cfgObj->dump(array('pay_bn'=>$render->pagedata['order']['pay_bn']), 'id,pay_type');
|
||
$render->pagedata['shop_id'] = $shop_id;
|
||
$render->pagedata['node_id'] = $shop_detail['node_id'];
|
||
$render->pagedata['payment'] = $payment;
|
||
$render->pagedata['payment_id'] = $payment_cfg['id'];
|
||
$render->pagedata['pay_type'] = $payment_cfg['pay_type'];
|
||
if ($payment_cfg['id']){
|
||
$order_paymentcfg = kernel::single('ome_payment_type')->paymethod($shop_id,$payment_cfg['pay_type']);
|
||
}
|
||
$render->pagedata['order_paymentcfg'] = $order_paymentcfg;
|
||
$render->pagedata['typeList'] = ome_payment_type::pay_type();
|
||
$aRet = $oPayment->getAccount();
|
||
$aAccount = array('--使用已存在帐户--');
|
||
foreach ($aRet as $v){
|
||
$aAccount[$v['bank']."-".$v['account']] = $v['bank']."-".$v['account'];
|
||
}
|
||
$render->pagedata['pay_account'] = $aAccount;
|
||
|
||
$paymentInfo = $oPayment->dump(array('order_id'=>$order_id));
|
||
$render->pagedata['account'] = $paymentInfo['account'];
|
||
$render->pagedata['payment_bank'] = $paymentInfo['bank'];
|
||
$render->pagedata['payment_type'] = $paymentInfo['pay_type'];
|
||
$render->pagedata['payment_account'] = $paymentInfo['pay_account'];
|
||
$render->pagedata['reason'] = app::get('ome')->model('refund_reason')->getList('reason',[]);
|
||
|
||
$render->pagedata['is_c2cshop'] = in_array($shop_detail['node_type'],ome_shop_type::shop_list()) ?true:false;
|
||
$render->pagedata['shop_name'] = ome_shop_type::shop_name($shop_detail['node_type']);
|
||
|
||
if (!$refund_money){
|
||
if ($return_id)
|
||
{
|
||
//处理售后的退款
|
||
$render->pagedata['return_id'] = $return_id;
|
||
$oReturn = app::get('ome')->model('return_product');
|
||
$return_detail = $oReturn->product_detail($return_id);
|
||
if ($return_detail['tmoney'] > 0)
|
||
{
|
||
$render->pagedata['refund_money'] = $return_detail['tmoney'];
|
||
}
|
||
else
|
||
{
|
||
$render->pagedata['refund_money'] = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$render->pagedata['refund_money'] = $render->pagedata['order']['payed'];
|
||
}
|
||
}else{
|
||
$render->pagedata['refund_money'] = $refund_money;
|
||
}
|
||
$render->pagedata['finder_id'] = $finder_id;
|
||
$memberid = $render->pagedata['order']['member_id'];
|
||
$oMember = &$render->app->model('members');
|
||
$render->pagedata['member'] = $oMember->member_detail($memberid);
|
||
$render->pagedata['aItems'] = $orefapply->getItemList($order_id);
|
||
switch ($addon['from']){
|
||
case 'order_edit'://订单编辑
|
||
$render->pagedata['ctl'] = 'admin_order';
|
||
$render->pagedata['act'] = 'do_refund';
|
||
$render->pagedata['addon'] = $addon;
|
||
break;
|
||
case 'remain_order_cancel'://余单撤消
|
||
$render->pagedata['ctl'] = 'admin_order';
|
||
$render->pagedata['act'] = 'remain_order_cancel_refund';
|
||
$render->pagedata['addon'] = $addon;
|
||
$diff_price = kernel::single('ome_order_func')->order_items_diff_money($order_id);
|
||
$render->pagedata['diff_price'] = $diff_price;
|
||
$render->pagedata['remain_cancel_flag'] = 'true';
|
||
break;
|
||
default:
|
||
$render->pagedata['ctl'] = 'admin_refund_apply';
|
||
$render->pagedata['act'] = 'showRefund';
|
||
}
|
||
$render->pagedata['pay_status'] = kernel::single('ome_order_status')->pay_status();
|
||
return $render->display('admin/refund/refund_apply.html');
|
||
}
|
||
|
||
/**
|
||
* !!!废弃,已不在使用!!!
|
||
* 现使用:kernel::single('ome_refund_apply')->createRefundApply($sdf, $is_update_order, $error_msg);
|
||
*
|
||
*
|
||
* 添加退款申请
|
||
* @access public
|
||
* @param $data $data POST提交数据 $refund_refer 退款申请来源 0:普通流程产生的退款申请 1:通过售后流程产生的退款申请
|
||
* @return 退款申请成功与失败状态及消息
|
||
*/
|
||
public function refund_apply_add($data,$refund_refer='0'){
|
||
$mathLib = kernel::single('eccommon_math');
|
||
if($data){
|
||
|
||
if(empty($data['pay_type']))
|
||
{
|
||
$msg['result'] = false;
|
||
$msg['msg'] = '请选择退款类型';
|
||
return $msg;
|
||
}
|
||
/*if(empty($data['payment']))
|
||
{
|
||
$msg['result'] = false;
|
||
$msg['msg'] = '请选择退款支付方式';
|
||
return $msg;
|
||
}*/
|
||
|
||
if( $data['refund_money'] <= 0)
|
||
{
|
||
$msg['result'] = false;
|
||
$msg['msg'] = '退款金额必须大于0';
|
||
return $msg;
|
||
}
|
||
|
||
$objOrder = app::get('ome')->model('orders');
|
||
$refundapp = app::get('ome')->model('refund_apply');
|
||
$oOrderItems = app::get('ome')->model('order_items');
|
||
$oLoger = app::get('ome')->model('operation_log');
|
||
$oShop = app::get('ome')->model ( 'shop' );
|
||
$bcmoney = $mathLib->getOperationNumber($data['bcmoney']);//补偿费用
|
||
$countPrice=0;
|
||
$countPrice=$data['refund_money'];
|
||
$totalPrice=0;
|
||
$totalPrice=$countPrice+$bcmoney;
|
||
$refund_apply_bn = $refundapp->gen_id();
|
||
if ($data['source'] && in_array($data['source'],array('archive'))) {
|
||
$archive_ordObj = kernel::single('archive_interface_orders');
|
||
$source = $data['source'];
|
||
$orderdata = $archive_ordObj->getOrders(array('order_id'=>$data['order_id']),'*');
|
||
}else{
|
||
$objOrder = app::get('ome')->model('orders');
|
||
$orderdata = $objOrder->order_detail($data['order_id']);
|
||
}
|
||
|
||
$data=array(
|
||
'return_id'=>$data['return_id'],
|
||
'refund_apply_bn'=>$refund_apply_bn,
|
||
'order_id'=>$data['order_id'],
|
||
'shop_id'=>$orderdata['shop_id'],
|
||
'pay_type'=>$data['pay_type'],
|
||
'bank'=>$data['bank'],
|
||
'account'=>$data['account'],
|
||
'pay_account'=>$data['pay_account'],
|
||
'money'=>$totalPrice,
|
||
'bcmoney'=>$bcmoney,
|
||
'apply_op_id'=>kernel::single('desktop_user')->get_id(),
|
||
'payment'=>is_numeric($data['payment'])?$data['payment']:null,
|
||
'memo'=>$data['memo'],
|
||
'verify_op_id' =>kernel::single('desktop_user')->get_id(),
|
||
'addon' => serialize(array('return_id'=>$data['return_id'])),
|
||
'refund_refer' => $refund_refer,
|
||
'cost_freight' =>$data['cost_freight'] ? $data['cost_freight'] : 0,
|
||
);
|
||
if ($source && in_array($source,array('archive'))) {
|
||
$data['source'] = 'archive';
|
||
$data['archive'] = 1;
|
||
}
|
||
// $shop_type = $oShop->getShoptype($orderdata['shop_id']);
|
||
$shop_info = $oShop->getShopInfo($orderdata['shop_id']);
|
||
$shop_type = $shop_info['shop_type'];
|
||
$data['shop_type'] = $shop_type;
|
||
$msg = array('result'=>true, 'msg'=>'申请退款成功,单据号为:'.$refund_apply_bn);
|
||
if(round($countPrice,3)>round(($orderdata['payed']),3))
|
||
{
|
||
$msg['result'] = false;
|
||
$msg['msg'] = '退款申请金额大于订单上的余额';
|
||
return $msg;
|
||
}
|
||
//余单撤销退款金额判断
|
||
if ($data['remain_cancel_flag'] == 'true' && $countPrice > $data['diff_price']){
|
||
$msg['result'] = false;
|
||
$msg['msg'] = '退款申请金额大于余单撤销金额';
|
||
return $msg;
|
||
}
|
||
|
||
$data['create_time'] = time();
|
||
|
||
// 经销店铺的单据,delivery_mode冗余到退款单申请表
|
||
if ($shop_info['delivery_mode'] == 'jingxiao') {
|
||
$data['delivery_mode'] = $shop_info['delivery_mode'];
|
||
}
|
||
|
||
if($refundapp->save($data))
|
||
{ //将订单更改为退款申请中
|
||
|
||
kernel::single('ome_order_func')->update_order_pay_status($data['order_id'], true, __CLASS__.'::'.__FUNCTION__);
|
||
/*if ($data['return_id'])
|
||
{
|
||
//插入return_refund_apply
|
||
$oreturn_refund_apply = app::get('ome')->model('return_refund_apply');
|
||
$return_ref_data = array('refund_apply_id'=>$data['apply_id'],'return_id'=>$data['return_id']);
|
||
$oreturn_refund_apply->save($return_ref_data);
|
||
}*/
|
||
$oLoger->write_log('refund_apply@ome',$data['apply_id'],'申请退款成功');
|
||
return $msg;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 批量处理售后申请单
|
||
* @param array apply_id
|
||
* @return
|
||
* @access public
|
||
* @author cyyr24@sina.cn
|
||
*/
|
||
function batch_update($status_type,$apply_id){
|
||
set_time_limit(0);
|
||
$oRefund_apply = app::get('ome')->model('refund_apply');
|
||
$oLoger = app::get('ome')->model('operation_log');
|
||
$oReturn_batch = app::get('ome')->model('return_batch');
|
||
|
||
$error_msg = array();
|
||
$need_apply_id = array();
|
||
|
||
foreach ($apply_id as $apply_id ) {
|
||
$apply_id = explode('||',$apply_id);
|
||
$need_apply_id[] = $apply_id[1];
|
||
}
|
||
$apply_list = $oRefund_apply->db->select('SELECT status,source,shop_type,apply_id,refund_apply_bn,shop_id,order_id,return_id,`oid` FROM sdb_ome_refund_apply WHERE apply_id in('.implode(',',$need_apply_id).')');
|
||
|
||
$fail = 0;$succ=0;
|
||
if ($status_type == 'agree') {
|
||
$batchList = $this->return_batch('accept_refund');
|
||
foreach ( $apply_list as $apply ) {#同意退款目前只有天猫需要回写
|
||
$apply_id = $apply['apply_id'];
|
||
$status = $apply['status'];
|
||
if (in_array( $status,array('0','1'))){
|
||
if ($apply['source'] == 'matrix') {
|
||
$return_batch = $batchList[$apply['shop_id']];
|
||
$refund = array(
|
||
'apply_id'=>$apply['apply_id'],
|
||
'refuse_message'=>$return_batch['memo'],
|
||
'oid' => $apply['oid'],
|
||
);
|
||
$rs = kernel::single('ome_service_refund_apply')->update_status($refund,2,'sync');
|
||
}
|
||
|
||
if ($rs && $rs['rsp'] == 'fail') {
|
||
$fail++;
|
||
$error_msg[] = '单号:'.$apply['refund_apply_bn'].",".$rs['msg'];
|
||
|
||
}else{
|
||
#更新退款单接受状态
|
||
$this->update_refund_applyStatus('2',$apply);
|
||
}
|
||
}
|
||
}
|
||
|
||
}elseif($status_type == 'refuse') {
|
||
$batchList = $this->return_batch('refuse');
|
||
|
||
//拒绝退款是否请求平台(birken勃肯客户搬物料代码功能)
|
||
$refuseRequest = app::get('ome')->getConf("ome.refund.refuse.request");
|
||
|
||
//淘宝拒绝天猫需上传凭证
|
||
foreach ( $apply_list as $apply ) {
|
||
$status = $apply['status'];
|
||
$apply_id = $apply['apply_id'];
|
||
if ( in_array( $status , array( '0','1','2' ) )) {
|
||
$rs = array();
|
||
if($refuseRequest != 'false' && $apply['source'] == 'matrix'){
|
||
$return_batch = $batchList[$apply['shop_id']];
|
||
$refund = array(
|
||
'apply_id'=>$apply_id,
|
||
'refuse_message'=>$return_batch['memo'],
|
||
'oid' => $apply['oid'],
|
||
);
|
||
$picurl = $return_batch['picurl'];
|
||
if ($apply['shop_type'] == 'tmall') {
|
||
$picurl = file_get_contents($picurl);
|
||
$picurl = base64_encode($picurl);
|
||
|
||
}
|
||
$refund['refuse_proof'] = $picurl;
|
||
|
||
//[抖音]不支持售前拒绝退款
|
||
if($apply['shop_type'] == 'luban'){
|
||
$params = $apply;
|
||
$params['status'] = '3';
|
||
|
||
$rs = kernel::single('ome_aftersale_service')->pre_save_refund($apply_id, $params);
|
||
}else{
|
||
$rs = kernel::single('ome_service_refund_apply')->update_status($refund,3,'sync');
|
||
}
|
||
|
||
}
|
||
|
||
if ( ($rs && $rs['rsp'] == 'fail') ) {
|
||
$fail++;
|
||
$error_msg[] = '单号:'.$apply['refund_apply_bn'].",".$rs['msg'];
|
||
|
||
}else{
|
||
$this->update_refund_applyStatus('3',$apply);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$result = array('error_msg'=>$error_msg,'fail'=>$fail);
|
||
return $result;
|
||
}
|
||
|
||
|
||
/**
|
||
* 退款单列表.
|
||
* @param type $varname description
|
||
* @return type description
|
||
* @access public
|
||
* @author cyyr24@sina.cn
|
||
*/
|
||
function refund_list($status_type,$apply_id)
|
||
{
|
||
$oRefund_apply = app::get('ome')->model('refund_apply');
|
||
if ($status_type == 'agree') {
|
||
$apply_list = $oRefund_apply->db->select('SELECT apply_id FROM sdb_ome_refund_apply WHERE apply_id in("'.implode('","',$apply_id).'") AND `status` in (\'0\',\'1\')');
|
||
}else{
|
||
$apply_list = $oRefund_apply->db->select('SELECT apply_id FROM sdb_ome_refund_apply WHERE apply_id in("'.implode('","',$apply_id).'") AND `status` in (\'0\',\'1\',\'2\')');
|
||
}
|
||
|
||
$apply_id_list = array();
|
||
foreach ($apply_list as $apply ) {
|
||
$apply_id_list[] = $apply['apply_id'];
|
||
}
|
||
return $apply_id_list;
|
||
}
|
||
|
||
/**
|
||
* 售后默认设置
|
||
*/
|
||
public function return_batch($batch_type){
|
||
$oReturn_batch = app::get('ome')->model('return_batch');
|
||
$batch = $oReturn_batch->getlist('*',array('is_default'=>'true','batch_type'=>$batch_type));
|
||
$batchList = array();
|
||
foreach ($batch as $item ) {
|
||
$batchList[$item['shop_id']] = $item;
|
||
}
|
||
return $batchList;
|
||
}
|
||
|
||
|
||
/**
|
||
* 更新退款申请单状态.
|
||
* @param status
|
||
* @return
|
||
* @access public
|
||
* @author cyyr24@sina.cn
|
||
*/
|
||
public function update_refund_applyStatus($status,$apply)
|
||
{
|
||
$oLoger = app::get('ome')->model('operation_log');
|
||
$oRefund_apply = app::get('ome')->model('refund_apply');
|
||
$Oreturn_product = app::get('ome')->model('return_product');
|
||
$apply_id = $apply['apply_id'];
|
||
$order_id = $apply['order_id'];
|
||
switch ($status) {
|
||
case '2':#接受
|
||
$refund_op = 'refund_pass@ome';
|
||
$refund_op_name = '接受';
|
||
break;
|
||
case '3':#拒绝
|
||
$refund_op = 'refund_refuse@ome';
|
||
$refund_op_name = '拒绝';
|
||
break;
|
||
default:
|
||
return true;
|
||
break;
|
||
}
|
||
$data['apply_id'] = $apply_id;
|
||
$data['status'] = $status;
|
||
$data['last_modified'] = time();
|
||
|
||
$oRefund_apply->save($data,true);
|
||
$memo = "退款申请 $refund_op_name";
|
||
if ($apply['oper_memo']) {
|
||
$memo = $apply['oper_memo'];
|
||
}
|
||
$oLoger->write_log($refund_op,$apply_id,$memo);
|
||
if ( $status == '3' ) {
|
||
$return_id = $apply['return_id'];
|
||
if ($return_id) {
|
||
$return_data = array ('return_id' => $return_id, 'status' => '9', 'last_modified' => time () );
|
||
$Oreturn_product->save ( $return_data );
|
||
|
||
$oLoger->write_log('return@ome',$return_id,$apply['refund_apply_bn'].$memo);
|
||
}
|
||
|
||
kernel::single('ome_order_func')->update_order_pay_status($order_id, true, __CLASS__.'::'.__FUNCTION__);
|
||
//生成售后单
|
||
kernel::single('sales_aftersale')->generate_aftersale($apply_id,'refund');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 识别当前退款申请是否需要请求接口进行退款
|
||
* @param $params 参数
|
||
* @param $err_msg 错误信息
|
||
* @return boolean true/false
|
||
* @access public
|
||
* @author xiayuanjun@shopex.cn
|
||
*/
|
||
public function checkForRequest($params, &$err_msg)
|
||
{
|
||
$err_msg = '';
|
||
$refund_request = false;
|
||
$c2c_shop = ome_shop_type::shop_list();
|
||
$orderInfo = $params['orderInfo']; //订单参数信息
|
||
$applyInfo = $params['applyInfo']; //退款申请单参数信息
|
||
$api_fail_flag = $params['api_fail_flag']; //是否存在请求接口失败,根据退款申请是否退款失败的状态标记
|
||
$api_refund_request = $params['api_refund_request']; //表单上标记是否允许请求
|
||
$is_archive = $params['is_archive']; //是否归档订单
|
||
$is_aftersale_refund = ($applyInfo['return_id'] > 0) ? true : false; //识别售后退款还是售前退款
|
||
|
||
//获取当前店铺相关信息
|
||
$shopObj = app::get('ome')->model('shop');
|
||
$shopInfo = $shopObj->dump($orderInfo['shop_id'], 'node_id,node_type,business_type,tbbusiness_type');
|
||
|
||
if ($api_fail_flag == 'false'){
|
||
//识别是否是已绑定的线上退款申请
|
||
if ($shopInfo['node_id'] && $orderInfo['source'] == 'matrix'){
|
||
//非C2C销售平台,这里主要指自有体系,不管线上线下产生的退款申请单
|
||
if(!in_array($shopInfo['node_type'],$c2c_shop)){
|
||
if ($api_refund_request == 'true'){
|
||
$refund_request = true;
|
||
}else{
|
||
$err_msg = '向前端退款失败,仅本地退款!';
|
||
}
|
||
}elseif($shopInfo['node_type'] == 'taobao' && $shopInfo['business_type'] == 'zx' && (strtolower($shopInfo['tbbusiness_type']) == 'b') && ($is_aftersale_refund || (!$is_aftersale_refund && $applyInfo['source'] == 'matrix'))){
|
||
if ($api_refund_request == 'true'){
|
||
//天猫店判断逻辑,如果是线上售前退款或者售后才允许发起
|
||
//售后退款的识别状态是否已退货入仓完成状态
|
||
if($is_aftersale_refund){
|
||
$returnPrdObj = app::get('ome')->model('return_product');
|
||
$return_info = $returnPrdObj->dump($applyInfo['return_id']);
|
||
$return_status = ($return_info['status'] == 4) ? true : false;
|
||
|
||
$refundExtMdl = 'return_product_tmall';
|
||
$refundExtFilter = array('return_id' => $applyInfo['return_id']);
|
||
}else{
|
||
$return_status = true;
|
||
|
||
$refundExtMdl = 'refund_apply_tmall';
|
||
$refundExtFilter = array('apply_id' => $applyInfo['apply_id']);
|
||
}
|
||
|
||
//获取原始退款金额
|
||
$refundOriginalObj = app::get('ome')->model($refundExtMdl);
|
||
$refundOriginalInfo = $refundOriginalObj->getList('refund_fee', $refundExtFilter , 0 , 1);
|
||
$original_refund_fee = $refundOriginalInfo[0]['refund_fee'];
|
||
|
||
//本次申请退款的金额
|
||
$money = $applyInfo['money'];
|
||
|
||
//当AG自动退款开启,原始退款金额存在并且实际退款等于原始申请退款金额,则允许接口请求自动退款
|
||
$aliag_status = app::get('ome')->getConf('shop.aliag.config.'.$orderInfo['shop_id']);
|
||
if($aliag_status && $return_status && $original_refund_fee && (round($original_refund_fee,3)== round($money,3))){
|
||
$refund_request = true;
|
||
}
|
||
}else{
|
||
$err_msg = '向前端退款失败,仅本地退款!';
|
||
}
|
||
}elseif(in_array($shopInfo['node_type'], array ('360buy')) && ($is_aftersale_refund || (!$is_aftersale_refund && $applyInfo['source'] == 'matrix'))){
|
||
if ($api_refund_request == 'true'){
|
||
//当AG自动退款开启,原始退款金额存在并且实际退款等于原始申请退款金额,则允许接口请求自动退款
|
||
$aliag_status = app::get('ome')->getConf('shop.aliag.config.'.$orderInfo['shop_id']);
|
||
if($aliag_status){
|
||
$refund_request = true;
|
||
}
|
||
}else{
|
||
$err_msg = '向前端退款失败,仅本地退款!';
|
||
}
|
||
}elseif(in_array($shopInfo['node_type'], ome_shop_type::shop_refund_list())){
|
||
if ($api_refund_request == 'true'){
|
||
$refund_request = true;
|
||
}
|
||
}
|
||
}
|
||
}else{
|
||
//请求失败过的如果还要发起接口请求允许发起
|
||
if ($api_refund_request == 'true'){
|
||
$refund_request = true;
|
||
}
|
||
}
|
||
|
||
if($shopInfo['node_type']=='website'){
|
||
$refund_request = true;
|
||
}
|
||
//bbc的0元退款申请单,需要发起同意请求,其他平台0元不发起
|
||
if($shopInfo['node_type'] !='bbc' ){
|
||
//退款金额为零将不发起前端同步
|
||
if ($applyInfo['money'] <= 0){
|
||
//$refund_request = false;
|
||
}
|
||
}
|
||
|
||
//归档订单不发起
|
||
if ($is_archive) {
|
||
$refund_request = false;
|
||
}
|
||
|
||
return $refund_request;
|
||
}
|
||
|
||
|
||
/**
|
||
* 创建退款申请单
|
||
*
|
||
* @param Array $data 提交的数据
|
||
* @param bool $is_update_order 更新订单付款状态
|
||
* @param String $error_msg
|
||
*
|
||
* @return Array
|
||
*/
|
||
public function createRefundApply(&$sdf, $is_update_order=false, &$error_msg)
|
||
{
|
||
$refundapp = app::get('ome')->model('refund_apply');
|
||
$logObj = app::get('ome')->model('operation_log');
|
||
|
||
//格式化数据
|
||
$sdf = $this->_format_refund_apply($sdf);
|
||
|
||
//[检查]普通流程产生的退款申请单
|
||
if($sdf['refund_refer'] == '0' && $sdf['source'] != 'matrix')
|
||
{
|
||
$result = $this->_check_refund_apply_data($sdf, $error_msg);
|
||
if(!$result)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
//创建退款单
|
||
$result = $refundapp->save($sdf);
|
||
if(!$result)
|
||
{
|
||
$error_msg = '创建退款申请单失败,单据号为:'. $sdf['refund_apply_bn'];
|
||
return false;
|
||
}
|
||
|
||
//[更新订单状态]普通流程产生的退款单
|
||
if($is_update_order)
|
||
{
|
||
$must_pause = true;
|
||
if($sdf['bool_type'] & ome_refund_bool_type::__PROTECTED_CODE){
|
||
$must_pause = false;
|
||
}
|
||
//将订单更改为退款申请中
|
||
kernel::single('ome_order_func')->update_order_pay_status($sdf['order_id'],$must_pause, __CLASS__.'::'.__FUNCTION__);
|
||
|
||
//log日志
|
||
$sdf['status'] = intval($sdf['status']);
|
||
if($sdf['status'])
|
||
{
|
||
$status_str = ome_refund_func::refund_apply_status_name($sdf['status']);
|
||
$memo = '创建退款申请单,状态:' . $status_str;
|
||
}
|
||
else
|
||
{
|
||
$memo = '申请退款成功';
|
||
}
|
||
$logObj->write_log('refund_apply@ome', $sdf['apply_id'], $memo);
|
||
|
||
return array('result'=>true, 'msg'=>'申请退款成功,单据号为:'. $sdf['refund_apply_bn']);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 检查普通流程产生的退款申请单
|
||
*
|
||
* @param Array $data 提交的数据
|
||
* @param String $error_msg
|
||
*/
|
||
public function _check_refund_apply_data($sdf, &$error_msg)
|
||
{
|
||
if(empty($sdf['order_id']))
|
||
{
|
||
$error_msg = '订单号不存在';
|
||
return false;
|
||
}
|
||
|
||
if(empty($sdf['pay_type']))
|
||
{
|
||
$error_msg = '请选择退款类型';
|
||
return false;
|
||
}
|
||
|
||
if($sdf['refund_money'] <= 0)
|
||
{
|
||
$error_msg = '退款金额必须大于0';
|
||
return false;
|
||
}
|
||
|
||
//退款申请金额
|
||
$countPrice = $sdf['refund_money'];
|
||
if(round($countPrice,3) > round($sdf['payed'],3))
|
||
{
|
||
$error_msg = '退款申请金额大于订单上的余额';
|
||
return false;
|
||
}
|
||
|
||
//余单撤销退款金额判断
|
||
if($sdf['remain_cancel_flag'] == 'true' && ($countPrice > $sdf['diff_price']))
|
||
{
|
||
$error_msg = '退款申请金额大于余单撤销金额';
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 格式化退款申请单数据
|
||
*
|
||
* @param Array $data 提交的数据
|
||
*
|
||
* @return Array
|
||
*/
|
||
public function _format_refund_apply($data)
|
||
{
|
||
//本地新建OR线上新建(local:本地, matrix:线上, archive:本地归档订单)
|
||
$source = (empty($data['source']) ? 'local' : $data['source']);
|
||
|
||
//退款申请来源(0:普通流程产生的退款申请 1:通过售后流程产生的退款申请)
|
||
$refund_refer = ($data['refund_refer'] == '1' ? '1' : '0');
|
||
|
||
//审核操作员
|
||
$op_id = kernel::single('desktop_user')->get_id();
|
||
$op_id = ($op_id ? $op_id :0);
|
||
|
||
//退款单状态
|
||
$status = ($data['status'] ? $data['status'] : '0');
|
||
|
||
//创建时间
|
||
$create_time = ($data['create_time'] ? $data['create_time'] : time());
|
||
|
||
//申请退款单号
|
||
$refundapp = app::get('ome')->model('refund_apply');
|
||
$refund_apply_bn = $data['refund_apply_bn'] ? $data['refund_apply_bn'] : $refundapp->gen_id();
|
||
|
||
//订单信息
|
||
if($data['order_id'])
|
||
{
|
||
$filter = array('order_id'=>$data['order_id']);
|
||
}
|
||
else
|
||
{
|
||
$filter = array('order_bn'=>$data['order_bn']);
|
||
}
|
||
|
||
if($source == 'archive')
|
||
{
|
||
$orderObj = app::get('archive')->model('orders');
|
||
$orderData = $orderObj->dump($filter, '*');
|
||
}else{
|
||
$orderObj = app::get('ome')->model('orders');
|
||
$orderData = $orderObj->dump($filter, '*');
|
||
}
|
||
|
||
if(empty($orderData))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
//店铺类型
|
||
$shopObj = app::get('ome')->model('shop');
|
||
// $shop_type = $shopObj->getShoptype($orderData['shop_id']);
|
||
$shop_info = $shopObj->getShopInfo($orderData['shop_id']);
|
||
$shop_type = $shop_info['shop_type'];
|
||
|
||
//普通申请单数据格式化
|
||
$data['bcmoney'] = ($data['bcmoney'] ? $data['bcmoney'] : 0);
|
||
if($source == 'local' && isset($data['refund_money']))
|
||
{
|
||
//金额
|
||
$mathLib = kernel::single('eccommon_math');
|
||
$data['bcmoney'] = $mathLib->getOperationNumber($data['bcmoney']);//补偿费用
|
||
$data['money'] = $data['refund_money'] + $data['bcmoney'];
|
||
|
||
//退款明细序列化字段
|
||
$data['addon'] = serialize(array('return_id'=>$data['return_id']));
|
||
}
|
||
|
||
//已退款金额
|
||
$data['refunded'] = ($data['refunded'] ? $data['refunded'] : 0);
|
||
|
||
//组织数据
|
||
$sdf = array(
|
||
'return_id' => (int)$data['return_id'],
|
||
'refund_apply_bn' => $refund_apply_bn,
|
||
'order_id' => $orderData['order_id'],
|
||
'shop_id' => $orderData['shop_id'],
|
||
'shop_type' => $shop_type,
|
||
'pay_type' => $data['pay_type'],
|
||
'bank' => $data['bank'],
|
||
'account' => $data['account'],
|
||
'pay_account' => $data['pay_account'],
|
||
'refund_money' => $data['refund_money'],
|
||
'money' => $data['money'],
|
||
'refunded' => $data['refunded'],
|
||
'bcmoney' => $data['bcmoney'],
|
||
'payed' => $orderData['payed'],
|
||
'payment' => is_numeric($data['payment'])?$data['payment']:null,
|
||
'memo' => $data['memo'],
|
||
'apply_op_id' => $op_id,//申请操作员
|
||
'verify_op_id' => $op_id,//审核操作员
|
||
'status' => $status,
|
||
'addon' => $data['addon'],//退款明细序列化字段
|
||
'create_time' => $create_time,
|
||
'refund_refer' => $refund_refer,
|
||
'source' => $source,
|
||
'org_id' => $orderData['org_id'],
|
||
'bn' => $data['bn'],
|
||
'oid' => $data['oid'],
|
||
'bool_type'=>$data['bool_type'],
|
||
'source_status'=>$data['source_status'],
|
||
);
|
||
|
||
// 经销店铺的单据,delivery_mode冗余到退款单申请表
|
||
if ($shop_info['delivery_mode'] == 'jingxiao') {
|
||
$sdf['delivery_mode'] = $shop_info['delivery_mode'];
|
||
}
|
||
|
||
// 更新
|
||
if ($data['apply_id']){
|
||
$sdf['apply_id'] = $data['apply_id'];
|
||
}
|
||
|
||
if($data['reship_id']) $sdf['reship_id'] = $data['reship_id'];
|
||
//退货商品序列化字段
|
||
if($data['product_data'])
|
||
{
|
||
$sdf['product_data'] = $data['product_data'];
|
||
}
|
||
|
||
//前端店铺最后更新时间
|
||
if($data['outer_lastmodify'])
|
||
{
|
||
$sdf['outer_lastmodify'] = $data['outer_lastmodify'];
|
||
}
|
||
|
||
//归档订单标识
|
||
if($source == 'archive')
|
||
{
|
||
$sdf['archive'] = 1;
|
||
}
|
||
|
||
//余单撤消标识
|
||
if($data['remain_cancel_flag'])
|
||
{
|
||
$sdf['remain_cancel_flag'] = $data['remain_cancel_flag'];
|
||
$sdf['diff_price'] = $data['diff_price'];
|
||
}
|
||
if ($data['order_source']) {
|
||
$sdf['order_source'] = $data['order_source'];
|
||
}
|
||
|
||
return $sdf;
|
||
}
|
||
|
||
/**
|
||
* [批量同意退款]识别当前退款申请是否需要请求接口进行退款
|
||
*
|
||
* @param $params 参数
|
||
* @param $err_msg 错误信息
|
||
* @return bool
|
||
*/
|
||
public function checkBatchForRequest($params, &$err_msg)
|
||
{
|
||
$refund_request = false;
|
||
|
||
//C2C前端店铺列表
|
||
$c2c_shop = ome_shop_type::shop_list();
|
||
|
||
$orderInfo = $params['orderInfo']; //订单参数信息
|
||
$applyInfo = $params['applyInfo']; //退款申请单参数信息
|
||
$api_fail_flag = $params['api_fail_flag'];
|
||
$api_refund_request = $params['api_refund_request'];
|
||
|
||
$is_archive = $params['is_archive']; //是否归档订单
|
||
|
||
$is_aftersale_refund = ($applyInfo['return_id'] > 0) ? true : false;//识别售后退款还是售前退款
|
||
|
||
//获取当前店铺相关信息
|
||
$shopObj = app::get('ome')->model('shop');
|
||
$shopInfo = $shopObj->dump($orderInfo['shop_id'], 'node_id,node_type,business_type,tbbusiness_type');
|
||
|
||
//识别是否是已绑定的线上退款申请
|
||
if($shopInfo['node_id'] && $orderInfo['source'] == 'matrix')
|
||
{
|
||
//非C2C销售平台,这里主要指自有体系
|
||
if(!in_array($shopInfo['node_type'], $c2c_shop))
|
||
{
|
||
if ($api_refund_request == 'true'){
|
||
$refund_request = true;
|
||
}else{
|
||
$err_msg = '向前端退款失败,仅本地退款!';
|
||
}
|
||
}
|
||
elseif($shopInfo['node_type'] == 'taobao' && $shopInfo['business_type'] == 'zx' && (strtolower($shopInfo['tbbusiness_type']) == 'b') && ($is_aftersale_refund || (!$is_aftersale_refund && $applyInfo['source'] == 'matrix')))
|
||
{
|
||
if ($api_refund_request == 'true'){
|
||
//天猫店判断逻辑,如果是线上售前退款或者售后才允许发起
|
||
//售后退款的识别状态是否已退货入仓完成状态
|
||
if($is_aftersale_refund){
|
||
$returnPrdObj = app::get('ome')->model('return_product');
|
||
$return_info = $returnPrdObj->dump($applyInfo['return_id']);
|
||
$return_status = ($return_info['status'] == 4) ? true : false;
|
||
|
||
$refundExtMdl = 'return_product_tmall';
|
||
$refundExtFilter = array('return_id' => $applyInfo['return_id']);
|
||
}else{
|
||
$return_status = true;
|
||
|
||
$refundExtMdl = 'refund_apply_tmall';
|
||
$refundExtFilter = array('apply_id' => $applyInfo['apply_id']);
|
||
}
|
||
|
||
//获取原始退款金额
|
||
$refundOriginalObj = app::get('ome')->model($refundExtMdl);
|
||
$refundOriginalInfo = $refundOriginalObj->getList('refund_fee', $refundExtFilter , 0 , 1);
|
||
$original_refund_fee = $refundOriginalInfo[0]['refund_fee'];
|
||
|
||
//本次申请退款的金额
|
||
$money = $applyInfo['money'];
|
||
|
||
//当AG自动退款开启,原始退款金额存在并且实际退款等于原始申请退款金额,则允许接口请求自动退款
|
||
$aliag_status = app::get('ome')->getConf('shop.aliag.config.'.$orderInfo['shop_id']);
|
||
if($aliag_status && $return_status && $original_refund_fee && (round($original_refund_fee,3)== round($money,3))){
|
||
$refund_request = true;
|
||
}
|
||
}else{
|
||
$err_msg = '向前端退款失败,仅本地退款!';
|
||
}
|
||
}elseif(in_array($shopInfo['node_type'], ome_shop_type::shop_refund_list())){
|
||
$refund_request = true;
|
||
}
|
||
}
|
||
|
||
//bbc的0元退款申请单,需要发起同意请求,其他平台0元不发起
|
||
if($shopInfo['node_type'] != 'bbc'){
|
||
//退款金额为零将不发起前端同步
|
||
if ($applyInfo['money'] <= 0){
|
||
$refund_request = false;
|
||
}
|
||
}
|
||
|
||
//归档订单不发起
|
||
if ($is_archive) {
|
||
$refund_request = false;
|
||
}
|
||
|
||
return $refund_request;
|
||
}
|
||
|
||
/**
|
||
* AG退款
|
||
* @param [type] $sdf [description]
|
||
* @return [type] [description]
|
||
*/
|
||
public function refund_ag($refund_apply_bn,$logi)
|
||
{
|
||
$refundApplyMdl = app::get('ome')->model('refund_apply');
|
||
|
||
//refund_appy
|
||
$refund_apply = $refundApplyMdl->db_dump(['refund_apply_bn' => $refund_apply_bn]);
|
||
if (!$refund_apply) {
|
||
return [false, '未检测到退款申请单'];
|
||
}
|
||
|
||
$order = app::get('ome')->model('orders')->db_dump(['order_id' => $refund_apply['order_id']],'order_id,order_bn,process_status,source,shop_id,shop_type,ship_status');
|
||
$shopType = $order['shop_type'];
|
||
$status = $refund_apply['status'];
|
||
|
||
// website来源订单允许 status: 0,1,2;其他来源只允许 status: 0
|
||
if (($shopType != 'website' && $status != 0) || ($shopType == 'website' && !in_array($status, [0, 1, 2]))) {
|
||
return [false, '退款申请状态不符合要求'];
|
||
}
|
||
|
||
if (!in_array($order['shop_type'], ['taobao','tmall','360buy','luban','pinduoduo','website'])) {
|
||
return [false ,'平台不支持AG退款'];
|
||
}
|
||
|
||
if ($order['source'] != 'matrix') {
|
||
return [false, '只支持平台订单AG退款'];
|
||
}
|
||
|
||
$aliag_status = app::get('ome')->getConf('shop.aliag.config.'.$order['shop_id']);
|
||
if (!$aliag_status) {
|
||
return [false, '未开启AG退款'];
|
||
}
|
||
|
||
$params = array(
|
||
'order_bn' => $order['order_bn'],
|
||
'apply_id' => $refund_apply['apply_id'],
|
||
'refund_bn' => $refund_apply['refund_apply_bn'],
|
||
'is_aftersale_refund' => false,
|
||
'shop_id' => $order['shop_id'],
|
||
'oid' => $refund_apply['oid'],
|
||
'company_code' => $logi['company_code'],
|
||
'logistics_no' => $logi['logistics_no'],
|
||
'trigger_event' => $logi['trigger_event'],
|
||
'refund_refer' => $refund_apply['refund_refer'],
|
||
'op_time' => $refund_apply['last_modified'],
|
||
'money' => $refund_apply['money'],
|
||
'order_id' => $refund_apply['order_id'],
|
||
'product_data' => $refund_apply['product_data'],
|
||
);
|
||
|
||
$params = array_merge((array)$params, (array)$logi);
|
||
|
||
//检查当前订单的状态
|
||
if(in_array($order['process_status'],array('unconfirmed','confirmed')) || $order['ship_status'] == '4'){
|
||
$params['cancel_dly_status'] = 'SUCCESS';
|
||
}else{
|
||
$params['cancel_dly_status'] = 'FAIL';
|
||
}
|
||
|
||
// 判断当前子单状态
|
||
if ($refund_apply['oid']) {
|
||
$order_object = app::get('ome')->model('order_objects')->db_dump([ 'order_id' => $order['order_id'], 'oid' => $refund_apply['oid'] ],'obj_id');
|
||
|
||
if ($order_object) {
|
||
$order_item = app::get('ome')->model('order_items')->db_dump([ 'order_id' => $order['order_id'], 'obj_id' => $order_object['obj_id'], 'split_num|than' => '0']);
|
||
|
||
if (!$order_item) {
|
||
$params['cancel_dly_status'] = 'SUCCESS';
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// 指定状态
|
||
if ($logi['cancel_dly_status']) {
|
||
$params['cancel_dly_status'] = $logi['cancel_dly_status'];
|
||
}
|
||
|
||
kernel::single('ome_service_refund')->refund_request($params);
|
||
|
||
//触发拒绝退款,需要打异常标识
|
||
if($params['cancel_dly_status'] == 'FAIL'){
|
||
//标记为异常
|
||
$refundApplyMdl->set_abnormal_status($refund_apply['apply_id'], ome_constants_refundapply_abnormal::__REPET_REFUND_CODE);
|
||
}
|
||
|
||
return [true, 'AG退款已发起'];
|
||
}
|
||
|
||
/**
|
||
* 创建完成退款申请单和退款单
|
||
* @Author: XueDing
|
||
* @Date: 2025/2/5 3:49 PM
|
||
* @param $refundapply|array|售后申请单相关字段
|
||
* @param $is_update_order|bool|是否更新订单状态
|
||
* @return array|true[]
|
||
*/
|
||
public function createFinishRefundApply($refundapply, $is_update_order = false)
|
||
{
|
||
$refundApplyMdl = app::get('ome')->model('refund_apply');
|
||
$opObj = app::get('ome')->model('operation_log');
|
||
|
||
//创建退款申请单
|
||
$apply = $this->createRefundApply($refundapply, $is_update_order, $error_msg);
|
||
if (!$apply) {
|
||
return [false, $error_msg];
|
||
}
|
||
$apply_id = $refundapply['apply_id'];
|
||
//更新为已退款
|
||
$applydata = array ();
|
||
$applydata['apply_id'] = $apply_id;
|
||
$applydata['status'] = 4; //已经退款
|
||
$applydata['last_modified'] = time();
|
||
$refundApplyMdl->save($applydata, true);
|
||
$opObj->write_log('refund_apply@ome', $applydata['apply_id'], "已退款成功,更新退款申请状态");
|
||
//创建退款单
|
||
$refundapply['refund_bn'] = $refundapply['refund_apply_bn'];
|
||
$refundapply['refund_fee'] = $refundapply['refund_money'];
|
||
$refundapply['t_ready'] = $refundapply['create_time'];
|
||
$refundapply['t_sent'] = $refundapply['create_time'];
|
||
$refundapply['t_received'] = $refundapply['create_time'];
|
||
$refundapply['refund_refer'] = $refundApplyMdl->get_schema()['columns']['refund_refer']['type'][$refundapply['refund_refer']];
|
||
list($res, $msg) = kernel::single('ome_order_refund')->create($refundapply);
|
||
if (!$res) {
|
||
return [false, $msg];
|
||
}
|
||
|
||
return [true];
|
||
}
|
||
}
|