Skip to content

Commit

Permalink
Added Creation of Promo Codes
Browse files Browse the repository at this point in the history
  • Loading branch information
Ojsholly committed Nov 12, 2020
1 parent ba035cb commit 4e0dca7
Show file tree
Hide file tree
Showing 8 changed files with 421 additions and 6 deletions.
116 changes: 116 additions & 0 deletions app/Http/Controllers/API/v1/PromoCode/PromoCodeController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

namespace App\Http\Controllers\API\v1\PromoCode;

use DateTime;
use Carbon\Carbon;
use App\Models\PromoCode;
use Illuminate\Http\Request;
use App\Http\Traits\DistanceTrait;
use App\Http\Controllers\Controller;
use App\Http\Requests\CreatePromoCodeRequest;

class PromoCodeController extends Controller
{

use DistanceTrait;

/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}

/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(CreatePromoCodeRequest $request)
{
if ($request->code == null) {
# code...
$request->code = PromoCode::generate();
}

$venue_coordinates = $this->get_latitude_and_longitude($request->venue);

if ($venue_coordinates == null) {
# code...

$response = [
'status' => 'error',
'message' => 'Sorry. Location not found.'
];

return response()->json($response, 400);
}

$expiry = PromoCode::fetch_ttl($request->expiry_date);

$promo_code = PromoCode::create([
'code' => $request->code,
'venue' => $request->venue,
'value' => $request->value,
'radius' => $request->radius,
'expires_at' => $expiry
]);

if ($promo_code == null) {
# code...
$response = [
'status' => 'error',
'message' => 'Error saving promo code.'
];

return response()->json($response, 400);
}


$response = [
'status' => 'success',
'message' => 'New Promo Code Successfully saved.'
];

return response()->json($response, 201);
}

/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}

/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}

/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
34 changes: 34 additions & 0 deletions app/Http/Requests/CreatePromoCodeRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreatePromoCodeRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'code' => 'nullable|string|unique:promo_codes',
'value' => 'required|numeric|gt:0',
'venue' => 'required|string',
'radius' => 'required|numeric|gt:0',
'expiry_date' => 'required|date|after_or_equal:' . date('Y-m-d')
];
}
}
99 changes: 99 additions & 0 deletions app/Http/Traits/DistanceTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

namespace App\Http\Traits;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Http\Client\ConnectionException;

trait DistanceTrait
{

// Using Haversine formula to calculate the shortest distance between both coordinates.

protected function get_distance(array $point1, array $point2)
{

$earth_radius = 6371; // earth radius in km
$point1_lat = $point1["latitude"];
$point2_lat = $point2["latitude"];

$lat_diff = deg2rad($point2_lat - $point1_lat);
$point1_long = $point1["longitude"];
$point2_long = $point2["longitude"];

$long_diff = deg2rad($point2_long - $point1_long);

$a = sin($lat_diff / 2) * sin($lat_diff / 2) + cos(deg2rad($point1_lat)) * cos(deg2rad($point2_lat)) * sin($long_diff / 2) * sin($long_diff / 2);
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));

$distance = $earth_radius * $c;
$distance = round($distance, 2);

return $distance; // in km
}

// Fetch the latitude and longitude of input address
protected function get_latitude_and_longitude($address)
{
try {
$client = new Client();

$res = $client->request('GET', 'https://maps.googleapis.com/maps/api/geocode/json', [
'query' => [
'address' => urlencode($address),
'key' => env('GOOGLE_MAPS_API_KEY')
]
]);

$response = json_decode($res->getBody());

if ($response->status == 'ZERO_RESULTS') {
# code...
return null;
}

$latitude = $response->results[0]->geometry->location->lat;
$longitude = $response->results[0]->geometry->location->lng;

$coordinates = [
"latitude" => $latitude,
"longitude" => $longitude
];

return $coordinates;
} catch (RequestException $e) {
$response = $e->getResponse();
$result = $response->getBody();

$data = [
'status' => 400,
'response' => $response,
'result' => $result
];

return $data;
} catch (ClientException $e) {
$response = $e->getResponse();
$result = $response->getBody();

$data = [
'status' => 400,
'response' => $response,
'result' => $result
];

return $data;
} catch (ConnectionException $e) {
$result = $response->getBody();

$data = [
'status' => 400,
'result' => $result
];

return $data;
}
}
}
38 changes: 38 additions & 0 deletions app/Models/PromoCode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace App\Models;

use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Model;
use Mvdnbrk\EloquentExpirable\Expirable;
use BinaryCabin\LaravelUUID\Traits\HasUUID;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class PromoCode extends Model
{
use HasFactory, HasUUID, SoftDeletes, Expirable;

/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'code',
'value',
'venue',
'radius',
'expires_at'
];

public static function generate()
{
return 'SB' . Str::random(6);
}

public static function fetch_ttl($datetime)
{
return now()->diffInSeconds($datetime);
}
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"laravel/framework": "^8.12",
"laravel/sanctum": "^2.8",
"laravel/tinker": "^2.5",
"mvdnbrk/laravel-model-expires": "^1.8",
"spatie/laravel-http-logger": "^1.6",
"unicodeveloper/laravel-password": "^1.0"
},
Expand Down
74 changes: 73 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4e0dca7

Please sign in to comment.