123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- <?php
- /**
- * 计算优惠类
- */
- namespace JinDouYun\Model\Cart;
- use Mall\Framework\Core\ErrorCode;
- use Mall\Framework\Core\ResultWrapper;
- use Mall\Framework\Core\StatusCode;
- use JinDouYun\Model\Market\MUserCoupon;
- use JinDouYun\Model\Market\MVipCard;
- class MPreferentialProcess{
- private $onlineUserCenterid;
- private $onlineEnterPriseId;
- private $userCouponIsMutex; // 用户领取过优惠劵是否互斥
- public function __construct($onlineUserCenterid, $onlineEnterPriseId)
- {
- $this->onlineUserCenterid = $onlineUserCenterid;
- $this->onlineEnterPriseId = $onlineEnterPriseId;
- }
- /**
- * 计算优惠核心方法
- * @param array $cartGoodsData 购物车商品数据
- * @param int $vipCardId 要使用的会员卡id
- * @params int $userCouponId 要使用的优惠劵id
- */
- public function Preferential($cartGoodsData, $vipCardId, $userCouponId)
- {
- $tmpCartGoodsData = $cartGoodsData;
- // 未指定要使用的会员卡id或优惠劵id
- if( !$vipCardId && !$userCouponId ) {
- return ResultWrapper::success($cartGoodsData);
- }
- $vipCartData = [];
- // 处理vip会员卡主流程
- if( $vipCardId ){
- // 获取vip会员卡信息
- $vipCartData = self::vipCartData($vipCardId);
- if(!$vipCartData->isSuccess()){
- return ResultWrapper::fail($vipCartData->getData(), $vipCartData->getErrorCode());
- }
- $vipCartData = $vipCartData->getData();
- // 没有折扣的会员卡不计算折扣
- if($vipCartData['vipDiscount'] == StatusCode::$delete){
- return ResultWrapper::success($cartGoodsData);
- }
- // 计算vip会员卡折后金额
- $cartGoodsData = self::vipCartCompute($cartGoodsData, $vipCartData);
- if(!$cartGoodsData->isSuccess()){
- return ResultWrapper::fail($cartGoodsData->getData(), $cartGoodsData->getErrorCode());
- }
- $cartGoodsData = $cartGoodsData->getData();
- }
- // 处理优惠券主流程
- if( $userCouponId ){
- // 获取优惠劵信息
- $userCouponData = self::couponData($userCouponId);
- if(!$userCouponData->isSuccess()){
- return ResultWrapper::fail($userCouponData->getData(), $userCouponData->getErrorCode());
- }
- $userCouponData = $userCouponData->getData();
- $this->userCouponIsMutex = $userCouponData['isMutex']; // 优惠劵与其他活动互斥
- /*if ($this->userCouponIsMutex == StatusCode::$standard){
- return ResultWrapper::success($cartGoodsData);
- }*/
- // 判断会员卡是否有优惠,且vip折扣后实付金额 小于 优惠金额,则先优惠后折扣
- if( $cartGoodsData['vipDiscount'] > 0 && ($cartGoodsData['payMoney'] < $userCouponData['reducePrice']) ) {
- // 计算优惠劵优惠后金额
- $tmpCartGoodsData = self::userCouponCompute($tmpCartGoodsData, $userCouponData);
- if(!$tmpCartGoodsData->isSuccess()){
- return ResultWrapper::fail($tmpCartGoodsData->getData(), $tmpCartGoodsData->getErrorCode());
- }
- $tmpCartGoodsData = $tmpCartGoodsData->getData();
- // 计算vip会员卡折后金额
- $tmpCartGoodsData = self::vipCartCompute($tmpCartGoodsData, $vipCartData);
- if(!$tmpCartGoodsData->isSuccess()){
- return ResultWrapper::fail($tmpCartGoodsData->getData(), $tmpCartGoodsData->getErrorCode());
- }
- $cartGoodsData = $tmpCartGoodsData->getData();
- }else{
- // 计算优惠劵优惠后金额
- $cartGoodsData = self::userCouponCompute($cartGoodsData, $userCouponData);
- if(!$cartGoodsData->isSuccess()){
- return ResultWrapper::fail($cartGoodsData->getData(), $cartGoodsData->getErrorCode());
- }
- $cartGoodsData = $cartGoodsData->getData();
- }
- }
- return ResultWrapper::success($cartGoodsData);
- }
- /**
- * 优惠劵计算流程
- * @params $vipCardId int 会员卡id
- * @return ResultWrapper
- */
- public function userCouponCompute($cartGoodsData, $userCouponData)
- {
- switch ($userCouponData['applyRange']){
- case StatusCode::$applyRange['allGoods']: // 全部商品
- // 判断是否满足优惠券使用门槛
- if( $userCouponData['minPrice'] == 0 || $cartGoodsData['payMoney'] >= $userCouponData['minPrice'] ){
- $result = self::userCouponDiscountCommon($cartGoodsData['payMoney'], $userCouponData['reducePrice']);
- $cartGoodsData['payMoney'] = $result['discountEndPayMoney']; // 修改订单总实际支付金额
- $cartGoodsData['preferential'] = $result['discountIngPayMoney']; // 修改订单优惠劵总优惠金额
- }
- break;
- case StatusCode::$applyRange['appointCategory']: // 指定分类
- $result = self::userCouponDiscountByGoods('categoryId', 'categoryCollect', $cartGoodsData,$userCouponData);
- if(!$result->isSuccess()){
- return ResultWrapper::fail($result->getErrorCode(), $result->getData());
- }
- $cartGoodsData = $result->getData();
- break;
- case StatusCode::$applyRange['appointBrand']: // 指定品牌
- $result = self::userCouponDiscountByGoods('brandId', 'brandCollect', $cartGoodsData,$userCouponData);
- if(!$result->isSuccess()){
- return ResultWrapper::fail($result->getErrorCode(), $result->getData());
- }
- $cartGoodsData = $result->getData();
- break;
- case StatusCode::$applyRange['goodsCollect']: // 指定商品
- $result = self::userCouponDiscountByGoods('goodsId', 'goodsCollect', $cartGoodsData, $userCouponData);
- if(!$result->isSuccess()){
- return ResultWrapper::fail($result->getErrorCode(), $result->getData());
- }
- $cartGoodsData = $result->getData();
- break;
- }
- if ($cartGoodsData['payMoney'] < 0) {
- $cartGoodsData['payMoney'] = 0; // 如果折后金额小于0,统一归零处理
- }
- return ResultWrapper::success($cartGoodsData);
- }
- /**
- * 指定商品分类/商品品牌/商品 计算优惠统一方法
- * @params string $typeField 指定类型
- * @params string $typeField 类型对应字段名
- */
- public function userCouponDiscountByGoods($type, $typeField, $cartGoodsData, $userCouponData)
- {
- if( empty($userCouponData[$typeField]) ){
- return ResultWrapper::success($cartGoodsData);
- }
- $goodsAmount = 0; // 满足优惠劵指定分类下的商品总金额
- $couponBrand = explode(',', $userCouponData[$typeField]);
- // 累加订单中每个店铺下参与优惠劵的商品总金额
- foreach ($cartGoodsData['goodsData'] as $shop) {
- foreach ($shop['shopGoodsData'] as $value) {
- if (in_array($value[$type], $couponBrand)) {
- $goodsAmount = bcadd($goodsAmount, $value['totalMoney']);
- }
- }
- }
- if( $goodsAmount <= 0 ){
- return ResultWrapper::fail('参与优惠劵优惠的商品总金额异常', ErrorCode::$notAllowAccess);
- }
- // 判断是否满足优惠券使用门槛
- if( $userCouponData['minPrice'] == 0 || $goodsAmount >= $userCouponData['minPrice'] ){
- $result = self::userCouponDiscountCommon($goodsAmount, $userCouponData['reducePrice']);
- $cartGoodsData['payMoney'] = bcsub($cartGoodsData['payMoney'], $result['discountIngPayMoney'], 2); // 修改订单总实际支付金额
- $cartGoodsData['preferential'] = $result['discountIngPayMoney']; // 修改订单优惠劵总优惠金额
- }
- return ResultWrapper::success($cartGoodsData);
- }
- /**
- * 优惠劵优惠统一方法
- * @params float $discountBeforePayMoney 优惠劵优惠前金额
- * @params float $discountMoney 优惠劵优惠金额
- * @return array 优惠后金额
- */
- public function userCouponDiscountCommon($discountBeforePayMoney, $discountMoney)
- {
- $discountEndPayMoney = bcsub($discountBeforePayMoney, $discountMoney, 2);
- // 如果优惠后的金额小于0,说明优惠金额大于商品原价了,优惠金额 = 商品金额, 多余优惠浪费掉了
- $discountIngPayMoney = ($discountEndPayMoney < 0 ) ? $discountBeforePayMoney : $discountMoney;
- return [
- 'discountEndPayMoney' => ($discountEndPayMoney < 0) ? 0 : $discountEndPayMoney,
- 'discountIngPayMoney' => $discountIngPayMoney,
- ];
- }
- /**
- * vip会员卡优惠计算流程
- * @params $vipCardId int 会员卡id
- * @return ResultWrapper
- */
- public function vipCartCompute($cartGoodsData, $vipCartData)
- {
- $discount = bcdiv($vipCartData['discount'], 10, 2); //折扣率
- // 所有商品
- if ($vipCartData['mode'] == StatusCode::$standard) {
- $result = self::vipCartDiscountCommon($cartGoodsData['payMoney'], $discount);
- $cartGoodsData['payMoney'] = $result['discountEndPayMoney']; // 修改订单总实际支付金额
- $cartGoodsData['vipDiscount'] = $result['discountIngPayMoney']; // 修改订单总会员卡优惠金额
- //是否开启折上折 暂时不支持 代码需要测试
- /*if ($cardInfo['doubleDiscount'] == StatusCode::$standard) {
- $data['vipDoubleDiscount'] = bcsub($data['payMoney'], bcmul($data['payMoney'], $discount, 2), 2);//折上折优惠金额
- $data['payMoney'] = bcmul($data['payMoney'], $discount, 2);
- if ($data['payMoney'] < 0) {
- $data['payMoney'] = 0;//若优惠券后价格小于0(可能是由于优惠券设计不合理)
- }
- }*/
- }else{ // 部分商品
- if( empty($vipCartData['goodsIds']) ){
- return ResultWrapper::success($cartGoodsData);
- }
- $goodsAmount = 0; // 参与会员卡折扣的商品总金额
- $vipGoodsIds = explode(',', $vipCartData['goodsIds']); // 会员卡设置的参与折扣商品
- // 累加订单中每个店铺下参与会员卡折扣的商品总金额
- foreach ($cartGoodsData['goodsData'] as $shop) {
- foreach ($shop['shopGoodsData'] as $value) {
- if (in_array($value['goodsId'], $vipGoodsIds)) {
- $goodsAmount = bcadd($goodsAmount, $value['totalMoney']);
- }
- }
- }
- if( $goodsAmount <= 0 ){
- return ResultWrapper::fail('参与会员卡优惠的商品总金额异常', ErrorCode::$notAllowAccess);
- }
- $result = self::vipCartDiscountCommon($goodsAmount, $discount);
- $cartGoodsData['payMoney'] = bcsub($cartGoodsData['payMoney'], $result['discountIngPayMoney']); // 修改订单总实际支付金额
- $cartGoodsData['vipDiscount'] = $result['discountIngPayMoney']; // 修改订单总会员卡优惠金额
- //是否开启折上折 暂时不支持 代码需要测试
- /*if ($cardInfo['doubleDiscount'] == StatusCode::$standard) {
- $data['vipDoubleDiscount'] = bcsub($data['payMoney'], bcmul($data['payMoney'], $discount, 2), 2);//折上折优惠金额
- $data['payMoney'] = bcmul($data['payMoney'], $discount, 2);
- if ($data['payMoney'] < 0) {
- $data['payMoney'] = 0;//若优惠券后价格小于0(可能是由于优惠券设计不合理)
- }
- }*/
- }
- if ($cartGoodsData['payMoney'] < 0) {
- $cartGoodsData['payMoney'] = 0; // 如果折后金额小于0,统一归零处理
- }
- return ResultWrapper::success($cartGoodsData);
- }
- /**
- * 计算会员卡折扣统一方法
- * @params float $discountBeforePayMoney 会员卡优惠前金额
- * @params float $discount 会员卡折扣率
- * @return array 优惠后金额
- */
- public function vipCartDiscountCommon($discountBeforePayMoney, $discount)
- {
- $discountEndPayMoney = bcmul( $discountBeforePayMoney, $discount, 2); // vip会员卡打折以后的订单金额 0.19
- $discountIngPayMoney = bcsub($discountBeforePayMoney, $discountEndPayMoney, 2); // vip会员卡打折免掉的金额 18.81
- return [
- 'discountEndPayMoney' => ($discountEndPayMoney < 0) ? 0 : $discountEndPayMoney,
- 'discountIngPayMoney' => ($discountIngPayMoney < 0) ? 0 : $discountIngPayMoney,
- ];
- }
- /**
- * 获取vip会员卡信息
- * @params $vipCardId int 会员卡id
- * @return ResultWrapper
- */
- public function vipCartData($vipCardId)
- {
- $objMVipCard = new MVipCard($this->onlineEnterPriseId, $this->onlineUserCenterid, true);
- $dbResult = $objMVipCard->getVipCardInfo($vipCardId);
- if(!$dbResult->isSuccess()){
- return ResultWrapper::fail($dbResult->getData(), $dbResult->getErrorCode());
- }
- $vipCartData = $dbResult->getData();
- if( empty($vipCardId) ){
- return ResultWrapper::fail('要使用的会员卡不存在', ErrorCode::$contentNotExists);
- }
- // 判断是否删除
- if($vipCartData['deleteStatus'] == StatusCode::$delete){
- return ResultWrapper::fail('当前购买的vip会员卡被删除了', ErrorCode::$notAllowAccess);
- }
- // 判断是否禁用
- if($vipCartData['enableStatus'] == StatusCode::$delete){
- return ResultWrapper::fail('当前购买的vip会员卡被禁用了', ErrorCode::$notAllowAccess);
- }
- return ResultWrapper::success($vipCartData);
- }
- /**
- * 获取优惠劵信息
- * @params $userCouponId int 用户领取优惠劵id
- * @return ResultWrapper
- */
- public function couponData($userCouponId)
- {
- // 查询用户领取过的优惠劵数据
- $objMUserCoupon = new MUserCoupon($this->onlineUserCenterid, $this->onlineEnterPriseId);
- $condition = [
- 'id' => $userCouponId,
- ];
- $userCouponData = $objMUserCoupon->getUserCoupon($condition);
- if(!$userCouponData->isSuccess()){
- return ResultWrapper::fail($userCouponData->getData(), $userCouponData->getErrorCode());
- }
- $userCouponData = $userCouponData->getData();
- if(empty($userCouponData)){
- return ResultWrapper::fail('要使用的优惠劵不存在', ErrorCode::$contentNotExists);
- }
- $userCouponData = array_pop($userCouponData);
- // 判断是否使用过了
- if($userCouponData['isUse'] == StatusCode::$delete){
- return ResultWrapper::fail('当前领取的优惠券已经使用过了', ErrorCode::$notAllowAccess);
- }
- // 判断下有效期
- if (time() <= $userCouponData['startTime'] || time() >= $userCouponData['endTime']){
- return ResultWrapper::fail('当前领取的优惠券已经过期了', ErrorCode::$notAllowAccess);
- }
- return ResultWrapper::success($userCouponData);
- }
- }
|