Files
2019-02-28 19:48:21 +08:00

517 lines
18 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* tpshop
* ============================================================================
* 版权所有 2015-2027 深圳搜豹网络科技有限公司,并保留所有权利。
* 网站地址: http://www.tp-shop.cn
* ----------------------------------------------------------------------------
* 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和使用 .
* 不允许对程序代码以任何形式任何目的的再发布。
* 采用最新Thinkphp5助手函数特性实现单字母函数M D U等简写方式
* ============================================================================
* Author: dyr
* Date: 2017-12-04
*/
namespace app\common\logic;
use app\common\model\Cart;
use app\common\model\CouponList;
use app\common\model\Shop;
use app\common\util\TpshopException;
use think\Model;
use think\Db;
/**
* 计算价格类
* Class CatsLogic
* @package Home\Logic
*/
class Pay
{
protected $payList;
protected $userId;
protected $user;
private $totalAmount = 0;//订单总价
private $orderAmount = 0;//应付金额
private $shippingPrice = 0;//物流费
private $goodsPrice = 0;//商品总价
private $cutFee = 0;//共节约多少钱
private $totalNum = 0;// 商品总共数量
private $integralMoney = 0;//积分抵消金额
private $userMoney = 0;//使用余额
private $payPoints = 0;//使用积分
private $couponPrice = 0;//优惠券抵消金额
private $orderPromId;//订单优惠ID
private $orderPromAmount = 0;//订单优惠金额
private $couponId;
private $shop;//自提点
/**
* 计算订单表的普通订单商品
* @param $order_goods
* @return $this
* @throws TpshopException
*/
public function payOrder($order_goods){
$this->payList = $order_goods;
$order = Db::name('order')->where('order_id', $this->payList[0]['order_id'])->find();
if(empty($order)){
throw new TpshopException('计算订单价格', 0, ['status' => -9, 'msg' => '找不到订单数据', 'result' => '']);
}
$reduce = tpCache('shopping.reduce');
if($order['pay_status'] == 0 && $reduce == 2){
$goodsListCount = count($this->payList);
for ($payCursor = 0; $payCursor < $goodsListCount; $payCursor++) {
$goods_stock = getGoodNum($this->payList[$payCursor]['goods_id'], $this->payList[$payCursor]['spec_key']); // 最多可购买的库存数量
if($goods_stock <= 0 && $this->payList[$payCursor]['goods_num'] > $goods_stock){
throw new TpshopException('计算订单价格', 0, ['status' => -9, 'msg' => $this->payList[$payCursor]['goods_name'].','.$this->payList[$payCursor]['spec_key_name'] . "库存不足,请重新下单", 'result' => '']);
}
}
}
$this->Calculation();
return $this;
}
/**
* 计算购买购物车的商品
* @param $cart_list
* @return $this
* @throws TpshopException
*/
public function payCart($cart_list){
$this->payList = $cart_list;
$goodsListCount = count($this->payList);
if ($goodsListCount == 0) {
throw new TpshopException('计算订单价格', 0, ['status' => -9, 'msg' => '你的购物车没有选中商品', 'result' => '']);
}
$this->Calculation();
return $this;
}
/**
* 计算购买商品表的商品
* @param $goods_list
* @return $this
* @throws TpshopException
*/
public function payGoodsList($goods_list)
{
$goodsListCount = count($goods_list);
if ($goodsListCount == 0) {
throw new TpshopException('计算订单价格', 0, ['status' => -9, 'msg' => '你的购物车没有选中商品', 'result' => '']);
}
$discount = $this->getDiscount();
for ($goodsCursor = 0; $goodsCursor < $goodsListCount; $goodsCursor++) {
//优先使用member_goods_price没有member_goods_price使用goods_price
if(empty($goods_list[$goodsCursor]['member_goods_price'])){
//积分商品不打折。因为是全积分商品打会员折扣,结算会出现负数
if($goods_list[$goodsCursor]['exchange_integral'] > 0){
$goods_list[$goodsCursor]['member_goods_price'] = $goods_list[$goodsCursor]['goods_price'];
}else{
$goods_list[$goodsCursor]['member_goods_price'] = $discount * $goods_list[$goodsCursor]['goods_price'];
}
}
}
$this->payList = $goods_list;
$this->Calculation();
return $this;
}
/**
* 初始化计算
*/
private function Calculation()
{
//查出搭配购的商品
if($this->payList){
$Cart = new Cart();
foreach ($this->payList as $cartKey => $cartVal) {
if ($cartVal['prom_type'] == 7) {
$arr = $Cart->where(['combination_group_id' => $cartVal['id'], 'id' => ['neq', $cartVal['id']]])->select();
$this->payList = array_merge($this->payList, $arr);
}
}
}
$goodsListCount = count($this->payList);
for ($payCursor = 0; $payCursor < $goodsListCount; $payCursor++) {
$this->payList[$payCursor]['goods_fee'] = $this->payList[$payCursor]['goods_num'] * $this->payList[$payCursor]['member_goods_price']; // 小计
$this->goodsPrice += $this->payList[$payCursor]['goods_fee']; // 商品总价
if(array_key_exists('market_price',$this->payList[$payCursor])){
$this->cutFee += $this->payList[$payCursor]['goods_num'] * ($this->payList[$payCursor]['market_price'] - $this->payList[$payCursor]['member_goods_price']);// 共节约
}
$this->totalNum += $this->payList[$payCursor]['goods_num'];
}
$this->orderAmount = $this->goodsPrice;
$this->totalAmount = $this->goodsPrice;
}
/**
* 设置用户ID
* @param $user_id
* @return $this
* @throws TpshopException
*/
public function setUserId($user_id)
{
$this->userId = $user_id;
$this->user = Db::name('users')->where(['user_id' => $this->userId])->find();
if(empty($this->user)){
throw new TpshopException("计算订单价格",0,['status' => -9, 'msg' => '未找到用户', 'result' => '']);
}
return $this;
}
public function setShopById($shop_id)
{
if($shop_id){
$this->shop = Shop::get($shop_id);
}
return $this;
}
/**
* 使用积分
* @throws TpshopException
* @param $pay_points
* @param $is_exchange|是否有使用积分兑换商品流程
* @param $port
* @return $this
*/
public function usePayPoints($pay_points, $is_exchange = false, $port = "pc")
{
if($pay_points > 0 && $this->orderAmount > 0){
//积分规则修改后的逻辑
$isUseIntegral = tpCache('integral.is_use_integral');
$isPointMinLimit = tpCache('integral.is_point_min_limit');
$isPointRate = tpCache('integral.is_point_rate');
$isPointUsePercent = tpCache('integral.is_point_use_percent');
$point_rate = tpCache('integral.point_rate');
if($is_exchange == false){
if($isUseIntegral==1 && $isPointUsePercent==1) {
$use_percent_point = tpCache('integral.point_use_percent')/100;
}else{
$use_percent_point = 1;
}
if($isUseIntegral==1 && $isPointMinLimit==1) {
$min_use_limit_point = tpCache('integral.point_min_limit');
}else{
$min_use_limit_point = 0;
}
if($isUseIntegral == 0 || $isPointRate != 1){
throw new TpshopException("计算订单价格",0,['status' => -1, 'msg' => '该笔订单不能使用积分', 'result' => '']);
}
if($use_percent_point > 0 && $use_percent_point < 1){
//计算订单最多使用多少积分
$point_limit = intval($this->totalAmount * $point_rate * $use_percent_point);
if($pay_points > $point_limit){
if($port=="mobile"){
$pay_points = $point_limit;
}else {
throw new TpshopException("计算订单价格", 0, ['status' => -1, 'msg' => "该笔订单, 您使用的积分不能大于" . $point_limit, 'result' => '']);
}
}
}
//计算订单最多使用多少积分(没勾选比例的情况)
$next_point_limit = intval($this->totalAmount * $point_rate * $use_percent_point);
if($port!="mobile" && $pay_points > $next_point_limit){
throw new TpshopException("计算订单价格", 0, ['status' => -1, 'msg' => "该笔订单, 您使用的积分不能大于" . $next_point_limit, 'result' => '']);
}
if($pay_points > $this->user['pay_points']){
throw new TpshopException("计算订单价格",0,['status' => -5, 'msg' => "你的账户可用积分为:" . $this->user['pay_points'], 'result' => '']);
}
if ($min_use_limit_point > 0 && $this->user['pay_points'] < $min_use_limit_point) {
throw new TpshopException("计算订单价格",0,['status' => -1, 'msg' => "积分小于".$min_use_limit_point."时 ,不能使用积分", 'result' => '']);
}
$order_amount_pay_point = round($this->orderAmount * $point_rate,2);
//$order_amount_pay_point = $this->orderAmount * $point_rate;
if($pay_points > $order_amount_pay_point){
$this->payPoints = $order_amount_pay_point;
}else{
$this->payPoints = $pay_points;
}
$this->integralMoney = $this->payPoints / $point_rate;
$this->orderAmount = $this->orderAmount - $this->integralMoney;
}else{
//积分兑换流程
if($pay_points <= $this->user['pay_points']){
$this->payPoints = $pay_points;
$this->integralMoney = $pay_points / $point_rate;//总积分兑换成的金额
}else{
$this->payPoints = 0;//需要兑换的总积分
$this->integralMoney = 0;//总积分兑换成的金额
}
$this->orderAmount = $this->orderAmount - $this->integralMoney;
}
}
return $this;
}
/**
* 使用余额
* @throws TpshopException
* @param $user_money
* @return $this
*/
public function useUserMoney($user_money)
{
if($user_money > 0){
if($user_money > $this->user['user_money']){
throw new TpshopException("计算订单价格",0,['status' => -6, 'msg' => "你的账户可用余额为:" . $this->user['user_money'], 'result' => '']);
}
if($this->orderAmount > 0){
if($user_money > $this->orderAmount){
$this->userMoney = $this->orderAmount;
$this->orderAmount = 0;
}else{
$this->userMoney = $user_money;
$this->orderAmount = $this->orderAmount - $this->userMoney;
}
}
}
return $this;
}
/**
* 减去应付金额
* @param $cut_money
* @return $this
*/
public function cutOrderAmount($cut_money){
$this->orderAmount = $this->orderAmount - $cut_money;
return $this;
}
/**
* 使用优惠券
* @param $coupon_id
* @return $this
*/
public function useCouponById($coupon_id){
if($coupon_id > 0){
$couponList = new CouponList();
$userCoupon = $couponList->where(['uid'=>$this->user['user_id'],'id'=>$coupon_id])->find();
if($userCoupon){
$coupon = Db::name('coupon')->where(['id'=>$userCoupon['cid'],'status'=>1])->find(); // 获取有效优惠券类型表
if($coupon){
$this->couponId = $coupon_id;
if ($this->orderAmount > 0) {
if ($coupon['money'] > $this->orderAmount) {
$this->couponPrice = $this->orderAmount;
$this->orderAmount = 0;
} else {
$this->couponPrice = $coupon['money'];
$this->orderAmount = $this->orderAmount - $this->couponPrice;
}
}
}
}
}
return $this;
}
/**
* 配送
* @param $district_id
* @throws TpshopException
* @return $this
*/
public function delivery($district_id){
if (array_key_exists('is_virtual', $this->payList[0]) && $this->payList[0]['is_virtual'] == 0) {
if (empty($this->shop) && empty($district_id)) {
throw new TpshopException("计算订单价格", 0, ['status' => -1, 'msg' => '请填写收货信息', 'result' => ['']]);
}
}
$GoodsLogic = new GoodsLogic();
$checkGoodsShipping = $GoodsLogic->checkGoodsListShipping($this->payList, $district_id);
foreach($checkGoodsShipping as $shippingKey => $shippingVal){
if($shippingVal['shipping_able'] != true){
throw new TpshopException("计算订单价格",0,['status'=>-1, 'code' => 301,
'msg'=>'订单中部分商品【 '.$shippingVal['goods_name'].' 】不支持对当前地址的配送请返回购物车修改',
'result'=>['goods_shipping'=>$checkGoodsShipping]]);
}
}
//使用自提点不计算运费
if(!empty($this->shop)){
return $this;
}
//预售活动暂不计算运费
if ($this->payList[0]['prom_type'] == 4) {
return $this;
}
$freight_free = tpCache('shopping.freight_free'); // 全场满多少免运费
if($this->goodsPrice < $freight_free || $freight_free == 0){
$this->shippingPrice = $GoodsLogic->getFreight($this->payList, $district_id);
$this->orderAmount = $this->orderAmount + $this->shippingPrice;
$this->totalAmount = $this->totalAmount + $this->shippingPrice;
}else{
$this->shippingPrice = 0;
}
return $this;
}
/**
* 获取折扣
* @return int
*/
private function getDiscount()
{
if(empty($this->user['discount'])){
return 1;
}else{
return $this->user['discount'];
}
}
/**
* 使用订单优惠
*/
public function orderPromotion()
{
$time = time();
$order_prom_where = ['type'=>['lt',2],'end_time'=>['gt',$time],'start_time'=>['lt',$time],'money'=>['elt',$this->goodsPrice],'is_close'=>0];
$orderProm = Db::name('prom_order')->where($order_prom_where)->order('money desc')->find();
if ($orderProm) {
if ($orderProm['type'] == 0) {
$expressionAmount = round($this->goodsPrice * $orderProm['expression'] / 100, 2);//满额打折
$this->orderPromAmount = round($this->goodsPrice - $expressionAmount, 2);
$this->orderPromId = $orderProm['id'];
} elseif ($orderProm['type'] == 1) {
$this->orderPromAmount = $orderProm['expression'];
$this->orderPromId = $orderProm['id'];
}
}
$this->orderAmount = $this->orderAmount - $this->orderPromAmount;
return $this;
}
/**
* 获取实际上使用的余额
* @return int
*/
public function getUserMoney()
{
return $this->userMoney;
}
/**
* 获取订单总价
* @return int
*/
public function getTotalAmount()
{
return number_format($this->totalAmount, 2, '.', '');
}
/**
* 获取订单应付金额
* @return int
*/
public function getOrderAmount()
{
return number_format($this->orderAmount, 2, '.', '');
}
/**
* 获取实际上使用的积分抵扣金额
* @return float
*/
public function getIntegralMoney(){
return $this->integralMoney;
}
/**
* 获取实际上使用的积分
* @return float|int
*/
public function getPayPoints()
{
return $this->payPoints;
}
/**
* 获取物流费
* @return int
*/
public function getShippingPrice()
{
return $this->shippingPrice;
}
/**
* 获取优惠券费
* @return int
*/
public function getCouponPrice()
{
return $this->couponPrice;
}
/**
* 商品总价
* @return int
*/
public function getGoodsPrice()
{
return $this->goodsPrice;
}
/**
* 获取用户
* @return mixed
*/
public function getUser()
{
return $this->user;
}
public function getPayList()
{
return $this->payList;
}
public function getCouponId()
{
return $this->couponId;
}
public function getOrderPromAmount()
{
return $this->orderPromAmount;
}
public function getOrderPromId()
{
return $this->orderPromId;
}
public function getShop()
{
return $this->shop;
}
public function getToTalNum()
{
return $this->totalNum;
}
public function toArray()
{
return [
'shipping_price' => round($this->shippingPrice, 2),
'coupon_price' => round($this->couponPrice, 2),
'user_money' => round($this->userMoney, 2),
'integral_money' => $this->integralMoney,
'pay_points' => $this->payPoints,
'order_amount' => round($this->orderAmount, 2),
'total_amount' => round($this->totalAmount, 2),
'goods_price' => round($this->goodsPrice, 2),
'total_num' => $this->totalNum,
'order_prom_amount' => round($this->orderPromAmount, 2),
];
}
}