| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023 |
- <?php
- namespace addons\ReservationService\common\services;
- use addons\ReservationService\common\enums\ReservationServiceEnum;
- use addons\ReservationService\common\logic\NoticeLogic;
- use addons\ReservationService\common\models\ReservationServiceGoodsSetting;
- use addons\ReservationService\common\models\ReservationServiceLevel;
- use addons\ReservationService\common\models\ReservationServiceOrder;
- use addons\ReservationService\common\models\ReservationServiceUser;
- use addons\ReservationService\common\models\ReservationServiceUserBookTime;
- use addons\SecondaryCard\common\models\SecondaryCard;
- use addons\SecondaryCard\common\models\SecondaryCardOrder;
- use addons\SecondaryCard\common\models\SecondaryCardUseLog;
- use addons\SecondaryCard\common\service\SecondaryCardOrderService;
- use addons\SecondaryCard\common\service\SecondaryCardService;
- use addons\Store\common\models\Store;
- use addons\Store\common\models\StoreClerk;
- use addons\Store\common\models\StoreGoods;
- use addons\Store\common\models\StoreGoodsReserve;
- use addons\Store\common\models\StoreGoodsReserveSku;
- use addons\Store\common\models\StoreOrder;
- use addons\Store\common\models\StoreOrderDetail;
- use addons\Store\common\models\StoreOrderMarketing;
- use addons\Store\common\models\StoreOrderReserve;
- use addons\Store\common\models\StoreReserveTechnicianScheduling;
- use addons\Store\common\services\StoreReserveSettingService;
- use common\enums\AddonsEnum;
- use common\enums\ClerkEnum;
- use common\enums\MarketingTypeEnum;
- use common\enums\OrderSourceEnum;
- use common\enums\OrderStatusEnum;
- use common\enums\PayTypeEnum;
- use common\enums\RabbitMqEnum;
- use common\enums\RefundStatusEnum;
- use common\enums\RefundTypeEnum;
- use common\enums\ShippingTypeEnum;
- use common\enums\StatusEnum;
- use common\enums\UserWalletEnum;
- use common\globals\GlobalInvoke;
- use common\helpers\FormatHelper;
- use common\helpers\LocationHelper;
- use common\logic\order\OrderRefundLogic;
- use common\models\common\ClerkLog;
- use common\models\common\Region;
- use common\models\goods\Goods;
- use common\models\goods\GoodsReserve;
- use common\models\goods\GoodsReserveSku;
- use common\models\mall\Mall;
- use common\models\mall\MallAddons;
- use common\models\order\Order;
- use common\models\order\OrderDetail;
- use common\models\order\OrderExpress;
- use common\models\order\OrderMarketing;
- use common\models\order\OrderRefund;
- use common\models\order\OrderReserve;
- use common\models\user\User;
- use services\common\UserWalletService;
- use Yii;
- use yii\helpers\Json;
- class OrderService
- {
- public function page(int $mall_id, array $params)
- {
- $where = [
- ['mall_id' => $mall_id],
- ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]],
- ];
- if(!empty($params['from'])){
- switch ($params['from']){
- case 'platform':
- $where[] = [
- 'or',
- ['>','goods_id',0],
- ['reservation_model'=>2]
- ];
- break;
- case 'store':
- $where[] = [
- 'or',
- ['>','goods_id',0],
- [
- 'and',
- ['>', 'secondary_card_id', 0],
- ['reservation_model' => 2]
- ],
- ];
- break;
- }
- }
- if (!empty($params['staff_user_id'])) {
- $where[] = ['staff_user_id' => $params['staff_user_id']];
- } else if (!empty($params['user_id'])) {
- $where[] = ['user_id' => $params['user_id']];
- } else if (!empty($params['keyword'])) {
- $uids = User::find()->where(['mall_id' => $mall_id])
- ->andWhere(['status' => StatusEnum::ENABLED])
- ->andWhere(['or', ['like', 'id', $params['keyword']], ['like', 'nickname', $params['keyword']], ['like', 'mobile', $params['keyword']]])
- ->select('id')
- ->column();
- if (empty($uids)) return [];
- $where[] = ['user_id' => $uids];
- }
- if (isset($params['service_status']) && $params['service_status'] !== '' && $params['service_status'] != 999) {
- $where[] = ['service_status' => $params['service_status']];
- }
- if (!empty($params['server_status'])) {
- $where[] = ['server_status' => $params['server_status']];
- }
- if (!empty($params['order_no'])) {
- $where[] = ['like', 'order_no', $params['order_no']];
- }
- if (!empty($params['service_type'])) {
- $where[] = ['service_type' => $params['service_type']];
- }
- if (!empty($params['create_type'])) {
- $where[] = ['create_type' => $params['create_type']];
- }
- switch ($params['time_type']){
- case 1:
- if (!empty($params['date_start'])) $where[] = ['>=', 'created_at', strtotime($params['date_start'])];
- if (!empty($params['date_end'])) $where[] = ['<=', 'created_at', strtotime($params['date_end'])];
- break;
- case 2:
- if (!empty($params['date_start'])) $where[] = ['>=', 'service_start_at', strtotime($params['date_start'])];
- if (!empty($params['date_end'])) $where[] = ['<=', 'service_start_at', strtotime($params['date_end'])];
- break;
- case 3:
- if (!empty($params['date_start'])) $where[] = ['>=', 'service_end_at', strtotime($params['date_start'])];
- if (!empty($params['date_end'])) $where[] = ['<=', 'service_end_at', strtotime($params['date_end'])];
- break;
- default:
- if (!empty($params['date_start'])) $where[] = ['>=', 'service_start_at', strtotime($params['date_start'])];
- if (!empty($params['date_end'])) $where[] = ['<=', 'service_start_at', strtotime($params['date_end'])];
- }
- if (!empty($params['reservation_model'])) {
- $where[] = ['reservation_model'=> $params['reservation_model']];
- }
- if (!empty($params['order_no'])) {
- $where[] = ['like', 'order_no', trim($params['order_no'])];
- }
- if (!empty($params['date_c_start'])) $where[] = ['>=', 'created_at', strtotime($params['date_c_start'])];
- if (!empty($params['date_c_end'])) $where[] = ['<=', 'created_at', strtotime($params['date_c_end'])];
- $with = [
- 'user',
- 'staff' => function ($q) {
- $q->where(['status' => StatusEnum::ENABLED]);
- },
- 'orderDetail',];
- // 门店
- if (!empty($params['store_id'])) {
- $where[] = ['store_id' => $params['store_id']];
- }
- $ret = ReservationServiceOrder::listPage([
- 'where' => $where,
- 'order' => 'id desc',
- 'limit' => $params['limit'] ?? 10,
- 'with' => $with
- ]);
- if (!empty(ReservationServiceOrder::getStaticError())) return ReservationServiceOrder::getStaticError();
- $ret['status_text_map'] = ReservationServiceEnum::RESERVE_ORDER_STATUS_MAP;
- $server_status_map = ReservationServiceEnum::SERVER_STATUS_MAP;
- if (!empty($ret['list'])) {
- $goods_ids = $store_goods_ids = [];
- foreach ($ret['list'] as &$item){
- if($item['store_id']){
- $store_goods_ids[]=$item['goods_id'];
- }else{
- $goods_ids[]=$item['goods_id'];
- }
- }
- $goods_list = Goods::lists(['where'=>[['id'=>$goods_ids]],'index'=>'id','select'=>'id,goods_name,cover_pic']);
- $store_goods_list = StoreGoods::lists(['where'=>[['id'=>$store_goods_ids]],'index'=>'id','select'=>'id,goods_name,cover_pic']);
- $mall_name = Yii::$app->services->setting->mall->get($mall_id, 'basic.name');
- $mall_logo = Yii::$app->services->setting->mall->get($mall_id, 'basic.logo');
- $secondary_card_order_list = [];
- //次卡部分----start
- if (MallAddons::isInstall($mall_id, 'SecondaryCard')) {
- $secondary_card_no_arr = array_column($ret['list'],'secondary_card_no');
- $secondary_card_order_list = SecondaryCardOrder::lists([
- 'where'=> [
- ['order_no'=>$secondary_card_no_arr],
- ],
- 'with'=>['secondaryCard'],
- 'index'=>'order_no'
- ]);
- $reservation_service_order_ids = array_column($ret['list'],'id');
- $use_log_list = SecondaryCardUseLog::lists(['where'=>[['reservation_service_order_id'=>$reservation_service_order_ids]],'index'=>'reservation_service_order_id']);
- }
- foreach ($ret['list'] as &$item) {
- $item['status_text'] = ReservationServiceEnum::RESERVE_ORDER_STATUS_MAP[$item['service_status']];
- $item['server_status_text'] = $server_status_map[$item['server_status']]??'';
- $item['service_start_at_text'] = "";
- $item['duration'] = ($item['service_end_at'] - $item['service_start_at']) / 60;
- $item['be_late'] = "";
- if (!empty($item['service_start_at'])){
- $item['service_start_at_text'] = date('Y-m-d H:i', $item['service_start_at']);
- if($item['service_type']== 2){
- if($item['at_store_time']){
- //已到店
- $late_time = $item['at_store_time']-$item['service_start_at'];
- }else{
- $late_time = time() - $item['service_start_at'];
- }
- if($late_time>=60){
- $item['be_late'] = '迟到';
- $day = bcdiv($late_time,86400);
- if(!empty($day)){
- $item['be_late'].= $day.'天';
- }
- $hour = bcdiv($late_time-$day*86400,3600);
- if(!empty($hour)){
- $item['be_late'].= $hour.'时';
- }
- $minute = bcdiv($late_time-$day*86400-$hour*3600,60);
- if(!empty($day)){
- $item['be_late'].= $minute.'分钟';
- }
- }
- }
- }
- $item['mall_name'] = $mall_name;
- $item['mall_logo'] = $mall_logo;
- $item['create_type_text'] = ReservationServiceEnum::CREATE_TYPE_MAP[ $item['create_type']] ?? '未知';
- if($item['store_id']){
- $item['goods']=$store_goods_list[$item['goods_id']]??[];
- }else{
- $item['goods']=$goods_list[$item['goods_id']]??[];
- }
- if (!empty($item['store_id'])) {
- $store = Store::findOne(['id' => $item['store_id']]);
- $item['mall_name'] = $store->store_name;
- $item['mall_logo'] = $store->logo_img;
- $reserveOrder = StoreOrderReserve::findOne(['main_order_id' => $item['order_id']]);
- if(empty($item['service_type'])){
- $item['service_type'] = $reserveOrder->service_type;
- }else{
- $item['service_type_text'] = ReservationServiceEnum::SERVICE_TYPE_MAP[ $item['service_type']] ?? '未知服务';
- }
- } else {
- $reserveOrder = OrderReserve::findOne(['order_id' => $item['order_id']]);
- if(empty($item['service_type'])){
- $item['service_type'] = $reserveOrder->service_type;
- }else{
- $item['service_type_text'] = ReservationServiceEnum::SERVICE_TYPE_MAP[ $item['service_type']] ?? '未知服务';
- }
- }
- $item['reserveOrder'] = [];
- if(!empty($reserveOrder)){
- $item['reserveOrder'] = $reserveOrder->toArray();
- }
- //次卡部分----start
- $item['secondary_card'] = [];
- $item['is_secondary_card'] = 0;
- if(!empty($secondary_card_order_list)&&isset($secondary_card_order_list[$item['secondary_card_no']])){
- $item['is_secondary_card'] = 1;
- $secondary_card_order = $secondary_card_order_list[$item['secondary_card_no']];
- $item['secondary_card'] = [
- 'name'=>$secondary_card_order['secondaryCard']['name'],
- 'font_color'=>$secondary_card_order['secondaryCard']['font_color'],
- 'background'=>$secondary_card_order['secondaryCard']['background'],
- 'order_no'=>$secondary_card_order['order_no'],
- 'reservation_service_order_id'=>$secondary_card_order['id'],
- ];
- $item['secondary_card']['order_source'] = \addons\SecondaryCard\common\service\SecondaryCardOrderService::getSourceName($secondary_card_order,$secondary_card_order['secondaryCard']['use_type']);
- $item['secondary_card']['service_times'] = $use_log_list[$item['id']]['clerk_nums']??1;
- $item['secondary_card']['service_income'] = $use_log_list[$item['id']]['service_income']??0;
- $item['secondary_card']['clerk_money'] = $use_log_list[$item['id']]['clerk_money']??0;
- // $item['service_type_text'] = \addons\SecondaryCard\common\service\SecondaryCardService::getServiceTypeText($secondary_card_order['secondaryCard']);
- }
- //次卡部分----end
- }
- }
- $tabsIndex = [999, 0, 1, 90, 100];
- if (!empty($params['staff_user_id'])) {
- foreach ($tabsIndex as $index) {
- $badgeQuery = ReservationServiceOrder::find()
- ->where(['mall_id' => $mall_id, 'staff_user_id' => $params['staff_user_id'], // 这里处理一下
- 'status' => StatusEnum::ENABLED]);
- $num = StatusEnum::DISABLED;
- switch ($index) {
- case ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL: // 待接单
- $num = $badgeQuery->andWhere(['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL])
- // ->andWhere(['>=', 'updated_at', time() - 86400])
- ->count();
- break;
- case ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING: // 待服务
- $num = $badgeQuery->andWhere(['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING])
- // ->andWhere(['>=', 'updated_at', time() - 86400])
- ->count();
- break;
- case ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER: // 待验收
- $num = $badgeQuery->andWhere(['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER])
- // ->andWhere(['>=', 'updated_at', time() - 86400])
- ->count();
- break;
- case ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH: // 已完成
- $num = 0;
- break;
- }
- $ret['tab_badge'][$index] = (int) $num;
- }
- }
- return $ret;
- }
- /**
- * 平台订单详情
- * @param int $mall_id
- * @param int $order_id
- * @param int $user_id
- * @param null $platform
- * @return array|mixed|string
- */
- public function orderDetail(int $mall_id, int $order_id, int $user_id = 0, $platform = null)
- {
- // 返回订单预约详情
- $select = 'id,mall_id,store_id,order_no,receiver_name,mobile,pay_money,shipping_money,original_goods_price,coupon_money,goods_price,order_status,pay_status,
- shipping_status,review_status,is_feedback,address,created_at,pay_time,region_name,remark,consign_time,finish_time,sign_time,shipping_type,payment_type,score,score_money,marketing_id,marketing_type,extra_info,order_source,is_bill';
- $where = [];
- $where[] = ['mall_id' => $mall_id];
- $where[] = ['id' => $order_id];
- if (!empty($user_id)) $where[] = ['user_id' => $user_id];
- $order = Order::getOne($where, true, ['detail' => function ($query) {
- $query->select('id,order_id,goods_id,goods_name,pic_url,num,price,is_feedback,sign_id,goods_attr_name,order_status,adjust_money,extra_info');
- }], false, $select);
- if (empty($order)) return '该订单不存在';
- $marketing = OrderMarketing::getMarketingInfo($order);
- $order['order_status_text'] = OrderStatusEnum::getMap();
- $order['is_feedback_text'] = OrderStatusEnum::getFeedbackMap();
- $order['shipping_type_text'] = ShippingTypeEnum::getMap();
- $order['payment_type_text'] = PayTypeEnum::getMap();
- $order['created_at'] = date('Y-m-d H:i:s', $order['created_at']);
- $order['pay_time'] = date('Y-m-d H:i:s', $order['pay_time']);
- if ($platform) $order['pay_type_list'] = \Yii::$app->services->pay->getEnablePayment($mall_id, $platform);
- $order['change_price'] = array_sum(array_column($order['detail'],'adjust_money'));//预留字段
- $order['marketing'] = $marketing;
- $order['marketing_type_map'] =MarketingTypeEnum::getMap();
- $order_setting = Yii::$app->services->setting->mall->get($mall_id, 'order');
- $order['payment_expire_time'] = $order_setting['payment_expire_time']??30;
- $order['auto_receiving_time'] = $order_setting['auto_receiving_time']??14;
- //查询商品单位
- if($order['detail']){
- foreach ($order['detail'] as $k => $v){
- $goods_unit = Goods::getOne([['=','id',$v['goods_id']]],false,'','','unit')['unit'];
- $order['detail'][$k]['unit'] = $goods_unit;
- }
- }
- // 获取订单详情的状态文字描述
- $order['status_text'] = OrderStatusEnum::getApiStatus($order['order_status'], $order['shipping_type']);
- $order['status'] == OrderStatusEnum::NOT_PAY && $order['status_text']['desc'] = $order['payment_expire_time'] . $order['status_text']['desc'];
- $order['status'] == OrderStatusEnum::SHIPMENTS && $order['status_text']['desc'] = $order['auto_receiving_time'] . $order['status_text']['desc'];
- $order['is_show_return_btn'] = 0;
- $order['return_prompt_content'] = '';
- $is_show_return_btn = $order_setting['is_show_return_btn'] ?? 0;
- if(empty($order['is_feedback']) && empty($order['mch_id']) && empty($order['store_id']) && $is_show_return_btn && in_array($order['order_status'], [OrderStatusEnum::SHIPMENTS,OrderStatusEnum::SING,OrderStatusEnum::PAY])){
- $order['is_show_return_btn'] = 1;
- $order['return_prompt_content'] = $order_setting['return_prompt_content'] ?? '';
- }
- if (!empty($order['store_id'])) {
- $store = Store::findOne(['id' => $order['store_id']]);
- $order['mall_name'] = $store->store_name;
- $order['mall_logo'] = $store->logo_img;
- } else {
- $order['mall_name'] = Yii::$app->services->setting->mall->get($mall_id, 'basic.name');
- $order['mall_logo'] = Yii::$app->services->setting->mall->get($mall_id, 'basic.logo');
- }
- // 公共调用
- return GlobalInvoke::exec(GlobalInvoke::ORDER_DETAIL, $mall_id, [
- 'order' => $order,
- 'mall_id' => $mall_id,
- ]) ?: $order;
- }
- /**
- * 通过订单ID获取订单详情
- * @param int $mall_id
- * @param int $user_id
- * @param int $order_id
- * @param $platform
- * @return array|mixed|string
- */
- public function getOrderDetailById(int $mall_id, int $user_id, int $order_id, $platform)
- {
- $order = $this->orderDetail($mall_id, $order_id, $user_id, $platform);
- if (is_array($order)) {
- /**
- * @var $orderReserve OrderReserve
- */
- $orderReserve = OrderReserve::getOne([
- ['mall_id' => $mall_id],
- ['order_id' => $order_id],
- ['reserve_type' => StatusEnum::ENABLED]
- ]);
- if (empty($orderReserve)) return '订单不存在';
- $order['reserve'] = $orderReserve->toArray();
- // 取出预约的服务人员
- $order['staff'] = ReservationServiceOrder::getOne([
- ['mall_id' => $mall_id],
- ['order_id' => $order_id],
- ['user_id' => $user_id],
- ['status' => StatusEnum::ENABLED],
- ], true, ['staff' => function($query) {
- $query->select('user_id, name, gender, age, avatar, store_id');
- }], 'id asc', 'id, user_id, service_status, staff_user_id, service_start_at, user_id, service_end_at');
- }
- return $order;
- }
- /**
- * 通过ID获取订单详情
- * @param int $mall_id
- * @param int $user_id
- * @param int $id
- * @return array|mixed|string
- */
- public function getDetailById(int $mall_id, int $user_id, int $id)
- {
- $rWhere = [
- ['mall_id' => $mall_id],
- ['id' => $id],
- // ['status' => StatusEnum::ENABLED],
- ['staff_user_id' => $user_id]
- ];
- // 判断当前用户是否有权限查看当前订单
- /**
- * @var $model ReservationServiceOrder
- */
- $model = ReservationServiceOrder::getOne($rWhere);
- if (empty($model)) return '预约记录不存在';
- if (!empty($model->store_id)) {
- $order_no = Order::find()->where(['mall_id' => $mall_id])
- ->andWhere(['id' => $model->order_id])
- ->select('order_no')->scalar();
- if (empty($order_no)) return '订单不存在.';
- $storeOrder = StoreOrder::findOne(['mall_id' => $mall_id, 'store_id' => $model->store_id, 'order_no' => $order_no]);
- if (empty($storeOrder)) return '订单不存在!';
- /**
- * @var $orderReserve StoreOrderReserve
- */
- $orderReserve = StoreOrderReserve::getOne([
- ['mall_id' => $mall_id],
- ['reserve_type' => StatusEnum::ENABLED],
- ['order_id' => $storeOrder->id]
- ]);
- } else {
- $where = [
- ['mall_id' => $mall_id],
- ['reserve_type' => StatusEnum::ENABLED],
- ['order_id' => $model->order_id]
- ];
- /**
- * @var $orderReserve OrderReserve
- */
- $orderReserve = OrderReserve::getOne($where);
- }
- if (empty($orderReserve)) return '订单不存在';
- $order = $this->orderDetail($mall_id, $model->order_id);
- if (is_array($order)) {
- $order['user'] = $model->getUser()->select('id, nickname, avatar_url, mobile')->one()->toArray();
- $order['reserve'] = $orderReserve->toArray();
- $order['service_status_map'] = [
- 0 => '待接单',
- 1 => '待核销',
- 20 => '已取消接单',
- 50 => '拒绝接单',
- 70 => '已关闭',
- 90 => '已核销',
- 100 => '已完成'
- ];
- // $order['service_status_map'] = ReservationServiceEnum::RESERVE_ORDER_STATUS_MAP;
- foreach ($order['detail'] as $val) {
- if ($val['order_status'] == -4) {
- $model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_CLOSED;
- break;
- }
- }
- $order['service_status_text'] = $order['service_status_map'][$model->service_status] ?? '未知状态';
- $order['service_start_at_text'] = date('Y-m-d H:i', $model->service_start_at);
- $order['service_min'] = ($model->service_end_at - $model->service_start_at) / 60; // 分钟
- $order['service_status'] = $model->service_status;
- $order['service_type'] = $orderReserve->service_type; // 是否为上面服务
- $order['create_type'] = $model->create_type;
- $order['commission'] = bcmul($model->commission, 1, 2);
- $order['service_type_text'] = ReservationServiceEnum::SERVICE_TYPE_MAP[$orderReserve->service_type] ?? '未知服务';
- if (!empty($order['finish_time'])) date('Y-m-d H:i:s', $order['finish_time']);
- if (!empty($order['sign_time'])) date('Y-m-d H:i:s', $order['sign_time']);
- }
- //次卡部分
- if(!empty($model->secondary_card_id)){
- if (MallAddons::isInstall($mall_id,'SecondaryCard')){
- $secondary_card = SecondaryCard::findOne(['id'=>$model->secondary_card_id]);
- $order['secondary_card'] = [
- 'name' => $secondary_card['name'],
- 'background' => $secondary_card['background'],
- 'font_color' => $secondary_card['font_color'],
- 'reservation_cancel_type' => $secondary_card['reservation_cancel_type'],
- 'service' => json_decode($secondary_card['service'],true),
- 'secondary_card_no' => $model->secondary_card_no,
- ];
- $order['service_type_text'] = SecondaryCardService::getServiceTypeText($secondary_card);
- $secondary_card_order = SecondaryCardOrder::findOne(['order_no'=>$model->secondary_card_no]);
- $order['secondary_card']['verifiable_times'] =$secondary_card_order['verifiable_times'];
- $order['secondary_card']['use_times'] =$secondary_card['verifiable_times']-$secondary_card_order['verifiable_times'];
- $order['secondary_card']['clerk_code'] = $secondary_card_order['clerk_code'];
- $order['secondary_card']['order_source'] = SecondaryCardOrderService::getSourceName($secondary_card_order,$secondary_card['use_type']);
- $use_log = SecondaryCardUseLog::findOne(['reservation_service_order_id'=>$model['id']]);
- $order['secondary_card']['order_money'] = bcdiv($secondary_card_order['pay_money'],$secondary_card['verifiable_times'],2) ;
- $order['secondary_card']['service_income'] = $use_log['service_income']??0;
- $order['secondary_card']['service_times'] = $use_log['clerk_nums']??1;
- $order['secondary_card']['clerk_money'] = $use_log['clerk_money']??0;
- }
- }
- return $order;
- }
- /**
- * 扫码获取的订单详情
- * @param int $mall_id
- * @param int $user_id
- * @param string $code
- * @param int $order_id
- * @param int $store_id
- * @return array|mixed|string
- */
- public function getDetailByCodeOrId(int $mall_id, int $user_id, string $code = '', int $order_id = 0, int $store_id = 0)
- {
- // 这里无效了
- if (!empty($store_id)) {
- if (empty($order_id)) return '订单ID不能为空';
- $order_no = Order::find()->where(['mall_id' => $mall_id])
- ->andWhere(['id' => $order_id])
- ->select('order_no')->scalar();
- if (empty($order_no)) return '订单不存在.';
- $storeOrder = StoreOrder::findOne(['mall_id' => $mall_id, 'store_id' => $store_id, 'order_no' => $order_no]);
- if (empty($storeOrder)) return '订单不存在!';
- /**
- * @var $orderReserve StoreOrderReserve
- */
- $orderReserve = StoreOrderReserve::getOne([
- ['mall_id' => $mall_id],
- ['reserve_type' => StatusEnum::ENABLED],
- ['order_id' => $storeOrder->id]
- ]);
- if (empty($orderReserve)) return '订单不存在';
- if ($orderReserve['service_type'] == 1) {
- $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $mall_id, 'store_id' => $store_id]))->detail();
- if (empty($store_reserve_setting['technician_verification_switch'])) {
- throw new \Exception('技师核销开关未开启');
- }
- }
- } else {
- $where = [
- ['mall_id' => $mall_id],
- ['reserve_type' => StatusEnum::ENABLED]
- ];
- if (!empty($code)) $where[] = ['reserve_code' => $code];
- if (!empty($order_id)) $where[] = ['order_id' => $order_id];
- /**
- * @var $orderReserve OrderReserve
- */
- $orderReserve = OrderReserve::getOne($where);
- if (empty($orderReserve)) {
- /**
- * @var $orderReserve StoreOrderReserve
- */
- $orderReserve = StoreOrderReserve::getOne([
- ['mall_id' => $mall_id],
- ['reserve_type' => StatusEnum::ENABLED],
- ['reserve_code' => $code]
- ]);
- if (empty($orderReserve)) return '订单不存在';
- $order_id = $orderReserve->main_order_id;
- $store_id = $orderReserve->store_id;
- $this->checkClerk($user_id, $store_id, $orderReserve['tech_id'], $orderReserve['service_type']);
- } else {
- $order_id = $orderReserve->order_id;
- }
- }
- $rWhere = [
- ['mall_id' => $mall_id],
- ['order_id' => $order_id],
- ['status' => StatusEnum::ENABLED],
- ];
- if (!empty($store_id)) {
- $rWhere[] = ['store_id' => $store_id];
- } else {
- $rWhere[] = ['staff_user_id' => $user_id];
- }
- // 判断当前用户是否有权限查看当前订单
- /**
- * @var $model ReservationServiceOrder
- */
- $model = ReservationServiceOrder::getOne($rWhere, false, [], 'id desc');
- if (empty($model)) return '预约记录不存在';
- if (!empty($store_id)) {
- $user_id = $model['staff_user_id'];////替换成技师的会员id
- }
- // self::checkStoreStaffCanClerk($mall_id, $store_id, $user_id);
- $order = $this->orderDetail($mall_id, $model->order_id);
- if (is_array($order)) {
- $order['user'] = $model->getUser()->select('id, nickname, avatar_url, mobile')->one()->toArray();
- $order['reserve'] = $orderReserve->toArray();
- $order['service_status_map'] = [
- 1 => '待核销',
- 70 => '已关闭',
- 90 => '已核销',
- 100 => '已完成'
- ];
- $order['service_status_text'] = $order['service_status_map'][$model->service_status] ?? '未知状态';
- $order['service_start_at_text'] = date('Y-m-d H:i', $model->service_start_at);
- }
- return $order;
- }
- /**
- * 检查门店技师在当前时间是否可以核销
- * @param $store_id
- * @param $user_id
- * @return true
- * @throws \Exception
- */
- public static function checkStoreStaffCanClerk($mall_id, $store_id, $user_id)
- {
- if (empty($store_id)) {
- return true;
- }
- $time = time();
- $date = date('Y-m-d', $time);
- $date_time = strtotime($date . ' 00:00:00');
- $scheduling = StoreReserveTechnicianScheduling::find()->where(['mall_id' => $mall_id, 'store_id' => $store_id, 'user_id' => $user_id, 'date_time' => $date_time, 'status' => StatusEnum::ENABLED])
- ->with(['schedulingTime'])->one();
- if (!empty($scheduling['is_all_day'])) {
- $store = Store::findOne(['id' => $store_id, 'mall_id' => $mall_id]);
- $business_time_start = strtotime($date . ' ' . $store['business_time_start'] . ':00');
- $business_time_end = strtotime($date . ' ' . $store['business_time_end'] . ':00');
- if ($time < $business_time_start || $time > $business_time_end) {
- throw new \Exception('当前时间不是门店营业时间');
- }
- } else {
- if (empty($scheduling['schedulingTime'])) {
- throw new \Exception('当前时间技师没有排班');
- }
- $is_true = false;
- foreach ($scheduling['schedulingTime'] as $val) {
- if ($time >= $val['start_time'] && $time <= $val['end_time']) {
- $is_true = true;
- break;
- }
- }
- if ($is_true == false) {
- throw new \Exception('当前时间技师没有排班');
- }
- }
- return true;
- }
- /**
- * 获取核销记录详情
- * @Author:hua
- * @Date:2024-03-14 10:26
- * @Copyright:copyright(c)2024 广东七件事集团
- * @param $mall_id
- * @param $reservation_service_order_id
- * @param $order_id
- * @return array|mixed|string
- */
- public function getClerkLogDetail( $mall_id, $reservation_service_order_id , $order_id )
- {
- $where = [
- ['mall_id' => $mall_id],
- ['reserve_type' => StatusEnum::ENABLED],
- ['order_id' => $order_id]
- ];
- $orderReserve = OrderReserve::getOne($where);
- if (empty($orderReserve)) {
- $orderReserve = StoreOrderReserve::getOne([
- ['mall_id' => $mall_id],
- ['reserve_type' => StatusEnum::ENABLED],
- ['main_order_id' => $order_id]
- ]);
- if (empty($orderReserve)) return '订单不存在';
- }
- $rWhere = [
- ['mall_id' => $mall_id],
- ['id' => $reservation_service_order_id],
- ['status' => StatusEnum::ENABLED],
- ];
- $model = ReservationServiceOrder::getOne($rWhere);
- if (empty($model)) return '预约记录不存在';
- $order = $this->orderDetail($mall_id, $model->order_id);
- if (is_array($order)) {
- $order['user'] = $model->getUser()->select('id, nickname, avatar_url, mobile')->one()->toArray();
- $order['reserve'] = $orderReserve->toArray();
- $order['service_status_map'] = [
- 1 => '待核销',
- 90 => '已核销',
- 100 => '已完成'
- ];
- $order['service_status_text'] = $order['service_status_map'][$model->service_status] ?? '未知状态';
- $order['service_start_at_text'] = date('Y-m-d H:i', $model->service_start_at);
- }
- return $order;
- }
- /**
- * 通过订单ID进行核销
- * @param int $mall_id
- * @param int $user_id
- * @param int $order_id
- * @param int $store_id
- * @return ReservationServiceOrder|string
- */
- public function underwriter(int $mall_id, int $user_id, int $order_id, int $store_id = 0)
- {
- $where = [
- ['mall_id' => $mall_id],
- ['order_id' => $order_id],
- ['status' => StatusEnum::ENABLED],
- ['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING],
- ];
- // 门店核销,门店所有技师都能进行核销处理,所以不需要绑定至某个用户,只需要判断当前用户是否为门店技师即可
- if (!empty($store_id)) {
- $where[] = ['store_id' => $store_id];
- } else {
- $where[] = ['staff_user_id' => $user_id];
- }
- /**
- * @var $model ReservationServiceOrder
- */
- $model = ReservationServiceOrder::getOne($where);
- if (empty($model)) return '预约记录不存在或不可核销';
- $t = \Yii::$app->db->beginTransaction();
- try {
- $model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER;
- $model->remark = "{$model->remark} 技师 [$user_id] 核销了当前订单 \n";
- if (!$model->save()) throw new \Exception($model->getErrorMessage());
- /**
- * @var $staff ReservationServiceUser
- */
- $staff = $model->getStaff()->one();
- // 累加订单
- if (!empty($model->store_id)) {
- $staff->store_order_num += 1;
- } else {
- $staff->order_num += 1;
- }
- if (!$staff->save()) throw new \Exception($staff->getErrorMessage());
- $user = User::findOne(['id' => $user_id]);
- $data['id'] = $order_id;
- $data['mall_id'] = $mall_id;
- $data['user_id'] = $model->user_id;
- $data['operator_id'] = $user_id;
- $data['operator_name'] = $user->nickname ?? $user->mobile;
- $data['from'] = OrderSourceEnum::SOURCE_RESERVE;
- $data['tech_id'] = $staff->id; // 技师ID
- $res = Order::takeDelivery($data);
- if ($res === false) throw new \Exception(Order::getStaticError());
- if (!empty($model->store_id)) {
- $orderReserve = StoreOrderReserve::findOne(['main_order_id' => $model->order_id]);
- if (empty($orderReserve)) throw new \Exception("预约订单不存在");
- } else {
- $orderReserve = OrderReserve::findOne(['order_id' => $model->order_id]);
- if (empty($orderReserve)) throw new \Exception("预约订单不存在");
- }
- $orderReserve->reserve_status = ReservationServiceEnum::CHECK_FAILED;
- // 如果是在后台直接核销的那么就没办法绑定技师了,所以一定需要技师进行核销才能处理
- if (empty($orderReserve->tech_id)) $orderReserve->tech_id = $staff->id; // 绑定技师ID
- if (!$orderReserve->save()) throw new \Exception($orderReserve->getErrorMessage());
- $t->commit();
- return $model;
- } catch (\Exception $e) {
- $t->rollBack();
- return $e->getMessage();
- }
- }
- /**
- * 通过核销码进行核销
- * @param int $mall_id
- * @param int $user_id
- * @param int $order_id
- * @param int $store_id
- * @return ReservationServiceOrder|string
- */
- public function clerk(int $mall_id, int $user_id, int $code, int $store_id = 0)
- {
- $where = [
- ['mall_id' => $mall_id],
- ['reserve_type' => StatusEnum::ENABLED]
- ];
- if (!empty($code)) $where[] = ['reserve_code' => $code];
- if (!empty($order_id)) $where[] = ['order_id' => $order_id];
- /**
- * @var $orderReserve OrderReserve
- */
- $orderReserve = OrderReserve::getOne($where);
- $service_type_text = ReservationServiceEnum::SERVICE_TYPE_MAP[$orderReserve['service_type']] ?? '';
- $mall_logo = Yii::$app->services->setting->mall->get($mall_id, 'basic.logo');
- $mall = Mall::findOne(['id'=>$mall_id]);
- $mall_name = $mall['name'];
- if (empty($orderReserve)) {
- /**
- * @var $orderReserve StoreOrderReserve
- */
- $orderReserve = StoreOrderReserve::getOne([
- ['mall_id' => $mall_id],
- ['reserve_type' => StatusEnum::ENABLED],
- ['reserve_code' => $code]
- ]);
- if (empty($orderReserve)) return '订单不存在';
- $this->checkClerk($user_id, $orderReserve->store_id, $orderReserve['tech_id'], $orderReserve['service_type']);
- $order_id = $orderReserve->main_order_id;
- $store_id = $orderReserve->store_id;
- $service_type_text = ReservationServiceEnum::SERVICE_TYPE_MAP[$orderReserve['service_type']] ?? '';
- $store = Store::findOne(['id' => $orderReserve['store_id']]);
- $mall_logo = $store['logo_img'];
- $mall_name = $store['store_name'];
- } else {
- $order_id = $orderReserve->order_id;
- }
- $order = Order::findOne(['id'=>$order_id]);
- $order_detail = OrderDetail::findOne(['order_id'=>$order_id]);
- $num = OrderDetail::find()->where(['order_id'=>$order_id])->sum('num');
- $where = [
- ['mall_id' => $mall_id],
- ['order_id' => $order_id],
- ['status' => StatusEnum::ENABLED],
- ['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING],
- ];
- $clerk_user_id = $user_id;//操作核销的会员id
- if (!empty($store_id)) {
- $where[] = ['store_id' => $store_id];
- } else {
- $where[] = ['staff_user_id' => $user_id];
- }
- /**
- * @var $model ReservationServiceOrder
- */
- $model = ReservationServiceOrder::getOne($where);
- if (empty($model)) return '预约记录不存在或不可核销';
- if (!empty($store_id)) {
- $user_id = $model['staff_user_id'];//替换成技师的会员id
- }
- // self::checkStoreStaffCanClerk($mall_id, $store_id, $user_id);
- $t = \Yii::$app->db->beginTransaction();
- try {
- $model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER;
- $model->server_status = ReservationServiceEnum::TO_BE_ACCEPTED;
- $model->remark = "{$model->remark} , [$clerk_user_id] 核销了当前订单 \n";
- if (!$model->save()) throw new \Exception($model->getErrorMessage());
- /**
- * @var $staff ReservationServiceUser
- */
- $staff = $model->getStaff()->one();
- if (empty($staff)) {
- throw new \Exception('该订单未分配技师,不能核销');
- }
- // 累加订单
- if (!empty($model->store_id)) {
- $staff->store_order_num += 1;
- } else {
- $staff->order_num += 1;
- }
- if (!$staff->save()) throw new \Exception($staff->getErrorMessage());
- $user = User::findOne(['id' => $user_id]);
- $data['id'] = $order_id;
- $data['mall_id'] = $mall_id;
- $data['user_id'] = $model->user_id;
- $data['operator_id'] = $user_id;
- $data['operator_name'] = $user->nickname ?? $user->mobile;
- $data['from'] = OrderSourceEnum::SOURCE_RESERVE;
- $data['tech_id'] = $staff->id; // 技师ID
- $res = Order::takeDelivery($data);
- if ($res === false) throw new \Exception(Order::getStaticError());
- // 因为进行核销后平台预约订单和门店预约订单状态并为改为待服务,所以进行核销后需要修改
- Order::updateAll(['order_status' => OrderStatusEnum::SING], ['id' => $model->order_id]);
- if (!empty($model->store_id)) {
- StoreOrder::updateAll(['order_status' => OrderStatusEnum::SING], ['id' => $orderReserve->order_id]);
- $orderReserve = StoreOrderReserve::findOne(['main_order_id' => $model->order_id]);
- if (empty($orderReserve)) throw new \Exception("预约订单不存在");
- } else {
- $orderReserve = OrderReserve::findOne(['order_id' => $model->order_id]);
- if (empty($orderReserve)) throw new \Exception("预约订单不存在");
- }
- $orderReserve->reserve_status = OrderReserve::RESERVE_STATUS_PENDDING;
- // 如果是在后台直接核销的那么就没办法绑定技师了,所以一定需要技师进行核销才能处理
- if (empty($orderReserve->tech_id)) $orderReserve->tech_id = $staff->id; // 绑定技师ID
- if (!$orderReserve->save()) throw new \Exception($orderReserve->getErrorMessage());
- $add_clerk_log_data = [
- 'mall_id' => $model['mall_id'],
- 'user_id' => $clerk_user_id,
- 'mall_logo' => $mall_logo,
- 'mall_name' => $mall_name,
- 'name' => $order_detail['goods_name'],
- 'pic' => $order_detail['pic_url'],
- 'clerk_code' => (string)$code,
- 'type' => ClerkEnum::RESERVATION_SERVICE_CLERK_CODE_PRE,
- 'extra' => json_encode([
- 'clerk_nums' => $num,
- 'verifiable_times' => 0,
- 'clerk_money' => 0,
- 'settled_money' => 0,
- 'order_money' => $order['pay_money'],
- 'pay_money' => $order['pay_money'],
- 'unit_times' => 0,
- 'service_type_text' => $service_type_text,
- 'service_income'=> $model['commission'],
- 'reservation_service_order_id'=> $model['id'],
- 'order_id'=> $order_id,
- ]),
- ];
- $clerk_log_model = ClerkLog::setData($add_clerk_log_data);
- if ($clerk_log_model == false) {
- throw new \Exception(ClerkLog::getStaticError());
- }
- $t->commit();
- return $model;
- } catch (\Exception $e) {
- $t->rollBack();
- \Yii::error('code:' . $code . ';;;' . $e->getMessage());
- return $e->getMessage();
- }
- }
- public function checkClerk($user_id, $store_id, $tech_id, $service_type)
- {
- $store = Store::findOne(['user_id' => $user_id, 'status' => StatusEnum::ENABLED]);
- //先判断是不是本店店长
- if (!empty($store)) {
- if ($store_id != $store['id']) {
- $reservation_service_user = ReservationServiceUser::findOne(['user_id' => $user_id, 'store_id' => $store_id, 'status' => StatusEnum::ENABLED]);
- if ($store_id != $reservation_service_user['store_id'] || $tech_id != $reservation_service_user['id']) {
- throw new \Exception('该订单你没有权限核销');
- }
- }
- } else {
- $reservation_service_user = ReservationServiceUser::findOne(['user_id' => $user_id, 'store_id' => $store_id, 'status' => StatusEnum::ENABLED]);
- if (empty($reservation_service_user)) {
- //不是店长,先判断是不是本店核销员
- $store_clerk = StoreClerk::findOne(['user_id' => $user_id, 'status' => StatusEnum::ENABLED]);
- if (empty($store_clerk) || $store_id != $store_clerk['store_id']) {
- throw new \Exception('该订单你没有权限核销');
- }
- } else {
- //技师,判断是不是同一个技师
- if ($store_id != $reservation_service_user['store_id'] || $tech_id != $reservation_service_user['id']) {
- throw new \Exception('该订单你没有权限核销');
- }
- if ($service_type == 1) {
- $store_reserve_setting = (new StoreReserveSettingService(['mall_id' => $reservation_service_user['mall_id'], 'store_id' => $store_id]))->detail();
- if (empty($store_reserve_setting['technician_verification_switch'])) {
- throw new \Exception('技师核销开关未开启');
- }
- }
- }
- }
- }
- /**
- * 接受订单
- * @param int $mall_id
- * @param int $user_id
- * @param int $order_id
- * @param int $store_id
- * @return ReservationServiceOrder|string
- */
- public function talking(int $mall_id, int $user_id, int $order_id, int $store_id = 0)
- {
- $where = [
- ['mall_id' => $mall_id],
- ['order_id' => $order_id],
- ['status' => StatusEnum::ENABLED],
- ['staff_user_id' => $user_id],
- ['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL]
- ];
- if (!empty($store_id)) $where[] = ['store_id' => $store_id];
- /**
- * @var $model ReservationServiceOrder
- */
- $model = ReservationServiceOrder::getOne($where);
- if (empty($model)) return '预约记录不存在';
- $t = \Yii::$app->db->beginTransaction();
- try {
- $model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING;
- $model->remark = "{$model->remark} 技师 [$user_id] 接受了当前订单的预约 \n";
- if (!$model->save()) throw new \Exception($model->getErrorMessage());
- // 同意之后是否需要写入预约时间?
- // 并且写入技师ID
- $staff = ReservationServiceUser::findOne(['user_id' => $user_id, 'status' => StatusEnum::ENABLED]);
- if (!empty($model->store_id)) {
- // 取出门店的预约订单
- $orderReserve = StoreOrderReserve::findOne(['main_order_id' => $order_id]);
- if (empty($orderReserve)) throw new \Exception("预约订单不存在");
- } else {
- $orderReserve = OrderReserve::findOne(['order_id' => $model->order_id]);
- if (empty($orderReserve)) throw new \Exception("预约订单不存在");
- }
- $orderReserve->tech_id = $staff->id;
- $orderReserve->reserve_status = StatusEnum::ENABLED;
- $orderReserve->reserve_date_time = date('Y-m-d H:i', $model->service_start_at) .','. date('Y-m-d H:i', $model->service_end_at);
- if (!$orderReserve->save()) throw new \Exception($orderReserve->getErrorMessage());
- // 被预约的时间
- $bookTime = new ReservationServiceUserBookTime();
- $bookTime->order_id = $model->order_id;
- $bookTime->user_id = $model->staff_user_id;
- $bookTime->mall_id = $model->mall_id;
- $bookTime->start_time = $model->service_start_at;
- $bookTime->end_time = $model->service_end_at;
- if (!$bookTime->save()) throw new \Exception($bookTime->getErrorMessage());
- $user = User::findOne(['id' => $user_id]);
- if(!empty($model->secondary_card_id)){
- $form['mall_id'] = $model->mall_id;
- $form['mch_id'] = 0;
- $form['shipping_type'] = 0;
- $form['id'] = $model->order_id;
- $form['operator_id'] = $user_id;
- $form['order_detail_ids'] = OrderDetail::find()->where(['order_id' => $model->order_id])->select('id')->column();
- $form['operator_name'] = !empty($user->nickname) ? $user->nickname : $user->mobile;
- OrderExpress::delivery($form); // 发货
- $form['mall_id'] = $mall_id;
- $form['shipping_type'] = 0;
- $form['mch_id'] = 0;
- $form['store_id'] = $model->store_id;
- $form['operator_id'] = $model->staff_user_id;
- $form['operator_name'] = !empty($user->nickname) ? $user->nickname : $user->mobile;
- $form['id'] = $orderReserve->order_id;
- $form['order_detail_ids'] = StoreOrderDetail::find()->where(['order_id' => $orderReserve->order_id])->select('id')->column();
- $res = StoreOrder::OrderExpressDelivery($form);
- if (!$res) throw new \Exception(StoreOrder::getStaticError());
- }else{
- if (empty($model->store_id)) { // 门店也需要执行?
- // 执行发货操作
- $form['mall_id'] = $model->mall_id;
- $form['mch_id'] = 0;
- $form['shipping_type'] = 0;
- $form['id'] = $model->order_id;
- $form['operator_id'] = $user_id;
- $form['order_detail_ids'] = OrderDetail::find()->where(['order_id' => $model->order_id])->select('id')->column();
- $form['operator_name'] = !empty($user->nickname) ? $user->nickname : $user->mobile;
- OrderExpress::delivery($form); // 发货
- } else { // 门店发货
- $form['mall_id'] = $mall_id;
- $form['shipping_type'] = 0;
- $form['mch_id'] = 0;
- $form['store_id'] = $model->store_id;
- $form['operator_id'] = $model->staff_user_id;
- $form['operator_name'] = !empty($user->nickname) ? $user->nickname : $user->mobile;
- $form['id'] = $orderReserve->order_id;
- $form['order_detail_ids'] = StoreOrderDetail::find()->where(['order_id' => $orderReserve->order_id])->select('id')->column();
- $res = StoreOrder::OrderExpressDelivery($form);
- if (!$res) throw new \Exception(StoreOrder::getStaticError());
- }
- }
- $main_order = Order::findOne(['order_no' => $model['order_no']]);
- $main_order->order_status = OrderStatusEnum::SHIPMENTS;
- $main_order->shipping_time = time();
- $main_order->save();
- $t->commit();
- // 记录数据
- (new NoticeLogic())->send(['mall_id' => $mall_id, 'id' => $order_id, 'sms_key' => ReservationServiceEnum::SMS_KEY_AGREE]);
- return $model;
- } catch (\Exception $e) {
- $t->rollBack();
- return $e->getMessage().$e->getFile().$e->getLine();
- }
- }
- /**
- * 拒绝接单
- * @param int $mall_id
- * @param int $user_id
- * @param int $order_id
- * @param int $store_id
- * @param string $reason
- * @return ReservationServiceOrder|string
- */
- public function reject(int $mall_id, int $user_id, int $order_id, int $store_id = 0, string $reason = '无')
- {
- $where = [
- ['mall_id' => $mall_id],
- ['order_id' => $order_id],
- ['status' => StatusEnum::ENABLED],
- ['staff_user_id' => $user_id],
- ['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL]
- ];
- if (!empty($store_id)) $where[] = ['store_id' => $store_id];
- /**
- * @var $model ReservationServiceOrder
- */
- $model = ReservationServiceOrder::getOne($where);
- if (empty($model)) return '预约记录不存在';
- $t = \Yii::$app->db->beginTransaction();
- try {
- $remark = "{$model->remark} 技师 [$user_id] 拒绝了当前订单的预约, 拒绝理由[$reason] \n";
- if($model->secondary_card_id){
- $order = Order::findOne(['id'=>$model->order_id]);
- $order->status = StatusEnum::DISABLED;
- $order->save();
- StoreOrder::updateAll(['status'=>StatusEnum::DISABLED],['order_no'=>$order->order_no]);
- $remark = "{$model->remark} 技师 [$user_id] 拒绝了当前次卡的预约, 拒绝理由[$reason] \n";
- }
- $model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_REJECT;
- $model->remark = $remark;
- $model->reject_reason = $reason;
- if (!$model->save()) throw new \Exception($model->getErrorMessage());
- if (!empty($model->store_id)) {
- /**
- * @var $reserveOrder StoreOrderReserve
- */
- $reserveOrder = StoreOrderReserve::getOne(['main_order_id' => $model['order_id']]);
- } else {
- /**
- * @var $reserveOrder OrderReserve
- */
- $reserveOrder = $model->getReserveOrder()->one();
- }
- $reserveOrder->reserve_status = OrderReserve::RESERVE_STATUS_WAIT; // 等待预约
- $reserveOrder->tech_id = 0;
- if (!$reserveOrder->save()) throw new \Exception($reserveOrder->getErrorMessage());
- $t->commit();
- // 记录数据
- (new NoticeLogic())->send(['mall_id' => $mall_id, 'id' => $order_id, 'sms_key' => ReservationServiceEnum::SMS_KEY_REJECT]);
- return $model;
- } catch (\Exception $e) {
- $t->rollBack();
- return $e->getMessage();
- }
- }
- /**
- * 取消预约
- * @param int $mall_id
- * @param int $user_id
- * @param int $order_id
- * @param int $store_id
- * @param bool $is_buyer
- * @return ReservationServiceOrder|string
- */
- public function cancel(int $mall_id, int $user_id, int $order_id, int $store_id = 0, bool $is_buyer = false)
- {
- $where = [
- ['mall_id' => $mall_id],
- ['order_id' => $order_id],
- ['status' => StatusEnum::ENABLED],
- // ['staff_user_id' => $user_id],
- ['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING]
- ];
- if ($is_buyer) {
- $role = '用户';
- $where[] = ['user_id' => $user_id];
- } else {
- $role = '技师';
- $where[] = ['staff_user_id' => $user_id];
- }
- if (!empty($store_id)) $where[] = ['store_id' => $store_id];
- /**
- * @var $model ReservationServiceOrder
- */
- $model = ReservationServiceOrder::getOne($where);
- if (empty($model)) return '预约记录不存在';
- $t = \Yii::$app->db->beginTransaction();
- try {
- $model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_CANCEL;
- $model->remark = "{$model->remark} {$role} [$user_id] 取消了当前订单的预约 \n";
- if (!$model->save()) throw new \Exception($model->getErrorMessage());
- if (!empty($model->store_id)) {
- $storeOrder = StoreOrder::findOne(['order_no' => $model->order_no]);
- if (empty($storeOrder)) throw new \Exception("预约订单不存在");
- $orderReserve = StoreOrderReserve::findOne(['order_id' => $storeOrder->id]);
- if (empty($orderReserve)) throw new \Exception("预约订单不存在");
- } else {
- $orderReserve = OrderReserve::findOne(['order_id' => $model->order_id]);
- if (empty($orderReserve)) throw new \Exception("预约订单不存在");
- }
- $orderReserve->tech_id = 0;
- $orderReserve->reserve_status = 0;
- // $orderReserve->reserve_date_time = '';
- if (!$orderReserve->save()) throw new \Exception($orderReserve->getErrorMessage());
- // 清除预约时间
- ReservationServiceUserBookTime::updateAll(['status' => StatusEnum::DELETE],
- ['and', ['status' => StatusEnum::ENABLED], ['order_id' => $model->order_id]]);
- // 清除发货信息
- if (empty($model->store_id)) {
- $order = Order::findOne(['id' => $order_id]);
- $order->sign_time = 0;
- $order->order_status = OrderStatusEnum::PAY;
- $order->shipping_status = StatusEnum::DISABLED;
- if (!$order->save()) throw new \Exception($order->getErrorMessage());
- // 清除详情发货信息
- OrderDetail::updateAll(['order_status' => OrderStatusEnum::PAY, 'shipping_status' => StatusEnum::DISABLED],
- ['in', 'id', OrderDetail::find()->where(['order_id' => $order_id])->select('id')->column()]);
- }
- if($model->secondary_card_id>0){
- $order = Order::findOne(['id' => $model->order_id]);
- $order->status = StatusEnum::DISABLED;
- if (!$order->save()) throw new \Exception($order->getErrorMessage());
- }
- $t->commit();
- return $model;
- } catch (\Exception $e) {
- $t->rollBack();
- return $e->getMessage();
- }
- }
- /**
- * 验收 - 等同于平台订单确认收货 - 门店后台/门店技师/技师
- * @param int $mall_id
- * @param int $order_id
- * @param int $user_id
- * @param int $store_id
- * @param null $admin
- * @param bool $run_global
- * @return ReservationServiceOrder|string
- */
- public function acceptance(int $mall_id, int $order_id, int $user_id = 0, int $store_id = 0, $admin = null, bool $run_global = true)
- {
- $where = [
- ['mall_id' => $mall_id],
- ['order_id' => $order_id],
- ['status' => StatusEnum::ENABLED],
- ['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER]
- ];
- if (!empty($store_id)) $where[] = ['store_id' => $store_id];
- if (!empty($user_id)) $where[] = ['user_id' => $user_id];
- /**
- * @var $model ReservationServiceOrder
- */
- $model = ReservationServiceOrder::getOne($where);
- if (empty($model)) return !$run_global ? '预约记录不存在' : true;
- if ($model->service_status == ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH) return $model;
- if ($model->service_status != ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER) return '当前状态不可验收';
- $t = \Yii::$app->db->beginTransaction();
- try {
- // 门店核销员
- if (!empty($user_id)) {
- $remark = "用户 [$user_id] 验收了当前预约订单";
- } elseif (!empty($store_id)) {
- $remark = "门店 [$store_id] 验收了当前预约订单";
- } elseif (!empty($admin)) {
- $remark = "后台雇员 [$admin->id] 验收了当前预约订单";
- } else {
- $remark = "系统自动验收了当前预约订单";
- }
- $model->service_status = ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH;
- $model->remark = "{$model->remark} $remark \n";
- $model->server_status = ReservationServiceEnum::COMPLETED;
- // $model->service_status = 100;
- if (!$model->save()) throw new \Exception($model->getErrorMessage());
- // 执行平台的处理
- if ($run_global) {
- $this->globalComplete($mall_id, $user_id, $model, $admin);
- }
- // 累加订单
- if (!empty($model->store_id)) {
- $staff = $model->getStaff()->one();
- $staff->store_order_num += 1;
- $staff->save();
- }
- $t->commit();
- return $model;
- } catch (\Exception $e) {
- $t->rollBack();
- Yii::error(FormatHelper::exception($e, __METHOD__));
- return $e->getMessage();
- }
- }
- /**
- * @param int $mall_id
- * @param int $user_id
- * @param ReservationServiceOrder $reservationServiceOrder
- * @param $admin
- * @return void
- * @throws \Exception
- */
- protected function globalComplete(int $mall_id, int $user_id, ReservationServiceOrder $reservationServiceOrder, $admin)
- {
- $nickname = "";
- $mobile = "";
- $operator_id = $user_id;
- if (!empty($admin)) {
- $nickname = $admin->account;
- $operator_id = $admin->id;
- } else if (!empty($user_id)) {
- /**
- * @var $user User
- */
- $user = User::findOne(['id' => $user_id]);
- $nickname = $user->nickname;
- $mobile = $user->mobile;
- }
- $data['id'] = $reservationServiceOrder->order_id;
- $data['mall_id'] = $mall_id;
- if (!empty($user)) $data['user_id'] = $user_id;
- $data['operator_id'] = $operator_id;
- $data['operator_name'] = !empty($nickname) ? $nickname : $mobile;
- $data['from'] = OrderSourceEnum::SOURCE_RESERVE;
- $res = Order::complete($data);
- if ($res === false) throw new \Exception(Order::getStaticError());
- }
- /**
- * @param int $mall_id
- * @param int $store_id
- * @return int[]
- */
- public function dataStatistics(int $mall_id, int $store_id = 0)
- {
- // 累计服务数量
- // 昨日服务数量
- $query = ReservationServiceOrder::find()->where(['mall_id' => $mall_id])
- ->andWhere(['status' => StatusEnum::ENABLED])
- // ->andWhere(['service_status' => [ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH, ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER]]);
- // 修改原因:现在按核销数量来计算,核销后,就会有核销备注“XXX核销了订单”,所以用备注不为空来计算
- ->andWhere(['!=', 'remark', '']);
- if (!empty($store_id)) $query->andWhere(['store_id' => $store_id]);
- $y = strtotime(date('Y-m-d')) - 86400;
- return [
- 'total' => $query->count(),
- 'yesterday' => $query
- ->andWhere(['between', 'service_start_at', $y, strtotime(date('Y-m-d'))])
- ->count(),
- ];
- }
- /**
- * 写入前校验
- * @param array $params
- * @return ReservationServiceUser
- * @throws \Exception
- */
- public function valid(array $params)
- {
- // 校验技师
- /**
- * @var $staff ReservationServiceUser
- */
- $staff = ReservationServiceUser::findOne(['mall_id' => $params['mall_id'], 'id' => $params['tech_id'],
- 'status' => StatusEnum::ENABLED, 'check_status' => ReservationServiceEnum::CHECK_ADOPT]);
- if (empty($staff)) throw new \Exception('技师不存在');
- // 距离判断?
- $distance = (new LocationHelper())->getDistanceByGeo($staff->latitude, $staff->longitude, $params['lat'], $params['lng']);
- if (!empty($params['store_id'])) {
- $goods = StoreGoodsReserve::findOne([
- 'goods_id' => $params['goods_id']
- ]);
- } else {
- $goods = GoodsReserve::findOne([
- 'goods_id' => $params['goods_id']
- ]);
- }
- if ($distance > $goods->distance) {
- throw new \Exception("不在支持范围");
- }
- return $staff;
- }
- /**
- * 写入数据 - 应该在订单支付的时候写入
- * @param array $params
- * @return ReservationServiceOrder
- * @throws \Exception
- */
- public function save(array $params)
- {
- // $staff = $this->valid($params);
- /**
- * @var $staff ReservationServiceUser
- */
- if (!empty($params['tech_id'])) {
- $staff = ReservationServiceUser::findOne(['mall_id' => $params['mall_id'], 'id' => $params['tech_id'],
- 'status' => StatusEnum::ENABLED, 'check_status' => ReservationServiceEnum::CHECK_ADOPT]);
- }
- // if (empty($staff)) throw new \Exception('技师不存在');
- // 是否已经预约过
- if (!empty(ReservationServiceOrder::find()->where(['order_id' => $params['order_id']])
- ->andWhere(['status' => StatusEnum::ENABLED])
- ->andWhere(['service_status' => [ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL, ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING,
- ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER, ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH]])->one())) {
- throw new \Exception("不可重复预约");
- };
- if (empty($params['store_id']) && !empty($params['tech_id'])) { // 门店没有佣金
- /**
- * @var $level ReservationServiceLevel
- */
- $level = $staff->getLevel()->andWhere(['mall_id' => $params['mall_id']])->one();
- $params['commission'] = $level->item_commission;
- if (empty($level->item_commission_type)) {
- $params['commission'] = bcmul(bcmul($params['commission'], $params['goods_price'], 2), 0.01, 2);
- }
- /**
- * @var $goodsSetting ReservationServiceGoodsSetting
- */
- $goodsSetting = ReservationServiceGoodsSetting::getOne([
- ['mall_id' => $params['mall_id']],
- ['status' => StatusEnum::ENABLED],
- ['item_id' => $params['goods_id']],
- ['item_type' => 'goods'],
- ['is_enable' => StatusEnum::ENABLED],
- ['commission_type' => UserWalletService::WALLET_TYPE_COMMISSION]
- ]);
- if (!empty($goodsSetting)) {
- $params['commission'] = $goodsSetting->commission;
- if (!empty($goodsSetting->is_percent)) {
- $params['commission'] = bcmul(bcmul($params['commission'], $params['goods_price'], 2), 0.01, 2);
- }
- }
- if ($params['commission'] < 0) $params['commission'] = 0;
- }
- if (empty($params['tech_id'])) {
- $params['is_match'] = StatusEnum::ENABLED;
- }
- $params['staff_user_id'] = $staff->user_id ?? 0;
- $model = new ReservationServiceOrder();
- $model->loadDefaultValues();
- if (!$model->load($params, '') || !$model->save()) throw new \Exception($model->getErrorMessage());
- // 记录数据
- (new NoticeLogic())->send(['mall_id' => $params['mall_id'], 'id' => $params['order_id'], 'sms_key' => ReservationServiceEnum::SMS_KEY_RESERVE]);
- return $model;
- }
- /**
- * 核销记录
- * @param int $mall_id
- * @param array $params
- * @return array|false|mixed|string|null
- */
- public function underwriterList(int $mall_id, array $params)
- {
- $where = [
- ['mall_id' => $mall_id],
- ['status' => StatusEnum::ENABLED],
- ['staff_user_id' => $params['user_id']],
- ['service_status' => [ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER, ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH]]
- ];
- $with = ['order' => function($query) {
- $query->with(['detail']);
- }, 'store' => function($query) {
- $query->select('id, store_name, logo_img');
- }];
- $ret = ReservationServiceOrder::listPage([
- 'where' => $where,
- 'order' => 'id desc',
- 'limit' => $params['limit'] ?? 10,
- 'with' => $with
- ]);
- if (!empty(ReservationServiceOrder::getStaticError())) return ReservationServiceOrder::getStaticError();
- return $ret;
- }
- /**
- * 获取技师信息
- * @param int $order_id
- * @param $mall_id
- * @return void
- */
- public function getStaffByOrderId(int $order_id, $mall_id)
- {
- $staff = ReservationServiceOrder::getOne([
- ['order_id' => $order_id],
- ['service_status' => [ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING,
- ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER,
- ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH, ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL]],
- ], true, ['staff' => function($query) use($mall_id) {
- $with = [];
- $is_install = MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_STORE);
- if ($is_install) {
- $with = ['store' => function($query) {
- $query->select('id, store_name, logo_img');
- }];
- }
- $query->select('name, user_id, avatar, age, store_id')->with($with)->andwhere(['status' => StatusEnum::ENABLED]);
- }], 'id desc', 'staff_user_id');
- return !empty($staff['staff']) ? $staff['staff'] : null;
- }
- /**
- * 全局调用
- * @param array $params
- * @return mixed
- */
- public function preview(array $params)
- {
- $response = $params['data'];
- $input = $params['params'];
- // 只能是一件商品
- if (count($response['group_order_goods']) > 1 || empty($response['group_order_goods'][0]['goods'])) return $response;
- if (count($response['group_order_goods'][0]['goods']) > 1) return $response;
- $change_shipping_type_list = false;
- foreach ($response['group_order_goods'][0]['goods'] as $good) {
- if (!empty($good['reserve']) && $good['reserve']['reserve_type'] == StatusEnum::ENABLED) { // 仅限于家政服务
- $good['reserve']['service_type'] = 1;
- $change_shipping_type_list = true;
- // switch ($good['reserve']['service_type']) {
- // case 1:
- // case 2:
- // case 3:
- foreach ($response['shipping_type_list'] as $key => $item) {
- if ($key != $good['reserve']['service_type']) unset($response['shipping_type_list'][$key]);
- if ($key > 2) unset($response['shipping_type_list'][$key]);
- }
- // break;
- // }
- }
- }
- // shipping_type_list
- if (!empty($input['tech_id'])) {
- $response['tech'] = $this->findByTech($input['tech_id'], $input['latitude'], $input['longitude'], $params['mall_id']);
- }
- if ($change_shipping_type_list) {
- if (!empty($response['shipping_type_list'][1])) $response['shipping_type_list'][1] = '上门服务';
- if (!empty($response['shipping_type_list'][2])) $response['shipping_type_list'][2] = '到店服务';
- }
- // 是否需要校验短信验证码
- return $response;
- }
- /**
- * @param int $tech_id
- * @param $lat
- * @param $lng
- * @param $mall_id
- * @return array|mixed
- */
- public function findByTech(int $tech_id, $lat, $lng, $mall_id)
- {
- // 判断预约服务是否安装门店
- $with = [];
- $is_install = MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_STORE);
- if ($is_install) {
- $with = ['store' => function($query) {
- $query->select("id, store_name, logo_img, shop_owner, shop_mobile, longitude, latitude, address, province_id, city_id, district_id");
- }];
- }
- $tech = ReservationServiceUser::getOne([
- ['id' => $tech_id]
- ], true, $with, 'id asc', 'avatar, name, age, gender, store_id');
- if (!empty($tech['store'])) {
- $tech['store']['region'] = implode("", Region::find()->where(['id' =>
- [$tech['store']['province_id'], $tech['store']['city_id'], $tech['store']['district_id']]])
- ->select('name')->column());
- $tech['store']['distance'] = LocationHelper::formatDistance((new LocationHelper())->getDistanceByGeo($lat, $lng,
- $tech['store']['latitude'], $tech['store']['longitude']));
- }
- return $tech;
- }
- /**
- * 执行退款
- * @return void
- * @throws \Exception
- */
- public function refund()
- {
- foreach (ReservationServiceOrder::find()->select('id, mall_id')->where(['is_refund' => StatusEnum::DISABLED])
- ->andWhere(['>', 'refund_at', 0])->andWhere(['<=', 'refund_at', time()])
- ->andWhere(['service_status' => [ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL, ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING]])
- ->each() as $item) {
- // 这里操作退款
- // 先申请退款
- // 再执行退款
- \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER,
- RabbitMqEnum::ORDER_QUEUE, ['mall_id' => $item->mall_id, 'id' => $item->id], self::class, 'createRefund');
- // $this->createRefund(['mall_id' => $item->mall_id, 'id' => $item->id]);
- }
- }
- /**
- * 生成退款订单
- * @param array $data
- * @return bool
- */
- public function createRefund(array $data)
- {
- $rOrder = ReservationServiceOrder::findOne(['id' => $data['id']]);
- if (empty($rOrder) || $rOrder->is_refund != StatusEnum::DISABLED) return true;
- $order = Order::findOne(['id' => $rOrder->order_id]);
- $order_detail_id = OrderDetail::find()->where(['order_id' => $order->id])->scalar();
- // 申请退款
- $t = Yii::$app->db->beginTransaction();
- try {
- $rOrder->is_refund = 1; // 退款中
- if (!$rOrder->save()) throw new \Exception($rOrder->getErrorMessage());
- $params = [
- 'order_detail_id' => $order_detail_id,
- 'reason' => '预约订单超时自动售后退款',
- 'remark' => '',
- 'type' => RefundTypeEnum::MONEY,
- 'refund_price' => $order->pay_money,
- 'user_id' => $order->user_id,
- 'mall_id' => $order->mall_id,
- 'pic_list' => Json::encode([]),
- ];
- $res = OrderRefund::feedback($params);
- if ($res === false) throw new \Exception(Order::getStaticError());
- $t->commit();
- $event = new \common\events\order\OrderRefundEvent();
- $event->mall_id = $order->mall_id;
- $order_detail['order_detail_id'] = $order_detail_id;
- $order_detail['id'] = $res->id;
- $order_detail['operator_id'] = 0;
- $order_detail['operator_name'] = '系统自动申请';
- Yii::$app->services->events->dispatch($event, $order_detail, $event->listeners);
- \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER,
- RabbitMqEnum::ORDER_QUEUE, ['mall_id' => $order->mall_id, 'id' => $res->id, 'r_order_id' => $rOrder->id],
- self::class, 'refundPay');
- // $this->refundPay(['mall_id' => $order->mall_id, 'id' => $res->id, 'r_order_id' => $rOrder->id]);
- } catch (\Exception $e) {
- $t->rollBack();
- // var_dump($e->getMessage(), $e->getFile(), $e->getLine());
- \Yii::error(FormatHelper::exception($e, __METHOD__));
- return false;
- }
- return true;
- }
- /**
- * 退款支付打款
- * @param array $params
- * @return bool
- */
- public function refundPay(array $params)
- {
- $rOrder = ReservationServiceOrder::findOne(['id' => $params['r_order_id']]);
- if (empty($rOrder) || $rOrder->is_refund != StatusEnum::ENABLED) return true;
- // 退货地址
- $address = ['consignee' => '','mobile' => '','address' => ''];
- // 换货物流信息
- $express = ['saler_express' => '','saler_express_no' => '','customer_name' => ''];
- $data = [
- 'id' => $params['id'],
- 'step_status' => RefundStatusEnum::STEP_6, // 直接打款操作
- 'address' => $address,
- 'express' => $express,
- 'refund_reason' => '',
- 'not_dec_fee' => StatusEnum::ENABLED, // 不需要手续费
- ];
- // 申请退款
- $t = Yii::$app->db->beginTransaction();
- try {
- $rOrder->is_refund = 100; // 退款中
- if (!$rOrder->save()) throw new \Exception($rOrder->getErrorMessage());
- $logic = new OrderRefundLogic();
- $res = $logic->execute($rOrder->mall_id, $data);
- if (!$res) throw new \Exception($logic->getError());
- $t->commit();
- } catch (\Exception $e) {
- $t->rollBack();
- // var_dump("1", $e->getMessage(), $e->getFile(), $e->getLine());
- \Yii::error(FormatHelper::exception($e, __METHOD__));
- return false;
- }
- return true;
- }
- /**
- * 执行退款 废弃
- * @param array $data
- * @return bool
- */
- public function completeRefund(array $data)
- {
- $rOrder = ReservationServiceOrder::findOne(['id' => $data['id']]);
- if (empty($rOrder) || $rOrder->is_refund != StatusEnum::DISABLED) return true;
- $order = Order::findOne(['id' => $rOrder->order_id]);
- // 申请退款
- $t = Yii::$app->db->beginTransaction();
- try {
- $rOrder->is_refund = 100; // 退款中
- if (!$rOrder->save()) throw new \Exception($rOrder->getErrorMessage());
- $order_detail_id = OrderDetail::find()->where(['order_id' => $order->id])->scalar();
- $wallet_type = UserWalletService::WALLET_TYPE_BALANCE;
- if ($order->payment_type == PayTypeEnum::SCORE) $wallet_type = UserWalletService::WALLET_TYPE_SCORE;
- OrderDetail::updateAll(['is_feedback' => OrderStatusEnum::getIsFeedbackStatus(RefundStatusEnum::STEP_6),
- 'updated_at' => time()], ['order_id' => $order->id]);
- $is_install = MallAddons::isInstall($order->mall_id, AddonsEnum::ADDONS_NAME_STORE);
- Order::autoUpdateStatus($order);
- if($is_install){
- $store_order = StoreOrder::findOne(['order_no'=>$order['order_no']]);
- if(!empty($store_order)){
- $order['out_trade_no'] = $store_order['out_trade_no'];
- StoreOrderDetail::updateAll(['is_feedback' => OrderStatusEnum::getIsFeedbackStatus(RefundStatusEnum::STEP_6), 'updated_at' => time()],
- ['main_order_detail_id' => $order_detail_id]);
- StoreOrder::autoUpdateStatus($store_order);
- }
- }
- // 申请退款
- if(in_array($order->payment_type, [PayTypeEnum::BALANCE, PayTypeEnum::SCORE])){
- // 本地支付
- // 如果是代付,那么就需要原路退回
- $insert_wallet[] = [
- 'mall_id' => $order->mall_id,
- 'user_id' => $order->user_id,
- 'is_frozen' => false,
- 'wallet_type' => $wallet_type,// 暂定退回余额或积分
- 'money' => $order->pay_money,
- 'desc' => '预约订单超时自动售后退款',
- 'source_table' => ReservationServiceOrder::tableName(),
- 'source_table_id' => $rOrder->id,
- 'from_type' => UserWalletEnum::REFUND,
- 'capital_type' => UserWalletEnum::REFUND_ORDER,
- 'order_no' => $order->order_no,
- 'not_add_total' => true
- ];
- $res = UserWalletService::batchHandleByQueue($insert_wallet);
- if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
- } elseif(in_array($order->payment_type,[PayTypeEnum::JOINPAY,PayTypeEnum::ALI,PayTypeEnum::JOINPAY_FAST_PAY,PayTypeEnum::WECHAT])){
- //原路返回
- $out_trade_no = $order['out_trade_no'];
- $res = Yii::$app->services->pay->refund($order->pay_money,$order->pay_money, $out_trade_no, $order, '预约订单超时自动售后退款');
- if ($res === false) throw new \Exception('退款失败');
- }
- elseif (
- // 当res返回为false 说明没有相对于的退款方式
- $res = GlobalInvoke::exec(GlobalInvoke::INVOKE_ORDER_REFUND, $order->mall_id, [
- 'id' => 0,
- 'mall_id' => $order->mall_id,
- 'refund' => [
- 'order_id' => $order->id,
- 'order_no' => $order->order_no,
- 'refund_price' => $order->pay_money
- ],
- 'order_no' => $order['order_no'],
- 'refund_order_no' => $order['order_no'],
- 'params' => [],
- 'pay_type' => $order->payment_type,
- ])
- ) {
- // 当res不为空 进此判断
- list($boolean, $msg) = $res;
- if ($boolean === false) {
- throw new \Exception($msg);
- }
- } else {
- }
- // 订单营销扣减返还
- if(empty($order['store_id'])){
- $res = OrderMarketing::deductBack($order['id'], [$order_detail_id],
- [$order_detail_id],$order->mall_id,$order->user_id,'订单退款',
- UserWalletEnum::REFUND,UserWalletEnum::REFUND_ORDER);
- if (!$res) throw new \Exception(OrderMarketing::getStaticError());
- }else{
- if(MallAddons::isInstall($order['mall_id'],AddonsEnum::ADDONS_NAME_STORE)){
- $store_order = StoreOrder::findOne(['order_no'=>$order['order_no']]);
- $store_order_detail_ids = array_column($store_order->detail,'id');
- $store_order_detail_arr = array_column($store_order->detail,'id','main_order_detail_id');
- $store_order_detail_id = $store_order_detail_arr[$order_detail_id]??0;
- $res = StoreOrderMarketing::deductBack($store_order,$store_order_detail_ids,[$store_order_detail_id],$order->mall_id,
- $order->user_id,'订单退款',UserWalletEnum::REFUND,UserWalletEnum::REFUND_ORDER);
- if (!$res) throw new \Exception(StoreOrderMarketing::getStaticError());
- }
- }
- $t->commit();
- } catch (\Exception $e) {
- $t->rollBack();
- \Yii::error(FormatHelper::exception($e, __METHOD__));
- return false;
- }
- return true;
- }
- /**
- * 关闭预约订单
- * @param int $mall_id
- * @param int $order_id
- * @return int
- */
- public function closed(int $mall_id, int $order_id)
- {
- return ReservationServiceOrder::updateAll(['service_status' => ReservationServiceEnum::RESERVE_ORDER_STATUS_CLOSED],
- ['and', ['order_id' => $order_id], ['mall_id' => $mall_id], ['service_status' =>
- [ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL, ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING, ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER]]]);
- }
- /**
- * 详情
- * @param $params
- * @return mixed
- */
- public function globalDetail($params)
- {
- if (empty($params['reserve'])) return $params['order'];
- if ($params['order']['reserve']['reserve_type'] == StatusEnum::ENABLED) {
- $params['order']['can_reserve'] = ReservationServiceOrder::find()->where(['order_id' => $params['order']['id']])
- ->andWhere(['service_status' => [
- ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL,
- ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING,
- ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER,
- ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH,
- ]])->count() == 0 ? StatusEnum::ENABLED : StatusEnum::DISABLED;
- }
- return $params['order'];
- }
- /**
- * 列表
- * @param $params
- * @return mixed
- */
- public function globalList($params)
- {
- if (empty($params['reserve'])) return $params['order'];
- if (!empty($params['order'])) {
- foreach ($params['order'] as &$item) {
- // 判断订单是否为预约订单
- if ($item['reserve']['reserve_type'] == StatusEnum::ENABLED) {
- $item['can_reserve'] = ReservationServiceOrder::find()->where(['order_id' => $item['id']])
- ->andWhere(['service_status' => [
- ReservationServiceEnum::RESERVE_ORDER_STATUS_NORMAL,
- ReservationServiceEnum::RESERVE_ORDER_STATUS_TALKING,
- ReservationServiceEnum::RESERVE_ORDER_STATUS_UNDERWRITER,
- ReservationServiceEnum::RESERVE_ORDER_STATUS_FINISH,
- ]])->count() == 0 ? StatusEnum::ENABLED : StatusEnum::DISABLED;
- }
- if ($item['order_source']=='Reserve'){
- $service_order = ReservationServiceOrder::find()->where(['order_id' => $item['id']])->one();
- $item['staff_user_id'] = 0;
- $item['nickname'] = '';
- if(!empty($service_order['staff_user_id'])){
- $user = User::findOne(['id'=>$service_order['staff_user_id']]);
- $item['nickname'] = $user['nickname'];
- $item['staff_user_id'] = $service_order['staff_user_id'];
- }
- }
- }
- }
- return $params['order'];
- }
- /**
- * 预约满员检测
- * @param $goods_reserve_sku_id
- * @param $store_id
- * @param $date
- * @return bool
- * @throws \Exception
- */
- public function checkReserveFull($goods_reserve_sku_id,$store_id = 0,$date = null)
- {
- if (empty($date)) {
- $time = time();
- } else {
- $time = strtotime($date . ':00');
- }
- $date = date('Y-m-d', $time);
- $start_time = strtotime($date.' 00:00:00');
- $end_time = strtotime($date.' 23:59:59');
- if(empty($store_id)){
- $query = OrderReserve::find()->where(['attr_id' => $goods_reserve_sku_id]);
- $store_id = 0;
- $class = GoodsReserveSku::class;
- }else{
- $query = StoreOrderReserve::find()->where(['attr_id' => $goods_reserve_sku_id]);
- //门店
- $class = StoreGoodsReserveSku::class;
- }
- $query->andWhere(['!=', 'order_status', -4]);
- $goods_reserve_sku = $class::findOne(['id'=>$goods_reserve_sku_id]);
- if(empty($goods_reserve_sku)){
- throw new \Exception('预约商品不存在');
- }
- $counts = $query
- ->andWhere(['>=', 'service_start_at', $start_time])->andWhere(['<=', 'service_start_at', $end_time])
- ->andWhere(['store_id'=>$store_id])
- ->count();
- if ($goods_reserve_sku['reserve_max_buy'] > 0 && $counts >= $goods_reserve_sku['reserve_max_buy']) {
- return false;
- }
- return true;
- }
- }
|