admin/app/frontend/modules/orderGoods/price/option/BaseOrderGoodsPrice.php

389 lines
13 KiB
PHP
Raw 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
namespace app\frontend\modules\orderGoods\price\option;
/**
* Created by PhpStorm.
* User: shenyang
* Date: 2017/5/19
* Time: 下午6:04
*/
use app\common\exceptions\AppException;
use app\common\facades\Setting;
use app\common\helpers\Serializer;
use app\frontend\models\order\PreOrderCoinExchange;
use app\frontend\models\orderGoods\PreOrderGoodsCoinExchange;
use app\frontend\modules\deduction\orderGoods\PreOrderGoodsDeduction;
use app\frontend\modules\order\PriceNode;
use app\frontend\modules\order\PriceNodeTrait;
use app\frontend\modules\orderGoods\discount\BaseDiscount;
use app\frontend\modules\orderGoods\GoodsPriceNodeBase;
use app\frontend\modules\orderGoods\OrderGoodsCouponPriceNode;
use app\frontend\modules\orderGoods\OrderGoodsDeductionPriceNode;
use app\frontend\modules\orderGoods\OrderGoodsDiscountPriceNode;
use app\frontend\models\orderGoods\PreOrderGoodsDiscount;
use app\frontend\modules\orderGoods\OrderGoodsTaxfeeNode;
use app\frontend\modules\orderGoods\price\adapter\GoodsAdapterManager;
use app\frontend\modules\orderGoods\taxFee\BaseTaxFee;
use Yunshop\CulturalSpace\models\CulturalFund;
use Yunshop\CulturalSpace\models\GoodsCulturalSpace;
use Yunshop\Rebate\models\GoodsRebate;
use Yunshop\Rebate\models\Rebate;
abstract class BaseOrderGoodsPrice extends OrderGoodsPrice
{
use PriceNodeTrait;
/**
* @var float
*/
private $deductionAmount;
private $deductionCount;
/**
* @var float
*/
private $paymentAmount;
/**
* @var float
*/
private $price;
protected $priceClass;
private $deductionWeight = 0;
public function _getPriceNodes()
{
// 订单节点
$nodes = collect([
new GoodsPriceNodeBase($this, 1000)
]);
// 订单优惠的节点
$discountNodes = $this->orderGoods->getDiscounts()->map(function (BaseDiscount $discount) {
return new OrderGoodsDiscountPriceNode($this, $discount);
});
// foreach (\app\common\modules\shop\ShopConfig::current()->get('shop-foundation.goods-discount') as $configItem) {
// $discountNodes->push(new OrderGoodsDiscountPriceNode($this, call_user_func($configItem['class'], $this->orderGoods), $configItem['weight']));
// }
// 订单抵扣节点(!!!不要在循环中自增权重设置为相同的权重是为getPriceBeforeByWeight方法更容易编写
$deductionNodes = $this->orderGoods->getOrderGoodsDeductions()->map(function (PreOrderGoodsDeduction $preOrderGoodsDeduction) {
return new OrderGoodsDeductionPriceNode($this, $preOrderGoodsDeduction, 2200);
});
$taxNodes = $this->orderGoods->getTaxFees()->map(function (BaseTaxFee $taxFee) {
return new OrderGoodsTaxfeeNode($this, $taxFee, 2300);
});
// 按照weight排序
return $nodes->merge($discountNodes)->merge($deductionNodes)->merge($taxNodes)->sortBy(function (PriceNode $priceNode) {
return $priceNode->getWeight();
})->values();
}
/**
* @return mixed
*/
abstract protected function goods();
abstract protected function aGoodsPrice();
/**
* 成交价
* @return mixed
*/
public function getPrice()
{
// 判断:开启文创豆兑换 价格为0
if((int)request()->input('is_legumes_exchange') == 1) return 0;
if (isset($this->price)) return $this->price;
if ($this->isCoinExchange()) return 0;
// 商品销售价 - 等级优惠金额
$this->price = $this->getGoodsPrice();
$this->price = max($this->price, 0);
// 判断:是否开启消费返利
$goodsRebate = GoodsRebate::uniacid()->where('goods_id',$this->orderGoods->goods_id)->first();
if($goodsRebate->is_open == 1){
// 判断:当前返利记录是否存在
$rebateInfo = Rebate::uniacid()
->selectRaw('max(reality_thaw_time) as last_reality_thaw_time,max(status) as max_status')
->where('uid', $this->orderGoods->uid)
->where('goods_id', $this->orderGoods->goods_id)
->first();
// 不存在返利记录,从未购买 原价购买
if(empty($rebateInfo)) return $this->price;
$rebateInfo = $rebateInfo->toArray();
// 判断最大状态是否为1或者2 不是则失效,原价购买
if(!in_array($rebateInfo['max_status'],[0,1,2])) return $this->price;
// 判断:最后结算信息获取 并且判断是否需要复购,需要则返回复购价格
$endInfo = Rebate::uniacid()
->where('uid', $this->orderGoods->uid)
->where('goods_id', $this->orderGoods->goods_id)
->where('reality_thaw_time', $rebateInfo['last_reality_thaw_time'])
->first();
// 是否需要复购 需要则返回复购价格,否则无操作
if($endInfo->is_repurchase == 1){
$endInfo = $endInfo->toArray();
$this->price = $endInfo['repurchase_money'] ?? $this->price;
}
}
return $this->price;
}
public function getLegumes(){
if((int)request()->input('is_legumes_exchange') == 1){
$legumes_exchange_price = GoodsCulturalSpace::uniacid()->where('goods_id',(int)$this->orderGoods->goods_id)->value('legumes_exchange_price');
$current_fee = CulturalFund::uniacid()->value('current_fee');
$this->legumes_rate = $current_fee;
$this->legumes_exchange_price = $legumes_exchange_price;
$this->use_legumes_exchange = (float)ceil(sprintf("%.2f",$legumes_exchange_price / $current_fee));
return $this->use_legumes_exchange;
}
return 0;
}
public function getLegumesPrice(){
if((int)request()->input('is_legumes_exchange') == 1){
$this->use_legumes_exchange_price = GoodsCulturalSpace::uniacid()->where('goods_id',(int)$this->orderGoods->goods_id)->value('legumes_exchange_price');
return $this->use_legumes_exchange_price;
}
return 0;
}
//todo blank 商品价格适配器
public function goodsPriceManager()
{
if (isset($this->priceClass)) {
return $this->priceClass;
}
$this->priceClass = GoodsAdapterManager::preOrderGoods($this->orderGoods);
return $this->priceClass;
}
public function getVipPrice(){
// 判断:开启文创豆兑换 价格为0
if((int)request()->input('is_legumes_exchange') == 1) return 0;
if ($this->isCoinExchange()) {
return 0;
}
return $this->getGoodsPrice() - $this->getMemberLevelDiscountAmount();
}
private $isCoinExchange;
/**
* @return bool
*/
private function isCoinExchange()
{
if (!isset($this->isCoinExchange) && (int)request()->input('is_legumes_exchange') != 1) {
//blank not deduction
if ($this->orderGoods->order->isDeductionDisable()) {
$this->isCoinExchange = false;
return $this->isCoinExchange;
}
// 判断:当前商品是否为积分商品&& (int)$this->orderGoods->pointGoods->id > 0
if (!$this->orderGoods->goods->hasOneSale->has_all_point_deduct ) {
$this->isCoinExchange = false;
}
else {
$this->isCoinExchange = true;
$relations = collect(\app\common\modules\shop\ShopConfig::current()->get('shop-foundation.coin-exchange'))->sortBy('weight');
foreach ($relations as $configItem) {
$coinExchange = call_user_func($configItem['class'], $this);
if(!$coinExchange->validate()) continue;
$orderCoinExchange = $coinExchange->setLog();
//todo 权重最大的过了直接断循环
break;
}
if(empty($orderCoinExchange)){
//获取商城设置: 判断 积分、余额 是否有自定义名称
$shopSet = \Setting::get('shop.shop');
// 优惠记录
$preOrderGoodsDiscount = new PreOrderGoodsDiscount([
'discount_code' => 'coinExchange',
'amount' => $this->getGoodsPrice() ?: 0,
'name' => $shopSet['credit1'] ? $shopSet['credit1'] . '全额抵扣' : '积分全额抵扣',
]);
$preOrderGoodsDiscount->setOrderGoods($this->orderGoods);
// 全额抵扣记录
$orderGoodsCoinExchange = new PreOrderGoodsCoinExchange([
'code' => 'point',
'amount' => $this->getGoodsPrice() ?: 0,
'coin' => $this->orderGoods->goods->hasOneSale->all_point_deduct * $this->orderGoods->total,
'name' => $shopSet['credit1'] ? $shopSet['credit1'] . '全额抵扣' : '积分全额抵扣',
]);
$orderGoodsCoinExchange->setOrderGoods($this->orderGoods);
$orderCoinExchange = new PreOrderCoinExchange([
'code' => 'point',
'amount' => $this->getGoodsPrice() ?: 0,
'coin' => $this->orderGoods->goods->hasOneSale->all_point_deduct * $this->orderGoods->total,
'name' => $shopSet['credit1'] ? $shopSet['credit1'] . '全额' : '积分全额',
'uid' => $this->orderGoods->uid,
]);
}
$this->orderGoods->order->getOrderCoinExchanges()->addAndGroupByCode($orderCoinExchange);
}
}
return $this->isCoinExchange;
}
/**
* 获取订单商品支付金额
* @return float|mixed
* @throws \app\common\exceptions\AppException
*/
public function getPaymentAmount()
{
if (!isset($this->paymentAmount)) {
$this->paymentAmount = $this->getPriceAfter($this->getPriceNodes()->last()->getKey());
$this->paymentAmount = max($this->paymentAmount, 0);
}
if((int)$this->orderGoods->pointGoods->id > 0){
$this->paymentAmount = sprintf("%.2f",$this->orderGoods->pointGoods->use_money * $this->orderGoods->total);
}
return $this->paymentAmount;
}
/**
* 销售价(商品的原销售价)
* @return mixed
*/
public function getGoodsPrice(){
if((int)$this->orderGoods->pointGoods->id > 0){
return sprintf("%.2f",$this->orderGoods->pointGoods->use_money * $this->orderGoods->total);
}
return $this->aGoodsPrice() * $this->orderGoods->total;
}
/**
* 成本价
* @return mixed
*/
public function getGoodsCostPrice()
{
return $this->goods()->cost_price * $this->orderGoods->total;
}
/**
* 市场价
* @return mixed
*/
public function getGoodsMarketPrice()
{
return $this->goods()->market_price * $this->orderGoods->total;
}
/**
* 优惠券价
* @return int
*/
public function getCouponAmount()
{
if (!isset($this->orderGoods->coupons)) {
return 0;
}
return $this->orderGoods->coupons->sum('amount');
}
/**
* 获取订单商品抵扣金额
* @return float
*/
public function getDeductionAmount()
{
if ($this->deductionCount != $this->orderGoods->getOrderGoodsDeductions()->count()) {
$this->deductionCount = $this->orderGoods->getOrderGoodsDeductions()->count();
trace_log()->deduction('订单商品计算者', "订单商品计算所有已用的抵扣金额");
$this->deductionAmount = $this->orderGoods->getOrderGoodsDeductions()->getUsedPoint()->getMoney();
}
return $this->deductionAmount;
}
protected $vipDiscountAmount;
protected $vipDiscountLog;
public function getMemberLevelDiscountAmount()
{
if (!isset($this->vipDiscountAmount)) {
$this->vipDiscountAmount = $this->_getVipDiscountAmount($this->goodsPriceManager());
$this->vipDiscountLog = $this->goods()->vipDiscountLog;
}
return $this->vipDiscountAmount;
}
public function getVipDiscountLog()
{
if (!isset($this->vipDiscountLog)) {
$this->getMemberLevelDiscountAmount();
}
return $this->vipDiscountLog;
}
/**
* 商品的会员等级折扣金额
* @return mixed
*/
protected function _getVipDiscountAmount($price)
{
return $this->goods()->getVipDiscountAmount($price) * $this->orderGoods->total;
}
/**
* 不可用
* 商品的会员等级折扣金额(缓存)
* @return mixed
*/
public function getVipDiscountAmount($price)
{
return 0;
if (!isset($this->vipDiscountAmount)) {
$this->vipDiscountAmount = $this->_getVipDiscountAmount($price);
if ($this->vipDiscountAmount) {
$preOrderGoodsDiscount = new PreOrderGoodsDiscount([
'discount_code' => $this->goods()->vipDiscountLog->code,
'amount' => $this->vipDiscountAmount ?: 0,
'name' => $this->goods()->vipDiscountLog->name,
]);
$preOrderGoodsDiscount->setOrderGoods($this->orderGoods);
}
}
return $this->vipDiscountAmount;
}
}