mirror of
https://gitee.com/ShopeX/OMS
synced 2026-03-30 13:05:34 +08:00
1313 lines
55 KiB
PHP
1313 lines
55 KiB
PHP
<?php
|
||
/**
|
||
* Copyright 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.
|
||
*/
|
||
/**
|
||
* @desc 售后接口数据转换
|
||
* @author: jintao
|
||
* @since: 2016/7/21
|
||
*/
|
||
class erpapi_shop_response_aftersalev2 extends erpapi_shop_response_abstract {
|
||
|
||
protected $_change_return_type = false;
|
||
protected $item_convert_field = [
|
||
'sdf_field' =>'outer_id',
|
||
'order_field' =>'bn',
|
||
'default_field' =>'bn'
|
||
];
|
||
|
||
static public $refund_status = array(
|
||
'REFUND_WAIT_SELLER_AGREE'=>'0',
|
||
'WAIT_SELLER_AGREE'=>'0',
|
||
'WAIT_BUYER_RETURN_GOODS'=>'2',//卖家已经同意退款
|
||
'SELLER_REFUSE_BUYER'=>'3',//卖家拒绝seller_refuse
|
||
'CLOSED'=>'3',//退款关闭
|
||
'SUCCESS'=>'4',//退款成功
|
||
'WAIT_SELLER_CONFIRM_GOODS'=>'0',//买家已经退货 对应何流程?不处理
|
||
);
|
||
|
||
static public $return_status = array(
|
||
'WAIT_SELLER_AGREE'=>'1',
|
||
'WAIT_BUYER_RETURN_GOODS'=>'3',//卖家已经同意退款
|
||
'SELLER_REFUSE_BUYER'=>'5',//卖家拒绝
|
||
'CLOSED'=>'5',//退款关闭
|
||
'SUCCESS'=>'4',//退款成功
|
||
'WAIT_SELLER_CONFIRM_GOODS'=>'6',//买家已经退货
|
||
'CONFIRM_FAILED' => '5',
|
||
);
|
||
|
||
static public $reship_status = array(
|
||
'confirm_failed' => '5',
|
||
'wait_buyer_return_goods' => '0',
|
||
'wait_seller_confirm_goods' => '1',
|
||
'confirm_success' => '7',
|
||
'success' =>'0',
|
||
'10009' => '1',
|
||
);
|
||
|
||
//平台退款的类型
|
||
static public $tag_types = array(
|
||
'价保退款' => '1', //天猫平台
|
||
'返现退款' => '2', //天猫平台
|
||
'赔付退款' => '3', //天猫平台
|
||
'1' => '1', //抖音平台(价保退款单)
|
||
'极速退款' => '5', //极速退款
|
||
'售后仅退款' => '6',
|
||
'发货前退款' => '7',
|
||
);
|
||
|
||
//平台订单状态
|
||
protected $_sourceStatus = array();
|
||
protected $refund_item_all = false;
|
||
|
||
protected function _formatAddParams($params) {
|
||
$sdf = array(
|
||
'order_bn' => $params['tid'],
|
||
'platform_order_bn' => $params['tid'], //平台订单号
|
||
'refund_bn' => $params['refund_id'],
|
||
'status' => $params['status'],
|
||
'source_status' => $this->_sourceStatus[$params['source_status']] ? : $params['source_status'],
|
||
'platform_status' => $params['source_status'], //平台退款状态
|
||
'refund_fee' => $params['refund_fee'] ? sprintf('%.2f', $params['refund_fee']) : 0,
|
||
'refund_type' => $params['refund_type'],
|
||
'reason' => $params['reason'],
|
||
'modified' => $params['modified'] ? kernel::single('ome_func')->date2time($params['modified']) : time(),
|
||
'created' => $params['created'] ? kernel::single('ome_func')->date2time($params['created']) : time(),
|
||
't_begin' => $params['t_begin'] ? kernel::single('ome_func')->date2time($params['t_begin']) : time(),
|
||
'cur_money' => $params['cur_money'],
|
||
'pay_type' => $params['pay_type'] ? $params['pay_type'] : 'online',
|
||
'alipay_no' => $params['alipay_no'],
|
||
'payment' => $params['payment'],
|
||
'account' => $params['account'],
|
||
'bank' => $params['bank'],
|
||
'buyer_nick' => $params['buyer_nick'],
|
||
'desc' => $params['desc'],
|
||
'shipping_type' => $params['shipping_type'],
|
||
'logistics_company' => $params['logistics_company'] ? $params['logistics_company'] : $params['company_name'],
|
||
'logistics_no' => $params['logistics_no'] ? $params['logistics_no'] : $params['sid'],
|
||
'pay_account' => $params['pay_account'],
|
||
'has_good_return' => $params['has_good_return'] ? strtolower($params['has_good_return']) : '',
|
||
'good_return_time' => $params['good_return_time'] ? strtotime($params['good_return_time']) : 0,
|
||
'refund_item_list' => $params['refund_item_list'] ? json_decode($params['refund_item_list'],true) : [],
|
||
'org_id' => $this->__channelObj->channel['org_id'],
|
||
'refund_refer' => $params['refund_refer'], //退款来源(aftersale:售后仅退款,normal:普通)
|
||
'extend_field' => $params['extend_field'] ? json_decode($params['extend_field'],true) : [],
|
||
'from_platform' => $params['from_platform'],
|
||
);
|
||
|
||
if($params['platform_order_bn']){
|
||
$sdf['platform_order_bn'] = $params['platform_order_bn'];
|
||
}
|
||
|
||
if($params['platform_aftersale_bn']){
|
||
$sdf['platform_aftersale_bn'] = $params['platform_aftersale_bn'];
|
||
}
|
||
|
||
//组织架构ID
|
||
if(isset($params['cos_id'])){
|
||
$sdf['cos_id'] = $params['cos_id'];
|
||
}
|
||
|
||
//贸易公司ID
|
||
if(isset($params['betc_id'])){
|
||
$sdf['betc_id'] = $params['betc_id'];
|
||
}
|
||
|
||
$sdf['t_ready'] = $sdf['t_begin'];
|
||
$sdf['t_sent'] = $sdf['modified'];
|
||
|
||
//上一次已经作废掉的退货单号
|
||
if($params['cancel_reship_bn']){
|
||
$sdf['cancel_reship_bn'] = $params['cancel_reship_bn'];
|
||
}
|
||
//极速退款标识
|
||
if($params['jsrefund_flag']){
|
||
$sdf['jsrefund_flag'] = 1;
|
||
}
|
||
|
||
//客户实退
|
||
if($sdf['extend_field'] && $sdf['extend_field']['real_refund_amount']) {
|
||
$sdf['real_refund_amount'] = $sdf['extend_field']['real_refund_amount'];
|
||
}
|
||
self::trim($sdf);
|
||
return $sdf;
|
||
}
|
||
|
||
/**
|
||
* @param array $sdf
|
||
* @param array $convert 例 array('sdf_field'=>'item_id','order_field'=>'shop_goods_id','default_field'=>'outer_id');
|
||
* @return array 返回 以bn作主键的数组 捆绑商品使用捆绑商品的bn
|
||
*/
|
||
|
||
protected function _formatAddItemList($sdf, $convert = array()) {
|
||
if(empty($convert)) {
|
||
return array();
|
||
}
|
||
$itemList = $sdf['refund_item_list']['return_item'];
|
||
$sdfField = $convert['sdf_field'];
|
||
$orderField = $convert['order_field'];
|
||
$defaultField = $convert['default_field'];
|
||
$arrOrderField = array();
|
||
foreach($itemList as $val) {
|
||
if($val[$sdfField]) {
|
||
$arrOrderField[] = $val[$sdfField];
|
||
}
|
||
}
|
||
$filter = array(
|
||
$orderField => $arrOrderField,
|
||
'order_id' => $sdf['order']['order_id']
|
||
);
|
||
$object = app::get('ome')->model('order_objects')->getList($orderField . ', bn, obj_id, quantity,`delete`', $filter);
|
||
$arrBn = array();
|
||
$arrQuantity = array();
|
||
$arrObjId = array();
|
||
foreach($object as $oVal) {
|
||
if($oVal['delete'] == 'true') {
|
||
$this->_refundOidIsDeleted = true;
|
||
}
|
||
$arrBn[$oVal[$orderField]] = $oVal['bn'];
|
||
$arrQuantity[$oVal[$orderField]] = $oVal['quantity'];
|
||
$arrObjId[$oVal[$orderField]] = $oVal['obj_id'];
|
||
}
|
||
$arrItem = array();
|
||
foreach ($itemList as $item) {
|
||
$item['bn'] = $arrBn[(string)$item[$sdfField]] ? $arrBn[(string)$item[$sdfField]] : $item[$defaultField];
|
||
$item['bn'] = (string) $item['bn'];
|
||
if($item['nums'] && !$item['num']) {
|
||
$item['num'] = $item['nums'];
|
||
unset($item['nums']);
|
||
}
|
||
if($this->refund_item_all) {
|
||
$item['num'] = $arrQuantity[(string)$item[$sdfField]];
|
||
}
|
||
if($arrItem[$item['bn']]) {
|
||
$arrItem[$item['bn']]['num'] += $item['num'];
|
||
} else {
|
||
$arrItem[$item['bn']] = $item;
|
||
}
|
||
if($arrObjId[(string)$item[$sdfField]]) {
|
||
$arrItem[$item['bn']]['obj_id'][] = $arrObjId[(string)$item[$sdfField]];
|
||
}
|
||
}
|
||
|
||
return $arrItem;
|
||
}
|
||
|
||
protected function _calculateAddPriceFromRefundFee($items, $sdf) {
|
||
// 再根据退款金额重新计算单价
|
||
$refundFee = $sdf['refund_fee'] ? $sdf['refund_fee'] : $sdf['return_product']['money'];
|
||
$options = array (
|
||
'part_total' => $refundFee,
|
||
'part_field' => 'amount',
|
||
'porth_field' => 'porth_field',
|
||
);
|
||
$items = kernel::single('ome_order')->calculate_part_porth($items, $options);
|
||
foreach ($items as $i => $item) {
|
||
$items[$i]['price'] = $item['num'] > 0 ? bcdiv($item['amount'], $item['num'], 2) : 0;
|
||
}
|
||
|
||
return $items;
|
||
}
|
||
|
||
protected function _getAddType($sdf) {
|
||
return '';
|
||
}
|
||
|
||
protected function _refundApplyAdditional($sdf) {
|
||
return array();
|
||
}
|
||
|
||
//退款单 退款申请单 数据转换
|
||
protected function _refundAddSdf($sdf)
|
||
{
|
||
//拼多多、抖音平台退款未包含平台优惠特殊处理
|
||
$sdf = $this->_formatRefundFee($sdf);
|
||
$sdf['status'] = self::$refund_status[strtoupper($sdf['status'])];
|
||
$refundApplyBn = $sdf['refund_bn'];
|
||
if($sdf['reason']) {
|
||
if(preg_match('/#(\d+)#/', $sdf['reason'],$matches)) {
|
||
$refundApplyBn = $matches[1];
|
||
}
|
||
$sdf['reason'] = preg_replace('/#(\d+)#/', '', $sdf['reason']);
|
||
}
|
||
$shopId = $this->__channelObj->channel['shop_id'];
|
||
|
||
// 退款申请单
|
||
$refundApplyModel = app::get('ome')->model('refund_apply');
|
||
$refundApply = $refundApplyModel->getList('apply_id,return_id,refund_apply_bn,refund_refer,status,money,payment,memo,addon,outer_lastmodify,reship_id', array('refund_apply_bn'=>$refundApplyBn,'shop_id'=>$shopId), 0, 1);
|
||
$sdf['refund_version_change'] = false;
|
||
if($refundApply) {
|
||
$sdf['refund_apply'] = $refundApply[0];
|
||
if ($sdf['modified'] > $sdf['refund_apply']['outer_lastmodify']) {
|
||
$sdf['refund_version_change'] = true;
|
||
}
|
||
$refundApplyModel->update([
|
||
'source_status' => kernel::single('ome_refund_func')->get_source_status($sdf['source_status'])],
|
||
['apply_id'=>$sdf['refund_apply']['apply_id']]);
|
||
}
|
||
|
||
// 退款单
|
||
$refundModel = app::get('ome')->model('refunds');
|
||
$refund = $refundModel->getList('refund_id', array('refund_bn'=>$sdf['refund_bn'],'shop_id'=>$shopId));
|
||
if($refund) {
|
||
$sdf['refund'] = $refund[0];
|
||
}
|
||
|
||
$payment_cfg = $this->get_payment($sdf['payment'],$sdf['shop_type']);
|
||
if($payment_cfg) {
|
||
$sdf['payment'] = $payment_cfg['id'];
|
||
}
|
||
|
||
if ($sdf['status'] == '4' || $sdf['refund_type'] == 'refund') {
|
||
$this->__apilog['title'] = '店铺(' . $this->__channelObj->channel['name'] . ')退款单,单号:' . $sdf['refund_bn'];
|
||
$sdf['response_bill_type'] = 'refund';
|
||
|
||
//单独只创建退款申请单、退款单,不编辑订单明细、也不更新订单金额
|
||
//@todo:平台订单全额退款、已取消,同分同秒推送过来,OMS只更新订单为全额退款或取消订单,未创建退款单;
|
||
if($sdf['order']['pay_status'] == '5' && bccomp($sdf['order']['payed'], $sdf['refund_fee'], 3) < 0){
|
||
$sdf['response_bill_type'] = 'refundonly';
|
||
}
|
||
|
||
} else {
|
||
$this->__apilog['title'] = '店铺(' . $this->__channelObj->channel['name'] . ')退款申请单,单号:' . $sdf['refund_bn'];
|
||
if ($sdf['status'] == '0' || empty($sdf['refund_apply'])) {
|
||
$sdf['table_additional'] = $this->_refundApplyAdditional($sdf);
|
||
}
|
||
$sdf['response_bill_type'] = 'refund_apply';
|
||
}
|
||
|
||
return $sdf;
|
||
}
|
||
|
||
protected function _returnProductAdditional($sdf) {
|
||
return array();
|
||
}
|
||
|
||
protected function _getOrderDelivery($sdf) {
|
||
//获取订单关联的所有已发货的发货单(支持return_back追回状态)
|
||
if ($sdf['order']['tran_type'] == 'archive'){
|
||
$sql = "SELECT dord.delivery_id, d.branch_id, d.logi_no, d.logi_name FROM sdb_archive_delivery_order AS dord
|
||
LEFT JOIN sdb_archive_delivery AS d ON(dord.delivery_id=d.delivery_id)
|
||
WHERE dord.order_id='".$sdf['order']['order_id']."' AND d.status IN('succ','return_back')";
|
||
$archive_delivery = kernel::database()->selectrow($sql);
|
||
return $archive_delivery;
|
||
}
|
||
|
||
//获取订单关联的发货单(支持return_back追回状态)
|
||
$sql = "SELECT dord.delivery_id, d.branch_id, d.logi_no, d.logi_name FROM sdb_ome_delivery_order AS dord
|
||
LEFT JOIN sdb_ome_delivery AS d ON(dord.delivery_id=d.delivery_id)
|
||
WHERE dord.order_id='".$sdf['order']['order_id']."'
|
||
AND (d.parent_id=0 OR d.is_bind='true')
|
||
AND d.disabled='false' AND d.status IN('succ','return_back')";
|
||
$result = kernel::database()->select($sql);
|
||
if(count($result) > 1 && !empty($sdf['refund_item_list'])) {
|
||
$arrDelivery = array();
|
||
foreach ($result as $key => $val) {
|
||
$arrDelivery[$val['delivery_id']] = $val;
|
||
}
|
||
$productId = '';
|
||
foreach($sdf['refund_item_list'] as $iVal) {
|
||
if($iVal['product_id']) {
|
||
$productId = $iVal['product_id'];
|
||
break;
|
||
}
|
||
}
|
||
$deliItemModel = app::get('ome')->model('delivery_items');
|
||
$itemData = $deliItemModel->getList('delivery_id', array('delivery_id'=>array_keys($arrDelivery), 'product_id'=>$productId), 0, 1);
|
||
}
|
||
return $itemData ? $arrDelivery[$itemData[0]['delivery_id']] : $result[0];
|
||
}
|
||
|
||
protected function _returnProductReship($returnProductId, $orderId) {
|
||
$rs = array();
|
||
$oReship = app::get('ome')->model('reship');
|
||
$field = 'reship_id,reship_bn,return_id,is_check,return_logi_name,return_logi_no,outer_lastmodify,branch_id,return_type,status,change_order_id,jsrefund_flag';
|
||
$reship = $oReship->getList($field, array('return_id' => $returnProductId), 0, 1);
|
||
if($reship) {
|
||
$rs['reship'] = $reship[0];
|
||
$otherFilter = ' AND r.reship_id != ' . $rs['reship']['reship_id'];
|
||
}
|
||
$sql = "SELECT i.order_item_id,i.bn, i.num FROM sdb_ome_reship as r left join sdb_ome_reship_items as i on r.reship_id=i.reship_id WHERE i.return_type='return' AND r.is_check!='5' AND r.order_id='" . $orderId . "' " . $otherFilter;
|
||
$otherReship = $oReship->db->select($sql);
|
||
if($otherReship) {
|
||
$rs['other_reship_items'] = $otherReship;
|
||
}
|
||
return $rs;
|
||
}
|
||
|
||
//检查售后申请单版本是否更新
|
||
protected function _getReturnVersionChange($sdf)
|
||
{
|
||
$version_change = false;
|
||
|
||
if ($sdf['modified'] > $sdf['return_product']['outer_lastmodify'] && ($sdf['return_product']['content']!=$sdf['reason']) || $sdf['return_product']['money']!=$sdf['refund_fee']) {
|
||
$version_change = true;
|
||
}
|
||
|
||
return $version_change;
|
||
}
|
||
|
||
protected function _returnFreight($sdf) {
|
||
return [];
|
||
}
|
||
|
||
//售后申请单数据转换
|
||
protected function _returnProductAddSdf($sdf) {
|
||
$this->__apilog['title'] = '店铺(' . $this->__channelObj->channel['name'] . ')售后申请单,单号:' . $sdf['refund_bn'];
|
||
|
||
//场景:换货完成又进行退货
|
||
if($sdf['change_order_id']){
|
||
$this->__apilog['title'] = '换货完成后申请售后退货,申请单号:' . $sdf['refund_bn'];
|
||
}
|
||
|
||
$sdf['response_bill_type'] = 'return_product';
|
||
$sdf['status'] = self::$return_status[strtoupper($sdf['status'])];
|
||
$returnModel = app::get('ome')->model('return_product');
|
||
$tgReturn = $returnModel->getList('*', array('shop_id'=>$sdf['shop_id'],'return_bn'=>$sdf['refund_bn']));
|
||
$sdf['refund_version_change'] = false;
|
||
$returnId = -1;
|
||
if($tgReturn) {
|
||
$sdf['return_product'] = $tgReturn[0];
|
||
$returnId = $sdf['return_product']['return_id'];
|
||
//版本是否更新
|
||
$sdf['refund_version_change'] = $this->_getReturnVersionChange($sdf);
|
||
|
||
|
||
if ($this->_change_return_type === true && $sdf['return_product']['return_type'] =='change'){
|
||
//$sdf['refund_version_change'] = true;
|
||
//
|
||
if(!in_array($sdf['status'],array('5','9'))){
|
||
$sdf['change_return_type'] = true;
|
||
//$sdf['status'] = '1';
|
||
|
||
}
|
||
}
|
||
}
|
||
$reshipData = $this->_returnProductReship($returnId, $sdf['order']['order_id']);
|
||
if($reshipData['reship']) {
|
||
$sdf['reship'] = $reshipData['reship'];
|
||
}
|
||
if($reshipData['other_reship_items']) {
|
||
$sdf['other_reship_items'] = $reshipData['other_reship_items'];
|
||
}
|
||
|
||
$delivery = $this->_getOrderDelivery($sdf);
|
||
if ($delivery) {
|
||
$sdf['delivery_id'] = $delivery['delivery_id'];
|
||
$sdf['branch_id'] = $delivery['branch_id'];
|
||
if($sdf['refund_to_returnProduct']) {
|
||
$sdf['logistics_company'] = $delivery['logi_name'];
|
||
$sdf['logistics_no'] = $delivery['logi_no'];
|
||
}
|
||
}
|
||
if($sdf['shop']['delivery_mode'] != 'jingxiao') {
|
||
//取默认退货仓
|
||
$return_auto_branch = app::get('ome')->getConf('return.auto_branch');
|
||
if ($return_auto_branch){
|
||
$sdf['branch_id'] = $return_auto_branch;
|
||
|
||
}
|
||
$return_auto_shop_branch = app::get('ome')->getConf('return.auto_shop_branch');
|
||
if($return_auto_shop_branch[$sdf['shop_id']]) {
|
||
$sdf['branch_id'] = $return_auto_shop_branch[$sdf['shop_id']];
|
||
}
|
||
}
|
||
if ($sdf['status'] == '1' || !$sdf['return_product']) {
|
||
// 如果前端传了会员名
|
||
if ($sdf['buyer_nick']) {
|
||
$shopMemberModel = app::get('ome')->model('shop_members');
|
||
$member = $shopMemberModel->getList('member_id', array('shop_member_id' => $sdf['buyer_nick'], 'shop_id' => $sdf['shop_id']), 0, 1);
|
||
$sdf['member_id'] = $member[0]['member_id'];
|
||
} else {
|
||
$sdf['member_id'] = $sdf['order']['member_id'];
|
||
}
|
||
$sdf['table_additional'] = $this->_returnProductAdditional($sdf);
|
||
$sdf['table_return_freight'] = $this->_returnFreight($sdf);
|
||
} else {
|
||
$returnItemModel = app::get('ome')->model('return_product_items');
|
||
$tgReturnItems = $returnItemModel->getList('*',array('return_id'=>$sdf['return_product']['return_id']));
|
||
if (!$tgReturnItems) {
|
||
$this->__apilog['result']['msg'] = '缺少明细';
|
||
return false;
|
||
}
|
||
$sdf['refund_item_list'] = $tgReturnItems;
|
||
$sdf['branch_id'] = $tgReturnItems[0]['branch_id'];
|
||
}
|
||
$sdf['choose_type_flag'] = 1;
|
||
return $sdf;
|
||
}
|
||
|
||
protected function _reshipAddItemList($sdf) {
|
||
$returnList = array();
|
||
$itemsObj = app::get('ome')->model('return_product_items');
|
||
$refundItemList = $itemsObj->getList('product_id,bn,name,num,price,order_item_id,amount',array('return_id'=>$sdf['return_product']['return_id']));
|
||
if($refundItemList) {
|
||
$items_ids = array();
|
||
foreach($refundItemList as $var_ril){
|
||
$items_ids[] = $var_ril["order_item_id"];
|
||
}
|
||
if(!empty($items_ids)){
|
||
$mdl_order_items = app::get('ome')->model('order_items');
|
||
$rs_items = $mdl_order_items->getList("item_id,sendnum",array("item_id"=>$items_ids));
|
||
$rl_item_id_info = array();
|
||
foreach($rs_items as $var_item){
|
||
$rl_item_id_info[$var_item["item_id"]] = $var_item["sendnum"];
|
||
}
|
||
foreach($refundItemList as $var_rfil){
|
||
$returnList[] = array(
|
||
"product_id" => $var_rfil["product_id"],
|
||
"bn" => $var_rfil["bn"],
|
||
"name" => $var_rfil["name"],
|
||
"num" => $var_rfil["num"],
|
||
"price" => $var_rfil["price"],
|
||
"amount" => $var_rfil["amount"],
|
||
"order_item_id" => $var_rfil["order_item_id"],
|
||
"sendNum" => $rl_item_id_info[$var_rfil["order_item_id"]],
|
||
);
|
||
}
|
||
}
|
||
}
|
||
return $returnList;
|
||
}
|
||
|
||
/**
|
||
* 退后单数据转换
|
||
* @param $sdf
|
||
* @param $params 平台推送的原数据
|
||
* @return array
|
||
*/
|
||
protected function _reshipAddSdf($sdf, $params=null) {
|
||
$this->__apilog['title'] = '店铺(' . $this->__channelObj->channel['name'] . ')退货单,单号:' . $sdf['refund_bn'];
|
||
|
||
//场景:换货完成又进行退货
|
||
if($sdf['change_order_id']){
|
||
$this->__apilog['title'] = '换货完成后申请退货,申请单号:' . $sdf['refund_bn'];
|
||
}
|
||
|
||
$sdf['response_bill_type'] = 'reship';
|
||
$sdf['status'] = self::$reship_status[strtolower($sdf['status'])];
|
||
$sdf['shop_id'] = $this->__channelObj->channel['shop_id'];
|
||
// 售后单
|
||
$returnFilter = array('shop_id'=>$sdf['shop_id'],'return_bn'=>$sdf['refund_bn'],'source'=>'matrix');
|
||
$returnModel = app::get('ome')->model('return_product');
|
||
$tgReturn = $returnModel->getList('return_id,return_bn,delivery_id,status,money,is_fail,archive,return_type,outer_lastmodify,changebranch_id', $returnFilter, 0, 1);
|
||
if (!$tgReturn) {
|
||
//单拉售后单
|
||
$returnRsp = kernel::single('erpapi_router_request')->set('shop', $sdf['shop_id'])->finance_getRefundDetail($sdf['refund_bn'],$sdf['refund_phase'], $sdf['order_bn']);
|
||
if ($returnRsp['rsp'] == 'succ') {
|
||
$msg = '';
|
||
$rs = kernel::single('ome_return')->get_return_log($returnRsp['data'],$sdf['shop_id'],$msg);
|
||
if ($rs) {
|
||
$tgReturn = $returnModel->getList('return_id,return_bn,delivery_id,status,money,is_fail,archive,return_type,outer_lastmodify,changebranch_id', $returnFilter, 0, 1);
|
||
}
|
||
}
|
||
}
|
||
if ($tgReturn[0]['archive'] == '1'){
|
||
$sdf['archive'] = '1';
|
||
$sdf['source'] = 'archive';
|
||
|
||
}
|
||
|
||
if (!$tgReturn) {
|
||
//单拉售后单
|
||
$this->__apilog['result']['msg'] = "售后申请单不存在,不可以创建退货单!";
|
||
return false;
|
||
}
|
||
if($tgReturn[0]['is_fail'] == 'true') {
|
||
$this->__apilog['result']['msg'] = "售后申请单处于失败状态,不可以创建退货单!";
|
||
return false;
|
||
}
|
||
$sdf['return_product'] = $tgReturn[0];
|
||
if(!$sdf['change_order_id']){
|
||
$sdf['refund_item_list'] = $this->_reshipAddItemList($sdf);
|
||
}
|
||
|
||
$oDc = app::get('ome')->model('dly_corp');
|
||
$dcData = $oDc->getList('name', array('corp_id'=>$sdf['order']['logi_id']), 0, 1);
|
||
$sdf['logi_name'] = $dcData[0]['name'];
|
||
$Odelivery = app::get('ome')->model('delivery');
|
||
$deliveryinfo = $Odelivery->getList('branch_id', array('delivery_id'=>$sdf['return_product']['delivery_id']), 0, 1);
|
||
if ($tgReturn[0]['archive'] == '1'){
|
||
$deliveryinfo = app::get('archive')->model('delivery')->getList('branch_id', array('delivery_id'=>$sdf['return_product']['delivery_id']), 0, 1);
|
||
}
|
||
$sdf['branch_id'] = $deliveryinfo[0]['branch_id'];
|
||
$reshipData = $this->_returnProductReship($sdf['return_product']['return_id'], $sdf['order']['order_id']);
|
||
if($reshipData['reship']) {
|
||
$sdf['reship'] = $reshipData['reship'];
|
||
}
|
||
if($reshipData['other_reship_items']) {
|
||
$sdf['other_reship_items'] = $reshipData['other_reship_items'];
|
||
}
|
||
|
||
//@todo:客服拒绝退货后,平台介入或顾客上传凭证后,重新恢复退货;
|
||
//场景:顾客申请退货,商家在天猫后台拒绝退货退款;顾客上传退货凭证后,平台自动同意退货申请,恢复原退货单;
|
||
if($sdf['return_product']['status'] == '5' && $params){
|
||
//判断是否允许恢复售后
|
||
$isRecoverReturn = $this->_checkRecoverReturn($sdf);
|
||
if($isRecoverReturn === true){
|
||
//修改拒绝的售后申请单号和退换货单号
|
||
$cancel_reship_bn = '';
|
||
$isEditReturnBn = $this->_transformReturnBn($sdf, $cancel_reship_bn);
|
||
if($isEditReturnBn === true){
|
||
//重新开始创建售后申请单
|
||
$params['refund_type'] = 'return';
|
||
$params['cancel_reship_bn'] = $cancel_reship_bn;
|
||
|
||
return $this->add($params);
|
||
}
|
||
}
|
||
}
|
||
|
||
return $sdf;
|
||
}
|
||
|
||
/**
|
||
* 添加
|
||
* @param mixed $params 参数
|
||
* @return mixed 返回值
|
||
*/
|
||
public function add($params){
|
||
$this->__apilog['title'] = '店铺(' . $this->__channelObj->channel['name'] . ')售后业务处理[订单:' . $params['tid'] . ']';
|
||
$this->__apilog['original_bn'] = $params['tid'];
|
||
$this->__apilog['result']['data'] = array('tid'=>$params['tid'],'aftersale_id'=>$params['refund_id'],'retry'=>'false');
|
||
|
||
//加判断yjdf非经销过来的不收
|
||
if(in_array($this->__channelObj->channel['delivery_mode'], array('shopyjdf'))){
|
||
if(!isset($params['from_platform']) || empty($params['from_platform']) ){
|
||
$this->__apilog['result']['msg'] = '店铺为:一件代发,不接收非经销来源数据';
|
||
return false;
|
||
}
|
||
}
|
||
|
||
$sdf = $this->_formatAddParams($params);
|
||
if(empty($sdf) || !is_array($sdf)) {
|
||
if(!$this->__apilog['result']['msg']) {
|
||
$this->__apilog['result']['msg'] = '没有数据,不接收售后单';
|
||
}
|
||
return false;
|
||
}
|
||
$shopId = $sdf['shop_id'] = $this->__channelObj->channel['shop_id'];
|
||
$sdf['shop_type'] = $this->__channelObj->channel['shop_type'];
|
||
$sdf['shop'] = $this->__channelObj->channel;
|
||
$sdf['shop']['delivery_mode'] = $this->__channelObj->channel['delivery_mode'];
|
||
$field = 'order_id,status,process_status,ship_status,pay_status,payed,cost_payment,pay_bn,member_id,logi_id,logi_no,ship_name,ship_area,ship_addr,ship_zip,ship_tel,ship_email,ship_mobile,shipping,is_protect,is_cod,source,order_type,createtime,abnormal,source_status,api_version,platform_order_bn,total_amount,sync,service_price';
|
||
$tgOrder = $this->getOrder($field, $shopId, $sdf['order_bn'],'aftersale');
|
||
|
||
if($tgOrder === 0) {
|
||
$this->_dealRefundNoOrder($sdf);
|
||
$this->__apilog['result']['msg'] = '没有订单' . $sdf['order_bn'];
|
||
return false;
|
||
}
|
||
if($tgOrder['platform_order_bn']) {
|
||
$sdf['platform_order_bn'] = $tgOrder['platform_order_bn'];
|
||
}
|
||
//删除退款日志
|
||
if(!$tgOrder && in_array(strtoupper($sdf['status']), array('SELLER_REFUSE_BUYER', 'SUCCESS', 'CLOSED'))) {
|
||
$filter = array(
|
||
'order_bn' => $sdf['order_bn'],
|
||
'shop_id' => $sdf['shop_id'],
|
||
'refund_bn' => $sdf['refund_bn']
|
||
);
|
||
app::get('ome')->model('refund_no_order')->delete($filter);
|
||
$tgOrder = $this->getOrder($field, $shopId, $sdf['order_bn']);
|
||
}
|
||
|
||
//添加退款日志
|
||
if (!$tgOrder) {
|
||
if(!in_array(strtoupper($sdf['status']), array('SELLER_REFUSE_BUYER', 'SUCCESS', 'CLOSED'))) {
|
||
$this->_dealRefundNoOrder($sdf);
|
||
}
|
||
$this->__apilog['result']['msg'] = '没有订单' . $sdf['order_bn'];
|
||
return false;
|
||
}
|
||
|
||
$sdf['order'] = $tgOrder;
|
||
|
||
// 兼容换了又退
|
||
list($is_change, $change_msg, $change_order, $convert) = $changeRs = $this->getChangeReturnProduct($sdf);
|
||
if($is_change === true){
|
||
// OMS生成的新订单号
|
||
$sdf['tid'] = $sdf['order_bn'] = $change_order['order_bn'];
|
||
|
||
// OMS换货生成的新订单信息
|
||
$sdf['order'] = $change_order;
|
||
}
|
||
|
||
// $this->__apilog['result']['data']['changeRs'] = $changeRs;
|
||
|
||
|
||
$type = $this->_getAddType($sdf);
|
||
if(empty($type)) {
|
||
if(!$this->__apilog['result']['msg']) {
|
||
$this->__apilog['result']['msg'] = '所属店铺类型,不接收售后单';
|
||
}
|
||
return false;
|
||
}
|
||
|
||
//未签收的售后仅退款转为售后退货
|
||
if($type == 'refund'
|
||
&& in_array($sdf['order']['ship_status'], ['1', '3'])
|
||
&& $sdf['order']['status'] == 'finish'
|
||
&& $sdf['order']['source_status'] != 'TRADE_FINISHED'
|
||
&& !(strpos($sdf['reason'], '运费') !== false || strpos($sdf['reason'], '买贵必赔') !== false || strpos($sdf['reason'], '保价') !== false || $sdf['tag_type'] == '1')
|
||
&& !(strpos($sdf['desc'], '换货转退款') !== false)
|
||
&& in_array(app::get('ome')->getConf('ome.reship.refund.only.reship'), ['true', 'refund'])
|
||
) {
|
||
//[天猫定制订单]申请售后仅退款,不用转换拦截退货单
|
||
if($sdf['order']['order_type'] == 'custom' && in_array($sdf['shop_type'], ['taobao', 'tmall'])){
|
||
//不用转换为:returnProduct
|
||
}else{
|
||
$sdf['refund_to_returnProduct'] = true;
|
||
if(app::get('ome')->getConf('ome.reship.refund.only.reship') != 'refund'){
|
||
$type = 'returnProduct';
|
||
}
|
||
}
|
||
}
|
||
|
||
//识别如果是已完成的售后,转成退款单更新的逻辑
|
||
if(in_array($type, ['returnProduct','reship']) && (strtolower($sdf['status']) == 'success' || $sdf['jsrefund_flag']==1) ){
|
||
$refundOriginalObj = app::get('ome')->model('return_product');
|
||
$refundOriginalInfo = $refundOriginalObj->getList('return_id', array('return_bn'=>$sdf['refund_bn'],'status' =>'4') , 0 , 1);
|
||
if($refundOriginalInfo){
|
||
$refundApplyObj = app::get('ome')->model('refund_apply');
|
||
$refundApplyInfo = $refundApplyObj->getList('refund_apply_bn', array('return_id'=>$refundOriginalInfo[0]['return_id'],'status' =>array('0','1','2','5','6')) , 0 , 1);
|
||
if($refundApplyInfo){
|
||
$sdf['refund_bn'] = $refundApplyInfo[0]['refund_apply_bn'];
|
||
$sdf['tmall_has_finished_return_product'] = true;
|
||
$type = 'refund';
|
||
if($sdf['jsrefund_flag'] && strtolower($sdf['status']) != 'success'){
|
||
$sdf['status']='success';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$this->_refundOidIsDeleted = false;
|
||
//获取订单上退货基础物料列表
|
||
if(is_array($sdf['refund_item_list'])) {
|
||
if(!$sdf['change_order_id']){
|
||
$refundItemList = $this->_formatAddItemList($sdf);
|
||
if(empty($refundItemList)) {
|
||
$sdf['refund_item_list'] = '';
|
||
}else{
|
||
//根据申请退货商品关联退货订单明细
|
||
$sdf['refund_item_list'] = $this->_calculateAddPrice($refundItemList, $sdf);
|
||
}
|
||
} else {
|
||
$rfItems = $sdf['refund_item_list'];
|
||
foreach($rfItems as $k => $v) {
|
||
$rfItems[$k]['porth_field'] = $v['price'] * $v['num'];
|
||
}
|
||
$sdf['refund_item_list'] = $this->_calculateAddPriceFromRefundFee($rfItems, $sdf);
|
||
}
|
||
|
||
}
|
||
//未签收的售后仅退款转为售后退货,若订单商品被删除,则重新生成退款单
|
||
if($sdf['refund_to_returnProduct'] && $this->_refundOidIsDeleted) {
|
||
$type = 'refund';
|
||
}
|
||
|
||
if($type == 'refund') {
|
||
return $this->_refundAddSdf($sdf);
|
||
} elseif( $type == 'returnProduct') {
|
||
$returnSdf = $this->_returnProductAddSdf($sdf);
|
||
|
||
//暂停换出订单
|
||
if($returnSdf['reship']['change_order_id']){
|
||
kernel::single('ome_return')->pauseChangeOrder($returnSdf['reship']['change_order_id']);
|
||
}
|
||
if(in_array($sdf['shop_type'], array('xhs','wxshipin')) && $returnSdf['return_product']['return_type'] == 'change'){
|
||
$lubanLib = kernel::single('ome_reship_luban');
|
||
$result = $lubanLib->transformExchange($returnSdf);
|
||
if($result['rsp'] == 'succ'){
|
||
//原换货申请单已经拒绝,这里置为空;
|
||
$returnSdf['return_product'] = array();
|
||
|
||
//打标识,后面自动审核售后申请单,并且使用OMS本地生成的退货单号
|
||
$returnSdf['isTransformExchange'] = 'succeed';
|
||
}else{
|
||
//作废换货单失败
|
||
$lubanLib->disposeExchangeBusiness($returnSdf);
|
||
|
||
//打失败标识
|
||
$returnSdf['isTransformExchange'] = 'fail';
|
||
}
|
||
}
|
||
|
||
return $returnSdf;
|
||
} elseif($type == 'reship') {
|
||
return $this->_reshipAddSdf($sdf, $params);
|
||
} else {
|
||
if(!$this->__apilog['result']['msg']) {
|
||
$this->__apilog['result']['msg'] = '不接收售后单';
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 客服拒绝退货后,平台介入或顾客上传凭证后,重新恢复退货;
|
||
* 场景:顾客申请退货,商家在天猫后台拒绝退货退款;顾客上传退货凭证后,平台自动同意退货申请,恢复原退货单;
|
||
*
|
||
* @param $sdf
|
||
* @return void
|
||
*/
|
||
public function _checkRecoverReturn($sdf)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 修改拒绝的售后申请单号和退换货单号
|
||
* @param $sdf
|
||
* @param $cancel_reship_bn 已经作废掉的退货单号
|
||
* @return void
|
||
*/
|
||
public function _transformReturnBn($sdf, &$cancel_reship_bn='')
|
||
{
|
||
$returnProductObj = app::get('ome')->model('return_product');
|
||
$operateLog = app::get('ome')->model('operation_log');
|
||
|
||
//params
|
||
$refund_bn = $sdf['refund_bn'];
|
||
|
||
//售后申请单信息
|
||
if(empty($sdf['return_product'])){
|
||
return false;
|
||
}
|
||
|
||
//售后申请单不是拒绝状态
|
||
if($sdf['return_product']['status'] != '5'){
|
||
return false;
|
||
}
|
||
|
||
//换货单信息
|
||
if($sdf['reship']){
|
||
//退换货单不是已取消状态
|
||
if($sdf['reship']['is_check'] != '5'){
|
||
return false;
|
||
}
|
||
|
||
$reship_id = $sdf['reship']['reship_id'];
|
||
$reship_bn = $sdf['reship']['reship_bn'];
|
||
|
||
//修改作废的退换货单号
|
||
$cancel_reship_bn = $reship_bn .'-'. $reship_id;
|
||
$update_sql = "UPDATE sdb_ome_reship SET reship_bn='". $cancel_reship_bn ."' WHERE reship_bn='". $reship_bn ."' AND is_check='5'";
|
||
$returnProductObj->db->exec($update_sql);
|
||
|
||
//log
|
||
$operateLog->write_log('reship@ome', $reship_id, '平台恢复售后申请,修改拒绝的退换货单号为:'. $cancel_reship_bn);
|
||
}
|
||
|
||
//售后申请单信息
|
||
$return_id = $sdf['return_product']['return_id'];
|
||
$return_bn = $sdf['return_product']['return_bn'];
|
||
|
||
//修改作废售后申请单号
|
||
$cancel_return_bn = $return_bn .'-'. $return_id;
|
||
$update_sql = "UPDATE sdb_ome_return_product SET return_bn='". $cancel_return_bn ."' WHERE return_bn='". $return_bn ."' AND status='5'";
|
||
$returnProductObj->db->exec($update_sql);
|
||
|
||
//log
|
||
$operateLog->write_log('return@ome', $return_id, '平台恢复售后申请,修改售后申请单号为:'. $cancel_return_bn);
|
||
|
||
//作废平台售后申请单号
|
||
if(in_array($sdf['shop_type'], array('taobao', 'tmall')) && $sdf['shop_id']){
|
||
$update_sql = "UPDATE sdb_ome_return_product_tmall SET return_bn='". $cancel_return_bn ."' WHERE shop_id='". $sdf['shop_id'] ."' AND return_bn='". $return_bn ."'";
|
||
$returnProductObj->db->exec($update_sql);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
protected function _formatLogisticsUpdate($params)
|
||
{
|
||
if (is_string($params['logistics_info'])) {
|
||
$logistics_info = json_decode($params['logistics_info'], true);
|
||
$process_data = array();
|
||
$process_data['shipcompany'] = $logistics_info['logistics_company'];
|
||
$process_data['logino'] = $logistics_info['logistics_no'];
|
||
}
|
||
$sdf = array(
|
||
'order_bn' => $params['tid'],
|
||
'return_bn' => $params['aftersale_id'],
|
||
'process_data' => $process_data
|
||
);
|
||
return $sdf;
|
||
}
|
||
|
||
/**
|
||
* logisticsUpdate
|
||
* @param mixed $params 参数
|
||
* @return mixed 返回值
|
||
*/
|
||
public function logisticsUpdate($params) {
|
||
$sdf = $this->_formatLogisticsUpdate($params);
|
||
$this->__apilog['title'] = '前端店铺更新物流信息V1[售后单号:'.$sdf['return_bn'].' ]';
|
||
$this->__apilog['original_bn'] = $sdf['order_bn'];
|
||
$shopId = $this->__channelObj->channel['shop_id'];
|
||
$sdf['node_type'] = $this->__channelObj->channel['node_type'];
|
||
// 订单
|
||
$orderModel = app::get('ome')->model('orders');
|
||
$tgOrder = $orderModel->getList('order_id', array('order_bn'=>$sdf['order_bn'],'shop_id'=>$shopId));
|
||
if (!$tgOrder) {
|
||
$this->__apilog['result']['msg'] = '没有订单' . $sdf['order_bn'];
|
||
return false;
|
||
}
|
||
$returnModel = app::get('ome')->model('return_product');
|
||
$tgReturn = $returnModel->getList('return_id, process_data', array('return_bn'=>$sdf['return_bn'],'order_id'=>$tgOrder[0]['order_id']));
|
||
if (!$tgReturn) {
|
||
$this->__apilog['result']['msg'] = '没有售后申请单' . $sdf['return_bn'];
|
||
return false;
|
||
}
|
||
$sdf['return_id'] = $tgReturn[0]['return_id'];
|
||
$sdf['old_process_data'] = unserialize($tgReturn[0]['process_data']);
|
||
|
||
return $sdf;
|
||
}
|
||
|
||
/**
|
||
* [换货完成又退货]通过原平台订单找到换货生成的OMS新订单
|
||
*
|
||
* @param $sdf
|
||
* @return array
|
||
*/
|
||
public function getChangeReturnProduct($sdf)
|
||
{
|
||
$orderObj = app::get('ome')->model('orders');
|
||
$reshipMdl = app::get('ome')->model('reship');
|
||
if($sdf['change_order_flag']) return false;
|
||
//sdf
|
||
// $oid = $sdf['oid'];
|
||
$shop_id = $sdf['shop_id'];
|
||
$order_bn = $sdf['order_bn'];
|
||
$refund_bn = $sdf['refund_bn'];
|
||
|
||
$orderFilter = [
|
||
'shop_id' => $shop_id,
|
||
'platform_order_bn' => $order_bn,
|
||
'ship_status' => ['1','2','3','4'],
|
||
];
|
||
|
||
// 判断是否数据已经存在
|
||
$rp = app::get('ome')->model('return_product')->db_dump([
|
||
'return_bn' => $refund_bn,
|
||
'shop_id' => $shop_id,
|
||
], 'order_id');
|
||
|
||
$field = 'order_id,order_bn,status,process_status,ship_status,pay_status,payed,cost_payment,pay_bn,member_id,logi_id,logi_no,ship_name,ship_area,ship_addr,ship_zip,ship_tel,ship_email,ship_mobile,shipping,is_protect,is_cod,source,order_type,createtime,abnormal,platform_order_bn,total_amount';
|
||
if ($rp && $rp['order_id'] != $sdf['order']['order_id']){
|
||
$order = $orderObj->db_dump(['order_id' => $rp['order_id']], $field);
|
||
|
||
return [true, '匹配成功', $order];
|
||
}
|
||
|
||
// 定位退货订单
|
||
$orderList = $orderObj->getList($field, $orderFilter);
|
||
|
||
if (!$orderList) {
|
||
return [false, '未找到平台订单号:'.$order_bn];
|
||
}
|
||
|
||
if (1 == count($orderList) && $orderList[0]['source'] == 'matrix'){
|
||
return [false, '未存在换货订单'];
|
||
}
|
||
|
||
$orderList = array_column($orderList, null, 'order_id');
|
||
$objects = app::get('ome')->model('order_objects')->getList('order_id,obj_id,oid,quantity,bn', [
|
||
'order_id'=> array_keys($orderList),
|
||
'delete' => 'false',
|
||
]);
|
||
$objects = array_column($objects, null, 'obj_id');
|
||
|
||
$items = app::get('ome')->model('order_items')->getList('item_id,obj_id,order_id,bn,nums,sendnum,return_num,item_type', [
|
||
'order_id' => array_keys($orderList),
|
||
'filter_sql' => ' sendnum > return_num ',
|
||
'delete' => 'false',
|
||
]);
|
||
|
||
$returnDetails = [];
|
||
foreach ($items as $item) {
|
||
$oid = $objects[$item['obj_id']]['oid'];
|
||
$quantity = $objects[$item['obj_id']]['quantity'];
|
||
|
||
$bn = $item['bn'];
|
||
$returnableNum = $item['sendnum'] - $item['return_num'];
|
||
|
||
//item_type
|
||
if (in_array($item['item_type'], array('pkg', 'lkb'))){
|
||
$returnableNum = floor($returnableNum / $item['nums'] * $quantity);
|
||
}
|
||
|
||
$returnDetails[$item['order_id']]['oid_list'][$oid] = $returnableNum;
|
||
|
||
$returnDetails[$item['order_id']]['bn_list'][$bn] = $returnableNum;
|
||
}
|
||
|
||
foreach ($returnDetails as $order_id => $value){
|
||
$oid_list = $value['oid_list'];
|
||
$bn_list = $value['bn_list'];
|
||
|
||
// 按OID查
|
||
$match = true;
|
||
foreach($sdf['refund_item_list']['return_item'] as $key => $return_item){
|
||
if ($return_item['oid'] && $oid_list[$return_item['oid']] && intval($oid_list[$return_item['oid']]) >= intval($return_item['num'])) {
|
||
continue;
|
||
}
|
||
|
||
$match = false;
|
||
}
|
||
|
||
if ($match === true){
|
||
return [true, '匹配成功', $orderList[$order_id]];
|
||
}
|
||
|
||
// 按货号查
|
||
$match = true;
|
||
foreach($sdf['refund_item_list']['return_item'] as $return_item){
|
||
if ($return_item['outer_id'] && $bn_list[$return_item['outer_id']] && intval($bn_list[$return_item['outer_id']]) >= intval($return_item['num'])) {
|
||
continue;
|
||
}
|
||
|
||
$match = false;
|
||
}
|
||
|
||
if ($match === true){
|
||
return [true, '匹配成功', $orderList[$order_id],$this->item_convert_field];
|
||
}
|
||
|
||
|
||
}
|
||
|
||
return [false, '匹配失败'];
|
||
}
|
||
|
||
|
||
/**
|
||
* 换货申请转退货申请
|
||
*
|
||
* @param $sdf
|
||
* @return array
|
||
*/
|
||
public function getChangeApplyToReturnApply($sdf)
|
||
{
|
||
$returnMdl = app::get('ome')->model('return_product');
|
||
$reshipMdl = app::get('ome')->model('reship');
|
||
|
||
$refund_bn = $sdf['refund_bn'];
|
||
$shop_id = $sdf['shop_id'];
|
||
|
||
// 有进行中的换货申请
|
||
$return = $returnMdl->db_dump([
|
||
'return_bn' => $refund_bn,
|
||
'return_type' => 'change',
|
||
'status' => ['1','2','3','6','7','8'],
|
||
'shop_id' => $shop_id,
|
||
]);
|
||
if ($return) {
|
||
|
||
}
|
||
|
||
// 有进行中的退换货单
|
||
$reship = $reshipMdl->db_dump([
|
||
'reship_bn' => $refund_bn,
|
||
'shop_id' => $shop_id,
|
||
'return_type' => 'change',
|
||
'is_check' => ['0', '1', '2'],
|
||
]);
|
||
if ($reship) {
|
||
|
||
}
|
||
|
||
return [true, '请放心申请'];
|
||
}
|
||
|
||
/**
|
||
* 获取订单退货商品及计算退货明细金额
|
||
*
|
||
* @param $refundItems
|
||
* @param $sdf
|
||
* @return array
|
||
*/
|
||
protected function _calculateAddPrice($refundItems, $sdf)
|
||
{
|
||
if(empty($refundItems)) {
|
||
return array();
|
||
}
|
||
|
||
$orderMdl = app::get('ome')->model('orders');
|
||
|
||
$orderLib = kernel::single('ome_order');
|
||
|
||
//order
|
||
$order = $sdf['order'];
|
||
$order_id = $order['order_id'];
|
||
|
||
//申请退货金额
|
||
$refund_fee = ($sdf['refund_fee'] ? $sdf['refund_fee'] : $sdf['return_product']['money']);
|
||
|
||
//订单详细信息
|
||
$orderInfo = $orderMdl->dump($order_id, '*', array('order_objects'=>array('*',array('order_items'=>array('*')))));
|
||
|
||
//[兼容微信小程序]一次申请多个不同SKU进行退货,分摊申请退货的金额
|
||
if(count($refundItems) > 1){
|
||
//获取订单销售物料价格
|
||
$goodsList = array();
|
||
$goodsDeleteList = array();
|
||
if($orderInfo['order_objects']){
|
||
foreach ($orderInfo['order_objects'] as $objKey => $objVal)
|
||
{
|
||
$goods_bn = $objVal['bn'];
|
||
|
||
//goods
|
||
if($objVal['delete'] == 'true'){
|
||
$goodsDeleteList[$goods_bn] = $objVal;
|
||
}else{
|
||
$goodsList[$goods_bn] = $objVal;
|
||
}
|
||
}
|
||
}
|
||
|
||
//金额占比基数
|
||
foreach ($refundItems as $itemKey => $itemVal)
|
||
{
|
||
if (in_array($orderInfo['shop_type'], ['website'])) {
|
||
$refundItems[$itemKey]['oid_refund_fee'] = $itemVal['amount'];
|
||
} else {
|
||
//num
|
||
if(empty($itemVal['num'])){
|
||
$itemVal['num'] = 1;
|
||
$refundItems[$itemKey]['num'] = $itemVal['num'];
|
||
}
|
||
|
||
//price:京东平台推送价格字段为空值
|
||
if(empty($itemVal['price'])){
|
||
$goods_bn = isset($itemVal['bn']) ? $itemVal['bn'] : '';
|
||
|
||
//price
|
||
if(isset($goodsList[$goods_bn])){
|
||
$itemVal['price'] = $goodsList[$goods_bn]['price'];
|
||
}elseif(isset($goodsDeleteList[$goods_bn])){
|
||
$itemVal['price'] = $goodsDeleteList[$goods_bn]['price'];
|
||
}else{
|
||
$itemVal['price'] = 1;
|
||
}
|
||
|
||
$refundItems[$itemKey]['price'] = $itemVal['price'];
|
||
}
|
||
|
||
$refundItems[$itemKey]['porth_field'] = $itemVal['price'] * $itemVal['num'];
|
||
}
|
||
|
||
}
|
||
|
||
if (!in_array($orderInfo['shop_type'], ['website'])) {
|
||
//均摊退货的金额
|
||
$options = array (
|
||
'part_total' => $refund_fee, //需要分摊的总额
|
||
'part_field' => 'oid_refund_fee', //需要分摊的字段
|
||
'porth_field' => 'porth_field', //作为基数的字段
|
||
);
|
||
$refundItems = kernel::single('ome_order')->calculate_part_porth($refundItems, $options);
|
||
}
|
||
}else{
|
||
foreach ($refundItems as $itemKey => $itemVal)
|
||
{
|
||
$refundItems[$itemKey]['oid_refund_fee'] = $refund_fee;
|
||
}
|
||
}
|
||
|
||
//order_objects
|
||
$reutrnItems = array();
|
||
$is_calculate = false;
|
||
foreach ($orderInfo['order_objects'] as $objKey => $objVal)
|
||
{
|
||
$goods_bn = $objVal['bn'];
|
||
$obj_quantity = $objVal['quantity'];
|
||
|
||
//没有订单item明细
|
||
if(empty($objVal['order_items'])){
|
||
continue;
|
||
}
|
||
|
||
//check
|
||
if($objVal['delete'] == 'true'){
|
||
continue;
|
||
}
|
||
|
||
//退货销售物料不存在,直接跳过
|
||
if(!isset($refundItems[$goods_bn])){
|
||
continue;
|
||
}
|
||
$skuReturnInfo = $refundItems[$goods_bn];
|
||
//如果和找到的obj行不一致,跳过
|
||
if($skuReturnInfo['obj_id'] && !in_array($objVal['obj_id'],$skuReturnInfo['obj_id'])){
|
||
continue;
|
||
}
|
||
//退货数量
|
||
$return_num = intval($skuReturnInfo['num']);
|
||
$return_num_radio = $return_num / $obj_quantity;
|
||
|
||
//oid退货金额
|
||
$oid_refund_fee = $skuReturnInfo['oid_refund_fee'];
|
||
|
||
//使用订单明细上items层金额贡献比,这样更准确;
|
||
//@todo:根据订单object层实付金额获取items层明细对应的金额占比;
|
||
list($rateRs, $itemRates) = $orderLib->getItemRateByObject($objVal);
|
||
|
||
//obj_type
|
||
//if(in_array($objVal['obj_type'], array('pkg','pko','gift','lkb'))) {
|
||
// //是否重算无摊金额
|
||
// $is_calculate = true;
|
||
//}
|
||
|
||
//退货数量与购买数量一致&&退货金额与订单实付金额一致
|
||
$temp_refund_fee = $oid_refund_fee;
|
||
$item_line_i = 0;
|
||
$item_count = count($objVal['order_items']);
|
||
$can_unset_refund_item = true; // 控制是否可以删除refundItems的标记
|
||
foreach($objVal['order_items'] as $itemKey => $itemVal)
|
||
{
|
||
$item_id = $itemVal['item_id'];
|
||
$product_bn = $itemVal['bn'];
|
||
|
||
$item_line_i++;
|
||
|
||
//check
|
||
if($itemVal['delete'] == 'true'){
|
||
continue;
|
||
}
|
||
|
||
//订单实付金额占比
|
||
if($rateRs) {
|
||
$item_rate = $itemRates[$item_id];
|
||
} else {
|
||
$item_rate = 1;
|
||
}
|
||
|
||
//检验申请退货数量(两种场景:1、与购买数量一致; 2、小于购买数量; )
|
||
if($obj_quantity == $return_num){
|
||
//1、整退
|
||
$item_return_num = $itemVal['quantity'];
|
||
|
||
//item_return_amount
|
||
if($item_line_i == $item_count){
|
||
$item_return_amount = $temp_refund_fee;
|
||
}else{
|
||
$item_return_amount = $oid_refund_fee * $item_rate;
|
||
$item_return_amount = sprintf('%.2f', $item_return_amount);
|
||
|
||
$temp_refund_fee -= $item_return_amount;
|
||
}
|
||
}else{
|
||
//2、部分退
|
||
$item_return_num = $itemVal['quantity'] * $return_num_radio;
|
||
$item_return_num = intval($item_return_num);
|
||
|
||
//[兼容]福袋类型(防止:数量*贡献占比 = 0,导致代码报错)
|
||
//@todo:福袋购买多件销售物料时,分配到基础物料时,是可以分配给多个不同基础物料,每个1件;
|
||
if($item_return_num < 1){
|
||
$item_return_num = $itemVal['quantity'];
|
||
}
|
||
|
||
//兼容小程序同一个商品,存在多行明细的情况
|
||
//因为_formatAddItemList里是按照bn sum的
|
||
if (in_array($orderInfo['shop_type'], ['website']) && $item_return_num > $itemVal['quantity']) {
|
||
$item_return_num = $itemVal['quantity'];
|
||
$refundItems[$goods_bn]['num'] -= $itemVal['quantity'];
|
||
$can_unset_refund_item = false; // 如果退货数量大于购买数量,不能删除refundItems
|
||
}
|
||
|
||
//item_return_amount
|
||
if($item_line_i == $item_count){
|
||
$item_return_amount = $temp_refund_fee;
|
||
}else{
|
||
$item_return_amount = $oid_refund_fee * $item_rate;
|
||
$item_return_amount = sprintf('%.2f', $item_return_amount);
|
||
|
||
$temp_refund_fee -= $item_return_amount;
|
||
}
|
||
}
|
||
|
||
//退货单价
|
||
$item_price = sprintf('%.2f', $item_return_amount / $item_return_num);
|
||
|
||
//data
|
||
$tmpReturn = array(
|
||
'obj_type' => $objVal['obj_type'],
|
||
'item_type' => $itemVal['item_type'],
|
||
'product_id' => $itemVal['product_id'],
|
||
'bn' => $product_bn,
|
||
'name' => $itemVal['name'],
|
||
'price' => $item_price,
|
||
'amount' => $item_return_amount,
|
||
'porth_field' => $item_return_amount,
|
||
'num' => $item_return_num,
|
||
'sendNum' => $itemVal['sendnum'], //sendNum字母必须大写
|
||
'order_item_id' => $itemVal['item_id'],
|
||
'item_flag' => 'is_equal', //价格和数量相等标记
|
||
);
|
||
$tmpReturn = array_merge($skuReturnInfo, $tmpReturn);
|
||
|
||
$reutrnItems[] = $tmpReturn;
|
||
}
|
||
|
||
//unset
|
||
// 只有在所有item的退货数量都不大于购买数量时才删除refundItems
|
||
if ($can_unset_refund_item) {
|
||
unset($refundItems[$goods_bn]);
|
||
}
|
||
}
|
||
|
||
//申请退货商品未找到订单item明细
|
||
if($refundItems && is_array($refundItems)) {
|
||
//product_bn
|
||
$productBns = array_column($refundItems, 'bn');
|
||
|
||
//material
|
||
$materialList = kernel::single('material_basic_select')->getlist('bm_id,material_bn,material_name', array('material_bn'=>$productBns));
|
||
if($materialList){
|
||
$materialList = array_column($materialList, null, 'material_bn');
|
||
|
||
//format
|
||
foreach ($refundItems as $itemKey => $itemVal)
|
||
{
|
||
$material_bn = $itemVal['bn'];
|
||
|
||
//check
|
||
if(isset($materialList[$material_bn])){
|
||
$refundItems[$itemKey]['product_id'] = $materialList[$material_bn]['bm_id'];
|
||
$refundItems[$itemKey]['name'] = $materialList[$material_bn]['material_name'];
|
||
}
|
||
}
|
||
}
|
||
|
||
//merge
|
||
$reutrnItems = array_merge(array_values($refundItems), $reutrnItems);
|
||
}
|
||
|
||
//金额分摊
|
||
if($is_calculate){
|
||
$reutrnItems = $this->_calculateAddPriceFromRefundFee($reutrnItems, $sdf);
|
||
}
|
||
|
||
return $reutrnItems;
|
||
}
|
||
|
||
protected function _formatRefundFee($sdf) {
|
||
return $sdf;
|
||
}
|
||
}
|