canyin-project/ybcy/models/common/Bill.php
2024-11-01 16:07:54 +08:00

476 lines
20 KiB
PHP

<?php
namespace app\models\common;
use Yii;
use yii\base\Model;
use yii\db\ActiveRecord;
use app\models\common\Config;
use yii\db\Expression;
class Bill extends ActiveRecord{
public static function origin() {
return [1];
}
/**
* @param $uniacid[小程序id]
* @param $type[1冻结2正常]
* @param $origin[1外卖订单2充值订单3积分商城4.券包5.收银]
* @param $outTradeNo[订单号]
* @param $item[1.加2减]
* @return bool
* @throws \yii\db\Exception
*/
public static function bill($uniacid,$type,$origin,$outTradeNo,$item){
$fxItem=0;
$now=time();
$billInfo=(new \yii\db\Query())
->select(['id'])
->from('{{%ybwm_bill}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
if ($billInfo) {
return true;
}
$order=[];
if($origin==1){
//外卖订单
$order=(new \yii\db\Query())
->from('{{%ybwm_takeout_order}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
//deliveryPreferential配送费优惠
//platformCouponPreferential 平台卡券优惠
//couponPreferential 商家优惠券优惠
//newMoney 新客优惠
//preferentialMoney 满减优惠
$goodsPreferential=bcadd(bcadd(bcadd($order['platformCouponPreferential'],$order['couponPreferential'],2),$order['newMoney'],2),$order['preferentialMoney'],2);
$goodsMoney=bcsub($order['originMoney'],$goodsPreferential,2);
if($goodsMoney<=0){
$goodsMoney=0.01;
}
$bill['storeGoodsMoney']=self::storeIncome($order['storeId'],$goodsMoney,'goods');//商家商品所得
$bill['storeBoxMoney']=self::storeIncome($order['storeId'],$order['boxMoney'],'box');//商家餐盒费所得
$bill['storeDeliveryMoney']=self::storeIncome($order['storeId'],$order['deliveryMoney'],'deliver');//商家配送费所得
$bill['storeActualMoney']=bcadd(bcadd($bill['storeGoodsMoney'],$bill['storeBoxMoney'],2),$bill['storeDeliveryMoney'],2);//商家总所得
if($order['subsidy']){
$bill['subsidy']=$order['subsidy'];//补贴
$bill['storeActualMoney']=bcadd($bill['storeActualMoney'],$bill['subsidy'],2);
}
$fxItem=1;
}
if($origin==2){
//充值订单
$order=(new \yii\db\Query())
->from('{{%ybwm_user_balance_order}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
}
if($origin==3){
//积分商城订单
$order=(new \yii\db\Query())
->from('{{%ybwm_integral_order}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
}
if($origin==4){
//券包订单
$order=(new \yii\db\Query())
->from('{{%ybwm_roll_bag_order}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
$bill['storeActualMoney']=$order['money'];
}
if($origin==5){
//收银
$order=(new \yii\db\Query())
->from('{{%ybwm_cashier_order}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
$bill['storeActualMoney']=self::storeIncome($order['storeId'],$order['money'],'cashier');//商家商品所得
$fxItem=4;
}
if($origin==6){
//快餐
$order=(new \yii\db\Query())
->from('{{%ybwm_instore_order}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
$bill['storeActualMoney']=self::storeIncome($order['storeId'],$order['money'],'fast');//商家商品所得
if($order['subsidy']){
$bill['subsidy']=$order['subsidy'];//补贴
$bill['storeActualMoney']=bcadd($bill['storeActualMoney'],$bill['subsidy'],2);
}
$fxItem=3;
}
if($origin==7){
//店内
$order=(new \yii\db\Query())
->from('{{%ybwm_instore_order}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
$bill['storeActualMoney']=self::storeIncome($order['storeId'],$order['money'],'inStore');//商家商品所得
if($order['subsidy']){
$bill['subsidy']=$order['subsidy'];//补贴
$bill['storeActualMoney']=bcadd($bill['storeActualMoney'],$bill['subsidy'],2);
}
$fxItem=2;
}
if($origin==8){
//付费会员
$order=(new \yii\db\Query())
->from('{{%ybwm_user_vip_order}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
}
if($origin==9){
//预约
$order=(new \yii\db\Query())
->from('{{%ybwm_appointment}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
}
if(!$order){
return false;
}
// if($order['storeId']){
// $storeSet=Config::getStoreSet('serviceCharge',$order['storeId']);
// if($storeSet['rule']==2){
// $entryDay=$storeSet['entryDay']?:0;
// }else{
// $storeInfo=(new \yii\db\Query())
// ->select('areaId,typeId')
// ->from('{{%ybwm_store}}')
// ->where('id=:id',[':id'=>$order['storeId']])->one();
// $serviceCharge=Config::getSystemSet('serviceCharge',$uniacid);
// if($serviceCharge['rule']==1){
// $entryDay=$serviceCharge['day']?:0;
// }elseif($serviceCharge['rule']==2){
// $storeType=(new \yii\db\Query())
// ->from('{{%ybwm_core_category}}')
// ->where('id=:id',[':id'=>$storeInfo['typeId']])->one();
// $entryDayData=json_decode($storeType['data'],true);
// $entryDay=$entryDayData['day']?:0;
// }elseif($serviceCharge['rule']==3){
// $storeType=(new \yii\db\Query())
// ->from('{{%ybwm_core_category}}')
// ->where('id=:id',[':id'=>$storeInfo['areaId']])->one();
// $entryDayData=json_decode($storeType['data'],true);
// $entryDay=$entryDayData['day']?:0;
// }
// }
// }
$entryDay=0;
$bill['uniacid'] = $uniacid;
$bill['payPort'] = $order['payPort']?:1;
$bill['userId'] = $order['userId'];
$bill['storeId'] = $order['storeId']?:0;
$bill['orderId'] = $order['id'];
$bill['money'] = $order['money'];
$bill['payMode'] = $order['payMode']; //微信小程序支付
$bill['item'] = $item; //加
$bill['origin'] = $origin; //1外卖订单
$bill['type'] = $type; //冻结
$bill['outTradeNo'] = $outTradeNo;
$bill['payType'] = $order['payType'];
$bill['createdAt'] = $now;
$bill['statisticsAt'] = $now;
$bill['platform'] = $order['origin']?:1;
$bill['entryAt'] = strtotime(date("Y-m-d",$now+86400*$entryDay));
//print_R($bill);die;
$res=Yii::$app->db->createCommand()->insert('{{%ybwm_bill}}', $bill)->execute();
if($res){
if($type==2 AND $bill['storeId']){
if($bill['origin']==1){
$note='外卖订单入账';
$origin=1;
}elseif($bill['origin']==7){
$note='店内订单入账';
$origin=2;
}elseif($bill['origin']==6){
$note='快餐订单入账';
$origin=3;
}elseif($bill['origin']==5){
$note='当面付订单入账';
$origin=4;
}elseif($bill['origin']==4){
$note='券包订单入账';
$origin=5;
}elseif($bill['origin']==9){
$note='预约订单入账';
$origin=9;
}
self::saveStoreBill($uniacid,$bill['storeId'],$bill['storeActualMoney'],$item,$origin,$note,time(),$outTradeNo);
}
if($fxItem){
Member::distributionOrder($uniacid,$order['userId'],$outTradeNo,$order['money'],$fxItem,$type);
}
return true;
}else{
return false;
}
}
/**商家佣金计算
* @param $storeId [商家id]
* @param $money [金额]
* @param string $type [商品 goods;配送费 deliver;餐盒费 box]
* @param string $returnType [1.商家所得2.平台抽佣]
* @return int|string
*/
public static function storeIncome($storeId,$money,$type='goods',$returnType=1){
$store=(new \yii\db\Query())
->select('uniacid,typeId,areaId,isMain')
->from('{{%ybwm_store}}')
->where('id=:id',[':id'=>$storeId])->one();
$res=Config::getSystemSet('serviceCharge',$store['uniacid']);
$storeSet=Config::getStoreSet('serviceCharge',$storeId);
if($storeSet['rule']==2){
$res=$storeSet;
}else{
if(!$res){
return $money?:0;
}
if($res['rule']==2){
//按商家分组
$storeType=(new \yii\db\Query())
->from('{{%ybwm_core_category}}')
->where('id=:id',[':id'=>$store['typeId']])->one();
$res=json_decode($storeType['data'],true);
}elseif($res['rule']==3){
//按商家区域
$storeType=(new \yii\db\Query())
->from('{{%ybwm_core_category}}')
->where('id=:id',[':id'=>$store['areaId']])->one();
$res=json_decode($storeType['data'],true);
}elseif($res['rule']==4){
//按商家单独
$res=Config::getStoreSet('serviceCharge',$storeId);
}
}
if($res['type']==1){
//按比例
$platformMoney=bcmul($money,$res[$type.'PlatformProportion']/100,2);//平台抽佣金额
if($platformMoney<$res[$type.'DownMoney'] AND $res[$type.'DownMoney']>0){
//小于最低抽佣金额
$platformMoney=$res[$type.'DownMoney'];
}
}else{
//按固定金额
$platformMoney=$res[$type."FixedMoney"];//平台抽佣金额
}
if($returnType==2){
//返回平台佣金
return $platformMoney>$money?$money:$platformMoney;
}
$storeMoney=bcsub($money,$platformMoney,2);
if($storeMoney<0){
return 0;
}else{
return $storeMoney;
}
}
//计算部分商品应退款金额
public static function goodsRefund($goodsId){
//计算规则(退款商品价格+包装费)/(总商品价格+总商品包装费)*(订单实付金额-原配送费)
$goods=(new \yii\db\Query())
->from('{{%ybwm_order_goods}}')
->where('id=:id',[':id'=>$goodsId])->one();
$order=(new \yii\db\Query())
->from('{{%ybwm_takeout_order}}')
->where('id=:id',[':id'=>$goods['orderId']])->one();
$goodsMoney=bcadd($goods['money'],$goods['boxMoney'],2);//单个商品金额加包装费
$allGoodsMoney=bcadd($order['originMoney'],$order['boxMoney'],2);//总商品金额加总包装费
$orderMoney=bcsub($order['money'],$order['deliveryMoney'],2);//实付金额减去原始配送费
return bcmul(bcdiv($goodsMoney,$allGoodsMoney,2),$orderMoney,2);
}
//退款修改账单
public static function refundBill($orderId,$refundType,$orderType=1){
if($orderType==1){
$order=(new \yii\db\Query())
->select('outTradeNo,refundMoney')
->from('{{%ybwm_takeout_order}}')
->where('id=:id',[':id'=>$orderId])->one();
}
if($orderType==2){
$order=(new \yii\db\Query())
->select('outTradeNo,refundMoney')
->from('{{%ybwm_instore_order}}')
->where('id=:id',[':id'=>$orderId])->one();
}
if($orderType==3){
$order=(new \yii\db\Query())
->select('outTradeNo,refundMoney')
->from('{{%ybwm_appointment}}')
->where('id=:id',[':id'=>$orderId])->one();
}
$bill['storeGoodsMoney']=0;//商家商品所得
$bill['storeBoxMoney']=0;//商家餐盒费所得
$bill['storeDeliveryMoney']=0;//商家配送费所得
$bill['storeActualMoney']=0;//商家总所得
$bill['refundMoney']=$order['refundMoney'];//退款金额
$bill['refundAt']=time();//退款时间
$bill['refundType']=$refundType;//1.用户退款2商户退款
$res=Yii::$app->db->createCommand()->update('{{%ybwm_bill}}', $bill, ['outTradeNo'=>$order['outTradeNo']])->execute();
if($res){
return true;
}else{
return false;
}
}
//根据时间获取订单的折线图数据(每小时)
public static function billCountByHours($uniacid,$startTime,$endTime,$type,$time,$storeId=null){
$query=(new \yii\db\Query())
->select(new Expression("from_unixtime(statisticsAt,'%H') as hours,count(*)money"))
->from('{{%ybwm_bill}}')
->where(['deleteAt' => 0,'uniacid'=>$uniacid])
->andWhere('statisticsAt>=:starTime AND statisticsAt<=:endTime',[':starTime'=>$startTime,':endTime'=>$endTime]);
if($storeId){
$query->andWhere(['in','storeId',$storeId]);
}
$data=$query->groupBy(new Expression("from_unixtime(statisticsAt,'%H')"))->all();
$data=CreatQuery($type,$data,$time);
return $data;
}
//根据时间获取订单的折线图数据(每小时)
public static function billDataByHours($uniacid,$startTime,$endTime,$type,$time,$storeId=null){
// $data=[];
$query=(new \yii\db\Query())
->select(new Expression("from_unixtime(statisticsAt,'%H') as hours,sum(money)money"))
->from('{{%ybwm_bill}}')
->where(['deleteAt' => 0,'uniacid'=>$uniacid])
->andWhere('statisticsAt>=:starTime AND statisticsAt<=:endTime',[':starTime'=>$startTime,':endTime'=>$endTime]);
if($storeId){
$query->andWhere(['in','storeId',$storeId]);
}
$query->andWhere(['in','origin',self::origin()]);
$data=$query->groupBy(new Expression("from_unixtime(statisticsAt,'%H')"))->all();
$data=CreatQuery($type,$data,$time);
return $data;
}
//根据时间获取订单的折线图数据(每天)
public static function billDataByDay($uniacid,$startTime,$endTime,$storeId=null,$type=1){
if($type==2){
$select="from_unixtime(statisticsAt,'%Y-%m-%d') as hours,count(id)money";
}else{
$select="from_unixtime(statisticsAt,'%Y-%m-%d') as hours,sum(money)money";
}
$query=(new \yii\db\Query())
->select(new Expression($select))
->from('{{%ybwm_bill}}')
->where(['deleteAt' => 0,'uniacid'=>$uniacid])
->andWhere('statisticsAt>=:starTime AND statisticsAt<=:endTime',[':starTime'=>$startTime,':endTime'=>$endTime]);
if($storeId){
$query->andWhere(['in','storeId',$storeId]);
}
$query->andWhere(['in','origin',[1,5,6,7]]);
$data=$query->groupBy(new Expression("from_unixtime(statisticsAt,'%%Y-%m-%d')"))->all();
$data=dataByTime($data,date('Y-m-d 23:59:59',$endTime));
return $data;
}
//查看商家服务费率
public static function getStoreRate($storeId){
$store=(new \yii\db\Query())
->select('uniacid,typeId,areaId,isMain')
->from('{{%ybwm_store}}')
->where('id=:id',[':id'=>$storeId])->one();
$res=Config::getSystemSet('serviceCharge',$store['uniacid']);
$storeSet=Config::getStoreSet('serviceCharge',$storeId);
if($storeSet['rule']==2){
$res=$storeSet;
}else{
if($res['rule']==2){
//按商家分组
$storeType=(new \yii\db\Query())
->from('{{%ybwm_core_category}}')
->where('id=:id',[':id'=>$store['typeId']])->one();
$res=json_decode($storeType['data'],true);
}elseif($res['rule']==3){
//按商家区域
$storeType=(new \yii\db\Query())
->from('{{%ybwm_core_category}}')
->where('id=:id',[':id'=>$store['areaId']])->one();
$res=json_decode($storeType['data'],true);
}elseif($res['rule']==4){
//按商家单独
$res=Config::getStoreSet('serviceCharge',$storeId);
}
}
return $res;
}
/**
* @param $uniacid
* @param $storeId
* @param $money
* @param $item
* @param $origin[1外卖2店内3快餐4当面付5券包6提现7.提现拒绝8.扣除手续费]
* @param $time
* @param $note
* @param $outTradeNo
* @return bool
* @throws \yii\db\Exception
*/
public static function saveStoreBill($uniacid,$storeId,$money,$item,$origin,$note,$time,$outTradeNo){
$bill['uniacid'] = $uniacid;
$bill['storeId'] = $storeId;
$bill['money'] = $money;
$bill['item'] = $item; //1.加2.减
$bill['origin'] = $origin;
$bill['createdAt'] = time();
$bill['note'] = $note;
$bill['outTradeNo'] = $outTradeNo;
$storeBill=StoreBill::getMerchantMoney($uniacid,$storeId);
$bill['currentMoney'] = $storeBill['money'];
$res=Yii::$app->db->createCommand()->insert('{{%ybwm_store_bill}}', $bill)->execute();
if($res){
return true;
}else{
return false;
}
}
//更新财务表状态
public static function updBill($outTradeNo){
$info=(new \yii\db\Query())
->from('{{%ybwm_bill}}')
->where('outTradeNo=:outTradeNo',[':outTradeNo'=>$outTradeNo])->one();
$bill=Yii::$app->db->createCommand()->update('{{%ybwm_bill}}', ['type'=>2,'changeAt'=>time()], 'outTradeNo=:outTradeNo', ['outTradeNo' =>$outTradeNo])->execute();
if($bill){
if($info['payMode']>5){
//线下支付扣除服务费
$money=bcsub($info['money'],$info['storeActualMoney'],2);
if($money>0){
self::saveStoreBill($info['uniacid'],$info['storeId'],$money,2,8,'扣除服务费',time(),$info['outTradeNo']);
}
}else{
if($info['origin']==1){
$note='外卖订单入账';
$origin=1;
}elseif($info['origin']==7){
$note='店内订单入账';
$origin=2;
}elseif($info['origin']==6){
$note='快餐订单入账';
$origin=3;
}elseif($info['origin']==5){
$note='当面付订单入账';
$origin=4;
}elseif($info['origin']==4){
$note='券包订单入账';
$origin=5;
}elseif($info['origin']==9){
$note='预约订单入账';
$origin=6;
}
self::saveStoreBill($info['uniacid'],$info['storeId'],$info['storeActualMoney'],1,$origin,$note,$info['entryAt'],$info['outTradeNo']);
}
return true;
}else{
return false;
}
}
}