文件
mashangyoujiu/Application/Common/Order/BillOrder.class.php

575 行
22 KiB
PHP
可执行文件

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?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);
}
}
}