first commit
This commit is contained in:
commit
d2b89cef7d
|
@ -0,0 +1,18 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[docker-compose.yml]
|
||||
indent_size = 4
|
|
@ -0,0 +1,56 @@
|
|||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=base64:pECxKdEqRKAZRX/2sUxIwWQLK617XWmqUqtuwNCBEr0=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://127.0.0.1:8000/
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=ecommerce
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
|
||||
MIDTRANS_ID_MERCHANT=G415351610
|
||||
MIDTRANS_CLIENT_KEY=SB-Mid-client-4QzG9xHXyPZzefUN
|
||||
MIDTRANS_SERVER_KEY=SB-Mid-server-qbkLVLWGDXpR9tBHb7YUrX9s
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
FILESYSTEM_DRIVER=local
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=mailhog
|
||||
MAIL_PORT=1025
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS=null
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
|
@ -0,0 +1,5 @@
|
|||
* text=auto
|
||||
*.css linguist-vendored
|
||||
*.scss linguist-vendored
|
||||
*.js linguist-vendored
|
||||
CHANGELOG.md export-ignore
|
|
@ -0,0 +1,15 @@
|
|||
/node_modules
|
||||
/public/hot
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
/vendor
|
||||
.env
|
||||
.env.backup
|
||||
.phpunit.result.cache
|
||||
docker-compose.override.yml
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
/.idea
|
||||
/.vscode
|
|
@ -0,0 +1,14 @@
|
|||
php:
|
||||
preset: laravel
|
||||
version: 8
|
||||
disabled:
|
||||
- no_unused_imports
|
||||
finder:
|
||||
not-name:
|
||||
- index.php
|
||||
- server.php
|
||||
js:
|
||||
finder:
|
||||
not-name:
|
||||
- webpack.mix.js
|
||||
css: true
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array<int, class-string<Throwable>>
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed for validation exceptions.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class OutOfStockException extends Exception
|
||||
{
|
||||
public function report()
|
||||
{
|
||||
\Log::debug('The product is out of stock');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Models\Order;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
|
||||
class RevenueExport implements FromCollection
|
||||
{
|
||||
public function collection()
|
||||
{
|
||||
// Retrieve data from Booking and Order models
|
||||
$bookings = Booking::all();
|
||||
$orders = Order::all();
|
||||
|
||||
// Merge data from bookings and orders into one collection
|
||||
$data = $bookings->merge($orders);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Models\Order;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
|
||||
class RevenueExport implements FromCollection
|
||||
{
|
||||
public function collection()
|
||||
{
|
||||
// Retrieve data from Booking and Order models
|
||||
$bookings = Booking::all();
|
||||
$orders = Order::all();
|
||||
|
||||
// Merge data from bookings and orders into one collection
|
||||
$data = $bookings->merge($orders);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
class General
|
||||
{
|
||||
/**
|
||||
* Convert number to roman
|
||||
*
|
||||
* @param int $integer name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function integerToRoman($integer)
|
||||
{
|
||||
$integer = intval($integer);
|
||||
$result = '';
|
||||
|
||||
// Create a lookup array that contains all of the Roman numerals.
|
||||
$lookup = ['M' => 1000, 'CM' => 900, 'D' => 500, 'CD' => 400, 'C' => 100, 'XC' => 90, 'L' => 50, 'XL' => 40, 'X' => 10, 'IX' => 9, 'V' => 5, 'IV' => 4, 'I' => 1];
|
||||
|
||||
foreach ($lookup as $roman => $value) {
|
||||
$matches = intval($integer/$value);
|
||||
$result .= str_repeat($roman, $matches);
|
||||
$integer = $integer % $value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BaseController extends Controller
|
||||
{
|
||||
public function responseOk($result, $code = 200,$message = 'Success', $meta = []){
|
||||
$response = [
|
||||
'code' => $code,
|
||||
'data' => $result,
|
||||
'message' => $message,
|
||||
];
|
||||
|
||||
if($meta){
|
||||
$response['meta'] = $meta;
|
||||
}
|
||||
|
||||
return response()->json($response, $code);
|
||||
}
|
||||
|
||||
public function responseError($error, $code = 422,$errorDetails = []){
|
||||
$response = [
|
||||
'code' => $code,
|
||||
'error' => $error
|
||||
];
|
||||
|
||||
if(!empty($errorDetails)){
|
||||
$response['errorDetails'] = $errorDetails;
|
||||
}
|
||||
|
||||
return response()->json($response, $code);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,411 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Http\Controllers\API\BaseController;
|
||||
|
||||
use App\Http\Resources\Item as ItemResource;
|
||||
use App\Models\Review;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use PhpParser\Node\Stmt\TryCatch;
|
||||
|
||||
class CartController extends BaseController
|
||||
{
|
||||
public function index(Request $request,$sessionKey = null)
|
||||
{
|
||||
if ($sessionKey = $request->user()->id) {
|
||||
$cart = \Cart::session($sessionKey)->getContent();
|
||||
}else{
|
||||
$cart = \Cart::getContent();
|
||||
}
|
||||
|
||||
if ($sessionKey) {
|
||||
$shipping_cost = \Cart::session($sessionKey)->getCondition('shipping_cost');
|
||||
}
|
||||
|
||||
$shipping_cost = \Cart::getCondition('shipping_cost');
|
||||
|
||||
$condition = new \Darryldecode\Cart\CartCondition(
|
||||
[
|
||||
'name' => 'TAX 10%',
|
||||
'type' => 'tax',
|
||||
'target' => 'subtotal',
|
||||
'value' => '10%',
|
||||
]
|
||||
);
|
||||
|
||||
if ($sessionKey) {
|
||||
\Cart::session($sessionKey)->removeConditionsByType('tax');
|
||||
\Cart::session($sessionKey)->condition($condition);
|
||||
} else {
|
||||
\Cart::removeConditionsByType('tax');
|
||||
\Cart::condition($condition);
|
||||
}
|
||||
|
||||
if ($sessionKey) {
|
||||
$tax = \Cart::session($sessionKey)->getCondition('TAX 10%');
|
||||
}
|
||||
|
||||
$tax = \Cart::getCondition('TAX 10%');
|
||||
|
||||
if ($sessionKey) {
|
||||
$subTotal = \Cart::session($sessionKey)->getSubTotal();
|
||||
}
|
||||
|
||||
$subTotal = \Cart::getSubTotal();
|
||||
|
||||
if ($sessionKey) {
|
||||
$total = \Cart::session($sessionKey)->getTotal();
|
||||
}
|
||||
|
||||
$total = \Cart::getTotal();
|
||||
|
||||
$carts = [
|
||||
'item' => ItemResource::collection($cart),
|
||||
'shipping_cost' => $shipping_cost,
|
||||
'tax' => $tax,
|
||||
'sub_total' => $subTotal,
|
||||
'total' => $total,
|
||||
];
|
||||
|
||||
return $this->responseOk($carts,200,'success');
|
||||
}
|
||||
|
||||
public function store(Request $request, $sessionKey = 0)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'slug' => 'required',
|
||||
'qty' => 'required'
|
||||
]);
|
||||
|
||||
if($validator->fails()){
|
||||
return $this->responseError('add item failed !', 422, $validator->errors());
|
||||
}
|
||||
|
||||
$params = $request->all();
|
||||
$product = Product::where('slug',$params['slug'])->firstOrFail();
|
||||
|
||||
$carts = \Cart::getContent();
|
||||
$itemQuantity = 0;
|
||||
if ($carts) {
|
||||
foreach ($carts as $cart) {
|
||||
if ($cart->id == $product->id) {
|
||||
$itemQuantity = $cart->quantity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$itemQuantity += $request->qty;
|
||||
|
||||
if ($product->quantity < $itemQuantity) {
|
||||
// throw new \App\Exceptions\OutOfStockException('The product '. $product->sku .' is out of stock');
|
||||
}
|
||||
|
||||
$item = [
|
||||
'id' => md5($product->id),
|
||||
'name' => $product->name,
|
||||
'price' => $product->price,
|
||||
'quantity' => $request->qty,
|
||||
'associatedModel' => $product,
|
||||
];
|
||||
|
||||
if ($sessionKey = $request->user()->id) {
|
||||
\Cart::session($sessionKey)->add($item);
|
||||
$carts = \Cart::getContent();
|
||||
return $this->responseOk(true,200,'success');
|
||||
}else{
|
||||
\Cart::add($item);
|
||||
return $this->responseOk(true, 200,'success');
|
||||
}
|
||||
|
||||
return $this->responseError('add item failed !', 422);
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$params = $request->all();
|
||||
$validator = Validator::make($params, [
|
||||
'quantity' => 'required|numeric'
|
||||
]);
|
||||
|
||||
if($validator->fails()){
|
||||
return $this->responseError('update failed !', 422,$validator->errors());
|
||||
}
|
||||
|
||||
$sessionKey = $request->user()->id;
|
||||
|
||||
if ($sessionKey) {
|
||||
$carts = \Cart::session($sessionKey)->getContent();
|
||||
}else{
|
||||
$carts = \Cart::getContent();
|
||||
}
|
||||
|
||||
$item = !(empty($carts[$id])) ? $carts[$id] : null;
|
||||
if(!$item){
|
||||
return $this->responseError('item not found !', 404);
|
||||
}
|
||||
|
||||
if ($item->quantity < $params['quantity'] ) {
|
||||
// throw new \App\Exceptions\OutOfStockException('The product '. $carts[$cartId]->associatedModel->sku .' is out of stock');
|
||||
}
|
||||
|
||||
$cartUpdate = \Cart::update($id,[
|
||||
'quantity' => [
|
||||
'relative' => false,
|
||||
'value' => $params['quantity'],
|
||||
],
|
||||
]);
|
||||
|
||||
return $this->responseOk($cartUpdate, 200,'the item has been updated !');
|
||||
}
|
||||
|
||||
public function destroy(Request $request, $id)
|
||||
{
|
||||
$sessionKey = $request->user()->id;
|
||||
|
||||
if ($sessionKey) {
|
||||
$carts = \Cart::session($sessionKey)->getContent();
|
||||
}else{
|
||||
$carts = \Cart::getContent();
|
||||
}
|
||||
|
||||
$item = !(empty($carts[$id])) ? $carts[$id] : null;
|
||||
if(!$item){
|
||||
return $this->responseError('item not found !', 404);
|
||||
}
|
||||
|
||||
if ($sessionKey) {
|
||||
$cartDelete = \Cart::session($sessionKey)->remove($id);
|
||||
return $this->responseOk($cartDelete, 200,'the item has been deleted !');
|
||||
}else {
|
||||
$cartDelete = \Cart::remove($id);
|
||||
return $this->responseOk($cartDelete, 200,'the item has been deleted !');
|
||||
}
|
||||
|
||||
$this->responseError('deleted item failed !', 400);
|
||||
}
|
||||
|
||||
public function clear(Request $request){
|
||||
|
||||
$sessionKey = $request->user()->id;
|
||||
|
||||
if ($sessionKey) {
|
||||
$cartDestroy = \Cart::session($sessionKey)->clear();
|
||||
}
|
||||
|
||||
$cartDestroy = \Cart::clear();
|
||||
|
||||
if($cartDestroy){
|
||||
return $this->responseOk($cartDestroy, 200, 'the item has been cleared !');
|
||||
}
|
||||
|
||||
return $this->responseError('clear cart item failed !', 400);
|
||||
|
||||
}
|
||||
|
||||
public function shippingOptions(Request $request)
|
||||
{
|
||||
$parameter = $request->all();
|
||||
|
||||
$validator = Validator::make($parameter, [
|
||||
'city_id' => 'required|numeric'
|
||||
]);
|
||||
|
||||
$sessionKey = $request->user()->id;
|
||||
|
||||
if($validator->fails()){
|
||||
return $this->responseError('get shipping options failed !', 422, $validator->errors());
|
||||
}
|
||||
|
||||
if ($sessionKey) {
|
||||
\Cart::session($sessionKey)->isEmpty();
|
||||
} else {
|
||||
\Cart::isEmpty();
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$totalWeight = 0;
|
||||
if ($sessionKey) {
|
||||
$items = \Cart::session($sessionKey)->getContent();
|
||||
} else {
|
||||
$items = \Cart::getContent();
|
||||
}
|
||||
|
||||
foreach ($items as $item) {
|
||||
$totalWeight += ($item->quantity * $item->associatedModel->weight);
|
||||
}
|
||||
|
||||
$params = [
|
||||
'origin' => env('RAJAONGKIR_ORIGIN'),
|
||||
'destination' => $parameter['city_id'],
|
||||
'weight' => $totalWeight,
|
||||
];
|
||||
|
||||
$results = [];
|
||||
foreach ($this->couriers as $code => $courier) {
|
||||
$params['courier'] = $code;
|
||||
|
||||
$response = $this->rajaOngkirRequest('cost', $params, 'POST');
|
||||
|
||||
if (!empty($response['rajaongkir']['results'])) {
|
||||
foreach ($response['rajaongkir']['results'] as $cost) {
|
||||
if (!empty($cost['costs'])) {
|
||||
foreach ($cost['costs'] as $costDetail) {
|
||||
$serviceName = strtoupper($cost['code']) .' - '. $costDetail['service'];
|
||||
$costAmount = $costDetail['cost'][0]['value'];
|
||||
$etd = $costDetail['cost'][0]['etd'];
|
||||
|
||||
$result = [
|
||||
'service' => $serviceName,
|
||||
'cost' => $costAmount,
|
||||
'etd' => $etd,
|
||||
'courier' => $code,
|
||||
];
|
||||
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response = [
|
||||
'origin' => $params['origin'],
|
||||
'destination' => $params ['destination'],
|
||||
'weight' => $totalWeight,
|
||||
'results' => $results,
|
||||
];
|
||||
|
||||
return $this->responseOk($response, 200,'success !');
|
||||
|
||||
} catch (\GuzzleHttp\Exception\RequestException $err) {
|
||||
return $this->responseError($err->getMessage(), 400);
|
||||
}
|
||||
return $this->responseError('get shipping options failed !', 400);
|
||||
|
||||
}
|
||||
|
||||
public function setShipping(Request $request)
|
||||
{
|
||||
$params = $request->all();
|
||||
$validator = Validator::make($params, [
|
||||
'city_id' => ['required', 'numeric'],
|
||||
'shipping_service' => ['required', 'string'],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return $this->responseError('Set shipping failed', 422, $validator->errors());
|
||||
}
|
||||
|
||||
$sessionKey = $request->user()->id;
|
||||
|
||||
if ($sessionKey) {
|
||||
\Cart::session($sessionKey)->removeConditionsByType('shipping');
|
||||
}
|
||||
|
||||
\Cart::removeConditionsByType('shipping');
|
||||
|
||||
$shippingService = $request->get('shipping_service');
|
||||
$destination = $request->get('city_id');
|
||||
|
||||
$totalWeight = 0;
|
||||
if ($sessionKey) {
|
||||
$items = \Cart::session($sessionKey)->getContent();
|
||||
} else {
|
||||
$items = \Cart::getContent();
|
||||
}
|
||||
|
||||
foreach ($items as $item) {
|
||||
$totalWeight += ($item->quantity * $item->associatedModel->weight);
|
||||
}
|
||||
|
||||
$params = [
|
||||
'origin' => env('RAJAONGKIR_ORIGIN'),
|
||||
'destination' => $destination,
|
||||
'weight' => $totalWeight,
|
||||
];
|
||||
|
||||
$results = [];
|
||||
foreach ($this->couriers as $code => $courier) {
|
||||
$params['courier'] = $code;
|
||||
|
||||
$response = $this->rajaOngkirRequest('cost', $params, 'POST');
|
||||
|
||||
if (!empty($response['rajaongkir']['results'])) {
|
||||
foreach ($response['rajaongkir']['results'] as $cost) {
|
||||
if (!empty($cost['costs'])) {
|
||||
foreach ($cost['costs'] as $costDetail) {
|
||||
$serviceName = strtoupper($cost['code']) .' - '. $costDetail['service'];
|
||||
$costAmount = $costDetail['cost'][0]['value'];
|
||||
$etd = $costDetail['cost'][0]['etd'];
|
||||
|
||||
$result = [
|
||||
'service' => $serviceName,
|
||||
'cost' => $costAmount,
|
||||
'etd' => $etd,
|
||||
'courier' => $code,
|
||||
];
|
||||
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$shippingOptions = [
|
||||
'origin' => $params['origin'],
|
||||
'destination' => $destination,
|
||||
'weight' => $totalWeight,
|
||||
'results' => $results,
|
||||
];
|
||||
|
||||
$selectedShipping = null;
|
||||
if ($shippingOptions['results']) {
|
||||
foreach ($shippingOptions['results'] as $shippingOption) {
|
||||
if (str_replace(' ', '', $shippingOption['service']) == $shippingService) {
|
||||
$selectedShipping = $shippingOption;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$status = null;
|
||||
$message = null;
|
||||
$data = [];
|
||||
|
||||
if ($selectedShipping) {
|
||||
$status = 200;
|
||||
$message = 'Success set shipping cost';
|
||||
|
||||
$condition = new \Darryldecode\Cart\CartCondition(
|
||||
[
|
||||
'name' => 'shipping_cost',
|
||||
'type' => 'shipping',
|
||||
'target' => 'total',
|
||||
'value' => '+'. $selectedShipping['cost'],
|
||||
]
|
||||
);
|
||||
|
||||
\Cart::condition($condition);
|
||||
|
||||
if ($sessionKey) {
|
||||
$carts= \Cart::session($sessionKey)->getTotal();
|
||||
}
|
||||
|
||||
$carts = \Cart::getTotal();
|
||||
|
||||
$data['total'] = number_format($carts);
|
||||
|
||||
return $this->responseOk($data, 200, 'success');
|
||||
}
|
||||
|
||||
return $this->responseError('Failed to set shipping cost', 400);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,347 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Product;
|
||||
use App\Models\Shipment;
|
||||
use App\Models\OrderItem;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\API\BaseController;
|
||||
|
||||
class OrderController extends BaseController
|
||||
{
|
||||
public function checkout(Request $request){
|
||||
$params = $request->user()->toArray();
|
||||
$params = array_merge($params, $request->all());
|
||||
|
||||
$sessionKey = $request->user()->id;
|
||||
|
||||
$orders = \DB::transaction(
|
||||
function () use ($params, $sessionKey) {
|
||||
$destination = isset($params['ship_to']) ? $params['shipping_city_id'] : $params['city_id'];
|
||||
|
||||
if ($sessionKey) {
|
||||
\Cart::session($sessionKey)->isEmpty();
|
||||
} else {
|
||||
\Cart::isEmpty();
|
||||
}
|
||||
|
||||
$totalWeight = 0;
|
||||
if ($sessionKey) {
|
||||
$items = \Cart::session($sessionKey)->getContent();
|
||||
} else {
|
||||
$items = \Cart::getContent();
|
||||
}
|
||||
|
||||
foreach ($items as $item) {
|
||||
$totalWeight += ($item->quantity * $item->associatedModel->weight);
|
||||
}
|
||||
|
||||
$param = [
|
||||
'origin' => env('RAJAONGKIR_ORIGIN'),
|
||||
'destination' => $destination,
|
||||
'weight' => $totalWeight,
|
||||
];
|
||||
|
||||
$results = [];
|
||||
foreach ($this->couriers as $code => $courier) {
|
||||
$param['courier'] = $code;
|
||||
|
||||
$response = $this->rajaOngkirRequest('cost', $param, 'POST');
|
||||
|
||||
if (!empty($response['rajaongkir']['results'])) {
|
||||
foreach ($response['rajaongkir']['results'] as $cost) {
|
||||
if (!empty($cost['costs'])) {
|
||||
foreach ($cost['costs'] as $costDetail) {
|
||||
$serviceName = strtoupper($cost['code']) .' - '. $costDetail['service'];
|
||||
$costAmount = $costDetail['cost'][0]['value'];
|
||||
$etd = $costDetail['cost'][0]['etd'];
|
||||
|
||||
$result = [
|
||||
'service' => $serviceName,
|
||||
'cost' => $costAmount,
|
||||
'etd' => $etd,
|
||||
'courier' => $code,
|
||||
];
|
||||
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$shippingOptions = [
|
||||
'origin' => $param['origin'],
|
||||
'destination' => $destination,
|
||||
'weight' => $totalWeight,
|
||||
'results' => $results,
|
||||
];
|
||||
|
||||
$shippingService = $params['shipping_service'];
|
||||
|
||||
$selectedShipping = null;
|
||||
if ($shippingOptions['results']) {
|
||||
foreach ($shippingOptions['results'] as $shippingOption) {
|
||||
if (str_replace(' ', '', $shippingOption['service']) == $shippingService) {
|
||||
$selectedShipping = $shippingOption;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($sessionKey) {
|
||||
$condition = new \Darryldecode\Cart\CartCondition(
|
||||
[
|
||||
'name' => 'TAX 10%',
|
||||
'type' => 'tax',
|
||||
'target' => 'subtotal',
|
||||
'value' => '10%',
|
||||
]
|
||||
);
|
||||
|
||||
if ($sessionKey) {
|
||||
\Cart::session($sessionKey)->removeConditionsByType('tax');
|
||||
\Cart::session($sessionKey)->condition($condition);
|
||||
} else {
|
||||
\Cart::removeConditionsByType('tax');
|
||||
\Cart::condition($condition);
|
||||
}
|
||||
$items = \Cart::session($sessionKey)->getContent();
|
||||
}
|
||||
|
||||
$condition = new \Darryldecode\Cart\CartCondition(
|
||||
[
|
||||
'name' => 'TAX 10%',
|
||||
'type' => 'tax',
|
||||
'target' => 'subtotal',
|
||||
'value' => '10%',
|
||||
]
|
||||
);
|
||||
|
||||
if ($sessionKey) {
|
||||
\Cart::session($sessionKey)->removeConditionsByType('tax');
|
||||
\Cart::session($sessionKey)->condition($condition);
|
||||
} else {
|
||||
\Cart::removeConditionsByType('tax');
|
||||
\Cart::condition($condition);
|
||||
}
|
||||
$items = \Cart::getContent();
|
||||
|
||||
$baseTotalPrice = 0;
|
||||
foreach ($items as $item) {
|
||||
$baseTotalPrice += $item->getPriceSum();
|
||||
}
|
||||
|
||||
if ($sessionKey) {
|
||||
\Cart::session($sessionKey)->getSubTotal();
|
||||
}
|
||||
|
||||
\Cart::getSubTotal();
|
||||
|
||||
if ($sessionKey) {
|
||||
$taxAmount = (float) \Cart::session($sessionKey)->getCondition('TAX 10%')->parsedRawValue;
|
||||
}
|
||||
|
||||
$taxAmount = (float) \Cart::getCondition('TAX 10%')->parsedRawValue;
|
||||
|
||||
if ($sessionKey) {
|
||||
$taxPercent = (float) \Cart::session($sessionKey)->getCondition('TAX 10%')->getValue();
|
||||
}
|
||||
|
||||
$taxPercent = (float) \Cart::getCondition('TAX 10%')->getValue();
|
||||
|
||||
$shippingCost = $selectedShipping['cost'];
|
||||
$discountAmount = 0;
|
||||
$discountPercent = 0;
|
||||
$grandTotal = ($baseTotalPrice + $taxAmount + $shippingCost) - $discountAmount;
|
||||
|
||||
$orderDate = date('Y-m-d H:i:s');
|
||||
$paymentDue = (new \DateTime($orderDate))->modify('+7 day')->format('Y-m-d H:i:s');
|
||||
|
||||
$orderParams = [
|
||||
'user_id' => auth()->user()->id,
|
||||
'code' => Order::generateCode(),
|
||||
'status' => Order::CREATED,
|
||||
'order_date' => $orderDate,
|
||||
'payment_due' => $paymentDue,
|
||||
'payment_status' => Order::UNPAID,
|
||||
'base_total_price' => $baseTotalPrice,
|
||||
'tax_amount' => $taxAmount,
|
||||
'tax_percent' => $taxPercent,
|
||||
'discount_amount' => $discountAmount,
|
||||
'discount_percent' => $discountPercent,
|
||||
'shipping_cost' => $shippingCost,
|
||||
'grand_total' => $grandTotal,
|
||||
'note' => $params['note'],
|
||||
'customer_first_name' => $params['first_name'],
|
||||
'customer_last_name' => $params['last_name'],
|
||||
'customer_address1' => $params['address1'],
|
||||
'customer_address2' => $params['address2'],
|
||||
'customer_phone' => $params['phone'],
|
||||
'customer_email' => $params['email'],
|
||||
'customer_city_id' => $params['city_id'],
|
||||
'customer_province_id' => $params['province_id'],
|
||||
'customer_postcode' => $params['postcode'],
|
||||
'shipping_courier' => $selectedShipping['courier'],
|
||||
'shipping_service_name' => $selectedShipping['service'],
|
||||
];
|
||||
|
||||
$order = Order::create($orderParams);
|
||||
|
||||
if ($sessionKey) {
|
||||
$condition = new \Darryldecode\Cart\CartCondition(
|
||||
[
|
||||
'name' => 'TAX 10%',
|
||||
'type' => 'tax',
|
||||
'target' => 'subtotal',
|
||||
'value' => '10%',
|
||||
]
|
||||
);
|
||||
|
||||
if ($sessionKey) {
|
||||
\Cart::session($sessionKey)->removeConditionsByType('tax');
|
||||
\Cart::session($sessionKey)->condition($condition);
|
||||
} else {
|
||||
\Cart::removeConditionsByType('tax');
|
||||
\Cart::condition($condition);
|
||||
}
|
||||
$cartItems = \Cart::session($sessionKey)->getContent();
|
||||
}
|
||||
|
||||
$condition = new \Darryldecode\Cart\CartCondition(
|
||||
[
|
||||
'name' => 'TAX 10%',
|
||||
'type' => 'tax',
|
||||
'target' => 'subtotal',
|
||||
'value' => '10%',
|
||||
]
|
||||
);
|
||||
|
||||
if ($sessionKey) {
|
||||
\Cart::session($sessionKey)->removeConditionsByType('tax');
|
||||
\Cart::session($sessionKey)->condition($condition);
|
||||
} else {
|
||||
\Cart::removeConditionsByType('tax');
|
||||
\Cart::condition($condition);
|
||||
}
|
||||
$cartItems = \Cart::getContent();
|
||||
|
||||
if ($order && $cartItems) {
|
||||
foreach ($cartItems as $item) {
|
||||
$itemTaxAmount = 0;
|
||||
$itemTaxPercent = 0;
|
||||
$itemDiscountAmount = 0;
|
||||
$itemDiscountPercent = 0;
|
||||
$itemBaseTotal = $item->quantity * $item->price;
|
||||
$itemSubTotal = $itemBaseTotal + $itemTaxAmount - $itemDiscountAmount;
|
||||
|
||||
$product = isset($item->associatedModel->parent) ? $item->associatedModel->parent : $item->associatedModel;
|
||||
|
||||
$orderItemParams = [
|
||||
'order_id' => $order->id,
|
||||
'product_id' => $item->associatedModel->id,
|
||||
'qty' => $item->quantity,
|
||||
'base_price' => $item->price,
|
||||
'base_total' => $itemBaseTotal,
|
||||
'tax_amount' => $itemTaxAmount,
|
||||
'tax_percent' => $itemTaxPercent,
|
||||
'discount_amount' => $itemDiscountAmount,
|
||||
'discount_percent' => $itemDiscountPercent,
|
||||
'sub_total' => $itemSubTotal,
|
||||
'type' => $product->type,
|
||||
'name' => $item->name,
|
||||
'weight' => $item->associatedModel->weight,
|
||||
];
|
||||
|
||||
$orderItem = OrderItem::create($orderItemParams);
|
||||
|
||||
if ($orderItem) {
|
||||
$product = Product::findOrFail($product->id);
|
||||
$product->quantity -= $item->quantity;
|
||||
$product->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->initPaymentGateway();
|
||||
|
||||
$customerDetails = [
|
||||
'first_name' => $order->customer_first_name,
|
||||
'last_name' => $order->customer_last_name,
|
||||
'email' => $order->customer_email,
|
||||
'phone' => $order->customer_phone,
|
||||
];
|
||||
|
||||
$data_payment = [
|
||||
'enable_payments' => Payment::PAYMENT_CHANNELS,
|
||||
'transaction_details' => [
|
||||
'order_id' => $order->code,
|
||||
'gross_amount' => (int) $order->grand_total,
|
||||
],
|
||||
'customer_details' => $customerDetails,
|
||||
'expiry' => [
|
||||
'start_time' => date('Y-m-d H:i:s T'),
|
||||
'unit' => \App\Models\Payment::EXPIRY_UNIT,
|
||||
'duration' => \App\Models\Payment::EXPIRY_DURATION,
|
||||
],
|
||||
];
|
||||
|
||||
$snap = \Midtrans\Snap::createTransaction($data_payment);
|
||||
|
||||
if ($snap->token) {
|
||||
$order->payment_token = $snap->token;
|
||||
$order->payment_url = $snap->redirect_url;
|
||||
$order->save();
|
||||
}
|
||||
|
||||
$shippingFirstName = isset($params['ship_to']) ? $params['shipping_first_name'] : $params['first_name'];
|
||||
$shippingLastName = isset($params['ship_to']) ? $params['shipping_last_name'] : $params['last_name'];
|
||||
$shippingAddress1 = isset($params['ship_to']) ? $params['shipping_address1'] : $params['address1'];
|
||||
$shippingAddress2 = isset($params['ship_to']) ? $params['shipping_address2'] : $params['address2'];
|
||||
$shippingPhone = isset($params['ship_to']) ? $params['shipping_phone'] : $params['phone'];
|
||||
$shippingEmail = isset($params['ship_to']) ? $params['shipping_email'] : $params['email'];
|
||||
$shippingCityId = isset($params['ship_to']) ? $params['shipping_city_id'] : $params['city_id'];
|
||||
$shippingProvinceId = isset($params['ship_to']) ? $params['shipping_province_id'] : $params['province_id'];
|
||||
$shippingPostcode = isset($params['ship_to']) ? $params['shipping_postcode'] : $params['postcode'];
|
||||
|
||||
$shipmentParams = [
|
||||
'user_id' => auth()->user()->id,
|
||||
'order_id' => $order->id,
|
||||
'status' => Shipment::PENDING,
|
||||
'total_qty' => \Cart::getTotalQuantity(),
|
||||
'total_weight' => $totalWeight,
|
||||
'first_name' => $shippingFirstName,
|
||||
'last_name' => $shippingLastName,
|
||||
'address1' => $shippingAddress1,
|
||||
'address2' => $shippingAddress2,
|
||||
'phone' => $shippingPhone,
|
||||
'email' => $shippingEmail,
|
||||
'city_id' => $shippingCityId,
|
||||
'province_id' => $shippingProvinceId,
|
||||
'postcode' => $shippingPostcode,
|
||||
];
|
||||
|
||||
Shipment::create($shipmentParams);
|
||||
|
||||
return $order;
|
||||
}
|
||||
);
|
||||
|
||||
if ($orders) {
|
||||
if ($sessionKey) {
|
||||
\Cart::session($sessionKey)->clearCartConditions();
|
||||
\Cart::session($sessionKey)->clear();
|
||||
}
|
||||
|
||||
\Cart::clearCartConditions();
|
||||
\Cart::clear();
|
||||
|
||||
return $this->responseOk($orders, 200, 'success');
|
||||
}
|
||||
|
||||
return $this->responseError('Order process failed, 422');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Resources\Product as ProductResource;
|
||||
use App\Http\Controllers\API\BaseController;
|
||||
|
||||
class ProductController extends BaseController
|
||||
{
|
||||
private $paginate = 2;
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
if((int)$request->req_page && (int)$request->req_page < 10){
|
||||
$this->paginate = $request->req_page;
|
||||
}
|
||||
|
||||
$products = Product::paginate($this->paginate);
|
||||
|
||||
if ($q = $request->query('q')) {
|
||||
$products = Product::where('name','LIKE', '%'. $request->query('q'). '%')
|
||||
->orWhere('description', 'LIKE', '%' . $request->query('q') . '%')
|
||||
->paginate($this->paginate);
|
||||
}
|
||||
|
||||
$meta = [
|
||||
'paginate' => $this->paginate,
|
||||
'current_page' => $products->currentPage(),
|
||||
'total_pages' => $products->lastPage()
|
||||
];
|
||||
|
||||
return $this->responseOk(ProductResource::collection($products),200,'success', $meta);
|
||||
}
|
||||
|
||||
public function show(Request $request){
|
||||
$product = Product::with('media', 'category', 'tags')
|
||||
->where('slug', $request->slug)
|
||||
->withCount('media','approvedReviews')
|
||||
->withAvg('approvedReviews', 'rating')
|
||||
->active()
|
||||
->hasQuantity()
|
||||
->firstOrFail();
|
||||
|
||||
return $this->responseOk(new ProductResource($product),200,'success');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Http\Controllers\API\BaseController;
|
||||
|
||||
class UserController extends BaseController
|
||||
{
|
||||
public function login(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'email' => ['required', 'string', 'email'],
|
||||
'password' => ['required', 'string']
|
||||
]);
|
||||
|
||||
if($validator->fails()){
|
||||
return $this->responseError('Login Failed !', 422, $validator->errors());
|
||||
}
|
||||
|
||||
if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){
|
||||
$user = auth()->user();
|
||||
|
||||
$response = [
|
||||
'token' => $user->createToken('MyToken')->accessToken,
|
||||
'first_name' => $user->first_name,
|
||||
'last_name' => $user->last_name,
|
||||
];
|
||||
|
||||
return $this->responseOk($response);
|
||||
|
||||
}else {
|
||||
return $this->responseError('wrong email or password !', 401);
|
||||
}
|
||||
}
|
||||
|
||||
public function register(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'username' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return $this->responseError('Registration failed', 422, $validator->errors());
|
||||
}
|
||||
|
||||
$params = [
|
||||
'username' => $request->username,
|
||||
'email' => $request->email,
|
||||
'password' => bcrypt($request->password),
|
||||
];
|
||||
|
||||
if (!$user = User::create($params)) {
|
||||
return $this->responseError('Registration failed', 400);
|
||||
}
|
||||
|
||||
$token = $user->createToken('MyToken')->accessToken;
|
||||
|
||||
$response = [
|
||||
'token' => $token,
|
||||
'user' => $user,
|
||||
];
|
||||
|
||||
return $this->responseOk($response);
|
||||
}
|
||||
|
||||
public function getProfile(Request $request)
|
||||
{
|
||||
return $this->responseOk($request->user());
|
||||
}
|
||||
|
||||
public function logout(Request $request)
|
||||
{
|
||||
$request->user()->token()->revoke();
|
||||
|
||||
return $this->responseOk(null, 200, 'Logged out successfully.');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BookingController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$bookings = Booking::orderBy('id', 'DESC')->get();
|
||||
return view('admin.booking.index', compact('bookings'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Category;
|
||||
use App\Traits\ImageUploadTrait;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use App\Http\Requests\Admin\CategoryRequest;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
use ImageUploadTrait;
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//abort_if(Gate::denies('category_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$categories = Category::with('parent')->withCount('products')->latest()->paginate(5);
|
||||
|
||||
return view('admin.categories.index', compact('categories'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//abort_if(Gate::denies('category_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$parent_categories = Category::whereNull('category_id')->get(['id', 'name']);
|
||||
|
||||
return view('admin.categories.create', compact('parent_categories'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(CategoryRequest $request)
|
||||
{
|
||||
//abort_if(Gate::denies('category_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$image = NULL;
|
||||
if ($request->hasFile('cover')) {
|
||||
$image = $this->uploadImage($request->name, $request->cover, 'categories', 268, 268);
|
||||
}
|
||||
|
||||
Category::create([
|
||||
'name' => $request->name,
|
||||
'category_id' => $request->category_id,
|
||||
'cover' => $image,
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.categories.index')->with([
|
||||
'message' => 'success created !',
|
||||
'alert-type' => 'success'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Category $category)
|
||||
{
|
||||
//abort_if(Gate::denies('category_view'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
return view('admin.categories.show', compact('category'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Category $category)
|
||||
{
|
||||
//abort_if(Gate::denies('category_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$parent_categories = Category::whereNull('category_id')->get(['id', 'name']);
|
||||
|
||||
return view('admin.categories.edit', compact('parent_categories', 'category'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(CategoryRequest $request,Category $category)
|
||||
{
|
||||
//abort_if(Gate::denies('category_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$image = $category->cover;
|
||||
if ($request->has('cover')) {
|
||||
if ($category->cover != null && File::exists('storage/images/categories/'. $category->cover)) {
|
||||
unlink('storage/images/categories/'. $category->cover);
|
||||
}
|
||||
$image = $this->uploadImage($request->name, $request->cover, 'categories', 268, 268);
|
||||
}
|
||||
|
||||
$category->update([
|
||||
'name' => $request->name,
|
||||
'category_id' => $request->category_id,
|
||||
'cover' => $image,
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.categories.index')->with([
|
||||
'message' => 'success updated !',
|
||||
'alert-type' => 'info'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Category $category)
|
||||
{
|
||||
//abort_if(Gate::denies('category_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
if($category->category_id == null) {
|
||||
foreach($category->children as $child) {
|
||||
if (File::exists('storage/images/categories/'. $child->cover)) {
|
||||
unlink('storage/images/categories/'. $child->cover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($category->cover) {
|
||||
if (File::exists('storage/images/categories/'. $category->cover)) {
|
||||
unlink('storage/images/categories/'. $category->cover);
|
||||
}
|
||||
}
|
||||
|
||||
$category->delete();
|
||||
|
||||
return redirect()->route('admin.categories.index')->with([
|
||||
'message' => 'success deleted !',
|
||||
'alert-type' => 'danger',
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\Product;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function index(){
|
||||
$product_count = Product::count();
|
||||
$booking_count = Booking::count();
|
||||
$service_count = Service::count();
|
||||
$order = Order::count();
|
||||
|
||||
return view('admin.dashboard', compact('product_count','booking_count', 'service_count','order'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Obtained;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\StoreObtainedRequest;
|
||||
use App\Http\Requests\Admin\UpdateObtainedRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ObtainedController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//abort_if(Gate::denies('obtained_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$obtaineds = Obtained::paginate(5);
|
||||
|
||||
return view('admin.obtaineds.index', compact('obtaineds'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//abort_if(Gate::denies('obtained_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
return view('admin.obtaineds.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreObtainedRequest $request)
|
||||
{
|
||||
//abort_if(Gate::denies('obtained_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
Obtained::create($request->validated());
|
||||
|
||||
return redirect()->route('admin.obtained.index')->with('message', "Service Obtained Successfully Created !");
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Obtained $obtained
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Obtained $obtained)
|
||||
{
|
||||
return redirect()->route('admin.obtained.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Obtained $obtained
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Obtained $obtained)
|
||||
{
|
||||
//abort_if(Gate::denies('obtained_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
return view('admin.obtaineds.edit', compact('obtained'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Models\Obtained $obtained
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(UpdateObtainedRequest $request, Obtained $obtained)
|
||||
{
|
||||
//abort_if(Gate::denies('obtained_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$obtained->update($request->validated());
|
||||
|
||||
return redirect()->route('admin.obtained.index')->with('message', 'Service Obtained Successfully Updated !');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Obtained $obtained
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Obtained $obtained)
|
||||
{
|
||||
//abort_if(Gate::denies('obtained_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$obtained->delete();
|
||||
|
||||
return redirect()->route('admin.obtained.index')->with('message', 'Obtained Service Successfully Deleted !');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderItem;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Product;
|
||||
|
||||
class OrderController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$orders = Order::latest();
|
||||
|
||||
|
||||
|
||||
if ($request->input('status') && in_array($request->input('status'), array_keys(Order::STATUSES))) {
|
||||
$orders = $orders->where('status', '=', $request->input('status'));
|
||||
}
|
||||
|
||||
$startDate = $request->input('start');
|
||||
$endDate = $request->input('end');
|
||||
|
||||
if ($startDate && !$endDate) {
|
||||
return redirect('admin/orders');
|
||||
}
|
||||
|
||||
if (!$startDate && $endDate) {
|
||||
return redirect('admin/orders');
|
||||
}
|
||||
|
||||
if ($startDate && $endDate) {
|
||||
if (strtotime($endDate) < strtotime($startDate)) {
|
||||
return redirect('admin/orders');
|
||||
}
|
||||
|
||||
$orders = $orders->whereRaw("DATE(order_date) >= ?", $startDate)
|
||||
->whereRaw("DATE(order_date) <= ? ", $endDate);
|
||||
}
|
||||
|
||||
$orders = $orders->paginate(10);
|
||||
|
||||
return view('admin.orders.index', compact('orders'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Order $order)
|
||||
{
|
||||
return view('admin.orders.show', compact('order'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Order $order)
|
||||
{
|
||||
|
||||
// \DB::transaction(
|
||||
// function () use ($order) {
|
||||
// OrderItem::where('order_id', $order->id)->delete();
|
||||
// $order->shipment->delete();
|
||||
// $order->forceDelete();
|
||||
|
||||
// return true;
|
||||
// }
|
||||
// );
|
||||
OrderItem::where('order_id', $order->id)->delete();
|
||||
$order->delete();
|
||||
|
||||
return redirect()->route('admin.orders.index')->with([
|
||||
'message' => 'success deleted !',
|
||||
'alert-type' => 'danger'
|
||||
]);;
|
||||
}
|
||||
|
||||
public function cancel($id)
|
||||
{
|
||||
$order = Order::where('id', $id)
|
||||
->whereIn('status', [Order::CREATED, Order::CONFIRMED])
|
||||
->firstOrFail();
|
||||
|
||||
return view('admin.orders.cancel', compact('order'));
|
||||
}
|
||||
|
||||
public function cancelUpdate(Request $request, $id)
|
||||
{
|
||||
$request->validate(
|
||||
[
|
||||
'cancellation_note' => 'required|max:255',
|
||||
]
|
||||
);
|
||||
|
||||
$order = Order::findOrFail($id);
|
||||
|
||||
$cancelOrder = \DB::transaction(
|
||||
function () use ($order, $request) {
|
||||
$params = [
|
||||
'status' => Order::CANCELLED,
|
||||
'cancelled_by' => auth()->id(),
|
||||
'cancelled_at' => now(),
|
||||
'cancellation_note' => $request->cancellation_note,
|
||||
];
|
||||
|
||||
if ($cancelOrder = $order->update($params) && $order->orderItems->count() > 0) {
|
||||
foreach ($order->orderItems as $item) {
|
||||
$product = Product::findOrFail($item->product_id);
|
||||
$product->quantity += $item->qty;
|
||||
$product->save();
|
||||
}
|
||||
}
|
||||
|
||||
return $cancelOrder;
|
||||
}
|
||||
);
|
||||
|
||||
return redirect()->route('admin.orders.index')->with([
|
||||
'message' => 'success cancelled !',
|
||||
'alert-type' => 'danger'
|
||||
]);;
|
||||
}
|
||||
|
||||
public function complete(Request $request, $id)
|
||||
{
|
||||
$order = Order::findOrFail($id);
|
||||
|
||||
if (!$order->isDelivered()) {
|
||||
return redirect()->route('admin.orders.index');
|
||||
}
|
||||
|
||||
$order->status = Order::COMPLETED;
|
||||
$order->approved_by = auth()->id();
|
||||
$order->approved_at = now();
|
||||
|
||||
if ($order->save()) {
|
||||
return redirect()->route('admin.orders.index')->with([
|
||||
'message' => 'completed order !',
|
||||
'alert-type' => 'success'
|
||||
]);;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Tag;
|
||||
use App\Models\Product;
|
||||
use App\Models\Category;
|
||||
use App\Services\ImageService;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\Admin\ProductRequest;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ProductController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//abort_if(Gate::denies('product_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$products = Product::with('category', 'tags', 'firstMedia')->latest()->paginate(5);
|
||||
|
||||
return view('admin.products.index', compact('products'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//abort_if(Gate::denies('product_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$categories = Category::latest()->get(['id', 'name']);
|
||||
$tags = Tag::latest()->get(['id', 'name']);
|
||||
|
||||
return view('admin.products.create', compact('categories','tags'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ProductRequest $request)
|
||||
{
|
||||
//abort_if(Gate::denies('product_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
if ($request->validated()){
|
||||
$product = Product::create($request->except('tags', 'images', '_token'));
|
||||
$product->tags()->attach($request->tags);
|
||||
|
||||
if ($request->images && count($request->images) > 0) {
|
||||
(new ImageService())->storeProductImages($request->images, $product);
|
||||
}
|
||||
|
||||
return redirect()->route('admin.products.index')->with([
|
||||
'message' => 'success created !',
|
||||
'alert-type' => 'success'
|
||||
]);
|
||||
}
|
||||
|
||||
return back()->with([
|
||||
'message' => 'Something was wrong, please try again later',
|
||||
'alert-type' => 'danger'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Product $product)
|
||||
{
|
||||
//abort_if(Gate::denies('product_view'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
return view('admin.products.show', compact('product'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Product $product)
|
||||
{
|
||||
//abort_if(Gate::denies('product_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$categories = Category::latest()->get(['id', 'name']);
|
||||
$tags = Tag::latest()->get(['id', 'name']);
|
||||
|
||||
return view('admin.products.edit', compact('categories','product','tags'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ProductRequest $request,Product $product)
|
||||
{
|
||||
//abort_if(Gate::denies('product_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
if ($request->validated()) {
|
||||
$product->update($request->except('tags', 'images', '_token'));
|
||||
$product->tags()->sync($request->tags);
|
||||
|
||||
$i = $product->media()->count() + 1;
|
||||
|
||||
if ($request->images && count($request->images) > 0) {
|
||||
(new ImageService())->storeProductImages($request->images, $product, $i);
|
||||
}
|
||||
|
||||
return redirect()->route('admin.products.index')->with([
|
||||
'message' => 'success created !',
|
||||
'alert-type' => 'success'
|
||||
]);
|
||||
}
|
||||
|
||||
return back()->with([
|
||||
'message' => 'Something was wrong, please try again late',
|
||||
'alert-type' => 'danger'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Product $product)
|
||||
{
|
||||
//abort_if(Gate::denies('product_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
if ($product->media->count() > 0) {
|
||||
foreach ($product->media as $media) {
|
||||
(new ImageService())->unlinkImage($media->file_name, 'products');
|
||||
$media->delete();
|
||||
}
|
||||
}
|
||||
|
||||
$product->delete();
|
||||
|
||||
return redirect()->route('admin.products.index')->with([
|
||||
'message' => 'success deleted !',
|
||||
'alert-type' => 'danger',
|
||||
]);
|
||||
}
|
||||
|
||||
public function removeImage(Request $request)
|
||||
{
|
||||
//abort_if(Gate::denies('product_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$product = Product::findOrFail($request->product_id);
|
||||
$image = $product->media()->whereId($request->image_id)->first();
|
||||
|
||||
(new ImageService())->unlinkImage($image->file_name, 'products');
|
||||
$image->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Models\Order;
|
||||
use App\Exports\RevenueExport;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use PDF;
|
||||
|
||||
class ReportController extends Controller
|
||||
{
|
||||
public function export(Request $request)
|
||||
{
|
||||
$exportType = $request->input('export');
|
||||
|
||||
if ($exportType == 'pdf') {
|
||||
$data = Booking::all()->merge(Order::all());
|
||||
$startDate = $data->min('created_at')->format('Y-m-d'); // Tanggal pertama
|
||||
$endDate = $data->max('created_at')->format('Y-m-d');
|
||||
|
||||
$pdf = PDF::loadView('admin.reports.exports.revenue_pdf', compact('data', 'startDate', 'endDate'));
|
||||
return $pdf->download('revenue_report.pdf');
|
||||
} elseif ($exportType == 'xlsx') {
|
||||
return Excel::download(new RevenueExport(), 'revenue_report.xlsx');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Review;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\ReviewRequest;
|
||||
|
||||
class ReviewController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$reviews = Review::with('product', 'user')->latest()->paginate(5);
|
||||
|
||||
return view('admin.reviews.index', compact('reviews'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Review $review)
|
||||
{
|
||||
return view('admin.reviews.show', compact('review'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Review $review)
|
||||
{
|
||||
return view('admin.reviews.edit', compact('review'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ReviewRequest $request,Review $review)
|
||||
{
|
||||
$review->update($request->validated());
|
||||
|
||||
return redirect()->route('admin.reviews.index')->with([
|
||||
'message' => 'success updated !',
|
||||
'alert-type' => 'info'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Review $review)
|
||||
{
|
||||
$review->delete();
|
||||
|
||||
return redirect()->route('admin.reviews.index')->with([
|
||||
'message' => 'success deleted !',
|
||||
'alert-type' => 'danger'
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Schedule;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ScheduleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// abort_if(Gate::denies('schedule_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
//$schedules = Schedule::orderByRaw("CASE WHEN status = 'available' THEN 1 ELSE 2 END")->get();
|
||||
$schedules = Schedule::all();
|
||||
//return view('admin.index', compact('schedules'));
|
||||
return view('admin.schedule.index', compact('schedules'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
// abort_if(Gate::denies('schedule_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
return view('admin.schedule.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//abort_if(Gate::denies('schedule_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
// Ubah format tanggal ke 'yyyy-mm-dd'
|
||||
$date = \DateTime::createFromFormat('d-m-Y', $request->input('date'))->format('Y-m-d');
|
||||
|
||||
Schedule::create([
|
||||
'date' => $date,
|
||||
'start_time' => $request->input('start_time'),
|
||||
'end_time' => $request->input('end_time'),
|
||||
'max_slot' => $request->input('max_slot') // Tambahkan nilai 'max_slot'
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.schedule.index')->with('message', "Schedule Successfully Created !");
|
||||
}
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Schedule $schedule
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Schedule $schedule)
|
||||
{
|
||||
return redirect()->route('admin.schedule.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Schedule $schedule
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Schedule $schedule)
|
||||
{
|
||||
//abort_if(Gate::denies('schedule_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
return view('admin.schedule.edit', compact('schedule'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Models\Schedule $schedule
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, Schedule $schedule)
|
||||
{
|
||||
// Validasi input
|
||||
$request->validate([
|
||||
'date' => 'required',
|
||||
'start_time' => 'required',
|
||||
'end_time' => 'required',
|
||||
'max_slot' => 'required'
|
||||
]);
|
||||
|
||||
// Periksa apakah jumlah slot yang baru lebih besar dari jumlah slot yang sudah digunakan
|
||||
if ($request->max_slot > $schedule->used_slot) {
|
||||
// Jika lebih besar, maka ubah status menjadi "available"
|
||||
$request->merge(['status' => 'available']);
|
||||
}
|
||||
|
||||
// Update schedule
|
||||
$schedule->update([
|
||||
'date' => $request->date,
|
||||
'start_time' => $request->start_time,
|
||||
'end_time' => $request->end_time,
|
||||
'max_slot' => $request->max_slot,
|
||||
'status' => $request->status // Ubah status sesuai dengan logika di atas
|
||||
]);
|
||||
|
||||
// Redirect ke halaman index dengan pesan sukses
|
||||
return redirect()->route('admin.schedule.index')->with('message', "Schedule Successfully Updated !");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Schedule $schedule
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Schedule $schedule)
|
||||
{
|
||||
//abort_if(Gate::denies('schedule_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$schedule->delete();
|
||||
|
||||
return redirect()->route('admin.schedule.index')->with('message', "Schedule Successfully Deleted !");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\ServiceCategory;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ServiceCategoryController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//abort_if(Gate::denies('category_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
$serviceCategories = ServiceCategory::get();
|
||||
return view('admin.servicecategory.index', compact('serviceCategories'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//abort_if(Gate::denies('category_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
return view('admin.servicecategory.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//abort_if(Gate::denies('category_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
ServiceCategory::create([
|
||||
'name' => Str::ucfirst($request->get('name')),
|
||||
'slug' => Str::slug($request->get('name'))
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.category.index')->with('message', "Service Category Successfully Created !");
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\ServiceCategory $serviceCategory
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(ServiceCategory $serviceCategory)
|
||||
{
|
||||
return redirect()->route('admin.category.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\ServiceCategory $serviceCategory
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//abort_if(Gate::denies('category_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
$serviceCategory = ServiceCategory::findOrFail($id);
|
||||
return view('admin.serviceCategory.edit', compact('serviceCategory'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Models\ServiceCategory $serviceCategory
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
//abort_if(Gate::denies('category_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$serviceCategory = ServiceCategory::findOrFail($id);
|
||||
|
||||
$request->validate([
|
||||
'name' => 'required'
|
||||
]);
|
||||
|
||||
$serviceCategory->update([
|
||||
'name' => Str::ucfirst($request->name),
|
||||
'slug' => Str::slug($request->name)
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.category.index')->with('message', 'Service Category Successfully Updated !');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\ServiceCategory $serviceCategory
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//abort_if(Gate::denies('category_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
$serviceCategory = ServiceCategory::findOrFail($id);
|
||||
$serviceCategory->delete();
|
||||
return redirect()->route('admin.category.index')->with('message', 'Category Service Successfully Deleted !');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Service;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\StoreServiceRequest;
|
||||
use App\Http\Requests\Admin\UpdateServiceRequest;
|
||||
use App\Models\Obtained;
|
||||
use App\Models\ServiceCategory;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ServiceController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$services = Service::paginate(5);
|
||||
|
||||
return view('admin.services.index', compact('services'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$obtaineds = Obtained::pluck('name', 'id');
|
||||
$serviceCategories = ServiceCategory::get();
|
||||
|
||||
return view('admin.services.create', compact('obtaineds', 'serviceCategories'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreServiceRequest $request)
|
||||
{
|
||||
$service = Service::create($request->validated());
|
||||
$service->obtaineds()->sync($request->input('obtaineds'));
|
||||
|
||||
return redirect()->route('admin.service.index')->with('message', "Service Successfully Created !");
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Service $service)
|
||||
{
|
||||
return redirect()->route('admin.service.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Service $service)
|
||||
{
|
||||
$obtaineds = Obtained::pluck('name', 'id');
|
||||
$serviceCategories = ServiceCategory::get();
|
||||
|
||||
return view('admin.services.edit', compact('service', 'obtaineds', 'serviceCategories'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Models\Service $service
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(UpdateServiceRequest $request, Service $service)
|
||||
{
|
||||
$service->update($request->validated());
|
||||
$service->obtaineds()->sync($request->input('obtaineds'));
|
||||
|
||||
return redirect()->route('admin.service.index')->with('message', "Service Successfully Updated !");
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Service $service)
|
||||
{
|
||||
$service->delete();
|
||||
|
||||
return redirect()->route('admin.service.index')->with('message', "Service Successfully Deleted !");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\Shipment;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class ShipmentController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$shipments = Shipment::latest()->paginate(10);
|
||||
|
||||
return view('admin.shipments.index', compact('shipments'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Shipment $shipment)
|
||||
{
|
||||
$provinces = $this->getProvinces();
|
||||
$cities = isset($shipment->province_id) ? $this->getCities($shipment->province_id) : [];
|
||||
|
||||
return view('admin.shipments.edit', compact('shipment', 'provinces', 'cities'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, Shipment $shipment)
|
||||
{
|
||||
$request->validate(
|
||||
[
|
||||
'track_number' => 'required|max:255',
|
||||
]
|
||||
);
|
||||
|
||||
$order = \DB::transaction(
|
||||
function () use ($shipment, $request) {
|
||||
$shipment->track_number = $request->input('track_number');
|
||||
$shipment->status = Shipment::SHIPPED;
|
||||
$shipment->shipped_at = now();
|
||||
$shipment->shipped_by = auth()->id();
|
||||
|
||||
if ($shipment->save()) {
|
||||
$shipment->order->status = Order::DELIVERED;
|
||||
$shipment->order->save();
|
||||
}
|
||||
|
||||
return $shipment->order;
|
||||
}
|
||||
);
|
||||
|
||||
return redirect()->route('admin.orders.show', $order->id)->with([
|
||||
'message' => 'success updated shipment !',
|
||||
'alert-type' => 'info'
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Slide;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Traits\ImageUploadTrait;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use App\Http\Requests\Admin\SlideRequest;
|
||||
|
||||
class SlideController extends Controller
|
||||
{
|
||||
use ImageUploadTrait;
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$slides = Slide::latest()->paginate(5);
|
||||
|
||||
return view('admin.slides.index', compact('slides'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('admin.slides.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(SlideRequest $request)
|
||||
{
|
||||
$image = NULL;
|
||||
if ($request->hasFile('cover')) {
|
||||
$image = $this->uploadImage($request->title, $request->cover, 'slides', 500, 500);
|
||||
}
|
||||
|
||||
Slide::create([
|
||||
'title' => $request->title,
|
||||
'url' => $request->url,
|
||||
'body' => $request->body,
|
||||
'cover' => $image,
|
||||
'position' => Slide::max('position') + 1
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.slides.index')->with([
|
||||
'message' => 'success created !',
|
||||
'alert-type' => 'success'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Slide $slide)
|
||||
{
|
||||
return view('admin.slides.show', compact('slide'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Slide $slide)
|
||||
{
|
||||
return view('admin.slides.edit', compact('slide'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request,Slide $slide)
|
||||
{
|
||||
$image = $slide->cover;
|
||||
if ($request->has('cover')) {
|
||||
if ($slide->cover != null && File::exists('storage/images/slides/'. $slide->cover)) {
|
||||
unlink('storage/images/slides/'. $slide->cover);
|
||||
}
|
||||
$image = $this->uploadImage($request->title, $request->cover, 'slides', 450, 450);
|
||||
}
|
||||
|
||||
$slide->update([
|
||||
'title' => $request->title,
|
||||
'url' => $request->url,
|
||||
'body' => $request->body,
|
||||
'cover' => $image,
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.slides.index')->with([
|
||||
'message' => 'success updated !',
|
||||
'alert-type' => 'info'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Slide $slide)
|
||||
{
|
||||
if ($slide->cover) {
|
||||
if (File::exists('storage/images/slides/'. $slide->cover)) {
|
||||
unlink('storage/images/slides/'. $slide->cover);
|
||||
}
|
||||
}
|
||||
|
||||
$slide->delete();
|
||||
|
||||
return redirect()->route('admin.slides.index')->with([
|
||||
'message' => 'success deleted !',
|
||||
'alert-type' => 'danger'
|
||||
]);
|
||||
}
|
||||
|
||||
public function moveUp($slideId){
|
||||
$slide = Slide::findOrFail($slideId);
|
||||
|
||||
if (!$slide->prevSlide()) {
|
||||
return redirect()->route('admin.slides.index');
|
||||
}
|
||||
|
||||
\DB::transaction(
|
||||
function () use ($slide) {
|
||||
$currentPosition = $slide->position;
|
||||
$prevPosition = $slide->prevSlide()->position;
|
||||
|
||||
$prevSlide = Slide::find($slide->prevSlide()->id);
|
||||
$prevSlide->position = $currentPosition;
|
||||
$prevSlide->save();
|
||||
|
||||
$slide->position = $prevPosition;
|
||||
$slide->save();
|
||||
}
|
||||
);
|
||||
|
||||
return redirect()->route('admin.slides.index');
|
||||
}
|
||||
|
||||
public function moveDown($slideId){
|
||||
$slide = Slide::findOrFail($slideId);
|
||||
|
||||
if (!$slide->nextSlide()) {
|
||||
return redirect()->route('admin.slides.index');
|
||||
}
|
||||
|
||||
\DB::transaction(
|
||||
function () use ($slide) {
|
||||
$currentPosition = $slide->position;
|
||||
$prevPosition = $slide->nextSlide()->position;
|
||||
|
||||
$prevSlide = Slide::find($slide->nextSlide()->id);
|
||||
$prevSlide->position = $currentPosition;
|
||||
$prevSlide->save();
|
||||
|
||||
$slide->position = $prevPosition;
|
||||
$slide->save();
|
||||
}
|
||||
);
|
||||
|
||||
return redirect()->route('admin.slides.index');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Tag;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use App\Http\Requests\Admin\TagRequest;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//abort_if(Gate::denies('tag_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$tags = Tag::withCount('products')->latest()->paginate(5);
|
||||
|
||||
return view('admin.tags.index', compact('tags'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//abort_if(Gate::denies('tag_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
return view('admin.tags.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(TagRequest $request)
|
||||
{
|
||||
//abort_if(Gate::denies('tag_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
Tag::create($request->validated());
|
||||
|
||||
return redirect()->route('admin.tags.index')->with([
|
||||
'message' => 'success created !',
|
||||
'alert-type' => 'success'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Tag $tag)
|
||||
{
|
||||
//abort_if(Gate::denies('tag_view'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
return view('admin.tags.show', compact('tag'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Tag $tag)
|
||||
{
|
||||
//abort_if(Gate::denies('tag_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
return view('admin.tags.edit', compact('tag'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(TagRequest $request, Tag $tag)
|
||||
{
|
||||
//abort_if(Gate::denies('tag_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$tag->update($request->validated());
|
||||
|
||||
return redirect()->route('admin.tags.index')->with([
|
||||
'message' => 'success updated !',
|
||||
'alert-type' => 'info'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Tag $tag)
|
||||
{
|
||||
//abort_if(Gate::denies('tag_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');
|
||||
|
||||
$tag->delete();
|
||||
|
||||
return redirect()->route('admin.tags.index')->with([
|
||||
'message' => 'success deleted !',
|
||||
'alert-type' => 'danger',
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
use App\Models\Role;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\StoreUserRequest;
|
||||
use App\Http\Requests\Admin\UpdateUserRequest;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$users = User::paginate(5);
|
||||
|
||||
return view('admin.users.index', compact('users'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('admin.users.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreUserRequest $request)
|
||||
{
|
||||
$user = User::create($request->validated() + ['password' => bcrypt($request->password)]);
|
||||
|
||||
return redirect()->route('admin.users.index')->with('message', "Successfully Created !");
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$user = User::findOrFail($id);
|
||||
//$roles = Role::all(); // Ganti Role dengan model yang sesuai dengan role Anda
|
||||
return view('admin.users.edit', compact('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(UpdateUserRequest $request, $id)
|
||||
{
|
||||
$user = User::findOrFail($id);
|
||||
$user->update($request->validated() + ['password' => bcrypt($request->password)]);
|
||||
|
||||
return redirect()->route('admin.users.index')->with('message', "Successfully Updated !");
|
||||
}
|
||||
|
||||
// Methods for deleting users...
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
||||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Confirm Password Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password confirmations and
|
||||
| uses a simple trait to include the behavior. You're free to explore
|
||||
| this trait and override any functions that require customization.
|
||||
|
|
||||
*/
|
||||
|
||||
use ConfirmsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users when the intended url fails.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset emails and
|
||||
| includes a trait which assists in sending these notifications from
|
||||
| your application to your users. Feel free to explore this trait.
|
||||
|
|
||||
*/
|
||||
|
||||
use SendsPasswordResetEmails;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles authenticating users for the application and
|
||||
| redirecting them to your home screen. The controller uses a trait
|
||||
| to conveniently provide its functionality to your applications.
|
||||
|
|
||||
*/
|
||||
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ProfileRequest;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$provinces = $this->getProvinces();
|
||||
$cities = isset(auth()->user()->province_id) ? $this->getCities(auth()->user()->province_id) : [];
|
||||
$user = auth()->user();
|
||||
|
||||
return view('frontend.users.profile', compact('provinces', 'cities','user'));
|
||||
}
|
||||
|
||||
public function update(ProfileRequest $request){
|
||||
$user = auth()->user();
|
||||
|
||||
$user->update($request->validated());
|
||||
|
||||
return redirect()->route('profile.index')->with(['message' => 'success updated']);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles the registration of new users as well as their
|
||||
| validation and creation. By default this controller uses a trait to
|
||||
| provide this functionality without requiring any additional code.
|
||||
|
|
||||
*/
|
||||
|
||||
use RegistersUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after registration.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'username' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
//'phone' => ['required', 'string'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\Models\User
|
||||
*/
|
||||
protected function create(array $data)
|
||||
{
|
||||
$user = User::create([
|
||||
'username' => $data['username'],
|
||||
'email' => $data['email'],
|
||||
'password' => Hash::make($data['password']),
|
||||
//'phone' => $data['phone'],
|
||||
//'role' => 2, // Menetapkan peran secara langsung
|
||||
]);
|
||||
|
||||
if ($user->id === 1) {
|
||||
$user->role = 1; // ID 1 menjadi admin
|
||||
} else {
|
||||
$user->role = 2; // ID bukan 1, maka menjadi user biasa
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
return $user;
|
||||
//return $user;
|
||||
//$user->roles()->attach([2]);
|
||||
|
||||
//return $user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users after resetting their password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email Verification Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling email verification for any
|
||||
| user that recently registered with the application. Emails may also
|
||||
| be re-sent if the user didn't receive the original email message.
|
||||
|
|
||||
*/
|
||||
|
||||
use VerifiesEmails;
|
||||
|
||||
/**
|
||||
* Where to redirect users after verification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Models\Schedule;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class BookingController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required',
|
||||
'handphone' => 'required|numeric',
|
||||
'category' => 'required',
|
||||
'schedule_id' => 'required|exists:schedules,id',
|
||||
]);
|
||||
|
||||
$schedule = Schedule::find($request->schedule_id);
|
||||
$scheduleId = $schedule->id;
|
||||
$currentBookings = Booking::where('schedule_id', $request->schedule_id)->count();
|
||||
|
||||
if ($currentBookings >= $schedule->max_slot) {
|
||||
return redirect()->back()->with('error', 'Schedule is fully booked');
|
||||
}
|
||||
|
||||
$date = $schedule->date;
|
||||
$time = $schedule->time;
|
||||
$booking = Booking::create([
|
||||
'service_name' => $request->service_name,
|
||||
'name' => $request->name,
|
||||
'handphone' => $request->handphone,
|
||||
'category' => $request->category,
|
||||
'date' => $date,
|
||||
'time' => $time,
|
||||
'total' => $request->price,
|
||||
'status' => 'Unpaid',
|
||||
'schedule_id' => $request->schedule_id, // Assign schedule_id here
|
||||
]);
|
||||
|
||||
if ($request['cash'] === "on" && $request['cashless'] === "on") {
|
||||
return '<script>alert("Choose one payment only!!!");window.location.href="/orders/checkout"</script>';
|
||||
}
|
||||
|
||||
if ($currentBookings + 1 >= $schedule->max_slot) {
|
||||
$schedule->status = 'not available';
|
||||
$schedule->save();
|
||||
}
|
||||
if ($request['cash'] === "on") {
|
||||
$booking->update(['status' => 'Cash']);
|
||||
// $scheduleData->update(['status' => 'booked']);
|
||||
return view('frontend.booking.paycash', compact('booking'));
|
||||
}
|
||||
|
||||
// Set your Merchant Server Key
|
||||
\Midtrans\Config::$serverKey = config('midtrans.serverKey');
|
||||
// Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
|
||||
\Midtrans\Config::$isProduction = false;
|
||||
// Set sanitization on (default)
|
||||
\Midtrans\Config::$isSanitized = true;
|
||||
// Set 3DS transaction for credit card to true
|
||||
\Midtrans\Config::$is3ds = true;
|
||||
|
||||
$params = array(
|
||||
'transaction_details' => array(
|
||||
'order_id' => Str::random(15),
|
||||
'gross_amount' => $request->price,
|
||||
),
|
||||
'customer_details' => array(
|
||||
'name' => $request->name,
|
||||
'handphone' => $request->handphone,
|
||||
),
|
||||
);
|
||||
|
||||
$snapToken = \Midtrans\Snap::getSnapToken($params);
|
||||
|
||||
return view('frontend.booking.detail', compact('snapToken', 'booking', 'scheduleId'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Booking $booking
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($serviceId)
|
||||
{
|
||||
$service = Service::findOrFail($serviceId);
|
||||
$schedules = Schedule::where(['status' => 'available'])->get();
|
||||
return view('frontend.booking.index', compact('service', 'schedules'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Booking $booking
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Booking $booking)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Models\Booking $booking
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, Booking $booking)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Booking $booking
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Booking $booking)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function midtrans_callback(Request $request)
|
||||
{
|
||||
$serverKey = config('midtrans.serverKey');
|
||||
$hashed = hash('sha512', $request->order_id . $request->status_code . $request->gross_amount . $serverKey);
|
||||
|
||||
if ($hashed == $request->signature_key) {
|
||||
if ($request->transaction_status == 'capture') {
|
||||
$booking = Booking::find($request->order_id);
|
||||
$booking->update(['status' => 'Paid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function payment_success($bookingId, $scheduleId)
|
||||
{
|
||||
$booking = Booking::findOrFail($bookingId);
|
||||
$booking->update(['status' => 'Paid']);
|
||||
|
||||
$schedule = Schedule::findOrFail($scheduleId);
|
||||
//$schedule->update(['status' => 'booked']);
|
||||
|
||||
return redirect()->route('service.index');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Exceptions\OutOfStockException;
|
||||
|
||||
class CartController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$carts = \Cart::getContent();
|
||||
|
||||
return view('frontend.cart.index', compact('carts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$product = Product::findOrFail($request->product_id);
|
||||
|
||||
$carts = \Cart::getContent();
|
||||
$itemQuantity = 0;
|
||||
if ($carts) {
|
||||
foreach ($carts as $cart) {
|
||||
if ($cart->name == $product->name) {
|
||||
$itemQuantity = $cart->quantity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$itemQuantity += $request->qty;
|
||||
|
||||
try {
|
||||
if ($product->quantity < $itemQuantity) {
|
||||
throw new OutOfStockException('produk '. $product->name .' kosong !');
|
||||
}
|
||||
} catch (\App\Exceptions\OutOfStockException $exception) {
|
||||
return redirect()->back()->with([
|
||||
'message' => $exception->getMessage(),
|
||||
'alert-type' => 'danger',
|
||||
]);
|
||||
}
|
||||
|
||||
$item = [
|
||||
'id' => md5($product->id),
|
||||
'name' => $product->name,
|
||||
'price' => $product->price,
|
||||
'quantity' => $request->qty,
|
||||
'associatedModel' => $product,
|
||||
];
|
||||
|
||||
\Cart::add($item);
|
||||
|
||||
return redirect()->back()->with([
|
||||
'message' => 'success added to cart !',
|
||||
'alert-type' => 'success',
|
||||
]);;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request)
|
||||
{
|
||||
$params = $request->except('_token');
|
||||
|
||||
if($items = $params['items']){
|
||||
foreach($items as $cartId => $item){
|
||||
$carts = \Cart::getContent();
|
||||
|
||||
try {
|
||||
if ($carts[$cartId]->associatedModel->quantity < $item['quantity']) {
|
||||
throw new OutOfStockException('produk '. $carts[$cartId]->associatedModel->name .' tersisa ' . $carts[$cartId]->associatedModel->quantity);
|
||||
}
|
||||
} catch (\App\Exceptions\OutOfStockException $exception) {
|
||||
return redirect()->back()->with([
|
||||
'message' => $exception->getMessage(),
|
||||
'alert-type' => 'danger',
|
||||
]);
|
||||
}
|
||||
|
||||
\Cart::update($cartId,[
|
||||
'quantity' => [
|
||||
'relative' => false,
|
||||
'value' => $item['quantity'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->back()->with([
|
||||
'message' => 'success updated !',
|
||||
'alert-type' => 'info'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($cartId)
|
||||
{
|
||||
\Cart::remove($cartId);
|
||||
|
||||
return redirect()->back()->with([
|
||||
'message' => 'success deleted !',
|
||||
'alert-type' => 'danger'
|
||||
]);;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Midtrans\Config;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
protected $data = [];
|
||||
protected $uploadsFolder = 'uploads/';
|
||||
|
||||
protected $rajaOngkirApiKey = null;
|
||||
protected $rajaOngkirBaseUrl = null;
|
||||
protected $rajaOngkirOrigin = null;
|
||||
protected $couriers = [
|
||||
'jne' => 'JNE',
|
||||
'pos' => 'POS Indonesia',
|
||||
'tiki' => 'Titipan Kilat'
|
||||
];
|
||||
|
||||
protected $provinces = [];
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->rajaOngkirApiKey = config('rajaongkir.api_key');
|
||||
$this->rajaOngkirBaseUrl = config('rajaongkir.base_url');
|
||||
$this->rajaOngkirOrigin = config('rajaongkir.origin');
|
||||
}
|
||||
/**
|
||||
* Raja Ongkir Request (Shipping Cost Calculation)
|
||||
*
|
||||
* @param string $resource resource url
|
||||
* @param array $params parameters
|
||||
* @param string $method request method
|
||||
*
|
||||
* @return json
|
||||
*/
|
||||
protected function rajaOngkirRequest($resource, $params = [], $method = 'GET')
|
||||
{
|
||||
$client = new \GuzzleHttp\Client();
|
||||
|
||||
$headers = ['key' => $this->rajaOngkirApiKey];
|
||||
$requestParams = [
|
||||
'headers' => $headers,
|
||||
];
|
||||
|
||||
$url = $this->rajaOngkirBaseUrl . $resource;
|
||||
if ($params && $method == 'POST') {
|
||||
$requestParams['form_params'] = $params;
|
||||
} else if ($params && $method == 'GET') {
|
||||
$query = is_array($params) ? '?'.http_build_query($params) : '';
|
||||
$url = $this->rajaOngkirBaseUrl . $resource . $query;
|
||||
}
|
||||
|
||||
$response = $client->request($method, $url, $requestParams);
|
||||
|
||||
return json_decode($response->getBody(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get provinces
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getProvinces()
|
||||
{
|
||||
$provinceFile = 'provinces.txt';
|
||||
$provinceFilePath = $this->uploadsFolder. 'files/' . $provinceFile;
|
||||
|
||||
$isExistProvinceJson = \Storage::disk('local')->exists($provinceFilePath);
|
||||
|
||||
if (!$isExistProvinceJson) {
|
||||
$response = $this->rajaOngkirRequest('province');
|
||||
\Storage::disk('local')->put($provinceFilePath, serialize($response['rajaongkir']['results']));
|
||||
}
|
||||
|
||||
$province = unserialize(\Storage::get($provinceFilePath));
|
||||
|
||||
$provinces = [];
|
||||
if (!empty($province)) {
|
||||
foreach ($province as $province) {
|
||||
$provinces[$province['province_id']] = strtoupper($province['province']);
|
||||
}
|
||||
}
|
||||
|
||||
return $provinces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cities by province ID
|
||||
*
|
||||
* @param int $provinceId province id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getCities($provinceId)
|
||||
{
|
||||
$cityFile = 'cities_at_'. $provinceId .'.txt';
|
||||
$cityFilePath = $this->uploadsFolder. 'files/' .$cityFile;
|
||||
|
||||
$isExistCitiesJson = \Storage::disk('local')->exists($cityFilePath);
|
||||
|
||||
if (!$isExistCitiesJson) {
|
||||
$response = $this->rajaOngkirRequest('city', ['province' => $provinceId]);
|
||||
\Storage::disk('local')->put($cityFilePath, serialize($response['rajaongkir']['results']));
|
||||
}
|
||||
|
||||
$cityList = unserialize(\Storage::get($cityFilePath));
|
||||
|
||||
$cities = [];
|
||||
if (!empty($cityList)) {
|
||||
foreach ($cityList as $city) {
|
||||
$cities[$city['city_id']] = strtoupper($city['type'].' '.$city['city_name']);
|
||||
}
|
||||
}
|
||||
|
||||
return $cities;
|
||||
}
|
||||
|
||||
protected function initPaymentGateway()
|
||||
{
|
||||
// Set your Merchant Server Key
|
||||
Config::$serverKey = config('midtrans.serverKey');
|
||||
// Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
|
||||
Config::$isProduction = config('midtrans.isProduction');
|
||||
// Set sanitization on (default)
|
||||
Config::$isSanitized = config('midtrans.isSanitized');
|
||||
// Set 3DS transaction for credit card to true
|
||||
Config::$is3ds = config('midtrans.is3ds');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Product;
|
||||
use App\Models\Favorite;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FavoriteController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$favorites = Favorite::where('user_id', auth()->id())
|
||||
->paginate(10);
|
||||
|
||||
return view('frontend.favorites.index', compact('favorites'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
if(!auth()->check()){
|
||||
return response('kamu harus login dulu !',200);
|
||||
}
|
||||
$request->validate(
|
||||
[
|
||||
'product_slug' => 'required',
|
||||
]
|
||||
);
|
||||
|
||||
$product = Product::where('slug', $request->get('product_slug'))->firstOrFail();
|
||||
|
||||
$favorite = Favorite::where('user_id', auth()->id())
|
||||
->where('product_id', $product->id)
|
||||
->first();
|
||||
if ($favorite) {
|
||||
return response('You have added this product to your favorite before', 422);
|
||||
}
|
||||
|
||||
Favorite::create(
|
||||
[
|
||||
'user_id' => auth()->id(),
|
||||
'product_id' => $product->id,
|
||||
]
|
||||
);
|
||||
|
||||
return response('The product has been added to your favorite', 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Favorite $favorite)
|
||||
{
|
||||
$favorite->delete();
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Category;
|
||||
use App\Models\Product;
|
||||
use App\Models\Slide;
|
||||
use Illuminate\Http\Request;
|
||||
use phpDocumentor\Reflection\Types\Null_;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Support\Renderable
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$products = Product::latest()->get();
|
||||
$categories = Category::whereNull('category_id')->take(4)->get();
|
||||
$slides = Slide::latest()->get();
|
||||
|
||||
return view('frontend.homepage', compact('products', 'categories','slides'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Obtained;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ObtainedController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Obtained $obtained
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Obtained $obtained)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Obtained $obtained
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Obtained $obtained)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Models\Obtained $obtained
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, Obtained $obtained)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Obtained $obtained
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Obtained $obtained)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,432 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Exception;
|
||||
use Midtrans\Snap;
|
||||
use App\Models\Order;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Product;
|
||||
use App\Models\Shipment;
|
||||
use App\Models\OrderItem;
|
||||
use FontLib\Table\Type\name;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class OrderController extends Controller
|
||||
{
|
||||
public function process()
|
||||
{
|
||||
if (\Cart::isEmpty()) {
|
||||
return redirect()->route('cart.index');
|
||||
}
|
||||
|
||||
// \Cart::removeConditionsByType('shipping');
|
||||
|
||||
$items = \Cart::getContent();
|
||||
|
||||
// $totalWeight = 0;
|
||||
// foreach ($items as $item) {
|
||||
// $totalWeight += ($item->quantity * $item->associatedModel->weight);
|
||||
// }
|
||||
|
||||
// $provinces = $this->getProvinces();
|
||||
// $cities = isset(auth()->user()->city_id) ? $this->getCities(auth()->user()->province_id) : [];
|
||||
|
||||
return view('frontend.orders.checkout', compact('items'));
|
||||
}
|
||||
|
||||
public function cities(Request $request)
|
||||
{
|
||||
$cities = $this->getCities($request->query('province_id'));
|
||||
return response()->json(['cities' => $cities]);
|
||||
}
|
||||
|
||||
public function shippingCost(Request $request)
|
||||
{
|
||||
$items = \Cart::getContent();
|
||||
|
||||
$totalWeight = 0;
|
||||
foreach ($items as $item) {
|
||||
$totalWeight += ($item->quantity * $item->associatedModel->weight);
|
||||
}
|
||||
|
||||
$destination = $request->input('city_id');
|
||||
return $this->getShippingCost($destination, $totalWeight);
|
||||
}
|
||||
|
||||
private function getShippingCost($destination, $weight)
|
||||
{
|
||||
$params = [
|
||||
'origin' => env('RAJAONGKIR_ORIGIN'),
|
||||
'destination' => $destination,
|
||||
'weight' => $weight,
|
||||
];
|
||||
|
||||
$results = [];
|
||||
foreach ($this->couriers as $code => $courier) {
|
||||
$params['courier'] = $code;
|
||||
|
||||
$response = $this->rajaOngkirRequest('cost', $params, 'POST');
|
||||
|
||||
if (!empty($response['rajaongkir']['results'])) {
|
||||
foreach ($response['rajaongkir']['results'] as $cost) {
|
||||
if (!empty($cost['costs'])) {
|
||||
foreach ($cost['costs'] as $costDetail) {
|
||||
$serviceName = strtoupper($cost['code']) . ' - ' . $costDetail['service'];
|
||||
$costAmount = $costDetail['cost'][0]['value'];
|
||||
$etd = $costDetail['cost'][0]['etd'];
|
||||
|
||||
$result = [
|
||||
'service' => $serviceName,
|
||||
'cost' => $costAmount,
|
||||
'etd' => $etd,
|
||||
'courier' => $code,
|
||||
];
|
||||
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response = [
|
||||
'origin' => $params['origin'],
|
||||
'destination' => $destination,
|
||||
'weight' => $weight,
|
||||
'results' => $results,
|
||||
];
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function setShipping(Request $request)
|
||||
{
|
||||
\Cart::removeConditionsByType('shipping');
|
||||
|
||||
$items = \Cart::getContent();
|
||||
|
||||
$totalWeight = 0;
|
||||
foreach ($items as $item) {
|
||||
$totalWeight += ($item->quantity * $item->associatedModel->weight);
|
||||
}
|
||||
|
||||
$shippingService = $request->get('shipping_service');
|
||||
$destination = $request->get('city_id');
|
||||
|
||||
$shippingOptions = $this->getShippingCost($destination, $totalWeight);
|
||||
|
||||
$selectedShipping = null;
|
||||
if ($shippingOptions['results']) {
|
||||
foreach ($shippingOptions['results'] as $shippingOption) {
|
||||
if (str_replace(' ', '', $shippingOption['service']) == $shippingService) {
|
||||
$selectedShipping = $shippingOption;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$status = null;
|
||||
$message = null;
|
||||
$data = [];
|
||||
if ($selectedShipping) {
|
||||
$status = 200;
|
||||
$message = 'Success set shipping cost';
|
||||
|
||||
$this->addShippingCostToCart($selectedShipping['service'], $selectedShipping['cost']);
|
||||
|
||||
$data['total'] = number_format(\Cart::getTotal());
|
||||
} else {
|
||||
$status = 400;
|
||||
$message = 'Failed to set shipping cost';
|
||||
}
|
||||
|
||||
$response = [
|
||||
'status' => $status,
|
||||
'message' => $message
|
||||
];
|
||||
|
||||
if ($data) {
|
||||
$response['data'] = $data;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function addShippingCostToCart($serviceName, $cost)
|
||||
{
|
||||
$condition = new \Darryldecode\Cart\CartCondition(
|
||||
[
|
||||
'name' => $serviceName,
|
||||
'type' => 'shipping',
|
||||
'target' => 'total',
|
||||
'value' => '+' . $cost,
|
||||
]
|
||||
);
|
||||
|
||||
\Cart::condition($condition);
|
||||
}
|
||||
|
||||
private function getSelectedShipping($destination, $totalWeight, $shippingService)
|
||||
{
|
||||
$shippingOptions = $this->getShippingCost($destination, $totalWeight);
|
||||
|
||||
$selectedShipping = null;
|
||||
if ($shippingOptions['results']) {
|
||||
foreach ($shippingOptions['results'] as $shippingOption) {
|
||||
if (str_replace(' ', '', $shippingOption['service']) == $shippingService) {
|
||||
$selectedShipping = $shippingOption;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $selectedShipping;
|
||||
}
|
||||
|
||||
public function checkout(Request $request)
|
||||
{
|
||||
$token = $request->except('_token');
|
||||
|
||||
$order = \DB::transaction(function () use ($token) {
|
||||
// $destination = isset($params['ship_to']) ? $params['shipping_city_id'] : $params['city_id'];
|
||||
// $items = \Cart::getContent();
|
||||
|
||||
// $totalWeight = 0;
|
||||
// foreach ($items as $item) {
|
||||
// $totalWeight += ($item->quantity * $item->associatedModel->weight);
|
||||
// }
|
||||
|
||||
// $selectedShipping = $this->getSelectedShipping($destination, $totalWeight, $params['shipping_service']);
|
||||
|
||||
$baseTotalPrice = \Cart::getSubTotal();
|
||||
// $shippingCost = $selectedShipping['cost'];
|
||||
// $discountAmount = 0;
|
||||
// $discountPercent = 0;
|
||||
// $grandTotal = ($baseTotalPrice + $shippingCost) - $discountAmount;
|
||||
|
||||
$orderDate = date('Y-m-d H:i:s');
|
||||
$paymentDue = (new \DateTime($orderDate))->modify('+3 day')->format('Y-m-d H:i:s');
|
||||
|
||||
// $user_profile = [
|
||||
// 'username' => $params['username'],
|
||||
// 'first_name' => $params['first_name'],
|
||||
// 'last_name' => $params['last_name'],
|
||||
// 'address1' => $params['address1'],
|
||||
// 'address2' => $params['address2'],
|
||||
// 'province_id' => $params['province_id'],
|
||||
// 'city_id' => $params['city_id'],
|
||||
// 'postcode' => $params['postcode'],
|
||||
// 'phone' => $params['phone'],
|
||||
// 'email' => $params['email'],
|
||||
// ];
|
||||
|
||||
// auth()->user()->update($user_profile);
|
||||
|
||||
$orderParams = [
|
||||
'user_id' => auth()->id(),
|
||||
'code' => Order::generateCode(),
|
||||
'status' => Order::CREATED,
|
||||
'order_date' => $orderDate,
|
||||
'payment_due' => $paymentDue,
|
||||
'payment_status' => Order::UNPAID,
|
||||
'base_total_price' => $baseTotalPrice,
|
||||
// 'discount_amount' => $discountAmount,
|
||||
// 'discount_percent' => $discountPercent,
|
||||
// 'shipping_cost' => $shippingCost,
|
||||
// 'grand_total' => $grandTotal,
|
||||
'customer_first_name' => $token['username'],
|
||||
// 'customer_last_name' => $params['last_name'],
|
||||
// 'customer_address1' => $params['address1'],
|
||||
// 'customer_address2' => $params['address2'],
|
||||
'customer_phone' => $token['phone'],
|
||||
// 'customer_email' => $params['email'],
|
||||
// 'customer_city_id' => $params['city_id'],
|
||||
// 'customer_province_id' => $params['province_id'],
|
||||
// 'customer_postcode' => $params['postcode'],
|
||||
'note' => $token['note'],
|
||||
// 'shipping_courier' => $selectedShipping['courier'],
|
||||
// 'shipping_service_name' => $selectedShipping['service'],
|
||||
];
|
||||
|
||||
$order = Order::create($orderParams);
|
||||
|
||||
$cartItems = \Cart::getContent();
|
||||
|
||||
if ($order && $cartItems) {
|
||||
foreach ($cartItems as $item) {
|
||||
$itemDiscountAmount = 0;
|
||||
$itemDiscountPercent = 0;
|
||||
$itemBaseTotal = $item->quantity * $item->price;
|
||||
$itemSubTotal = $itemBaseTotal - $itemDiscountAmount;
|
||||
|
||||
$product = $item->associatedModel;
|
||||
|
||||
$orderItemParams = [
|
||||
'order_id' => $order->id,
|
||||
'product_id' => $item->associatedModel->id,
|
||||
'qty' => $item->quantity,
|
||||
'base_price' => $item->price,
|
||||
'base_total' => $itemBaseTotal,
|
||||
'discount_amount' => $itemDiscountAmount,
|
||||
'discount_percent' => $itemDiscountPercent,
|
||||
'sub_total' => $itemSubTotal,
|
||||
'name' => $item->name,
|
||||
'weight' => $item->associatedModel->weight,
|
||||
];
|
||||
|
||||
$orderItem = OrderItem::create($orderItemParams);
|
||||
|
||||
if ($orderItem) {
|
||||
$product = Product::findOrFail($product->id);
|
||||
$product->quantity -= $item->quantity;
|
||||
$product->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// $shippingFirstName = isset($params['ship_to']) ? $params['shipping_first_name'] : $params['first_name'];
|
||||
// $shippingLastName = isset($params['ship_to']) ? $params['shipping_last_name'] : $params['last_name'];
|
||||
// $shippingAddress1 = isset($params['ship_to']) ? $params['shipping_address1'] : $params['address1'];
|
||||
// $shippingAddress2 = isset($params['ship_to']) ? $params['shipping_address2'] : $params['address2'];
|
||||
// $shippingPhone = isset($params['ship_to']) ? $params['shipping_phone'] : $params['phone'];
|
||||
// $shippingEmail = isset($params['ship_to']) ? $params['shipping_email'] : $params['email'];
|
||||
// $shippingCityId = isset($params['ship_to']) ? $params['shipping_city_id'] : $params['city_id'];
|
||||
// $shippingProvinceId = isset($params['ship_to']) ? $params['shipping_province_id'] : $params['province_id'];
|
||||
// $shippingPostcode = isset($params['ship_to']) ? $params['shipping_postcode'] : $params['postcode'];
|
||||
|
||||
// $shipmentParams = [
|
||||
// 'user_id' => auth()->id(),
|
||||
// 'order_id' => $order->id,
|
||||
// 'status' => Shipment::PENDING,
|
||||
// 'total_qty' => \Cart::getTotalQuantity(),
|
||||
// 'total_weight' => $totalWeight,
|
||||
// 'first_name' => $shippingFirstName,
|
||||
// 'last_name' => $shippingLastName,
|
||||
// 'address1' => $shippingAddress1,
|
||||
// 'address2' => $shippingAddress2,
|
||||
// 'phone' => $shippingPhone,
|
||||
// 'email' => $shippingEmail,
|
||||
// 'city_id' => $shippingCityId,
|
||||
// 'province_id' => $shippingProvinceId,
|
||||
// 'postcode' => $shippingPostcode,
|
||||
// ];
|
||||
// Shipment::create($shipmentParams);
|
||||
|
||||
return $order;
|
||||
});
|
||||
|
||||
if (!isset($order)) {
|
||||
return redirect()->back()->with([
|
||||
'message' => 'something went wrong !',
|
||||
'alert-type' => 'danger'
|
||||
]);
|
||||
// return redirect()->route('checkout.received', $order->id);
|
||||
}
|
||||
|
||||
if ($request['cash'] === "on" && $request['cashless'] === "on") {
|
||||
return '<script>alert("Choose one payment only!!!");window.location.href="/orders/checkout"</script>';
|
||||
}
|
||||
|
||||
if ($request['cash'] === "on") {
|
||||
\Cart::clear();
|
||||
$order->update(['payment_status' => 'cash']);
|
||||
return view('frontend.orders.cash', compact('order'));
|
||||
}
|
||||
|
||||
// Set your Merchant Server Key
|
||||
\Midtrans\Config::$serverKey = config('midtrans.serverKey');
|
||||
// Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
|
||||
\Midtrans\Config::$isProduction = false;
|
||||
// Set sanitization on (default)
|
||||
\Midtrans\Config::$isSanitized = true;
|
||||
// Set 3DS transaction for credit card to true
|
||||
\Midtrans\Config::$is3ds = true;
|
||||
|
||||
$params = array(
|
||||
'transaction_details' => array(
|
||||
'order_id' => Str::random(15),
|
||||
'gross_amount' => $order->base_total_price,
|
||||
),
|
||||
'customer_details' => array(
|
||||
'name' => $request->username,
|
||||
'handphone' => $request->phone,
|
||||
),
|
||||
);
|
||||
|
||||
$snapToken = \Midtrans\Snap::getSnapToken($params);
|
||||
|
||||
return view('frontend.orders.confirmation', compact('snapToken', 'order'));
|
||||
|
||||
// $this->initPaymentGateway();
|
||||
|
||||
// $customerDetails = [
|
||||
// 'first_name' => $order->customer_first_name,
|
||||
// 'last_name' => $order->customer_last_name,
|
||||
// 'email' => $order->customer_email,
|
||||
// 'phone' => $order->customer_phone,
|
||||
// ];
|
||||
|
||||
// $transaction_details = [
|
||||
// 'enable_payments' => Payment::PAYMENT_CHANNELS,
|
||||
// 'transaction_details' => [
|
||||
// 'order_id' => $order->code,
|
||||
// 'gross_amount' => $order->grand_total,
|
||||
// ],
|
||||
// 'customer_details' => $customerDetails,
|
||||
// 'expiry' => [
|
||||
// 'start_time' => date('Y-m-d H:i:s T'),
|
||||
// 'unit' => Payment::EXPIRY_UNIT,
|
||||
// 'duration' => Payment::EXPIRY_DURATION,
|
||||
// ]
|
||||
// ];
|
||||
|
||||
// try {
|
||||
// $snap = Snap::createTransaction($transaction_details);
|
||||
|
||||
// $order->payment_token = $snap->token;
|
||||
// $order->payment_url = $snap->redirect_url;
|
||||
// $order->save();
|
||||
|
||||
// header('Location: ' . $order->payment_url);
|
||||
// exit;
|
||||
// } catch (Exception $e) {
|
||||
// echo $e->getMessage();
|
||||
// }
|
||||
}
|
||||
|
||||
public function order_success($orderId)
|
||||
{
|
||||
$order = Order::find($orderId);
|
||||
$order->update(['payment_status' => 'paid']);
|
||||
\Cart::clear();
|
||||
return redirect()->route('homepage');
|
||||
}
|
||||
|
||||
public function received($orderId)
|
||||
{
|
||||
$order = Order::where('id', $orderId)
|
||||
->where('user_id', auth()->id())
|
||||
->firstOrFail();
|
||||
|
||||
return view('frontend.orders.received', compact('order'));
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$orders = Order::where('user_id', auth()->id())
|
||||
->paginate(10);
|
||||
|
||||
return view('frontend.orders.index', compact('orders'));
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$order = Order::where('user_id', auth()->id())->findOrFail($id);
|
||||
|
||||
return view('frontend.orders.show', compact('order'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\Payment;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PaymentController extends Controller
|
||||
{
|
||||
public function notification(Request $request){
|
||||
$payload = $request->getContent();
|
||||
$notification = json_decode($payload);
|
||||
|
||||
$validSignatureKey = hash("sha512", $notification->order_id . $notification->status_code . $notification->gross_amount . 'SB-Mid-server-qfmZPQ6-2OoutunOib_XJpl3');
|
||||
if ($notification->signature_key != $validSignatureKey) {
|
||||
return response(['message' => 'Invalid signature'], 403);
|
||||
}
|
||||
|
||||
$this->initPaymentGateway();
|
||||
$statusCode = null;
|
||||
|
||||
$paymentNotification = new \Midtrans\Notification();
|
||||
|
||||
$order = Order::where('code', $paymentNotification->order_id)->firstOrFail();
|
||||
|
||||
if ($order->isPaid()) {
|
||||
return response(['message' => 'The order has been paid before'], 422);
|
||||
}
|
||||
|
||||
$transaction = $paymentNotification->transaction_status;
|
||||
$type = $paymentNotification->payment_type;
|
||||
$orderId = $paymentNotification->order_id;
|
||||
$fraud = $paymentNotification->fraud_status;
|
||||
|
||||
$vaNumber = null;
|
||||
$vendorName = null;
|
||||
if (!empty($paymentNotification->va_numbers[0])) {
|
||||
$vaNumber = $paymentNotification->va_numbers[0]->va_number;
|
||||
$vendorName = $paymentNotification->va_numbers[0]->bank;
|
||||
}
|
||||
|
||||
$paymentStatus = null;
|
||||
if ($transaction == 'capture') {
|
||||
// For credit card transaction, we need to check whether transaction is challenge by FDS or not
|
||||
if ($type == 'credit_card') {
|
||||
if ($fraud == 'challenge') {
|
||||
// TODO set payment status in merchant's database to 'Challenge by FDS'
|
||||
// TODO merchant should decide whether this transaction is authorized or not in MAP
|
||||
$paymentStatus = Payment::CHALLENGE;
|
||||
} else {
|
||||
// TODO set payment status in merchant's database to 'Success'
|
||||
$paymentStatus = Payment::SUCCESS;
|
||||
}
|
||||
}
|
||||
} else if ($transaction == 'settlement') {
|
||||
// TODO set payment status in merchant's database to 'Settlement'
|
||||
$paymentStatus = Payment::SETTLEMENT;
|
||||
} else if ($transaction == 'pending') {
|
||||
// TODO set payment status in merchant's database to 'Pending'
|
||||
$paymentStatus = Payment::PENDING;
|
||||
} else if ($transaction == 'deny') {
|
||||
// TODO set payment status in merchant's database to 'Denied'
|
||||
$paymentStatus = PAYMENT::DENY;
|
||||
} else if ($transaction == 'expire') {
|
||||
// TODO set payment status in merchant's database to 'expire'
|
||||
$paymentStatus = PAYMENT::EXPIRE;
|
||||
} else if ($transaction == 'cancel') {
|
||||
// TODO set payment status in merchant's database to 'Denied'
|
||||
$paymentStatus = PAYMENT::CANCEL;
|
||||
}
|
||||
|
||||
$paymentParams = [
|
||||
'order_id' => $order->id,
|
||||
'number' => Payment::generateCode(),
|
||||
'amount' => $paymentNotification->gross_amount,
|
||||
'method' => 'midtrans',
|
||||
'status' => $paymentStatus,
|
||||
'token' => $paymentNotification->transaction_id,
|
||||
'payloads' => $payload,
|
||||
'payment_type' => $paymentNotification->payment_type,
|
||||
'va_number' => $vaNumber,
|
||||
'vendor_name' => $vendorName,
|
||||
'biller_code' => $paymentNotification->biller_code,
|
||||
'bill_key' => $paymentNotification->bill_key,
|
||||
];
|
||||
|
||||
$payment = Payment::create($paymentParams);
|
||||
|
||||
if ($paymentStatus && $payment) {
|
||||
\DB::transaction(
|
||||
function () use ($order, $payment) {
|
||||
if (in_array($payment->status, [Payment::SUCCESS, Payment::SETTLEMENT])) {
|
||||
$order->payment_status = Order::PAID;
|
||||
$order->status = Order::CONFIRMED;
|
||||
$order->save();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$message = 'Payment status is : '. $paymentStatus;
|
||||
|
||||
$response = [
|
||||
'code' => 200,
|
||||
'message' => $message,
|
||||
];
|
||||
|
||||
return response($response, 200);
|
||||
}
|
||||
|
||||
public function completed(Request $request){
|
||||
$code = $request->query('order_id');
|
||||
$order = Order::where('code', $code)->firstOrFail();
|
||||
|
||||
if ($order->payment_status == Order::UNPAID) {
|
||||
return redirect('payments/failed?order_id='. $code);
|
||||
}
|
||||
|
||||
return view('frontend.payments.success');
|
||||
}
|
||||
|
||||
public function failed(Request $request){
|
||||
$code = $request->query('order_id');
|
||||
$order = Order::where('code', $code)->firstOrFail();
|
||||
|
||||
return redirect('orders/received/'. $order->id);
|
||||
}
|
||||
|
||||
public function unfinish(Request $request){
|
||||
$code = $request->query('order_id');
|
||||
$order = Order::where('code', $code)->firstOrFail();
|
||||
|
||||
return redirect('orders/received/'. $order->id);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ProductController extends Controller
|
||||
{
|
||||
public function show($slug)
|
||||
{
|
||||
$product = Product::with('media', 'category', 'tags')
|
||||
->where('slug', $slug)
|
||||
->withCount('media','approvedReviews')
|
||||
->withAvg('approvedReviews', 'rating')
|
||||
->active()
|
||||
->hasQuantity()
|
||||
->firstOrFail();
|
||||
|
||||
$relatedProducts = Product::with('firstMedia')->whereHas('category', function ($query) use ($product) {
|
||||
$query->whereId($product->category_id);
|
||||
})
|
||||
->where('id', '<>', $product->id)
|
||||
->inRandomOrder()
|
||||
->active()
|
||||
->hasQuantity()
|
||||
->take(4)
|
||||
->get(['id', 'slug', 'name', 'price']);
|
||||
|
||||
return view('frontend.product.show', compact('product', 'relatedProducts'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Obtained;
|
||||
use App\Models\Service;
|
||||
use App\Models\ServiceCategory;
|
||||
use App\Models\ServiceObtained;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ServiceController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$serviceCategories = ServiceCategory::get();
|
||||
return view('frontend.service.index', compact('serviceCategories'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($serviceCategory)
|
||||
{
|
||||
$services = Service::where(['name' => $serviceCategory])->get();
|
||||
$ser = Service::where(['name' => $serviceCategory])->get()->first();
|
||||
|
||||
return view('frontend.service.detail', compact('services', 'ser'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(Service $service)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Models\Service $service
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, Service $service)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Service $service)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ShopController extends Controller
|
||||
{
|
||||
public function index($slug = null)
|
||||
{
|
||||
return view('frontend.shop.index', compact('slug'));
|
||||
}
|
||||
|
||||
public function tag($slug)
|
||||
{
|
||||
return view('frontend.shop.tag', compact('slug'));
|
||||
}
|
||||
|
||||
public function search(Request $request)
|
||||
{
|
||||
$data = Product::select('slug', 'name')
|
||||
->where('name', 'LIKE', '%'.$request->productName. '%')
|
||||
->take(5)
|
||||
->get();
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
use Laravel\Passport\Http\Middleware\CheckClientCredentials;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array<int, class-string|string>
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array<string, array<int, class-string|string>>
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
// \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
'throttle:api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'sessions' => [
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'isAdmin' => \App\Http\Middleware\AdminMiddleware::class,
|
||||
'client' => CheckClientCredentials::class,
|
||||
];
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Shop;
|
||||
|
||||
use App\Models\Product;
|
||||
use Livewire\Component;
|
||||
use App\Models\Category;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
class ProductComponent extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
protected $paginationTheme = 'bootstrap';
|
||||
public $paginationLimit = 12;
|
||||
public $slug;
|
||||
public $sortingBy = 'default';
|
||||
|
||||
public function render()
|
||||
{
|
||||
switch ($this->sortingBy) {
|
||||
case 'popularity':
|
||||
$sortField = 'id';
|
||||
$sortType = 'desc';
|
||||
break;
|
||||
case 'low-high':
|
||||
$sortField = 'price';
|
||||
$sortType = 'asc';
|
||||
break;
|
||||
case 'high-low':
|
||||
$sortField = 'price';
|
||||
$sortType = 'desc';
|
||||
break;
|
||||
default:
|
||||
$sortField = 'id';
|
||||
$sortType = 'asc';
|
||||
}
|
||||
|
||||
|
||||
$products = Product::with('firstMedia');
|
||||
|
||||
if ($this->slug == '') {
|
||||
$products = $products;
|
||||
} else {
|
||||
$category = Category::whereSlug($this->slug)->first();
|
||||
|
||||
if (is_null($category->category_id)) {
|
||||
|
||||
$categoriesIds = Category::whereCategoryId($category->id)->pluck('id')->toArray();
|
||||
$categoriesIds[] = $category->id;
|
||||
$products = $products->whereHas('category', function ($query) use ($categoriesIds) {
|
||||
$query->whereIn('id', $categoriesIds);
|
||||
});
|
||||
|
||||
} else {
|
||||
$products = $products->with('category')
|
||||
->whereHas('category', function ($query) {
|
||||
$query->where([
|
||||
'slug' => $this->slug,
|
||||
]);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$products = $products
|
||||
->active()
|
||||
->orderBy($sortField, $sortType)
|
||||
->paginate($this->paginationLimit);
|
||||
|
||||
return view('livewire.shop.product-component', compact('products'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Shop;
|
||||
|
||||
use App\Models\Product;
|
||||
use Livewire\Component;
|
||||
use App\Models\Category;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
class ProductTagComponent extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
protected $paginationTheme = 'bootstrap';
|
||||
public $paginationLimit = 12;
|
||||
public $slug;
|
||||
public $sortingBy = 'default';
|
||||
|
||||
public function render()
|
||||
{
|
||||
switch ($this->sortingBy) {
|
||||
case 'popularity':
|
||||
$sortField = 'id';
|
||||
$sortType = 'desc';
|
||||
break;
|
||||
case 'low-high':
|
||||
$sortField = 'price';
|
||||
$sortType = 'asc';
|
||||
break;
|
||||
case 'high-low':
|
||||
$sortField = 'price';
|
||||
$sortType = 'desc';
|
||||
break;
|
||||
default:
|
||||
$sortField = 'id';
|
||||
$sortType = 'asc';
|
||||
}
|
||||
|
||||
$products = Product::with('media');
|
||||
|
||||
$products = $products->with('tags')->whereHas('tags', function ($query) {
|
||||
$query->where([
|
||||
'slug' => $this->slug,
|
||||
]);
|
||||
})
|
||||
->orderBy($sortField, $sortType)
|
||||
->paginate($this->paginationLimit);
|
||||
|
||||
return view('livewire.shop.product-component', compact('products'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Shop;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\Review;
|
||||
use Illuminate\Http\Request;
|
||||
use Livewire\Component;
|
||||
|
||||
|
||||
class SingleProductReviewComponent extends Component
|
||||
{
|
||||
public $showForm = true;
|
||||
public $canRate = false;
|
||||
public $product;
|
||||
public $content;
|
||||
public $rating;
|
||||
public $checkProduct;
|
||||
public $currentRatingId;
|
||||
|
||||
protected $listeners = [
|
||||
'update_rating' => 'mount',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->checkProduct = Order::whereHas('orderItems', function ($query) {
|
||||
$query->where('product_id', $this->product->id);
|
||||
})->where('user_id', auth()->id())->where('status', Order::COMPLETED)->first();
|
||||
|
||||
if ($this->checkProduct) {
|
||||
$this->canRate = true;
|
||||
}
|
||||
|
||||
if(auth()->user()){
|
||||
$rating = Review::where('user_id', auth()->id())->where('product_id', $this->product->id)->first();
|
||||
|
||||
if (!empty($rating)) {
|
||||
$this->rating = $rating->rating;
|
||||
$this->content = $rating->content;
|
||||
$this->currentRatingId = $rating->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'rating' => ['required'],
|
||||
'content' => ['required', 'string']
|
||||
];
|
||||
}
|
||||
|
||||
public function rate(Request $request)
|
||||
{
|
||||
if (!$this->checkProduct){
|
||||
$this->alert('error', 'You must buy this item first');
|
||||
return false;
|
||||
}
|
||||
|
||||
$rating = Review::where('user_id', auth()->id())->where('product_id', $this->product->id)->first();
|
||||
$this->validate();
|
||||
|
||||
if (empty($rating)) {
|
||||
$rating = new Review();
|
||||
$rating->user_id = auth()->id();
|
||||
$rating->product_id = $this->product->id;
|
||||
$rating->rating = $this->rating;
|
||||
$rating->content = $this->content;
|
||||
$rating->status = 1;
|
||||
$rating->save();
|
||||
} else {
|
||||
if ($rating->status == 'Inactive'){
|
||||
$this->alert('error', 'already rating this item');
|
||||
return false;
|
||||
}
|
||||
$rating->user_id = auth()->id();
|
||||
$rating->product_id = $this->product->id;
|
||||
$rating->rating = $this->rating;
|
||||
$rating->content = $this->content;
|
||||
$rating->ip_address = $request->ip();
|
||||
$rating->status = 1;
|
||||
$rating->update();
|
||||
}
|
||||
|
||||
$this->showForm = false;
|
||||
$this->emit('update_rating');
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$rating = Review::where('id', $id)->first();
|
||||
if ($rating && ($rating->user_id == auth()->id())) {
|
||||
$rating->delete();
|
||||
}
|
||||
if ($this->currentRatingId) {
|
||||
$this->currentRatingId = '';
|
||||
$this->rating = '';
|
||||
$this->content = '';
|
||||
}
|
||||
$this->emit('update_rating');
|
||||
$this->showForm = true;
|
||||
}
|
||||
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.shop.single-product-review-component');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AdminMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
|
||||
// Jika Anda tidak menggunakan tabel roles, Anda bisa langsung mengecek apakah pengguna adalah admin berdasarkan kebijakan aplikasi
|
||||
if (!auth()->user()->isAdmin()) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @param string|null ...$guards
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, ...$guards)
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array<int, string|null>
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
'payments/notification'
|
||||
];
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CategoryRequest 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()
|
||||
{
|
||||
switch ($this->method()) {
|
||||
case 'POST':
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'max:255', 'unique:categories'],
|
||||
'category_id' => ['nullable'],
|
||||
'cover' => ['nullable','mimes:jpg,jpeg,png,gif', 'max:20000'],
|
||||
];
|
||||
}
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'max:255', 'unique:categories,name,'.$this->route()->category->id],
|
||||
'category_id' => ['nullable'],
|
||||
'cover' => ['mimes:jpg,jpeg,png,gif', 'max:20000'],
|
||||
];
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ProductRequest 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()
|
||||
{
|
||||
switch ($this->method()) {
|
||||
case 'POST':
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'max:255', 'unique:products'],
|
||||
'price' => ['required', 'numeric'],
|
||||
'quantity' => ['required', 'numeric'],
|
||||
'category_id' => ['required'],
|
||||
'tags.*' => ['required'],
|
||||
'status' => ['required'],
|
||||
'weight' => ['required', 'numeric'],
|
||||
'description' => ['required', 'max:1000'],
|
||||
'details' => ['required', 'max:10000'],
|
||||
'images' => ['required'],
|
||||
'images.*' => ['mimes:jpg,jpeg,png,gif', 'max:4000']
|
||||
];
|
||||
}
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'max:255', 'unique:products,name,'.$this->route()->product->id],
|
||||
'description' => ['required', 'max:1000'],
|
||||
'price' => ['required', 'numeric'],
|
||||
'quantity' => ['required', 'numeric'],
|
||||
'category_id' => ['required'],
|
||||
'tags.*' => ['required'],
|
||||
'details' => ['required', 'max:10000'],
|
||||
'review_able' => ['nullable'],
|
||||
'status' => ['required'],
|
||||
'images' => ['nullable'],
|
||||
'images.*' => ['mimes:jpg,jpeg,png,gif', 'max:4000']
|
||||
];
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ReviewRequest 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 [
|
||||
'status' => ['required'],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SlideRequest 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()
|
||||
{
|
||||
switch ($this->method()) {
|
||||
case 'POST':
|
||||
{
|
||||
return [
|
||||
'title' => ['required', 'max:255'],
|
||||
'url' => ['required', 'max:255'],
|
||||
'body' => ['required', 'max:255'],
|
||||
'cover' => ['required','mimes:jpg,jpeg,png,gif', 'max:3000']
|
||||
];
|
||||
}
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
{
|
||||
return [
|
||||
'title' => ['required', 'max:255'],
|
||||
'url' => ['required', 'max:255'],
|
||||
'body' => ['required', 'max:255'],
|
||||
'cover' => ['mimes:jpg,jpeg,png,gif', 'max:3000']
|
||||
];
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreObtainedRequest 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 [
|
||||
'name' => 'required'
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreRoleRequest 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 [
|
||||
'title' => 'required',
|
||||
'permissions.*' => [
|
||||
'integer',
|
||||
],
|
||||
'permissions' => [
|
||||
'required',
|
||||
'array',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreServiceRequest 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 [
|
||||
'name' => 'required',
|
||||
'price' => 'required|numeric',
|
||||
'obtaineds.*' => [
|
||||
'integer',
|
||||
],
|
||||
'obtaineds' => [
|
||||
'required',
|
||||
'array',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreUserRequest 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 [
|
||||
'username' => ['required'],
|
||||
'email' => ['required', 'unique:users',],
|
||||
'roles.*' => ['integer',],
|
||||
'roles' => ['required', 'array',],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class TagRequest 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()
|
||||
{
|
||||
switch ($this->method()) {
|
||||
case 'POST':
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'max:255', 'unique:tags'],
|
||||
];
|
||||
}
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'max:255', 'unique:tags,name,'.$this->route()->tag->id],
|
||||
];
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateObtainedRequest 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 [
|
||||
'name' => 'required'
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdatePermissionRequest 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 [
|
||||
'title' => 'required'
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateRoleRequest 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 [
|
||||
'title' => 'required',
|
||||
|
||||
'permissions.*' => [
|
||||
'integer',
|
||||
],
|
||||
'permissions' => [
|
||||
'required',
|
||||
'array',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateServiceRequest 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 [
|
||||
'name' => 'required',
|
||||
'price' => 'required|numeric',
|
||||
'obtaineds.*' => [
|
||||
'integer',
|
||||
],
|
||||
'obtaineds' => [
|
||||
'required',
|
||||
'array',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateUserRequest 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 [
|
||||
'username' => [
|
||||
'required',
|
||||
],
|
||||
'email' => [
|
||||
'required',
|
||||
'unique:users,email,' . request()->route('user')->id,
|
||||
],
|
||||
'roles.*' => [
|
||||
'integer',
|
||||
],
|
||||
'roles' => [
|
||||
'required',
|
||||
'array',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ProfileRequest 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 [
|
||||
'username' => ['required',],
|
||||
'first_name' => ['required'],
|
||||
'last_name' => ['required'],
|
||||
'address1' => ['required'],
|
||||
'address2' => ['required'],
|
||||
'province_id' => ['required'],
|
||||
'city_id' => ['required'],
|
||||
'postcode' => ['required'],
|
||||
'phone' => ['required'],
|
||||
'email' => ['required', 'string', 'max:255', 'unique:users,email,' . auth()->id()],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class Item extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
$items = [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'price' => $this->price,
|
||||
'quantity' => $this->quantity,
|
||||
'attributes' => $this->attributes,
|
||||
'conditions' => $this->conditions,
|
||||
'product' => new Product($this->associatedModel),
|
||||
];
|
||||
|
||||
return $items;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ItemResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class Product extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
$image = $this->firstMedia ? asset('storage/images/products/' . $this->firstMedia->file_name) : null;
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'slug' => $this->slug,
|
||||
'price' => $this->price,
|
||||
'quantity' => $this->quantity,
|
||||
'description' => $this->description,
|
||||
'details' => $this->details,
|
||||
'image' => $image,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class ProductCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Booking extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
public function schedule()
|
||||
{
|
||||
return $this->belongsTo(Schedule::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Cviebrock\EloquentSluggable\Sluggable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Category extends Model
|
||||
{
|
||||
use HasFactory,Sluggable;
|
||||
|
||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* Return the sluggable configuration array for this model.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sluggable(): array
|
||||
{
|
||||
return [
|
||||
'slug' => [
|
||||
'source' => 'name',
|
||||
'onUpdate' => true
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function parent(){
|
||||
return $this->belongsTo(Category::class, 'category_id');
|
||||
}
|
||||
|
||||
public function children(){
|
||||
return $this->hasMany(Category::class);
|
||||
}
|
||||
|
||||
public function products()
|
||||
{
|
||||
return $this->hasMany(Product::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Favorite extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id','created_at','updated_at'];
|
||||
|
||||
public function product(){
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
|
||||
class Media extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
public function mediable(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Obtained extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Helpers\General;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Order extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||
|
||||
public const ORDERCODE = 'INV';
|
||||
|
||||
public const PAID = 'paid';
|
||||
public const UNPAID = 'unpaid';
|
||||
|
||||
public const CREATED = 'created';
|
||||
public const CONFIRMED = 'confirmed';
|
||||
public const DELIVERED = 'delivered';
|
||||
public const COMPLETED = 'completed';
|
||||
public const CANCELLED = 'cancelled';
|
||||
|
||||
public const STATUSES = [
|
||||
self::CREATED => 'Created',
|
||||
self::CONFIRMED => 'Confirmed',
|
||||
self::DELIVERED => 'Delivered',
|
||||
self::COMPLETED => 'Completed',
|
||||
self::CANCELLED => 'Cancelled',
|
||||
];
|
||||
|
||||
/**
|
||||
* Generate order code
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generateCode()
|
||||
{
|
||||
$dateCode = self::ORDERCODE . '/' . date('Ymd') . '/' . General::integerToRoman(date('m')). '/' . General::integerToRoman(date('d')). '/';
|
||||
|
||||
$lastOrder = self::select([\DB::raw('MAX(orders.code) AS last_code')])
|
||||
->where('code', 'like', $dateCode . '%')
|
||||
->first();
|
||||
|
||||
$lastOrderCode = !empty($lastOrder) ? $lastOrder['last_code'] : null;
|
||||
|
||||
$orderCode = $dateCode . '00001';
|
||||
if ($lastOrderCode) {
|
||||
$lastOrderNumber = str_replace($dateCode, '', $lastOrderCode);
|
||||
$nextOrderNumber = sprintf('%05d', (int)$lastOrderNumber + 1);
|
||||
|
||||
$orderCode = $dateCode . $nextOrderNumber;
|
||||
}
|
||||
|
||||
if (self::_isOrderCodeExists($orderCode)) {
|
||||
return generateOrderCode();
|
||||
}
|
||||
|
||||
return $orderCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the generated order code is exists
|
||||
*
|
||||
* @param string $orderCode order code
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function _isOrderCodeExists($orderCode)
|
||||
{
|
||||
return Order::where('code', '=', $orderCode)->exists();
|
||||
}
|
||||
|
||||
public function orderItems()
|
||||
{
|
||||
return $this->hasMany(OrderItem::class);
|
||||
}
|
||||
|
||||
public function shipment(){
|
||||
return $this->hasOne(Shipment::class);
|
||||
}
|
||||
|
||||
public function isPaid()
|
||||
{
|
||||
return $this->payment_status == self::PAID;
|
||||
}
|
||||
|
||||
public function isCreated()
|
||||
{
|
||||
return $this->status == self::CREATED;
|
||||
}
|
||||
|
||||
public function isConfirmed()
|
||||
{
|
||||
return $this->status == self::CONFIRMED;
|
||||
}
|
||||
|
||||
public function isDelivered()
|
||||
{
|
||||
return $this->status == self::DELIVERED;
|
||||
}
|
||||
|
||||
public function isCancelled(){
|
||||
return $this->status == self::CANCELLED ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add full_name custom attribute to order object
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getCustomerFullNameAttribute()
|
||||
{
|
||||
return "{$this->customer_first_name} {$this->customer_last_name}";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class OrderItem extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* Define relationship with the Product
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Payment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
public const PAYMENT_CHANNELS = ['credit_card', 'mandiri_clickpay', 'cimb_clicks',
|
||||
'bca_klikbca', 'bca_klikpay', 'bri_epay', 'echannel', 'permata_va',
|
||||
'bca_va', 'bni_va', 'other_va', 'gopay', 'indomaret',
|
||||
'danamon_online', 'akulaku'];
|
||||
|
||||
public const EXPIRY_DURATION = 1;
|
||||
public const EXPIRY_UNIT = 'days';
|
||||
|
||||
|
||||
public const CHALLENGE = 'challenge';
|
||||
public const SUCCESS = 'success';
|
||||
public const SETTLEMENT = 'settlement';
|
||||
public const PENDING = 'pending';
|
||||
public const DENY = 'deny';
|
||||
public const EXPIRE = 'expire';
|
||||
public const CANCEL = 'cancel';
|
||||
|
||||
|
||||
public const PAYMENTCODE = 'PAY';
|
||||
|
||||
public static function integerToRoman($integer)
|
||||
{
|
||||
$integer = intval($integer);
|
||||
$result = '';
|
||||
|
||||
// Create a lookup array that contains all of the Roman numerals.
|
||||
$lookup = ['M' => 1000, 'CM' => 900, 'D' => 500, 'CD' => 400, 'C' => 100, 'XC' => 90, 'L' => 50, 'XL' => 40, 'X' => 10, 'IX' => 9, 'V' => 5, 'IV' => 4, 'I' => 1];
|
||||
|
||||
foreach ($lookup as $roman => $value) {
|
||||
$matches = intval($integer/$value);
|
||||
$result .= str_repeat($roman, $matches);
|
||||
$integer = $integer % $value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function generateCode()
|
||||
{
|
||||
$dateCode = self::PAYMENTCODE . '/' . date('Ymd') . '/' . self::integerToRoman(date('m')). '/' . self::integerToRoman(date('d')). '/';
|
||||
|
||||
$lastOrder = self::select([\DB::raw('MAX(payments.number) AS last_code')])
|
||||
->where('number', 'like', $dateCode . '%')
|
||||
->first();
|
||||
|
||||
$lastOrderCode = !empty($lastOrder) ? $lastOrder['last_code'] : null;
|
||||
|
||||
$orderCode = $dateCode . '00001';
|
||||
if ($lastOrderCode) {
|
||||
$lastOrderNumber = str_replace($dateCode, '', $lastOrderCode);
|
||||
$nextOrderNumber = sprintf('%05d', (int)$lastOrderNumber + 1);
|
||||
|
||||
$orderCode = $dateCode . $nextOrderNumber;
|
||||
}
|
||||
|
||||
if (self::_isOrderCodeExists($orderCode)) {
|
||||
return generateOrderCode();
|
||||
}
|
||||
|
||||
return $orderCode;
|
||||
}
|
||||
|
||||
private static function _isOrderCodeExists($orderCode)
|
||||
{
|
||||
return Order::where('code', '=', $orderCode)->exists();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Cviebrock\EloquentSluggable\Sluggable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Product extends Model
|
||||
{
|
||||
use HasFactory, Sluggable;
|
||||
|
||||
protected $guarded = ['id', 'updated_at', 'created_at'];
|
||||
|
||||
/**
|
||||
* Return the sluggable configuration array for this model.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sluggable(): array
|
||||
{
|
||||
return [
|
||||
'slug' => [
|
||||
'source' => 'name',
|
||||
'onUpdate' => true
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function getStatusAttribute(): string
|
||||
{
|
||||
return $this->attributes['status'] == 0 ? 'Inactive' : 'Active';
|
||||
}
|
||||
|
||||
public function scopeActive($query)
|
||||
{
|
||||
return $query->whereStatus(true);
|
||||
}
|
||||
|
||||
public function scopeHasQuantity($query)
|
||||
{
|
||||
return $query->where('quantity', '>', 0);
|
||||
}
|
||||
|
||||
public function category(){
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
public function tags(){
|
||||
return $this->belongsToMany(Tag::class, 'product_tags');
|
||||
}
|
||||
|
||||
public function media(): MorphMany
|
||||
{
|
||||
return $this->morphMany(Media::class, 'mediable');
|
||||
}
|
||||
|
||||
public function firstMedia(): MorphOne
|
||||
{
|
||||
return $this->morphOne(Media::class, 'mediable')
|
||||
->orderBy('file_sort', 'asc');
|
||||
}
|
||||
|
||||
public function reviews()
|
||||
{
|
||||
return $this->hasMany(Review::class);
|
||||
}
|
||||
|
||||
public function approvedReviews()
|
||||
{
|
||||
return $this->hasMany(Review::class)->whereStatus(1);
|
||||
}
|
||||
|
||||
public function ratings()
|
||||
{
|
||||
return $this->hasMany(Rating::class);
|
||||
}
|
||||
|
||||
public function rate()
|
||||
{
|
||||
return $this->ratings->isNotEmpty() ? $this->ratings()->sum('value') / $this->ratings()->count() : 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Rating extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Review extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id','created_at','updated_at'];
|
||||
|
||||
public function getStatusAttribute()
|
||||
{
|
||||
return $this->attributes['status'] == 0 ? 'Inactive' : 'Active';
|
||||
}
|
||||
|
||||
public function user(){
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Schedule extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
|
||||
public function bookings()
|
||||
{
|
||||
return $this->hasMany(Booking::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Service extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
|
||||
public function obtaineds()
|
||||
{
|
||||
return $this->belongsToMany(Obtained::class, 'service_obtained');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ServiceCategory extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ServiceObtained extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'service_obtained';
|
||||
protected $guarded = ['id'];
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Shipment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||
|
||||
public const PENDING = 'pending';
|
||||
public const SHIPPED = 'shipped';
|
||||
|
||||
/**
|
||||
* Relationship to the order model
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Slide extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||
|
||||
public function prevSlide()
|
||||
{
|
||||
return self::where('position', '<', $this->position)
|
||||
->orderBy('position', 'DESC')
|
||||
->first();
|
||||
}
|
||||
|
||||
public function nextSlide()
|
||||
{
|
||||
return self::where('position', '>', $this->position)
|
||||
->orderBy('position', 'ASC')
|
||||
->first();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Cviebrock\EloquentSluggable\Sluggable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Tag extends Model
|
||||
{
|
||||
use HasFactory,Sluggable;
|
||||
|
||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* Return the sluggable configuration array for this model.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sluggable(): array
|
||||
{
|
||||
return [
|
||||
'slug' => [
|
||||
'source' => 'name'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function products(){
|
||||
return $this->belongsToMany(Tag::class, 'product_tags');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Passport\HasApiTokens;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'username',
|
||||
'email',
|
||||
'password',
|
||||
|
||||
'role', // Add the role attribute here
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* Check if the user is an admin.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAdmin(): bool
|
||||
{
|
||||
return $this->role === 'admin';
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue