unioil-loyalty-app/app/Http/Controllers/API/PromotionController.php

677 lines
22 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\API;
use App\Libraries\S3;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Contracts\PromotionResourceInterface;
use App\Contracts\AdminActionLogsInterface;
use App\Contracts\PromotionStationsInterface;
use App\Contracts\StationResourceInterface;
use App\Contracts\LoyaltyCardResourceInterface;
use App\Contracts\SystemPreferenceResourceInterface;
use App\Http\Resources\PromotionResource;
use App\Libraries\ParameterHelper;
use App\Helpers\CurrentUserHelper;
use App\Helpers\StringHelper;
use App\Helpers\HttpStatusCode;
use App\Http\Requests\PromotionValidation;
use App\Libraries\StaticContents;
use App\Promotions;
class PromotionController extends Controller
{
const MODULE = 'PROMOTIONS';
public $promotions;
public $station;
public $promotionStations;
protected $format;
protected $module;
protected $model;
protected $admin_logs;
protected $loyalty_card;
protected $system_preferences;
public function __construct(PromotionResourceInterface $promotions,
HttpStatusCode $httpStatusCode,
AdminActionLogsInterface $admin_logs,
PromotionStationsInterface $promotionStations,
StationResourceInterface $station,
LoyaltyCardResourceInterface $loyalty_card,
SystemPreferenceResourceInterface $system_preferences)
{
$this->promotions = $promotions;
$this->format = $httpStatusCode;
$this->module = "cardType";
$this->model = "cardType";
$this->admin_logs = $admin_logs;
$this->station = $station;
$this->loyalty_card = $loyalty_card;
$this->promotionStations = $promotionStations;
$this->system_preferences = $system_preferences;
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$params = [
'search' => ($request->has('_search') ? $request->get('_search') : NULL),
'page_size' => ($request->has('page_size') ? $request->get('page_size') : 10),
'page' => ($request->has('page') ? $request->get('page') : 10),
'sorting' => ParameterHelper::prepareSortingParameter($request)
];
// expire top two promotions if date is lapsed
$this->promotions->expire_top_two();
$list = $this->promotions->listing($params);
if(count($list))
{
$additionals = $this->format->success("Success",[],false);
$data = PromotionResource::collection($list)->additional($additionals);
return $data->response()->setStatusCode(200);
}
else
{
return $this->format->success("No records found",[]);
}
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(PromotionValidation $request)
{
$id = $this->promotions->store($request);
if($id)
{
$station_uuids = json_decode($request->get('station_uuid'));
if($station_uuids != null && count($station_uuids))
{
$station_details = $this->station->getDetailsWhereIn('station_uuid',$station_uuids);
$station_ids = array();
foreach ($station_details as $key => $value) {
$station_ids[] = $value['station_id'];
}
$this->promotionStations->store($id, $station_ids);
}
$this->admin_logs->log($id,self::MODULE,'STORE');
return $this->format->created('Promotion has been added');
}
else
{
return $this->format->notFound();
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($uuid)
{
$details = $this->promotions->getByField('promotion_uuid',$uuid,'promotionStations.station');
if($details->count())
{
$additionals = $this->format->success("Success",[],false);
$data = (new PromotionResource($details[0]))->additional($additionals);
return $data->response()->setStatusCode(200);
}
else
return $this->format->notFound();
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(PromotionValidation $request, $uuid)
{
$old_data = $this->promotions->getByField('promotion_uuid',$uuid);
if($old_data->count())
{
if($this->promotions->update($request,$uuid))
{
// delete existing stations
$this->promotionStations->delete($old_data[0]['promotion_id']);
// replace new assigned stations -- regardless if changed or not
$station_uuids = json_decode($request->get('station_uuid'));
if($station_uuids != null && count($station_uuids))
{
$station_details = $this->station->getDetailsWhereIn('station_uuid',$station_uuids);
$station_ids = array();
foreach ($station_details as $key => $value) {
$station_ids[] = $value['station_id'];
}
$this->promotionStations->store($old_data[0]['promotion_id'], $station_ids);
}
$this->admin_logs->log($old_data[0]['promotion_id'],self::MODULE,'UPDATE');
return $this->format->success("Promotion has been updated");
}
else
{
return $this->format->notFound('Something went wrong');
}
}
return $this->format->notFound();
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($uuid)
{
$details = $this->promotions->getByField('promotion_uuid',$uuid);
if($details->count())
{
$details = $details[0];
if($this->promotions->delete($uuid))
{
$this->admin_logs->log($details['promotion_id'],self::MODULE,'DELETE');
return $this->format->success("Promotion Successfully Deleted");
}
}
return $this->format->notFound();
}
public function promo_types()
{
return $this->format->success('Success',StaticContents::promo_type());
}
public function batch_delete(Request $request)
{
$uuid = $request->has('promotion_uuid') ? $request->get('promotion_uuid') : null;
if($uuid)
{
$details = $this->promotions->getDetailsWhereIn('promotion_uuid',$uuid);
$id = array();
if($this->promotions->delete($uuid))
{
foreach ($details as $key => $value)
{
$this->admin_logs->log($value['promotion_id'],self::MODULE,'DELETE');
}
return $this->format->success("Promotion Successfully Deleted");
}
else
{
return $this->format->badRequest('Something went wrong');
}
}
else
{
$data['promotion_uuid'] = 'promotion_uuid is required';
return $this->format->unprocessableEntity("Submit at least one item",$data);
}
}
public function get_promotions(Request $request)
{
$selected_promotion_uuid = $request->has('selected_promotion') ? $request->selected_promotion : null;
$list = $this->promotions->get_promotion($selected_promotion_uuid);
$data = array();
if($list->count())
{
foreach ($list as $key => $value) {
$data[] = array(
'promotion_uuid' => $value['promotion_uuid'],
'title' => $value['title'],
'date_start' => $value['date_start'],
'date_end' => $value['date_end'],
);
}
}
return $this->format->success('Success',$data);
}
public function disable_toptwo()
{
$promotion_uuid = request('promotion_uuid');
if($promotion_uuid)
{
$details = $this->promotions->getByField('promotion_uuid',$promotion_uuid);
if($details)
{
if($details[0]['is_toppromotion'] == 1)
return $this->format->success('Enable Add in Top 2 Promos',['is_toppromotion' => 'enable']);
}
}
$toptwo = Promotions::where('is_toppromotion',1)
->where('is_active',1)
->count();
if($toptwo >= 2)
{
return $this->format->success('Disable Add in Top 2 Promos',['is_toppromotion' => 'disable']);
}
else
{
return $this->format->success('Enable Add in Top 2 Promos',['is_toppromotion' => 'enable']);
}
}
public function mobile_promotions(Request $request)
{
if($request->has('lcard_uuid') && $request->lcard_uuid != '')
{
$member_details = $this->loyalty_card->getByField([
'lcard_uuid' => $request->get('lcard_uuid'),
'is_active' => 1
]);
}
$date_now = date('Y-m-d H:i:s');
$general = $this->promotions->get_promo_by_date_type($date_now, StaticContents::promo_type('General',true));
if(isset($member_details))
{
// loyalty exclusive & user specific
$loyalty_exclusive = $this->promotions->get_promo_by_date_type($date_now, StaticContents::promo_type('Loyalty Exclusive',true));
$birthday = date('Y-m-d H:i:s',strtotime($member_details[0]['birthdate']));
$user_specific = $this->promotions->get_promo_by_date_birthdate_type($date_now, $birthday,StaticContents::promo_type('User Specific',true));
$general = $general->merge($loyalty_exclusive);
$general = $general->merge($user_specific);
}
$data = [];
if(count($general))
{
$general = $general->sortByDesc('date_end');
// check if latest have equal dates
$same_start_dates = [];
foreach ($general as $key => $value) {
$same_start_dates[date('YmdHis',strtotime($value['date_start']))][] = $value;
}
$sorted_data = collect();
foreach ($same_start_dates as $date => $promos) {
$merge = collect($promos);
$merge = $merge->sortBy('created_at');
$sorted_data = $sorted_data->merge($merge);
}
foreach ($sorted_data as $key => $value) {
$stations = [];
foreach ($value['promotionStations'] as $k => $v) {
$stations[] = [
'station_uuid' => $v['station']['station_uuid'],
'name' => $v['station']['description'],
];
}
$image_url = S3::public_path($value['image']);
$data[] = [
'promotion_uuid' => $value['promotion_uuid'],
'title' => $value['title'],
'description' => $value['description'],
'image' => $image_url,
'date_start' => $value['date_start'],
'date_end' => $value['date_end'],
];
}
}
return $this->format->mobile_success('Success',$data);
}
public function mobile_promotions_gps(Request $request)
{
// get stations within the radius
$radius = $this->system_preferences->getByField('name','gps');
$station = $this->station->radius($radius[0]['value'], $request->longitude, $request->latitude);
if($station)
{
if($request->has('lcard_uuid') && $request->lcard_uuid != '')
{
$member_details = $this->loyalty_card->getByField([
'lcard_uuid' => $request->get('lcard_uuid'),
'is_active' => 1
]);
}
$station_ids = [];
foreach ($station as $key => $value) {
$station_ids[] = $value['station_id'];
}
$date_now = date('Y-m-d H:i:s');
$all_branches = collect();
if(count($station_ids))
{
$general = $this->promotions->get_promo_by_date_station_gps($station_ids, $date_now, StaticContents::promo_type('General',true));
}
$all_branches_general = $this->promotions->get_all_branch_promo($date_now, StaticContents::promo_type('General',true));
$all_branches = $all_branches->merge($all_branches_general);
if(isset($member_details) && count($member_details) > 0)
{
// loyalty exclusive & user specific
$loyalty_exclusive = $this->promotions->get_promo_by_date_station_gps($station_ids,$date_now, StaticContents::promo_type('Loyalty Exclusive',true));
$all_branches_loyalty = $this->promotions->get_all_branch_promo($date_now, StaticContents::promo_type('Loyalty Exclusive',true));
$all_branches = $all_branches->merge($all_branches_loyalty);
$birthday = date('Y-m-d H:i:s',strtotime($member_details[0]['birthdate']));
$user_specific = $this->promotions->get_promo_by_birthdate_station_gps($station_ids,$date_now, $birthday,StaticContents::promo_type('User Specific',true));
if(count($station_ids))
{
// all branches promotions
$all_branches_loyalty_exclusive = $this->promotions->get_all_branch_promo($date_now, StaticContents::promo_type('Loyalty Exclusive',true));
$all_branches_user_specific = $this->promotions->get_all_branch_promo_by_birthdate($date_now,$birthday, StaticContents::promo_type('User Specific',true));
// $general = $general->merge($all_branches_loyalty_exclusive);
// $general = $general->merge($all_branches_user_specific);
$all_branches = $all_branches->merge($all_branches_loyalty_exclusive);
$all_branches = $all_branches->merge($all_branches_user_specific);
}
$general = $general->merge($loyalty_exclusive);
$general = $general->merge($user_specific);
}
$data = [];
/*
SORTING RULE :
1. nearest station
2. date start (latest)
3. if date start is the same creation date (latest) should be first
*/
if(count($general) || count($all_branches))
{
// get from nearest station
$nearest = [];
if(count($station_ids))
{
for ($i=0; $i < count($station_ids); $i++)
{
foreach ($general as $key => $value)
{
foreach ($value['promotionStations'] as $k => $v)
{
if($v['station']['station_id'] == $station_ids[$i])
$nearest[] = $value;
}
}
if(count($nearest) > 0)
break;
}
}
if(count($all_branches))
{
$nearest = $general->merge($all_branches);
}
$general = collect($nearest);
$general = $general->sortByDesc('date_start');
// check if latest have equal dates
$ctr = 1;
$same_start_dates = [];
foreach ($general as $key => $value) {
if($ctr > 1)
{
if($previous_date_start == $value->date_start)
$same_start_dates[] = $value;
else
break;
}
else
$same_start_dates[] = $value;
$previous_date_start = $value->date_start;
$ctr++;
}
$general = collect($same_start_dates);
$general = $general->sortByDesc('created_dt');
foreach ($general as $key => $value) {
$stations = [];
foreach ($value['promotionStations'] as $k => $v) {
$stations[] = [
'station_uuid' => $v['station']['station_uuid'],
'name' => $v['station']['description'],
];
}
$image_url = S3::public_path($value['image']);
$data[] = [
'promotion_uuid' => $value['promotion_uuid'],
'title' => $value['title'],
'description' => $value['description'],
'image' => $image_url,
'date_start' => $value['date_start'],
'date_end' => $value['date_end'],
'station' => $stations,
];
break; // one return only
}
}
return $this->format->mobile_success('Success',$data);
}
}
public function getTopTwoPromotion(Request $request)
{
if($request->has('lcard_uuid') && $request->lcard_uuid != '')
{
$member_details = $this->loyalty_card->getByField([
'lcard_uuid' => $request->get('lcard_uuid'),
'is_active' => 1
]);
}
$date_now = date('Y-m-d');
$general = $this->promotions->getTopTwoPromotion(StaticContents::promo_type('General',true));
if (isset($member_details)){
if(count($member_details) == 1)
{
// loyalty exclusive & user specific
$loyalty_exclusive = $this->promotions->getTopTwoPromotion(StaticContents::promo_type('Loyalty Exclusive',true));
$birthday = date('Y-m-d H:i:s',strtotime($member_details[0]['birthdate']));
$birthdate = date('Y').'-'.date('m-d',strtotime($birthday));
$general = $general->merge($loyalty_exclusive);
if($date_now == $birthdate){
$user_specific = $this->promotions->getTopTwoPromotion(StaticContents::promo_type('User Specific',true));
$general = $general->merge($user_specific);
}
}
}
$data = [];
if(count($general))
{
$general = collect($general);
$general = $general->sortByDesc('date_start');
// check if latest have equal dates
$ctr = 1;
$same_start_dates = [];
foreach ($general as $key => $value) {
// if($ctr > 1)
// {
// if($previous_date_start == $value->date_start)
// $same_start_dates[] = $value;
// else
// break;
// }
// else
// $same_start_dates[] = $value;
// $previous_date_start = $value->date_start;
// $ctr++;
$same_start_dates[$value->date_start][] = $value;
}
$sorted_start_dates = collect();
foreach ($same_start_dates as $key => $value) {
$v = collect($value);
if(count($value) > 1)
{
$v_sort = $v->sortBy('created_at');
$sorted_start_dates = $sorted_start_dates->merge($v_sort);
}
else
$sorted_start_dates = $sorted_start_dates->merge($v);
}
$general = $sorted_start_dates;
foreach ($general as $key => $value) {
$image_url = S3::public_path($value['image']);//S3::public_path($value['image']);
$data[] = [
'promotion_uuid' => $value['promotion_uuid'],
'title' => $value['title'],
'description' => $value['description'],
'image' => $image_url,
'date_start' => $value['date_start'],
'date_end' => $value['date_end'],
];
}
}
return $this->format->mobile_success('Success',$data);
}
public function mobile_promotions_details($uuid)
{
$details = $this->promotions->getByField('promotion_uuid',$uuid);
if(count($details) > 0)
{
$image_url = str_replace('/public/index.php','',secure_url('storage/app/'.$details[0]['image']));
$image_url = str_replace('https','http',$image_url);
return $this->format->mobile_success('Success',[
'image' => $image_url,
'title' => $details[0]['title'],
'description' => $details[0]['description'],
]);
}
else
{
return $this->format->mobile_error('Incorrect promotion_uuid');
}
}
}