575 行
22 KiB
PHP
可执行文件
575 行
22 KiB
PHP
可执行文件
<?php
|
||
|
||
namespace Common\Order;
|
||
|
||
use Common\Model\RefundOrderModel;
|
||
use Common\Model\RetailBillDiscountModel;
|
||
use Common\Model\RetailBillOrderModel;
|
||
use Common\Model\RetailPayOrderModel;
|
||
use Common\Pay\Pay;
|
||
|
||
//[1.9.20]
|
||
|
||
/**
|
||
* Class BillOrder
|
||
* @package Common\Order
|
||
* [
|
||
* payType 获取所有支付类型
|
||
* getPayType 获取支付类型名称
|
||
* getBillPayType 根据pay_order表获取bill_order表的支付类型
|
||
* getPayOrderPayType 根据bill_order表获取pay_order表的支付类型
|
||
* getLineRefundOrderList 获取线下退款订单的列表
|
||
* getLineRefundOrderSumData 获取线下退款订单的统计数据
|
||
* failOrderRefund 部分退款失败订单继续退款
|
||
* orderRefund 订单退款
|
||
* ]
|
||
*/
|
||
class BillOrder
|
||
{
|
||
/**
|
||
* 支付类型
|
||
* @return array
|
||
*/
|
||
public function payType()
|
||
{
|
||
return array(
|
||
'1' => '现金',
|
||
'3' => '微信',
|
||
'4' => '支付宝',
|
||
'5' => '会员余额',
|
||
'6' => '小程序微信',
|
||
'7' => '其他支付',
|
||
'8' => '组合',
|
||
'9' => '德育币',
|
||
);
|
||
}
|
||
|
||
/**
|
||
* 获取订单支付类型描述
|
||
* @param $pay_type 支付类型值
|
||
* @param $bill_id 支付类型值
|
||
* @return mixed
|
||
*/
|
||
public function getPayType($pay_type, $bill_id)
|
||
{
|
||
switch ($pay_type) {
|
||
case 0:
|
||
//赊账
|
||
if (in_array('Credit', C('MODULE_ALLOW_LIST'))) {
|
||
$CreditRecord = new \Credit\Business\CreditRecord();
|
||
$pay_type_name = $CreditRecord->getPayTypeName($bill_id);
|
||
} else {
|
||
$pay_type_name = '其他支付';
|
||
}
|
||
break;
|
||
case 8:
|
||
$pay_type_name = '组合支付';
|
||
break;
|
||
case 7:
|
||
//其他支付
|
||
$PayOrder = new PayOrder();
|
||
$PayList = $PayOrder->getFindPayList('', '', $bill_id);
|
||
$pay_type_name = $PayList[0]['name'];
|
||
break;
|
||
default:
|
||
$pay_type_name = $this->payType()[$pay_type];
|
||
}
|
||
|
||
return $pay_type_name;
|
||
}
|
||
|
||
/**
|
||
* 根据pay_order表获取bill_order表的支付类型
|
||
* @param $pay_pay_type
|
||
* @return mixed
|
||
*/
|
||
public function getBillPayType($pay_pay_type)
|
||
{
|
||
//bill 1现金 3微信支付 4支付宝支付 5会员卡余额支付 6小程序商城微信支付 7其他支付方式 8组合支付 9德育币
|
||
//pay 1微信 2支付宝 3现金 4小程序微信 5其他支付方式 6会员余额 8德育币
|
||
$array = [
|
||
'1' => '3',
|
||
'2' => '4',
|
||
'3' => '1',
|
||
'4' => '6',
|
||
'5' => '7',
|
||
'6' => '5',
|
||
'8' => '9',
|
||
];
|
||
return $array[$pay_pay_type];
|
||
}
|
||
|
||
/**
|
||
* 根据bill_order表获取pay_order表的支付类型
|
||
* @param $bill_pay_type
|
||
* @return mixed
|
||
*/
|
||
public function getPayOrderPayType($bill_pay_type)
|
||
{
|
||
//bill 1现金 3微信支付 4支付宝支付 5会员卡余额支付 6小程序商城微信支付 7其他支付方式 8组合支付 9德育币
|
||
//pay 1微信 2支付宝 3现金 4小程序微信 5其他支付方式 6会员余额 8德育币
|
||
$array = [
|
||
'1' => '3',
|
||
'3' => '1',
|
||
'4' => '2',
|
||
'5' => '6',
|
||
'6' => '4',
|
||
'7' => '5',
|
||
'8' => '',
|
||
'9' => '8',
|
||
];
|
||
return $array[$bill_pay_type];
|
||
}
|
||
|
||
|
||
/**
|
||
* 处理线下退款订单的查询条件
|
||
* @param $param
|
||
* $param['merchant_id'] 商户ID
|
||
* $param['store_id'] 门店ID
|
||
* $param['time'] 时间范围
|
||
* $param['order_no'] 订单号/原订单号
|
||
* $param['pay_type'] 订单支付类型
|
||
* $param['status'] 订单退款状态
|
||
* $param['vip_phone'] 会员手机号/卡号/实体卡号
|
||
* @return array
|
||
*/
|
||
private function handleLineRefundMap($param)
|
||
{
|
||
$map = [
|
||
'b.merchant_id' => $param['merchant_id'],
|
||
'b.store_id' => $param['store_id'],
|
||
'b.order_type' => 2,
|
||
'b.type' => 2,
|
||
'b.pay_state' => ['in', '0,1'],
|
||
'b.refund_status' => ['in', '-1,2'],
|
||
];
|
||
|
||
if (!empty($param['time'])) {
|
||
$map['b.add_time'] = ['between', [strtotime($param['time'][0]), strtotime($param['time'][1])]];
|
||
}
|
||
if (!empty($param['order_no'])) {
|
||
$map['b.order_no|b.refund_no'] = ['like', "%" . trim($param['order_no']) . "%"];
|
||
}
|
||
if (!empty($param['pay_type'])) {
|
||
$map['b.pay_type'] = $param['pay_type'];
|
||
}
|
||
if (!empty($param['status'])) {
|
||
switch ($param['status']) {
|
||
case 1:
|
||
//退款成功
|
||
$map['b.refund_status'] = 2;
|
||
$map['b.pay_state'] = 1;
|
||
break;
|
||
case -1:
|
||
//退款失败
|
||
$map['b.pay_state'] = 0;
|
||
$map['b.refund_status'] = -1;
|
||
break;
|
||
}
|
||
}
|
||
//会员搜索
|
||
if (!empty($param['vip_phone'])) {
|
||
$map['v.mobile_phone|v.cardnum|v.card_key'] = ['like', '%' . $param['vip_phone'] . '%'];
|
||
$map['v.merchantid'] = $param['merchant_id'];
|
||
$map['v.status'] = 1;
|
||
}
|
||
return $map;
|
||
}
|
||
|
||
/**
|
||
* 获取线下退款订单的列表
|
||
* @param $param
|
||
* $param['merchant_id'] 商户ID
|
||
* $param['store_id'] 门店ID
|
||
* $param['time'] 时间范围
|
||
* $param['order_no'] 订单号/原订单号
|
||
* $param['pay_type'] 订单支付类型
|
||
* $param['status'] 订单退款状态
|
||
* $param['vip_phone'] 会员手机号/卡号/实体卡号
|
||
* $param['page'] 页码
|
||
* $param['limit'] 每页数量
|
||
* $param['is_export'] 是否为导出
|
||
* @return mixed
|
||
* @throws \think\Exception
|
||
* @throws \think\db\exception\DbException
|
||
*/
|
||
public function getLineRefundOrderList($param)
|
||
{
|
||
$map = $this->handleLineRefundMap($param);
|
||
if ($param['is_export']) {
|
||
//导出
|
||
$orderList = M('retail_bill_order as b')
|
||
->join('ls_retail_bill_discount as d ON b.id=d.bill_id')
|
||
->join('ls_retail_vip as v ON b.vid=v.id', 'LEFT')
|
||
->field('b.*,d.*,v.mobile_phone as vip_phone,v.name as vip_name,v.nickname as vip_nickname')
|
||
->where($map)
|
||
->order('b.id desc')
|
||
->select();
|
||
} else {
|
||
$orderList = M('retail_bill_order as b')
|
||
->join('ls_retail_bill_discount as d ON b.id=d.bill_id')
|
||
->join('ls_retail_vip as v ON b.vid=v.id', 'LEFT')
|
||
->page($param['page'], $param['limit'])
|
||
->field('b.*,d.*,v.mobile_phone as vip_phone,v.name as vip_name,v.nickname as vip_nickname')
|
||
->where($map)
|
||
->order('b.id desc')
|
||
->select();
|
||
}
|
||
$count = 0;
|
||
if (!empty($orderList)) {
|
||
if (!$param['is_export']) {
|
||
$count = M('retail_bill_order as b')
|
||
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
||
->join('ls_retail_vip as v on b.vid=v.id', 'LEFT')
|
||
->where($map)
|
||
->count();
|
||
}
|
||
|
||
$PayOrderModel = new RetailPayOrderModel();
|
||
foreach ($orderList as $key => &$val) {
|
||
$val['index'] = $key + 1;
|
||
$val['add_time'] = newDate("Y-m-d H:i:s", $val['add_time']);
|
||
if (!empty($val['vid'])) {
|
||
$val['identity'] = "会员";
|
||
} else {
|
||
$val['identity'] = "散客";
|
||
}
|
||
switch ($val['refund_status']) {
|
||
case '2':
|
||
$val['status_name'] = "退款成功";
|
||
$val['refund_money'] = $val['all_money'];
|
||
$val['wait_refund_money'] = 0;
|
||
break;
|
||
case '-1':
|
||
$val['status_name'] = "退款失败";
|
||
$pMap = [
|
||
'bill_id' => $val['id'],
|
||
'order_state' => 'REFUND',
|
||
];
|
||
$refund_money = $PayOrderModel->getSum($pMap, 'trade_amount');
|
||
$val['refund_money'] = $refund_money;
|
||
$val['wait_refund_money'] = bcsub($val['all_money'], $refund_money, 2) * 1;
|
||
if ($val['refund_money'] == 0) {
|
||
$val['status_name'] = "退款失败";
|
||
}
|
||
break;
|
||
}
|
||
$val['need_refund_state'] = $val['refund_money'] > 0 && $val['wait_refund_money'] > 0 ? 1 : 0;
|
||
$val['pay_type_name'] = $this->getPayType($val['pay_type']);
|
||
}
|
||
}
|
||
return callBack(statusCode()['success'], empty($orderList) ? '暂无数据' : '获取成功', [
|
||
'list' => $orderList,
|
||
'count' => intval($count),
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 获取线下退款订单的统计数据
|
||
* @param $param
|
||
* $param['merchant_id'] 商户ID
|
||
* $param['store_id'] 门店ID
|
||
* $param['time'] 时间范围
|
||
* $param['order_no'] 订单号/原订单号
|
||
* $param['pay_type'] 订单支付类型
|
||
* $param['status'] 订单退款状态
|
||
* $param['vip_phone'] 会员手机号/卡号/实体卡号
|
||
* @return mixed 退款失败订单数\退款失败金额\已退金额
|
||
* @throws \think\Exception
|
||
*/
|
||
public function getLineRefundOrderSumData($param)
|
||
{
|
||
$map = $this->handleLineRefundMap($param);
|
||
|
||
$refund_status = $map['b.refund_status'];
|
||
|
||
//退款订单的总金额
|
||
$refund_all_money = M('retail_bill_order as b')
|
||
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
||
->join('ls_retail_vip as v on b.vid=v.id', 'LEFT')
|
||
->where($map)
|
||
->sum('all_money');
|
||
$refund_all_money = $refund_all_money ? intval($refund_all_money) : 0;
|
||
|
||
//退款失败总条数
|
||
$map['b.refund_status'] = -1;
|
||
$refund_fail_count = M('retail_bill_order as b')
|
||
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
||
->join('ls_retail_vip as v on b.vid=v.id', 'LEFT')
|
||
->where($map)
|
||
->count();
|
||
|
||
//退款成功的金额
|
||
$map['b.refund_status'] = $refund_status;
|
||
$map['p.order_state'] = 'REFUND';
|
||
$refund_money = M('retail_bill_order as b')
|
||
->join('ls_retail_bill_discount as d on b.id=d.bill_id')
|
||
->join('ls_retail_pay_order as p on b.id=p.bill_id')
|
||
->join('ls_retail_vip as v on b.vid=v.id', 'LEFT')
|
||
->where($map)
|
||
->sum('trade_amount');
|
||
$refund_money = $refund_money ? intval($refund_money) : 0;
|
||
|
||
//退款失败的金额
|
||
$refund_fail_money = bcsub($refund_all_money, $refund_money, 2);
|
||
|
||
return callBack(statusCode()['success'], '获取成功', [
|
||
'refund_fail_count' => $refund_fail_count,
|
||
'refund_fail_money' => $refund_fail_money,
|
||
'refund_money' => $refund_money,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 部分退款失败订单继续退款
|
||
* @param $param
|
||
* $param['merchant_id'] *商户ID
|
||
* $param['store_id'] *门店ID
|
||
* $param['order_no'] *退款订单号
|
||
* $param['operate_id'] 操作者ID(修改收银员登录接口后记录)
|
||
* $param['cashier_id'] 收银员ID
|
||
* @return mixed
|
||
*/
|
||
public function failOrderRefund($param)
|
||
{
|
||
$BillOrderModel = new RetailBillOrderModel();
|
||
|
||
//查询退款订单
|
||
$oMap = [
|
||
'merchant_id' => $param['merchant_id'],
|
||
'store_id' => $param['store_id'],
|
||
'order_no' => strval($param['order_no']),
|
||
'refund_status' => -1,
|
||
'pay_state' => 0,
|
||
'order_type' => 2,
|
||
];
|
||
$param['refund_order'] = $BillOrderModel->getFind($oMap);
|
||
if (empty($param['refund_order'])) {
|
||
return callBack(statusCode()['error'], '订单不存在或已退款成功');
|
||
}
|
||
//查询原购买订单ID
|
||
$param['buy_bill_id'] = $BillOrderModel->getFindField(['order_no' => strval($param['refund_order']['refund_no'])], 'id');
|
||
|
||
//查询已退款金额
|
||
$PayOrderModel = new RetailPayOrderModel();
|
||
$param['refund_all_money'] = $PayOrderModel->getSum(['bill_id' => $param['refund_order']['id'], 'order_state' => 'SUCCESS'], 'trade_amount');
|
||
|
||
return $this->orderRefund($param);
|
||
}
|
||
|
||
/**
|
||
* 订单退款
|
||
* @param $param
|
||
* $param['merchant_id'] *商户ID
|
||
* $param['store_id'] *门店ID
|
||
* $param['order_no'] *退款订单号
|
||
* $param['operate_id'] 操作者ID(修改收银员登录接口后记录)
|
||
* $param['cashier_id'] 收银员ID
|
||
* $param['refund_order'] 退款订单信息
|
||
* $param['buy_bill_id'] 原购买订单ID
|
||
* $param['refund_all_money']已退款金额
|
||
* @return mixed
|
||
*/
|
||
public function orderRefund($param)
|
||
{
|
||
$BillOrderModel = new RetailBillOrderModel();
|
||
$PayOrderModel = new RetailPayOrderModel();
|
||
|
||
if (empty($param['refund_order'])) {
|
||
//查询退款订单
|
||
$oMap = [
|
||
'merchant_id' => $param['merchant_id'],
|
||
'store_id' => $param['store_id'],
|
||
'order_no' => strval($param['order_no']),
|
||
'refund_status' => -1,
|
||
'pay_state' => 0,
|
||
'order_type' => 2,
|
||
];
|
||
$refund_order = $BillOrderModel->getFind($oMap);
|
||
if (empty($refund_order)) {
|
||
return callBack(statusCode()['error'], '订单不存在或已退款成功');
|
||
}
|
||
} else {
|
||
$refund_order = $param['refund_order'];
|
||
}
|
||
if (empty($param['buy_bill_id'])) {
|
||
//查询原购买订单ID
|
||
$param['buy_bill_id'] = $BillOrderModel->getFindField(['order_no' => strval($refund_order['refund_no'])], 'id');
|
||
}
|
||
|
||
if (isset($param['refund_all_money'])) {
|
||
//查询已退款金额
|
||
$param['refund_all_money'] = $PayOrderModel->getSum(['bill_id' => $refund_order['id'], 'order_state' => 'SUCCESS'], 'trade_amount');
|
||
}
|
||
|
||
//计算待退款金额
|
||
$wait_refund_money = bcsub($refund_order['all_money'], $param['refund_all_money'], 2);
|
||
if ($wait_refund_money <= 0) {
|
||
return callBack(statusCode()['error'], '该订单已退款完毕,请勿重复操作');
|
||
|
||
}
|
||
|
||
//获取退款顺序
|
||
$RefundOrderModel = new RefundOrderModel();
|
||
$refundOrder = $RefundOrderModel->getFindOrderAsc($refund_order['merchant_id']);
|
||
|
||
$refundRes = []; //存储所有退款结果
|
||
foreach ($refundOrder as $key => $value) {
|
||
|
||
if ($refund_order['type'] == 1 && !in_array($key, ['wx_refund_order', 'vip_refund_order'])) continue;
|
||
|
||
$map = [
|
||
'bill_id' => $param['buy_bill_id'],
|
||
'order_state' => 'SUCCESS',
|
||
'order_type' => 1,
|
||
];
|
||
switch ($key) {
|
||
case 'cash_refund_order':
|
||
//现金
|
||
$map['pay_type'] = 3;
|
||
break;
|
||
case 'vip_refund_order':
|
||
//会员余额
|
||
$map['pay_type'] = 6;
|
||
break;
|
||
case 'other_refund_order':
|
||
//其他支付
|
||
$map['pay_type'] = 5;
|
||
break;
|
||
case 'al_refund_order':
|
||
//支付宝
|
||
$map['pay_type'] = 2;
|
||
break;
|
||
case 'wx_refund_order':
|
||
//微信
|
||
$map['pay_type'] = $refund_order['type'] == 1 ? 4 : 1;
|
||
break;
|
||
default:
|
||
if ($param['refund_all_money'] > 0) {
|
||
$BillOrderModel->updateOrder(['id' => $refund_order['id']], ['refund_status' => -1]);
|
||
}
|
||
return callBack(statusCode()['error'], '系统发生错误');
|
||
}
|
||
|
||
$payOrderList = $PayOrderModel->getSelect($map);
|
||
if (!empty($payOrderList)) {
|
||
foreach ($payOrderList as $val) {
|
||
$tempMoney = bcsub($val['trade_amount'], $val['refund_money'], 2);
|
||
if ($tempMoney && bcadd($param['refund_all_money'], $tempMoney, 2) > $wait_refund_money) {
|
||
$tempMoney = bcsub($wait_refund_money, $param['refund_all_money'], 2);
|
||
}
|
||
$tempMoney = floatval($tempMoney);//钱数转换类型
|
||
if (!empty($tempMoney)) {
|
||
//去退款
|
||
$refundRes[] = $this->refundBillOrderPrice([
|
||
'buy_bill_id' => $param['buy_bill_id'],
|
||
'new_bill_id' => $refund_order['id'],
|
||
'type' => $refund_order['type'] == 1 ? 4 : 1,
|
||
'pay_order' => $val,
|
||
'refund_money' => $tempMoney,
|
||
'cashier_id' => $param['cashier_id'],
|
||
]);
|
||
}
|
||
$param['refund_all_money'] = bcadd($param['refund_all_money'], $tempMoney, 2);
|
||
}
|
||
}
|
||
if (round($refund_order['all_money'] - $param['refund_all_money'], 2) <= 0) {
|
||
break;
|
||
}
|
||
}
|
||
if (empty($refundRes)) {
|
||
return callBack(statusCode()['error'], '退款失败');
|
||
}
|
||
//已退款金额
|
||
$refund_success_money = round($refund_order['all_money'] - $wait_refund_money, 2);
|
||
$message = [];
|
||
$is_fail = false; //判断是否有失败的退款
|
||
$is_success = false; //判断是否有成功的退款
|
||
foreach ($refundRes as $v) {
|
||
if ($v['status'] === 0) {
|
||
//退款失败
|
||
$is_fail = true;
|
||
$message[] = $v['message'];
|
||
} else if ($v['status'] == 1) {
|
||
$refund_success_money = round($refund_success_money + $v['data']['actual_refund_money'], 2);
|
||
$is_success = true;
|
||
}
|
||
}
|
||
if (count($refundRes) == 1 && $is_fail) {
|
||
//退款失败
|
||
return callBack(statusCode()['error'], '退款失败:' . implode(',', $message));
|
||
} else if ($is_fail && $is_success) {
|
||
//存储为退款失败订单
|
||
$save = [
|
||
'refund_status' => -1,
|
||
];
|
||
$BillOrderModel->updateOrder(['id' => $refund_order['id']], $save);
|
||
return callBack(statusCode()['error'], '部分退款成功:' . implode(',', $message));
|
||
} else {
|
||
//全部退款成功
|
||
if (bcsub($refund_order['all_money'], $wait_refund_money, 2) > 0 || count($refundRes) > 1) {
|
||
//组合退款
|
||
$pay_type = 8;
|
||
} else {
|
||
$pay_type = $this->getBillPayType($payOrderList[0]['pay_type']);
|
||
}
|
||
$save = [
|
||
'refund_status' => 2,
|
||
'pay_type' => $pay_type,
|
||
];
|
||
$BillOrderModel->updateOrder(['id' => $refund_order['id']], $save);
|
||
$Sell = new Sell();
|
||
$result = $Sell->refundGoods([
|
||
'refund_order' => $refund_order,
|
||
'pay_type' => $pay_type,
|
||
'buy_bill_id' => $param['buy_bill_id'],
|
||
]);
|
||
|
||
return callBack(statusCode()['success'], '退款成功', $result['data']);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 去退款
|
||
* @param $param
|
||
* $param['buy_bill_id'] 原购买订单ID
|
||
* $param['new_bill_id'] 退款订单ID
|
||
* $param['type'] 订单场景 1收银机 2商户后台 3门店后台 4小程序 5公众号 6快捷收款
|
||
* $param['pay_order'] 支付流水订单
|
||
* $param['refund_money'] 退款金额
|
||
* $param['cashier_id'] 收银员ID
|
||
* @return array
|
||
*/
|
||
private function refundBillOrderPrice($param)
|
||
{
|
||
$Refund = new Pay();
|
||
$res = $Refund->refund([
|
||
'pay_order' => $param['pay_order'],
|
||
'vip_scene_type' => $param['type'],
|
||
'bill_id' => $param['new_bill_id'],
|
||
'cashier_id' => $param['cashier_id'],
|
||
'refund_money' => $param['refund_money'],
|
||
]);
|
||
if ($res['status'] == 1) {
|
||
//支付流水修改
|
||
$BillModel = new RetailBillOrderModel();
|
||
|
||
//增加bill_order表的退款金额
|
||
$BillModel->toSetInc(['id' => $param['buy_bill_id']], 'refund_money', $res['data']['actual_refund_money']);
|
||
if (isset($res['data']['pay_coupon'])) {
|
||
//减去代金券的金额
|
||
$BillModel->toSetDec(['id' => $param['new_bill_id']], 'all_money', $res['data']['pay_coupon']['pay_coupon_fee']);
|
||
$BillModel->toSetDec(['id' => $param['new_bill_id']], 'refund_money', $res['data']['pay_coupon']['pay_coupon_fee']);
|
||
$DisCountModel = new RetailBillDiscountModel();
|
||
$DisCountModel->updateOrder(['bill_id' => $param['new_bill_id']], [
|
||
'pay_coupon_id_str' => $res['data']['pay_coupon']['pay_coupon_id_str'],
|
||
'pay_coupon_fee' => $res['data']['pay_coupon']['pay_coupon_fee']
|
||
]);
|
||
}
|
||
return callBack(statusCode()['success'], '退款成功', $res);
|
||
} else {
|
||
return callBack(statusCode()['error'], '退款失败', $res);
|
||
}
|
||
}
|
||
} |