restore composer.json, add mysqli extension

This commit is contained in:
2026-04-15 17:02:52 +05:00
commit 77cf56a348
4317 changed files with 1397107 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

18
.editorconfig Executable file
View File

@@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
[docker-compose.yml]
indent_size = 4

72
.env.example Executable file
View File

@@ -0,0 +1,72 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_TIMEZONE="Asia/Tashkent"
APP_URL="http://localhost:9005"
BOT_CHAT_ID=1
BOT_TOKEN=1
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database
BCRYPT_ROUNDS=12
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database
CACHE_STORE=database
CACHE_PREFIX=
MEMCACHED_HOST=127.0.0.1
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=log
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
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
VITE_APP_NAME="${APP_NAME}"
FORCE_HTTPS=true
SMS_USERNAME=
SMS_PASSWORD=
SMS_URL=

11
.gitattributes vendored Executable file
View File

@@ -0,0 +1,11 @@
* text=auto eol=lf
*.blade.php diff=html
*.css diff=css
*.html diff=html
*.md diff=markdown
*.php diff=php
/.github export-ignore
CHANGELOG.md export-ignore
.styleci.yml export-ignore

69
.github/workflows/deploy.yml vendored Executable file
View File

@@ -0,0 +1,69 @@
name: Ci/Cd
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
Counter:
runs-on: self-hosted
steps:
- name: Checkout the code
uses: actions/checkout@v3
- name: Copy .env
run: |
cp /dockers/app/.env /actions-runner/_work/quyoshli_ecom/quyoshli_ecom/.env
- name: Initialize Counter
run: |
if [ ! -f /dockers/counter/counter.txt ]; then
echo 0 > /dockers/counter/counter.txt
fi
- name: Increment the Counter
run: |
COUNTER=$(cat /dockers/counter/counter.txt)
COUNTER=$((COUNTER+1))
echo $COUNTER > /dockers/counter/counter.txt
echo "Current run count: $COUNTER"
Deploy:
runs-on: self-hosted
needs: Counter
steps:
- name: Deploy Docker Services
run: |
cd /actions-runner/_work/quyoshli_ecom/quyoshli_ecom
# docker compose -f cloud-docker-compose.yaml down
# docker rmi laravel
docker compose -f cloud-docker-compose.yaml up -d --build
Deploy2:
runs-on: self-hosted
needs: Deploy
steps:
- name: Deploy dashboard service
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
SERVER_IP: ${{ secrets.SERVER_IP }}
USER_NAME: ${{ secrets.USER_NAME }}
run: |
echo "$SSH_PRIVATE_KEY" > private_key
chmod 600 private_key
ssh -i private_key -o StrictHostKeyChecking=no $USER_NAME@$SERVER_IP "cd /var/www/quyoshli_ecom && git pull origin master"
rm private_key
Checker:
runs-on: self-hosted
needs: Deploy
steps:
- name: Check
if: success()
run: |
COUNTER=$(cat /dockers/counter/counter.txt)
if [ $COUNTER -ge 20 ]; then
echo "Running Docker prune..."
docker system prune -a --volumes -f
echo 0 > /dockers/counter/counter.txt
else
echo "Not time for prune yet."
fi

23
.gitignore vendored Executable file
View File

@@ -0,0 +1,23 @@
/.phpunit.cache
/node_modules
/public/build
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.env.production
.phpactor.json
.phpunit.result.cache
Homestead.json
Homestead.yaml
auth.json
npm-debug.log
yarn-error.log
/.fleet
/.idea
/.vscode
/quyoshli-database
composer.lock
public/uploads

42
Dockerfile Executable file
View File

@@ -0,0 +1,42 @@
FROM webdevops/php-nginx:8.2-alpine
WORKDIR /app
COPY ./custom/php.ini /opt/docker/etc/php/php.ini
COPY ./custom/custom_nginx.conf /opt/docker/etc/nginx/vhost.conf
COPY ./custom/nginx.conf /opt/docker/etc/nginx/nginx.conf
COPY .env ./
COPY . ./
# RUN chown -R www-data:www-data /app \
# && chmod -R 777 /app/storage \
# && chmod -R 777 /app/bootstrap/cache
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
COPY composer.json composer.lock /app
RUN composer update
RUN composer install \
--ignore-platform-reqs \
--no-interaction \
--no-plugins \
--no-scripts \
--prefer-dist
RUN chown -R www-data:www-data /app/public \
&& chown -R www-data:www-data /app/storage \
&& chmod -R 777 /app/storage \
&& chmod -R 777 /app/bootstrap/cache \
&& chmod -R 777 /app/public
RUN apk add php-gd
RUN php artisan key:generate
#RUN php artisan migrate --seed
RUN apk update && apk add nodejs npm
RUN npm install
RUN npm run build
EXPOSE 80

0
README.md Executable file
View File

52
app/Api/Firebase.php Executable file
View File

@@ -0,0 +1,52 @@
<?php
namespace App\Api;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
class Firebase
{
protected $client;
protected $token = 'token';
public function __construct()
{
$this->client = new Client();
}
/**
* @param $notification
* @param $tokens
* @return \Exception|ClientException|\Psr\Http\Message\StreamInterface
*/
public function send_notification($notification, $tokens)
{
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = [
// "priority"=>"high",
"registration_ids" => $tokens,
'notification' => $notification,
'data' => $notification,
//'content-available' => true,
'priority' => 'high'
];
$headers = [
"Authorization" => "key={$this->token}",
'Content-Type' => 'application/json',
];
try {
$request = $this->client->post($url, [
'headers' => $headers,
'json' => $fields,
]);
$response = $request->getBody();
return $response;
} catch (ClientException $exception) {
return $exception;
}
}
}

60
app/Api/ImageResize.php Executable file
View File

@@ -0,0 +1,60 @@
<?php
namespace App\Api;
use Carbon\Carbon;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image as Imagee;
class ImageResize
{
/**
* @param string $type
* @return string
*/
private function mkdir(string $type)
{
$folder = Carbon::now()->format('Y/m/d');
$path = "uploads/{$type}/thumbs/{$folder}";
if (!file_exists($path)) {
mkdir($path, 0755, true);
}
return $path;
}
/**
* @param $path
* @param $size
* @param $type
* @return string
*/
public function resize($path, $size, $type)
{
$name = basename($path);
$folder = $this->mkdir($type);
$path_thumb = "{$folder}/{$name}";
if (env('FILESYSTEM_DISK') == 's3') {
try{
$file = Storage::disk("public")->get($path);
}catch(Exception $e){
$file = file_get_contents($path);
}
$img = Imagee::make($file);
$img->resize($size, null, function ($constraint) {
$constraint->aspectRatio();
});
// delete temp file
$img->save("{$path_thumb}", 100);
Storage::disk('s3')->put($path_thumb, file_get_contents($path_thumb));
} else {
$img = Imagee::make(public_path($path));
$img->resize($size, null, function ($constraint) {
$constraint->aspectRatio();
});
$img->save(public_path() . "/{$path_thumb}", 100);
}
return $path_thumb;
}
}

103
app/Api/Sms.php Executable file
View File

@@ -0,0 +1,103 @@
<?php
namespace App\Api;
use GuzzleHttp\Client;
class Sms
{
const URL = '';
const ORIGINATOR = '';
protected $client;
public function __construct()
{
$this->client = new Client();
}
public function send(int $phone, string $message)
{
$data = [
'messages' => [
[
'recipient' => $phone,
'message-id' => time(),
'sms' => [
'originator' => '3700',
'content' => [
'text' => $message
]
]
]
]
];
$data_string = json_encode($data);
$username = env("SMS_USERNAME");
$password = env("SMS_PASSWORD");
$url = env('SMS_URL');
$debug = [
'ok' => false,
'url' => $url,
'username' => $username,
'phone' => $phone,
];
if (!$url || !$username || !$password) {
$debug['error_stage'] = 'env_missing';
$debug['missing'] = [
'SMS_URL' => (bool)$url,
'SMS_USERNAME' => (bool)$username,
'SMS_PASSWORD' => (bool)$password,
];
return $debug;
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 25);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
[
'Content-Type: application/json',
'Accept: application/json',
'Content-Length: ' . strlen($data_string),
]
);
$result = curl_exec($ch);
$debug['curl_errno'] = curl_errno($ch);
$debug['curl_error'] = curl_error($ch);
$debug['http_code'] = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
$debug['curl_info'] = curl_getinfo($ch);
$debug['response_head'] = is_string($result) ? mb_substr($result, 0, 2000) : $result;
curl_close($ch);
if ($debug['curl_errno'] !== 0) {
$debug['error_stage'] = 'curl_exec';
return $debug;
}
if ($debug['http_code'] < 200 || $debug['http_code'] >= 300) {
$debug['error_stage'] = 'http_non_2xx';
return $debug;
}
$debug['ok'] = true;
$debug['error_stage'] = null;
return $debug;
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Console\Commands;
use App\Models\Billing;
use App\Models\Currency;
use Illuminate\Console\Command;
class BillingCurrencyChange extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:billing-currency-change';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*/
public function handle()
{
$currency = Currency::latest()->first();
Billing::chunk(100, function ($billings) use ($currency) {
foreach ($billings as $billing) {
$billing->amount = $billing->amount * $currency->dollar;
$billing->save();
}
});
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Console\Commands;
use App\Models\Currency;
use App\Models\Order;
use Illuminate\Console\Command;
class OrderCurrencyChange extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:order-currency-change';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*/
public function handle()
{
$currency = Currency::latest()->first();
Order::chunk(100, function ($orders) use ($currency) {
foreach ($orders as $order) {
$order->price_products = $order->price_products * $currency->dollar;
$order->price_delivery = $order->price_delivery * $currency->dollar;
$order->price_total = $order->price_total * $currency->dollar;
$order->price_master = $order->price_master * $currency->dollar;
$order->save();
}
});
}
}

115
app/Console/Commands/SmsTest.php Executable file
View File

@@ -0,0 +1,115 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Api\Sms;
use Throwable;
class SmsTest extends Command
{
protected $signature = 'sms:test {phone?} {message?}';
protected $description = 'Send test SMS via Sms class (with deep diagnostics)';
private function diagPath(): string
{
return function_exists('storage_path')
? storage_path('logs/sms_test.log')
: __DIR__ . '/../../../storage/logs/sms_test.log';
}
private function dlog(string $level, string $msg, array $ctx = []): void
{
$path = $this->diagPath();
$dir = dirname($path);
if (!is_dir($dir)) {
@mkdir($dir, 0777, true);
}
$line = json_encode([
'ts' => date('c'),
'level' => $level,
'msg' => $msg,
'ctx' => $ctx,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
@file_put_contents($path, $line . PHP_EOL, FILE_APPEND);
}
public function handle(): int
{
$phone = $this->argument('phone') ?? '+998333013332';
$message = $this->argument('message') ?? 'Ishladi Polat';
$phoneDigits = (int)preg_replace('/[^0-9]/', '', (string)$phone);
$this->info("Sending SMS to: {$phoneDigits}");
$this->info("Message: {$message}");
$this->line("Diag log: " . $this->diagPath());
$this->dlog('info', 'sms:test started', [
'pid' => getmypid(),
'cwd' => getcwd(),
'php' => PHP_VERSION,
'app_env' => env('APP_ENV'),
'log_path' => $this->diagPath(),
'phone' => $phoneDigits,
]);
// ENV snapshot (mask password)
$envSnap = [
'SMS_URL' => env('SMS_URL'),
'SMS_USERNAME' => env('SMS_USERNAME'),
'SMS_PASSWORD' => env('SMS_PASSWORD') ? '***set***' : null,
];
$this->dlog('info', 'env snapshot', $envSnap);
try {
$sms = new Sms();
$result = $sms->send($phoneDigits, $message);
if (is_array($result)) {
$ok = (bool)($result['ok'] ?? false);
$this->dlog($ok ? 'info' : 'error', 'send() returned array', $result);
$this->line("HTTP: " . ($result['http_code'] ?? 'n/a'));
$this->line("CURL errno: " . ($result['curl_errno'] ?? 'n/a'));
$this->line("CURL error: " . ($result['curl_error'] ?? 'n/a'));
$this->line("Response (head): " . ($result['response_head'] ?? 'n/a'));
if ($ok) {
$this->info("SMS send SUCCESS");
return self::SUCCESS;
}
$this->error("SMS send FAILED (see sms_test.log)");
return self::FAILURE;
}
$ok = (bool)$result;
$this->dlog($ok ? 'info' : 'error', 'send() returned bool', ['ok' => $ok]);
if ($ok) {
$this->info("SMS send SUCCESS");
return self::SUCCESS;
}
$this->error("SMS send FAILED (see sms_test.log)");
return self::FAILURE;
} catch (Throwable $e) {
$this->dlog('error', 'EXCEPTION', [
'message' => $e->getMessage(),
'class' => get_class($e),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => substr($e->getTraceAsString(), 0, 4000),
]);
$this->error("EXCEPTION: " . $e->getMessage());
$this->line("Where: " . $e->getFile() . ":" . $e->getLine());
return self::FAILURE;
}
}
}

46
app/Console/Kernel.php Executable file
View File

@@ -0,0 +1,46 @@
<?php
namespace App\Console;
use App\Jobs\Cron\CloseOrderJob;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Jobs\Cron\BackProductJob;
use App\Jobs\Cron\SendSmsJob;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->job(new BackProductJob)->everyMinute()->timezone('Asia/Tashkent')->withoutOverlapping();
$schedule->job(new SendSmsJob)->everyMinute()->timezone('Asia/Tashkent')->withoutOverlapping();
$schedule->job(new CloseOrderJob())->everyMinute()->timezone('Asia/Tashkent')->withoutOverlapping();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}

112
app/Exceptions/Handler.php Executable file
View File

@@ -0,0 +1,112 @@
<?php
namespace App\Exceptions;
use Sentry\State\Scope;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\JsonResponse;
use Throwable;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Illuminate\Validation\ValidationException;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json([
'status' => false,
'error' => 401,
'message' => trans('app.errors.401')
], 401);
}
return redirect()->guest('login');
}
/**
* @param Throwable $exception
* @throws \Exception
*/
public function report(Throwable $exception)
{
// if (app()->bound('sentry') && $this->shouldReport($exception)) {
// $user = request()->user();
//
// if (!empty($user)) {
// //$token = Token::where('token', $token)->first();
// app('sentry')->configureScope(function (Scope $scope) use ($user): void {
// $scope->setUser([
// 'id' => $user->id,
// 'phone' => $user->phone,
// ]);
// });
// }
//
// app('sentry')->captureException($exception);
// }
if (app()->bound('sentry') && $this->shouldReport($exception)) {
app('sentry')->captureException($exception);
}
parent::report($exception);
}
/**
* @param \Illuminate\Http\Request $request
* @param Throwable $exception
* @return \Illuminate\Http\JsonResponse|\Symfony\Component\HttpFoundation\Response
* @throws Throwable
*/
public function render($request, Throwable $exception)
{
// Check if the request expects JSON
if ($request->expectsJson()) {
// Handle 404 Not Found exception
if ($exception instanceof NotFoundHttpException) {
return response()->json([
'error' => 'Resource not found'
], 404);
}
// Handle validation exceptions
if ($exception instanceof ValidationException) {
return response()->json([
'error' => 'Validation error',
'details' => $exception->errors(),
], 422);
}
// Handle generic exceptions
return response()->json([
'error' => $exception->getMessage(),
], $this->isHttpException($exception) ? $exception->getStatusCode() : 500);
}
// For non-API requests, use the default render method
return parent::render($request, $exception);
}
}

17
app/Exports/OrdersExport.php Executable file
View File

@@ -0,0 +1,17 @@
<?php
namespace App\Exports;
use App\Models\Order;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;
class OrdersExport implements FromView
{
public function view(): View
{
return view('dashboard.orders.export', [
'orders' => Order::all()
]);
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace App\Exports;
use App\Models\Product;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;
class ProductsForPriceExport implements FromView
{
public function view(): View
{
$products = Product::notChilds()->get();
return view('dashboard.products.export', [
'products' => $products
]);
}
}

74
app/Exports/UsersExport.php Executable file
View File

@@ -0,0 +1,74 @@
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;
use App\Models\User;
//use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
class UsersExport implements FromQuery, WithMapping, WithHeadings
{
use Exportable;
private $date_to;
private $date_from;
private $search_id;
private $search_phone;
private $search_ip;
private $sort_type;
public function __construct($date_from, $date_to, $search_id, $search_phone, $search_ip, $sort_type)
{
$this->date_from = $date_from;
$this->date_to = $date_to;
$this->search_id = $search_id;
$this->search_phone = $search_phone;
$this->search_ip = $search_ip;
$this->sort_type = $sort_type;
}
public function map($user): array
{
return [
'id' => $user->id,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'phone' => $user->phone,
'ip' => $user->ip,
'registered_date' => $user->created_at,
'last_activity' => $user->updated_at,
];
}
public function headings(): array
{
return [
'# ID',
'Имя',
'Фамилия',
'Телефон',
'IP',
'Дата регистрации',
'Дата последней активности',
];
}
public function query()
{
$users = User::query()->latest('id')
->steped();
if (!is_null($this->date_from)) {
$users = $users->filterByDate($this->date_from, $this->date_to, $this->sort_type);
}
if (!is_null($this->search_id) || !is_null($this->search_phone) || !is_null($this->search_ip)) {
$users = $users->search($this->search_id, $this->search_phone, $this->search_ip);
}
return $users;
}
}

259
app/Helpers/Cart.php Executable file
View File

@@ -0,0 +1,259 @@
<?php
namespace App\Helpers;
use App\Models\Cart as Model;
use App\Models\Product;
use Illuminate\Support\Facades\Cookie;
class Cart
{
/**
* @return array
*/
public function getProducts()
{
if (Cookie::has('cart_token')) {
$cart = Model::findByToken(Cookie::get('cart_token'))
->with('product:id,child_id', 'product.product:id,name,price,price_discount,poster_thumb,slug,leader_of_sales,currency,article_number,count,available')
->whereHas('product', function ($query) {
$query->whereHas('product', function ($query) {
return $query->isAvailable();
});
})
->get();
} else if (auth()->check()) {
$cart = Model::findByUser(auth()->user()->id)
->with('product:id,child_id', 'product.product:id,name,price,price_discount,poster_thumb,slug,leader_of_sales,currency,article_number,count,available')
->whereHas('product', function ($query) {
$query->whereHas('product', function ($query) {
return $query->isAvailable();
});
})
->get();
} else {
$cart = collect([]);
}
$cart->map(function ($cart) {
if (!empty($cart->product) && !empty($cart->product->product)) {
$cart->price = $cart->product->product->getPrice();
$cart->price_discount = $cart->product->product->price_discount == null ? null : $cart->product->product->getDiscountPrice();
} else {
$cart->price = 0;
$cart->price_discount = 0;
}
});
$prices = $cart->map(function ($cart) {
$price = 0;
$price_discount = 0;
$price_current = 0;
$price += $cart->price * $cart->count;
$price_discount += $cart->price_discount * $cart->count;
$price_current = $cart->price_discount ? $cart->price_discount * $cart->count : $cart->price * $cart->count;
return $price_current;
});
$prices = array_sum($prices->toArray());
return [$prices, $cart];
}
/**
* @param $request
* @return mixed
*/
public function store($request)
{
if (Cookie::has('cart_token')) {
$cart = Model::findByToken(Cookie::get('cart_token'))->where('product_id', $request->product_id)->where('size', $request->getSize())->first();
if (!empty($cart)) {
$cart->update([
'count' => $cart->count + $request->count
]);
} else {
Model::create([
'product_id' => $request->product_id,
'count' => $request->count,
'size' => $request->getSize(),
'token' => $request->cookie('cart_token')
]);
}
$count = Model::findByToken($request->cookie('cart_token'))->whereHas('product', function ($query) {
$query->whereHas('product');
})->count();
} elseif (auth()->check()) {
$cart = Model::findByUser(auth()->user()->id)->where('product_id', $request->product_id)->where('size', $request->getSize())->first();
if (!empty($cart)) {
$cart->update([
'count' => $cart->count + $request->count
]);
} else {
Model::create([
'product_id' => $request->product_id,
'count' => $request->count,
'size' => $request->getSize(),
'user_id' => auth()->user()->id
]);
}
$count = auth()->user()->cart()->whereHas('product', function ($query) {
$query->whereHas('product');
})->count();
}
return $count;
}
/**
* @param $product
* @return mixed
*/
public function delete($product)
{
if (Cookie::has('cart_token')) {
$cart = Model::findByToken(Cookie::get('cart_token'))->where('product_id', $product)->first();
if (!empty($cart))
$cart->delete();
$count = Model::findByToken(Cookie::get('cart_token'))->whereHas('product', function ($query) {
$query->whereHas('product');
})->count();
} else if (auth()->check()) {
$cart = Model::findByUser(auth()->user()->id)->where('product_id', $product)->first();
if (!empty($cart))
$cart->delete();
$count = auth()->user()->cart()->whereHas('product', function ($query) {
$query->whereHas('product');
})->count();
}
return $count;
}
/**
*
*/
public function removeAll()
{
if (Cookie::has('cart_token')) {
$cart = Model::findByToken(Cookie::get('cart_token'))->delete();
} elseif (auth()->check()) {
$cart = Model::findByUser(auth()->user()->id)->delete();
}
}
/**
* @param $request
* @return array
*/
public function update($request)
{
$product = Product::find($request->product_id);
$max_count = $product->product->count;
if (Cookie::has('cart_token')) {
$cart = Model::findByToken($request->cookie('cart_token'))->where('product_id', $request->product_id)->where('size', $request->getSize())->first();
if (!empty($cart)) {
$cart->update([
'count' => $request->count
]);
} else {
$cart = Model::create([
'product_id' => $request->product_id,
'count' => $request->count,
'size' => $request->getSize(),
'token' => $request->cookie('cart_token')
]);
}
$count = Model::findByToken($request->cookie('cart_token'))->whereHas('product', function ($query) {
$query->whereHas('product');
})->count();
} elseif (auth()->check()) {
$cart = Model::findByUser(auth()->user()->id)->where('product_id', $request->product_id)->where('size', $request->getSize())->first();
if (!empty($cart)) {
$cart->update([
'count' => $request->count
]);
} else {
$cart = Model::create([
'product_id' => $request->product_id,
'count' => $request->count,
'size' => $request->getSize(),
'user_id' => auth()->user()->id
]);
}
$count = auth()->user()->cart()->whereHas('product', function ($query) {
$query->whereHas('product');
})->count();
}
// $price = 0;
// $price_discount = 0;
// $price_current = 0;
//
// $price += $cart->product->product->getPrice();
// $price_discount += $cart->product->product->getDiscountPrice();
//
// $price_current = $cart->product->product->price_discount ? $price_discount : $price;
list($price) = $this->getProducts();
return [$price, $count, $max_count];
}
public function getBasketCount()
{
if (Cookie::has('cart_token')) {
$count = Model::findByToken(Cookie::get('cart_token'))->whereHas('product', function ($query) {
$query->whereHas('product', function ($query) {
return $query->isAvailable();
});
})->count();
} elseif (auth()->check()) {
$count = auth()->user()->cart()->whereHas('product', function ($query) {
$query->whereHas('product', function ($query) {
return $query->isAvailable();
});
})->count();
}
return $count;
}
/**
* @param $user_id
*/
public function AddToCartUpdate($user_id)
{
$token = Cookie::get('cart_token');
$carts = Model::findByToken($token)->get()->map(function ($cart) {
return $cart->product_id;
});
$cart_user = Model::findByUser($user_id)->get()->map(function ($cart) {
return $cart->product_id;
});
$product_id = array_diff($carts->toArray(), $cart_user->toArray());
Model::whereIn('product_id', $product_id)->findByToken($token)->update([
'token' => null,
'user_id' => $user_id
]);
Cookie::queue(Cookie::forget('cart_token'));
}
}

382
app/Helpers/DashboardStatic.php Executable file
View File

@@ -0,0 +1,382 @@
<?php
namespace App\Helpers;
use App\Models\Billing;
use App\Models\Order;
use App\Models\User;
use Illuminate\Support\Facades\DB;
class DashboardStatic
{
public static function getCountProcessing()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = self::getCountStaticsSql('processing', $start, $now);
return $data;
}
public static function getCountCollected()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = self::getCountStaticsSql('collected', $start, $now);
return $data;
}
public static function getCountClosed()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = self::getCountStaticsSql('closed', $start, $now);
return $data;
}
public static function getCountCancelled()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = self::getCountStaticsSql('cancelled', $start, $now);
return $data;
}
public static function getCountReplacement()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = self::getCountStaticsSql('replacement', $start, $now);
return $data;
}
public static function getCountArchived()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = Order::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
// ->archived(true)
->get();
$data = $data->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
})->collapse();
$order_data = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$order_data[] = isset($data[$day]) ? $data[$day] : 0;
}
return $order_data;
}
public static function getUserStatics()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$users = User::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
->get();
//$users = collect($users)->groupBy('date');
$users = $users->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
});
return $users;
$data = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$data[] = isset($users[$day]) ? $users[$day] : 0;
}
return $data;
}
private static function getCountStaticsSql($status, $start, $now)
{
$data = Order::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->where('status', $status)
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
// ->archived(false)
->get();
$data = $data->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
})->collapse();
$order_data = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$order_data[] = isset($data[$day]) ? $data[$day] : 0;
}
return $order_data;
}
public static function getCountInWay()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = Order::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->whereIn('status', ['waiting_buyer', 'in_way'])
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
// ->archived(false)
->get();
$data = $data->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
})->collapse();
$order_data = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$order_data[] = isset($data[$day]) ? $data[$day] : 0;
}
return $order_data;
}
public static function getSuccessTransactions()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = Billing::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->where('status', 'payed')
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
->get();
$data = $data->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
})->collapse();
$transactions = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$transactions[] = isset($data[$day]) ? $data[$day] : 0;
}
return $transactions;
}
public static function getWaitingTransactions()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = Billing::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->where('status', 'waiting')
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
->get();
$data = $data->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
})->collapse();
$transactions = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$transactions[] = isset($data[$day]) ? $data[$day] : 0;
}
return $transactions;
}
public static function getRefusedTransactions()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = Billing::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->where('status', 'refused')
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
->get();
$data = $data->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
})->collapse();
$transactions = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$transactions[] = isset($data[$day]) ? $data[$day] : 0;
}
return $transactions;
}
public static function getCreditPayed()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = Order::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->where('payment_type', 'credit')
->where('payment_status', 'payed')
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
// ->archived(false)
->get();
$data = $data->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
})->collapse();
$order_data = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$order_data[] = isset($data[$day]) ? $data[$day] : 0;
}
return $order_data;
}
public static function getCancelledCredit()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = Order::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->where('payment_type', 'credit')
->where('payment_status', 'cancelled')
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
// ->archived(false)
->get();
$data = $data->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
})->collapse();
$order_data = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$order_data[] = isset($data[$day]) ? $data[$day] : 0;
}
return $order_data;
}
public static function getReviewCredit()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = Order::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->where('payment_type', 'credit')
->where('payment_status', 'review')
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
// ->archived(false)
->get();
$data = $data->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
})->collapse();
$order_data = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$order_data[] = isset($data[$day]) ? $data[$day] : 0;
}
return $order_data;
}
public static function getWaitingCredit()
{
$start = now()->subDays(30);
$now = now()->toDateString();
$data = Order::select(DB::raw("COUNT(id) as count"), DB::raw('DATE(created_at) as date'))
->where('payment_type', 'credit')
->where('payment_status', 'waiting')
->whereBetween('created_at', ["{$start->toDateString()} 00:00:01", "{$now} 23:59:59"])
->groupBy('date')
// ->archived(false)
->get();
$data = $data->map(function ($order) {
$array = [];
$array[$order->date] = $order->count;
return $array;
})->collapse();
$order_data = [];
for ($i = 0; $i <= 30; $i++) {
$day = $start->copy()->addDays($i)->toDateString();
$order_data[] = isset($data[$day]) ? $data[$day] : 0;
}
return $order_data;
}
}

181
app/Helpers/MainPage.php Executable file
View File

@@ -0,0 +1,181 @@
<?php
namespace App\Helpers;
use App\Models\Category;
use App\Models\Compilation;
use App\Models\Post;
use App\Models\Slider;
use Illuminate\Support\Str;
use Jenssegers\Agent\Agent;
class MainPage
{
protected $agent;
protected $lang;
/**
* MainPage constructor.
*/
public function __construct()
{
$this->agent = new Agent();
$this->lang = app()->getLocale();
}
/**
* @param $type
* @return mixed
*/
public function getMainProducts($type)
{
$newProducts = Compilation::published();
switch ($type) {
case 'new':
$newProducts = $newProducts->newProducts();
break;
case 'popular':
$newProducts = $newProducts->popularProducts();
break;
case 'lider':
$newProducts = $newProducts->liderProducts();
break;
default:
$newProducts = $newProducts->newProducts();
break;
}
$newProducts = $newProducts->published()->first()->products()->published()->with('categories:id,name,parent_id,slug', 'categories.parent.parent', 'children:id,child_id', 'children')->isAvailable()->get(['id', 'name', 'price', 'price_discount', 'poster_thumb', 'slug', 'leader_of_sales', 'currency', 'available', 'count']);
$newProducts->map(function ($product) {
$product->categories->map(function ($category) {
if ($category->parent) {
if ($category->parent->parent) {
$category->link = route('category.showParent', [$category->parent->parent->slug, $category->parent->slug, $category->slug]);
} else {
$category->link = route('category.show', [$category->parent->slug, $category->slug]);
}
} else {
$category->link = route('category.view', $category->slug);
}
});
$product->price = $product->getPrice();
$product->price_discount = $product->price_discount == null ? null : $product->getDiscountPrice();
});
return $newProducts;
}
/**
* @return mixed
*/
public function getPopularCategories()
{
$popularCategories = Category::latest('id')
->latest('id')
->where('popular', true)
->get();
$popularCategories->map(function ($category) {
if ($category->parent) {
if ($category->parent->parent) {
$category->link = route('category.showParent', [$category->parent->parent->slug, $category->parent->slug, $category->slug]);
} else {
$category->link = route('category.show', [$category->parent->slug, $category->slug]);
}
} else {
$category->link = route('category.view', $category->slug);
}
});
return $popularCategories;
}
/**
* @param $lang
* @return array
*/
public function getSliders($lang)
{
if ($this->agent->isMobile()) {
if ($this->agent->isTablet()) {
$sliders = Slider::where('language', $lang)
->where('type', 'desktop')
->where('placement', 'top')
->orderBy('position', 'asc')
->published()
->get();
$middleSliders = Slider::where('language', $lang)
->where('type', 'desktop')
->where('placement', 'middle')
->orderBy('position', 'asc')
->published()
->get();
} else {
$sliders = Slider::where('language', $lang)
->where('type', 'mobile')
->where('placement', 'top')
->orderBy('position', 'asc')
->published()
->get();
$middleSliders = Slider::where('language', $lang)
->where('type', 'mobile')
->where('placement', 'middle')
->orderBy('position', 'asc')
->published()
->get();
}
} else {
$sliders = Slider::where('language', $lang)
->where('type', 'desktop')
->where('placement', 'top')
->orderBy('position', 'asc')
->published()
->get();
$middleSliders = Slider::where('language', $lang)
->where('type', 'desktop')
->where('placement', 'middle')
->orderBy('position', 'asc')
->published()
->get();
}
return [$sliders, $middleSliders];
}
/**
* @param $lang
* @return array
*/
public function getPosts($lang)
{
$posts = Post::latest('id')
->where('language', $lang)
->where('topped', false)
->whereIn('type', ['news','sales'])
->limit(3)
->get();
$posts->map(function ($post) {
$post->date = $post->getDatePublic();
$post->content = Str::limit($post->content, 150);
});
$toppedPost = Post::where('topped', true)
->where('language', $lang)
->select('id', 'name', 'language', 'created_at', 'image', 'slug', 'type', 'content')
->first();
$toppedPost->date = $toppedPost->getDatePublic();
return [$posts, $toppedPost];
}
}

27
app/Helpers/MassAction.php Executable file
View File

@@ -0,0 +1,27 @@
<?php
namespace App\Helpers;
use App\Models\Product;
class MassAction
{
public function massDelete(array $attributes)
{
Product::whereIn('id', $attributes)->delete();
}
public function massUnpublish(array $attributes)
{
Product::whereIn('id', $attributes)->update([
'published' => false
]);
}
public function massPublish(array $attributes)
{
Product::whereIn('id', $attributes)->update([
'published' => true
]);
}
}

132
app/Helpers/Month.php Executable file
View File

@@ -0,0 +1,132 @@
<?php
namespace App\Helpers;
class Month
{
/**
* @param $lang
* @param $month
* @return string
*/
public static function LayoutMonth($lang, $month)
{
switch ($lang) {
case 'ru':
return self::monthRu($month);
break;
case 'uz':
return self::monthUz($month);
break;
}
}
/**
* @param $lang
* @param $month
* @return string
*/
public static function getMonth($lang, $month)
{
switch ($lang) {
case 'ru':
return self::monthRu($month);
break;
case 'uz':
return self::monthUz($month);
break;
}
}
/**
* @param $month
* @return string
*/
protected static function monthRu($month)
{
switch ($month) {
case '01':
return 'января';
break;
case '02':
return 'февраля';
break;
case '03':
return 'март';
break;
case '04':
return 'апреля';
break;
case '05':
return 'май';
break;
case '06':
return 'июня';
break;
case '07':
return 'июля';
break;
case '08':
return 'августа';
break;
case '09':
return 'сентября';
break;
case '10':
return 'октября';
break;
case '11':
return 'ноября';
break;
case '12':
return 'декабря';
break;
}
}
/**
* @param $month
* @return string
*/
protected static function monthUz($month)
{
switch ($month) {
case '01':
return 'yanvar';
break;
case '02':
return 'fevral';
break;
case '03':
return 'mart';
break;
case '04':
return 'april';
break;
case '05':
return 'may';
break;
case '06':
return 'iyun';
break;
case '07':
return 'iyul';
break;
case '08':
return 'avgust';
break;
case '09':
return 'sentyabr';
break;
case '10':
return 'oktyabr';
break;
case '11':
return 'noyabr';
break;
case '12':
return 'dekabr';
break;
}
}
}

212
app/Helpers/Product.php Executable file
View File

@@ -0,0 +1,212 @@
<?php
namespace App\Helpers;
use App\Models\User;
use App\Models\Order;
use App\Models\Currency;
use App\Models\OrderProducts;
use App\Models\Product as Model;
use App\Models\NotificationAvailable;
class Product
{
protected $currency;
public function __construct()
{
$this->currency = Currency::latest('id', 'desc')->limit(1)->first();
}
/**
* @param $product
* @return mixed
*/
public function getPopularProducts($product)
{
$popularProducts = Model::inRandomOrder()
->notChilds()
->published()
->whereNotIn('id', [$product->id])
->whereHas('childrens')
->isAvailable()
->with('comments', 'childrens:id,child_id,sizes,color_id', 'childrens.screens', 'childrens.color', 'children')
->limit(10)
->get();
$popularProducts->map(function ($product) {
$product->categories->map(function ($category) {
if ($category->parent) {
if ($category->parent->parent) {
$category->link = route('category.showParent', [$category->parent->parent->slug, $category->parent->slug, $category->slug]);
} else {
$category->link = route('category.show', [$category->parent->slug, $category->slug]);
}
} else {
$category->link = route('category.view', $category->slug);
}
});
});
$popularProducts->makeHidden(['created_at', 'updated_at', 'sizes', 'color_id']);
return $popularProducts;
}
/**
* @param Model $product
* @return array
*/
public function getProductShowAttributes(Model $product)
{
$product->update([
'views' => $product->views + 1
]);
$product->loadMissing(['comments', 'categories:id,name', 'childrens:id,child_id,sizes,color_id', 'childrens.screens', 'childrens.color', 'characteristics', 'children.screen']);
$product->price = $product->getPrice();
$product->price_discount = $product->price_discount == null ? null : $product->getDiscountPrice();
$product->makeHidden(['created_at', 'updated_at', 'sizes', 'color_id']);
$category = $product->categories()->first();
return [$product, $category];
}
/**
* @param $name
* @return mixed
*/
public function getSearchProduct($name)
{
$products = Model::select('id', 'name', 'poster_thumb', 'price', 'price_discount', 'slug', 'currency', 'popular', 'article_number', 'leader_of_sales', 'available', 'count')
->where('name->ru', 'ilike', '%'.$name.'%')
->with('children')
->whereHas('childrens')
->published()
->paginate(20);
$products->map(function ($product) {
$product->price = $product->getPrice();
$product->price_discount = $product->price_discount == null ? null : $product->getDiscountPrice();
});
return $products;
}
/**
* @param $request
*/
public function createNotificationProduct($request)
{
$phone = str_replace(['-', ' ', '(', ')', '+'], '', $request->phone);
NotificationAvailable::firstOrCreate([
'product_id' => $request->product_id,
'phone' => $phone
]);
}
/**
* @param Model $product
* @param $request
* @return mixed
*/
public function StoreBuyOneClick(Model $product, $request)
{
$currency = Currency::latest('id', 'desc')->first();
$price = $product->price_discount ? $product->getPriceDiscount() : $product->getPrice();
$phone = str_replace(['+', '(', ')', ' ', '-'], '', $request->phone);
if (auth()->check() && auth()->user()->phone == $phone) {
$user_id = auth()->user()->id;
} else {
$user_id = $this->createUser($phone, $request);
}
$order = Order::create([
'payment_type' => 'cash',
'user_id' => $user_id,
'type_delivery' => 'pickup',
'type' => 'one_click',
'currency' => $currency,
'payment_status' => 'cash',
'price_delivery' => 0,
'price_product' => $price,
'comment' => $request->comment
]);
$discount = $product->price_discount ? 100 - $product->price_discount * 100 / $product->price : null;
OrderProducts::create([
'order_id' => $order->id,
'product_id' => $product->id,
'discount' => round($discount),
'count' => 1,
'size' => null,
'color_id' => $product->children->id,
'price' => $price
]);
return $order;
}
public function storeOnCredit($product)
{
$price = $product->price_discount ? $product->getPriceDiscount() : $product->getPrice();
$currency = Currency::latest('id', 'desc')->first();
$order = Order::create([
'payment_type' => 'credit',
'user_id' => auth()->user()->id,
'type_delivery' => 'pickup',
'currency' => $currency,
'payment_status' => 'waiting',
'price_delivery' => 0,
'price_product' => $price,
]);
$discount = $product->price_discount ? 100 - $product->price_discount * 100 / $product->price : null;
OrderProducts::create([
'order_id' => $order->id,
'product_id' => $product->id,
'discount' => round($discount),
'count' => 1,
'size' => null,
'color_id' => $product->children->id,
'price' => round($price, 0)
]);
return $order;
}
/**
* @param $phone
* @param $request
* @return mixed
*/
private function createUser($phone, $request)
{
$user = User::findByPhone($phone)->first();
if (!empty($user)) {
$user_id = $user->id;
} else {
$user = User::create([
'first_name' => $request->first_name,
'phone' => $phone,
'email' => $request->email
]);
$user_id = $user->id;
}
return $user_id;
}
}

50
app/Helpers/helpers.php Executable file
View File

@@ -0,0 +1,50 @@
<?php
use App\Models\Cart;
use App\Models\PersonalAccessToken;
use App\Models\User;
use Illuminate\Support\Facades\Cookie;
if (! function_exists('getAuthUser')) {
function getAuthUser()
{
$bearer = request()->bearerToken();
if ($bearer) {
[$personalAccessTokenId, $token] = explode('|', $bearer, 2);
$personalAccessToken = PersonalAccessToken::find($personalAccessTokenId);
if ($personalAccessToken && hash_equals($personalAccessToken->token, hash('sha256', $token))) {
return User::find($personalAccessToken->tokenable_id);
}
}
return null;
}
}
if (! function_exists('getCart')) {
function getCart($productId = null)
{
$user = getAuthUser();
if ($user) {
$cart = Cart::where('user_id', $user->id)->get();
} else {
$cart = Cart::where('token', Cookie::get('cart_token'))->get();
}
if ($productId) {
return $cart->where('product_id', $productId)->first();
}
return $cart;
}
}
if (! function_exists('ceiling')) {
function ceiling(float|int $num, $significance = 1)
{
return (ceil($num / $significance)) * $significance;
}
}

View File

@@ -0,0 +1,177 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Models\Cart;
use App\Models\User;
use App\Services\API\SmsService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\RateLimiter;
use Symfony\Component\HttpFoundation\Response;
class AuthController extends Controller
{
public function resend(Request $request)
{
$request->validate([
'phone' => 'required',
]);
$phone = preg_replace("/[^0-9]/", "", $request->phone);
// Define the same rate limit key to share attempts between auth and resend
$rateLimitKey = 'verify_attempts_' . $phone;
// Set the same maximum attempts and decay time
$maxAttempts = 5;
$decayMinutes = 1;
// Check if the phone number has exceeded the rate limit
if (RateLimiter::tooManyAttempts($rateLimitKey, $maxAttempts)) {
$seconds = RateLimiter::availableIn($rateLimitKey);
return response()->json([
'message' => 'Too many attempts. Please try again in ' . $seconds . ' seconds.'
], 429); // 429 Too Many Requests
}
$user = User::where('phone', $phone)->first();
if ($user) {
// send SMS with verify code
$verify_code = SmsService::send($phone);
$user->update([
'verify_code' => $verify_code,
]);
// Increase the attempt count
RateLimiter::hit($rateLimitKey, $decayMinutes * 60);
return response()->json(['phone' => $phone]);
}
// return can't find user message
return response()->json(['message' => 'User not found']);
}
public function auth(Request $request)
{
$phone = preg_replace("/[^0-9]/", "", $request->input('phone'));
// Define the rate limit key based on the phone number.
$rateLimitKey = 'verify_attempts_' . $phone;
// Set the maximum attempts and the decay time (e.g., 5 attempts every 1 minute)
$maxAttempts = 5;
$decayMinutes = 1;
// Check if the phone number has exceeded the rate limit
if (RateLimiter::tooManyAttempts($rateLimitKey, $maxAttempts)) {
$seconds = RateLimiter::availableIn($rateLimitKey);
return response()->json([
'message' => 'Too many attempts. Please try again in ' . $seconds . ' seconds.'
], 429); // 429 Too Many Requests
}
$user = User::where('phone', $phone)->first();
// send SMS with verify code
$verify_code = SmsService::send($phone);
if ($user) {
$user->update([
'verify_code' => $verify_code,
]);
} else {
User::create([
'phone' => $phone,
'verify_code' => $verify_code,
]);
}
// Increase the attempt count
RateLimiter::hit($rateLimitKey, $decayMinutes * 60);
return response()->json(['phone' => $phone]);
}
public function verify(Request $request)
{
$request->validate([
'phone' => 'required',
'verify_code' => 'required',
]);
$phone = preg_replace("/[^0-9]/", "", $request->phone);
$user = User::where('phone', $phone)->first();
// check if user exists
if (!$user) {
return response()->json([
'message' => 'User not found'
], Response::HTTP_NOT_FOUND);
}
// check if verify code is correct
if ($user->verify_code != $request->verify_code) {
return response([
'message' => 'Verify code is incorrect'
], Response::HTTP_UNAUTHORIZED);
}
$token = $user->createToken('token')->plainTextToken;
$cookie = cookie('jwt', $token, 60 * 24 * 365, null, null, secure: true, httpOnly: true); // 1 year expiration
// clear verify code
$user->update([
'verify_code' => null,
]);
// Update cart, remove token and add user_id
$this->updateCart($user);
return response([
'data' => [
'id' => $user->id,
'phone' => $user->phone,
'access_token' => $token
]
])->withCookie($cookie);
}
public function logout()
{
$cookie = Cookie::forget('jwt');
// logout
auth()->user()->tokens()->delete();
return response([
'message' => 'Success'
])->withCookie($cookie);
}
private function getLocalToken()
{
return request()->header('X-Application-Token');
}
private function updateCart($user)
{
if ($this->getLocalToken()) {
// Update carts, remove token and add user_id
$carts = Cart::where('token', $this->getLocalToken())->get();
foreach ($carts as $cart) {
$cart->update([
'token' => null,
'user_id' => $user->id,
]);
}
}
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\BranchResource;
use App\Models\Branch;
class BranchController extends Controller
{
public function index()
{
$branches = Branch::all();
return BranchResource::collection($branches);
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\BrandPaginationResource;
use App\Models\Brand;
use Illuminate\Http\Request;
class BrandController extends Controller
{
public function index(Request $request)
{
$brands = Brand::query()->orderBy("position")->paginate($request->limit ?? 10);
return (new BrandPaginationResource($brands))->response();
}
}

View File

@@ -0,0 +1,338 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\CartResource;
use App\Models\PersonalAccessToken;
use Illuminate\Http\Request;
use App\Models\Cart;
use App\Models\Currency;
use App\Models\User;
use Illuminate\Support\Facades\DB;
class CartController extends Controller
{
public function getCart()
{
$currency = Currency::latest()->first();
// add currency to cache
cache()->put('currency', $currency, now()->addMinutes(60));
$bearer = $this->getBearerToken();
if ($bearer) {
[$personalAccessTokenId, $token] = explode('|', $bearer, 2);
$personalAccessToken = PersonalAccessToken::find($personalAccessTokenId);
if ($personalAccessToken && hash_equals($personalAccessToken->token, hash('sha256', $token))) {
// Authenticated
$cart = Cart::with('product')->whereHas('product', function ($product) {
$product->where('child_id', null);
})->where('user_id', $personalAccessToken->tokenable_id)->orderBy('id', 'desc')->get();
}
} else {
// Check for local token in request headers
$localToken = $this->getLocalToken();
if ($localToken) {
$cart = Cart::with('product')->whereHas('product', function ($product) {
$product->where('child_id', null);
})->where('token', $localToken)->get();
}
}
$price_solutions = 0;
$discount_solutions = 0;
$total_solutions = 0;
$price = 0;
$discount = 0;
$total = 0;
$getReadySolutionProductsCart = collect([]);
$getSingleProductsCart = collect([]);
if (isset($cart)) {
$getReadySolutionProductsCart = $cart->filter(function ($cart) {
return $cart->product->is_ready_solution == true;
});
$ready_solutions_count = 0;
$price_solutions = $getReadySolutionProductsCart->filter(function ($cart) {
return $cart->product->count >= $cart->count;
})->map(function ($cart) use (&$ready_solutions_count) {
$ready_solutions_count += $cart->count;
$cart->product->price_total = !empty($cart->product->price_discount) ? $cart->product->price_discount * $cart->count : $cart->product->price * $cart->count;
$cart->product->price_discount_total = !empty($cart->product->price_discount) ? ($cart->product->price - $cart->product->price_discount) * $cart->count : 0;
$cart->product->price_products = $cart->product->price * $cart->count;
return $cart;
});
$discount_solutions = $price_solutions->sum('product.price_discount_total');
$total_solutions = $price_solutions->sum('product.price_total');
$price_solutions = $price_solutions->sum('product.price_products');
$single_products_count = 0;
$getSingleProductsCart = collect($cart)->filter(function ($cart) {
return $cart->product->is_ready_solution == false;
});
$price = $getSingleProductsCart->filter(function ($cart) {
return $cart->product->count >= $cart->count;
})->map(function ($cart) use (&$single_products_count) {
$single_products_count += $cart->count;
$cart->product->price_total = !empty($cart->product->price_discount) ? $cart->product->price_discount * $cart->count : $cart->product->price * $cart->count;
$cart->product->price_discount_total = !empty($cart->product->price_discount) ? ($cart->product->price - $cart->product->price_discount) * $cart->count : 0;
$cart->product->price_products = $cart->product->price * $cart->count;
return $cart;
});
$discount = $price->sum('product.price_discount_total');
$total = $price->sum('product.price_total');
$price = $price->sum('product.price_products');
}
// get currency from cache
$currency = cache()->get('currency');
return [
'data' => [
'ready_solutions' => [
'products' => CartResource::collection($getReadySolutionProductsCart),
'price' => ceiling($price_solutions * $currency->dollar, 100),
'discount' => ceiling($discount_solutions * $currency->dollar, 100),
'total' => ceiling($total_solutions * $currency->dollar, 100),
],
'ready_solutions_count' => $ready_solutions_count,
'single_products' => [
'products' => CartResource::collection($getSingleProductsCart),
'price' => ceiling($price * $currency->dollar, 100),
'discount' => ceiling($discount * $currency->dollar, 100),
'total' => ceiling($total * $currency->dollar, 100),
],
'single_products_count' => $single_products_count
]
];
}
private function getUser()
{
$bearer = $this->getBearerToken();
$type = null;
$user = null;
$token = null;
if ($bearer) {
[$personalAccessTokenId, $token] = explode('|', $bearer, 2);
$personalAccessToken = PersonalAccessToken::find($personalAccessTokenId);
if ($personalAccessToken && hash_equals($personalAccessToken->token, hash('sha256', $token))) {
// Authenticated
$type = 'user';
$user = User::findOrFail($personalAccessToken->tokenable_id);
$token = null;
}
} else {
// Check for local token in request headers
$localToken = $this->getLocalToken();
if ($localToken) {
$type = 'token';
$user = null;
$token = $localToken;
}
}
return [
'type' => $type,
'user' => $user,
'token' => $token
];
}
public function addToCart(Request $request)
{
try {
// Validate the request
$request->validate([
'product_id' => 'required|exists:products,id',
]);
// Retrieve the bearer token from the request
$bearer = $this->getBearerToken();
if ($bearer) {
[$personalAccessTokenId, $token] = explode('|', $bearer, 2);
$personalAccessToken = PersonalAccessToken::find($personalAccessTokenId);
if ($personalAccessToken && hash_equals($personalAccessToken->token, hash('sha256', $token))) {
// Authenticated
$user = User::find($personalAccessToken->tokenable_id);
if ($user) {
$this->updateOrCreateCart($user, $request->product_id);
return response()->json(['status' => true, 'data' => null]);
}
}
}
// Check for local token in request headers
$localToken = $this->getLocalToken();
if (!$localToken) {
return response()->json(['message' => 'Unauthorized'], 401);
}
$this->updateOrCreateCartByToken($localToken, $request->product_id);
} catch (\Throwable $e) {
return response()->json([
'message' => $e->getMessage()
], 403);
}
return response()->json(['status' => true, 'data' => null]);
}
public function add(Cart $cart)
{
$user = $this->getUser();
try {
DB::beginTransaction();
if (empty($user['type']))
abort(403);
if ($user['type'] == 'token') {
if ($cart->token != $user['token'])
abort(403);
} else if ($user['type'] == 'user') {
if ($cart->user_id != $user['user']->id)
abort(403);
}
$cart->update([
'count' => $cart->count + 1
]);
} catch (\Throwable $e) {
report($e);
DB::rollBack();
return response()->json([
'message' => trans('errors.try_again')
])->setStatusCode(403);
}
DB::commit();
return $this->getCart();
}
public function decrease(Cart $cart)
{
$user = $this->getUser();
try {
DB::beginTransaction();
if (empty($user['type']))
abort(403);
if ($user['type'] == 'token') {
if ($cart->token != $user['token'])
abort(403);
} else if ($user['type'] == 'user') {
if ($cart->user_id != $user['user']->id)
abort(403);
}
if ($cart->count <= 1) {
$cart->delete();
} else {
$cart->update([
'count' => $cart->count - 1
]);
}
} catch (\Throwable $e) {
report($e);
DB::rollBack();
return response()->json([
'message' => trans('errors.try_again')
])->setStatusCode(403);
}
DB::commit();
return $this->getCart();
}
public function delete($cartId)
{
try {
DB::beginTransaction();
Cart::find($cartId)->delete();
} catch (\Throwable $e) {
report($e);
DB::rollBack();
return response()->json([
'message' => trans('errors.try_again')
])->setStatusCode(403);
}
DB::commit();
return $this->getCart();
}
protected function updateOrCreateCart($user, $productId)
{
$cart = $user->cart()->where('product_id', $productId)->first();
try {
if ($cart) {
// Update the existing cart item
Cart::where('id', $cart->id)->update([
'count' => $cart->count + 1
]);
} else {
// Create a new cart item
$user->cart()->create([
'product_id' => $productId,
'count' => 1,
]);
}
} catch (\Throwable $e) {
report($e);
return response()->json([
'message' => trans('errors.try_again')
])->setStatusCode(403);
}
}
protected function updateOrCreateCartByToken($localToken, $productId)
{
$cart = Cart::where('token', $localToken)
->where('product_id', $productId)
->first();
if ($cart) {
// Update the existing cart item
Cart::where('id', $cart->id)->update([
'count' => $cart->count + 1
]);
} else {
// Create a new cart item
Cart::create([
'token' => $localToken,
'product_id' => $productId,
'count' => 1,
]);
}
}
private function getLocalToken()
{
return request()->header('X-Application-Token');
}
private function getBearerToken()
{
return request()->bearerToken();
}
}

View File

@@ -0,0 +1,141 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\BrandResource;
use App\Http\Resources\CategoryResource;
use App\Http\Resources\ProductPaginationResource;
use App\Models\Category;
use App\Models\Currency;
use Illuminate\Http\Request;
class CategoryController extends Controller
{
public function index()
{
$categories = Category::where('parent_id', null)->orderBy('position', 'asc')->get();
return CategoryResource::collection($categories);
}
public function products(Request $request, int $category_id)
{
$category = Category::find($category_id);
// check if category exists
if (!$category) {
return response()->json(['message' => 'Category not found'], 404);
}
$currency = Currency::latest()->first();
// add currency to cache
cache()->put('currency', $currency, now()->addMinutes(60));
// filter products by views (popular)
// filter products by price (cheaper, expensive)
// filter products by created_at (new)
// filter products by brand_id
// filter products by power (less_power, more_power)
$products = $category->products()->where('published', true);
if ($request->has('sort_by')) {
switch ($request->sort_by) {
case 'popular':
$products->orderBy('views', 'desc');
break;
case 'cheaper':
// If price_discount is not null, order by price_discount; otherwise, order by price
$products->orderByRaw('CASE WHEN price_discount IS NOT NULL THEN price_discount ELSE price END ASC');
break;
case 'expensive':
// If price_discount is not null, order by price_discount; otherwise, order by price
$products->orderByRaw('CASE WHEN price_discount IS NOT NULL THEN price_discount ELSE price END DESC');
break;
case 'new':
$products->orderBy('created_at', 'desc');
break;
case 'less_power':
$products->orderBy('power', 'asc');
break;
case 'more_power':
$products->orderBy('power', 'desc');
break;
}
}
// elseif ($category->is_filter_power) {
// $products->orderBy('power', 'asc');
// }
else { // default sort by price
$products->orderBy('price', 'asc');
}
if ($request->has('brand_id')) {
$products->where('brand_id', $request->brand_id);
}
// price range filter
if ($request->has('price_from') || $request->has('price_to')) {
$products->where(function ($query) use ($request, $currency) {
if ($request->has('price_from')) {
$query->where(function ($subQuery) use ($request, $currency) {
$subQuery->where(function ($q) use ($request, $currency) {
$q->whereNotNull('price_discount')
->where('price_discount', '>=', $request->price_from / $currency->dollar);
})->orWhere(function ($q) use ($request, $currency) {
$q->whereNull('price_discount')
->where('price', '>=', $request->price_from / $currency->dollar);
});
});
}
if ($request->has('price_to')) {
$query->where(function ($subQuery) use ($request, $currency) {
$subQuery->where(function ($q) use ($request, $currency) {
// dd($q->first());
$q->whereNotNull('price_discount')
->where('price_discount', '<=', $request->price_to / $currency->dollar);
})->orWhere(function ($q) use ($request, $currency) {
$q->whereNull('price_discount')
->where('price', '<=', $request->price_to / $currency->dollar);
});
});
}
});
}
$products = $products->paginate($request->limit ?? 20);
return (new ProductPaginationResource($products))->response();
}
public function filter($category_id, Request $request)
{
$category = Category::find($category_id);
$lang = $request->header('Accept-Language') ?? 'ru';
return response()->json([
'data' => [
'sort_by' => [
[
'name' => $lang == 'ru' ? 'Популярные' : 'Mashhur',
'slug' => 'popular'
],
[
'name' => $lang == 'ru' ? 'Сначало подешевле' : 'Avval arzonlari',
'slug' => 'cheaper'
],
[
'name' => $lang == 'ru' ? 'Сначало подороже' : 'Avval qimmatlari',
'slug' => 'expensive'
],
[
'name' => $lang == 'ru' ? 'Новые' : 'Yangi kelganlar',
'slug' => 'new'
]
],
'brands' => BrandResource::collection($category->brands)
]
]);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\CompanyResource;
use App\Models\Company;
class CompanyController extends Controller
{
public function get()
{
$company = Company::first();
return new CompanyResource($company);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\CompilationResource;
use App\Http\Resources\ProductPaginationResource;
use App\Models\Compilation;
use App\Models\Currency;
class CompilationController extends Controller
{
public function index()
{
$compilations = Compilation::where('published', 1)->get();
$currency = Currency::latest()->first();
// add currency to cache
cache()->put('currency', $currency, now()->addMinutes(60));
return CompilationResource::collection($compilations);
}
public function show($id)
{
$compilation = Compilation::findOrFail($id);
$products = $compilation->products()->paginate($request->limit ?? 10);
return (new ProductPaginationResource($products));
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\FavoritePaginationResource;
use App\Models\Currency;
use App\Models\Favorite;
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class FavoriteController extends Controller
{
public function index(Request $request)
{
$currency = Currency::latest()->first();
// add currency to cache
cache()->put('currency', $currency, now()->addMinutes(60));
$user = $request->user();
$favorites = Favorite::where('user_id', $user->id)->whereHas('product', function ($q) {
$q->whereNull('child_id');
})->paginate($request->limit ?? 10);
return (new FavoritePaginationResource($favorites))->response();
}
public function store(Request $request, $product_id)
{
$product = Product::findOrFail($product_id);
$user = $request->user();
// check if product already in favorites
$favorite = Favorite::where('user_id', $user->id)->where('product_id', $product_id)->first();
if (!$favorite) {
Favorite::create([
'user_id' => $user->id,
'product_id' => $product_id
]);
}
return response()->json([
'message' => 'Successfully added to favorites'
])->setStatusCode(200);
}
public function destroy(Request $request, $product_id)
{
try {
DB::beginTransaction();
$user = $request->user();
Favorite::where('user_id', $user->id)->where('product_id', $product_id)->delete();
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
return response()->json(['message' => $e->getMessage()])->setStatusCode(500);
}
return response('', 204);
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Models\Setting;
class FeedbackController extends Controller
{
public function get()
{
$setting = Setting::first();
return response()->json([
'data' => [
'phone' => $setting->phone['default'],
'telegram_support' => isset($setting->socials['telegram']) ? $setting->socials['telegram'] : null,
]
]);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Firebase\Request;
use App\Models\Firebase;
class FirebaseController extends Controller
{
public function store(Request $request)
{
// get bearer token
$token = $request->bearerToken();
if ($token) {
$user = getAuthUser();
if ($user) {
Firebase::where('token', $token)->update([
'user_id' => $user->id,
]);
}
} else {
// store firebase token
Firebase::create([
'token' => $request->device_token,
'device_id' => $request->device_id,
'device_name' => $request->device_name,
'device_type' => $request->device_type,
]);
}
return response()->json([
'status' => 'success',
'data' => md5($request->device_token . $request->device_id)
]);
}
}

View File

@@ -0,0 +1,269 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Checkout\CheckoutRequest;
use App\Http\Resources\OrderPaginationResource;
use App\Http\Resources\OrderShowResource;
use App\Http\Resources\ProductResource;
use App\Http\Resources\StatusResource;
use App\Models\City;
use App\Models\Currency;
use App\Models\DeliveryPrice;
use App\Models\Order;
use App\Models\Power;
use App\Models\Product;
use App\Models\Setting;
use App\Services\API\OrderService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Services\API\ProductService;
use App\Services\BotService;
use Illuminate\Support\Facades\Auth;
class OrderController extends Controller
{
public function checkout(CheckoutRequest $request)
{
$currency = Currency::getCurrency()->dollar;
DB::beginTransaction();
try {
$data = $request->validated();
$orderService = new OrderService($data);
$row = $orderService->createOrder($data);
} catch (\Exception $e) {
DB::rollBack();
return response()->json([
'message' => $e->getMessage()
], 403);
}
DB::commit();
$url = null;
if (!in_array($row->order->payment_type, ['cash', 'bank'])) {
if ($row->order->payment_type == 'click') {
$merchant_id = env("CLICK_MERCHANT_ID");
$service_id = env("CLICK_SERVICE_ID");
$url = "https://my.click.uz/services/pay?service_id={$service_id}&merchant_id={$merchant_id}&amount={$row->billing->amount}&transaction_param={$row->billing->id}";
} else {
$amount = $row->billing->amount * 100;
$payme_url = "https://checkout.paycom.uz/" . base64_encode("m=66faa5c44f9ee150b7ff81cf;ac.key={$row->billing->id};a={$amount}");
$url = $payme_url; //route('payment.merchant', [$row->order->payment_type, $row->billing->id, $row->billing->amount]);
}
}
$order = Order::find($row->order->id);
$contract = $order->contracts()->latest()->first();
$products = $order->products()
->with(['product' => function ($query) {
$query->select('id', 'name', 'price'); // Faqat kerakli ustunlarni tanlash
}])
->get()
->map(function ($orderProduct) use ($currency) {
return [
'name' => "📦 " . $orderProduct->product->name['uz'],
'price' => ceiling($orderProduct->price * $currency, 100),
'count' => $orderProduct->count,
];
});
// set lang
app()->setLocale('uz');
$group_id = Setting::query()->first()->group_id;
$user = Auth::user();
$service = new BotService();
$service->sendMessage([
"group_id" => $group_id,
"order_id" => $row->order->id,
"order_url" => route("dashboard.orders.view", ["order" => $row->order->id]),
'client_type' => trans('admin.contract-templates.' . $row->order->client_type),
'delivery_type' => trans('admin.orders.type_delivery.' . $row->order->delivery_type),
"products" => $products,
"client" => $user->first_name . " " . $user->last_name,
"phone" => $user->phone,
'time' => now(),
'summa' => ceiling($order->price_total * $currency, 100),
]);
if ($row->order->client_type == 'physical') {
$client = $row->order->full_name;
} else {
$client = $row->order->legalInfo->company_name;
}
// download contract from s3
// $path = $contract->path; // S3 file path
// $localDirectory = storage_path('downloads');
// $localPath = storage_path('downloads/' . basename($contract->path));
// // Ensure 'downloads' directory exists
// if (!is_dir($localDirectory)) {
// mkdir($localDirectory, 0755, true);
// }
// // Retrieve the file from S3 and save locally
// $content = Storage::disk('s3')->get($path);
// file_put_contents($localPath, $content);
// $this->sendFileWithData($group_id, $row, $client, $localPath);
return response()->json([
'data' => [
"id" => $row->order->id,
"payment_status" => new StatusResource($order->getPaymentStatus),
// "billing_id" => !in_array($row->order->payment_type, ['cash', 'bank']) ? $row->billing->id : null,
"payment_type" => $row->order->payment_type,
"pay_url" => $url,
// "pay_url" => !in_array($row->order->payment_type, ['cash', 'bank']) ? "https://checkout.payme.uz" : null,
"contract_url" => $contract?->getPath() ?? null
]
], 201);
}
public function preview(Request $request)
{
$currency = Currency::latest()->first();
// add currency to cache
cache()->put('currency', $currency, now()->addMinutes(60));
$products = $this->getProducts($request);
$countCollection = collect($request->products);
$is_install = false;
foreach ($products as $product) {
// Find the corresponding count for the current product
if ((new ProductService($product))->isInstall()) {
$is_install = true; // Set the flag to true if any product is installed
}
$countItem = $countCollection->firstWhere('id', $product->id);
if ($countItem) {
// Update the product's count attribute (assuming you have a 'count' attribute in your Product model)
$product->count = $countItem['count'];
}
}
$power = Power::where('power', '>=', $products->sum('power'))->first();
if (empty($power)) {
$power_id = 0;
} else {
$power_id = $power->id;
}
// delivery price
if (!empty($request->city_id)) {
$city = City::where('id', $request->city_id)->first();
$delivery_price = DeliveryPrice::where('power_id', $power_id)->where('region_id', $city->region_id)->first();
} else {
$delivery_price = 0;
}
// installation price
$settings = Setting::query()->first();
$power = $products->sum('power') / 1000;
if ($request->type == 'ready_solutions') {
$installation_price = $power * ($settings->master_price / $currency->dollar);
} else {
$installation_price = 0;
}
// product price
$product_price = collect($products)->sum(function ($product) {
$count = collect(request()->products)->firstWhere('id', $product->id)['count'] ?? 0;
return $product->finalPrice * $count;
});
if (!empty($delivery_price)) {
$delivery_price = $delivery_price->price;
} else {
$delivery_price = 0;
}
$total = $product_price + ($delivery_price / $currency->dollar) + $installation_price;
return response()->json([
'data' => [
"is_install" => $is_install,
'products' => ProductResource::collection($products),
'delivery_price' => ceiling($delivery_price, 100),
'installation_price' => ceiling($installation_price * $currency->dollar, 100),
'total_price' => ceiling($total * $currency->dollar, 100),
'product_price' => ceiling($product_price * $currency->dollar, 100),
]
]);
}
private function getProducts(Request $request)
{
$products_cart = collect($request->only('products'))->flatten(1);
$product_ids = $products_cart->pluck('id');
$products = Product::whereIn('id', $product_ids)->get();
$products = $products->map(function ($product) use ($products_cart) {
$product->power = $product->power * $products_cart->filter(function ($cart) use ($product) {
return $cart['id'] == $product->id;
})->value('count');
return $product;
});
return $products;
}
public function list(Request $request)
{
$user = getAuthUser();
$orders = $user->orders()->orderBy('id', 'desc')->with('getCurrency')->paginate($request->limit ?? 10);
$currency = Currency::latest()->first();
// add currency to cache
cache()->put('currency', $currency, now()->addMinutes(60));
return (new OrderPaginationResource($orders))->response();
}
public function show($order_id)
{
$user = getAuthUser();
$order = $user->orders()->findOrFail($order_id);
$currency = $order->getCurrency;
// add currency to cache
cache()->put('currency', $currency, now()->addMinutes(60));
// chech if user has this order
if (!$order) {
return response()->json([
'message' => 'Order not found'
], 404);
}
return new OrderShowResource($order);
}
public function checkPaymentStatus($order_id)
{
// check if this order belongs to the user
$user = request()->user();
$order = $user->orders()->find($order_id);
// chech if user has this order
if (!$order) {
return response()->json([
'message' => 'Order not found'
], 404);
}
return response()->json([
'data' => [
'payment_status' => $order->payment_status //new StatusResource($order->getPaymentStatus),
]
]);
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\PageResource;
use App\Http\Resources\PowerResource;
use App\Http\Resources\RegionWithCityResource;
use App\Models\Page;
use App\Models\Power;
use App\Models\Region;
class PageController extends Controller
{
public function policy()
{
$policy = Page::where('slug', 'policy')->first();
return new PageResource($policy);
}
public function about()
{
$about = Page::where('slug', 'about')->first();
return new PageResource($about);
}
public function powers()
{
$powers = Power::all();
return PowerResource::collection($powers);
}
public function regions()
{
$regions = Region::all();
return RegionWithCityResource::collection($regions);
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Partner\PartnerRequest;
use App\Http\Resources\PartnerRequestResource;
use App\Http\Resources\PartnerResource;
use App\Http\Resources\PartnerShowResource;
use App\Models\Partner;
use App\Models\PartnerRequest as ModelsPartnerRequest;
class PartnerController extends Controller
{
public function index()
{
$partners = Partner::query()->orderBy("position")->get();
return PartnerResource::collection($partners);
}
public function show($partner_id)
{
$partner = Partner::findOrFail($partner_id);
return new PartnerShowResource($partner);
}
public function store(PartnerRequest $request)
{
$user = getAuthUser();
$partner = ModelsPartnerRequest::create([
'user_id' => $user->id,
'partner_id' => $request->partner_id,
'city_id' => $request->city_id,
'price' => $request->price,
'comment' => $request->comment,
'phone' => $request->phone,
'full_name' => $request->full_name,
]);
return new PartnerRequestResource($partner);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\PaymentSystemResource;
use App\Models\PaymentSystemModel;
class PaymentSystemController extends Controller
{
public function legal($legal)
{
if ($legal === 'legal') {
$systems = PaymentSystemModel::with('items')->whereIn('slug', ['money_transfer', 'cash'])->get();
} else {
$systems = PaymentSystemModel::with('items')->whereIn('slug', ['payment_systems', 'cash'])->get();
}
return [
'data' => [
'payment_types' => PaymentSystemResource::collection($systems)
]
];
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\ProductDetailResource;
use App\Http\Resources\ProductPaginationResource;
use App\Models\Currency;
use App\Models\Product;
class ProductController extends Controller
{
public function show($product_id)
{
$product = Product::where('published', true)->find($product_id);
if (!$product) {
return response()->json(['message' => 'Product not found'], 404);
}
$currency = Currency::latest()->first();
// add currency to cache
cache()->put('currency', $currency, now()->addMinutes(60));
// increment views
$product->increment('views');
return ['data' => new ProductDetailResource($product)];
}
public function search()
{
if (request()->has('query') && request('query') !== '' && request('query') !== null) {
$products = Product::query()->where('published', true);
$products->where('name->uz', 'ILIKE', '%' . request('query') . '%')
->orWhere('name->ru', 'ILIKE', '%' . request('query') . '%');
return (new ProductPaginationResource($products->paginate($request->limit ?? 10)))->response();
}
return response()->json([
"pagination" => [
"current" => 1,
"previous" => null,
"next" => null,
"total" => 0,
"perPage" => 10,
"totalItems" => 0
],
'data' => []
], 200);
}
public function productsByBrand($brand_id)
{
$currency = Currency::latest()->first();
// add currency to cache
cache()->put('currency', $currency, now()->addMinutes(60));
$products = Product::where('brand_id', $brand_id)->where('published', true)->paginate(10);
return (new ProductPaginationResource($products))->response();
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\RequestPaginationResource;
use App\Http\Resources\ServiceRequestResource;
use App\Models\ServiceRequest as ModelsServiceRequest;
use App\Models\PartnerRequest as ModelsPartnerRequest;
class RequestsController extends Controller
{
public function getServiceRequests()
{
$user = request()->user();
$requests = ModelsServiceRequest::where('user_id', $user->id)->orderBy('id', 'desc')->paginate(10);
return (new RequestPaginationResource($requests))->response();
}
public function getPartnerRequests()
{
$user = request()->user();
$requests = ModelsPartnerRequest::where('user_id', $user->id)->orderBy('id', 'desc')->paginate(10);
return (new RequestPaginationResource($requests))->response();
}
public function show($service_request_id)
{
$user = request()->user();
$request = ModelsServiceRequest::where('user_id', $user->id)->where('id', $service_request_id)->firstOrFail();
return new ServiceRequestResource($request);
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Service\ServiceRequest;
use App\Http\Resources\ProblemResource;
use App\Http\Resources\ServiceRequestResource;
use App\Http\Resources\ServiceResource;
use App\Models\Problem;
use App\Models\Service;
use App\Models\ServiceRequest as ModelsServiceRequest;
class ServiceController extends Controller
{
public function index()
{
$services = Service::orderBy('position', 'asc')->get();
return ServiceResource::collection($services);
}
public function store(ServiceRequest $request)
{
$user = $request->user();
$serviceRequest = ModelsServiceRequest::create([
'user_id' => $user->id,
'service_id' => $request->service_id,
'power_id' => $request->power_id,
'city_id' => $request->city_id,
'phone' => $request->phone,
'comment' => $request->comment,
'full_name' => $request->full_name,
'status' => 'pending',
'problem_id' => $request->problem_id
]);
return new ServiceRequestResource($serviceRequest);
}
public function show($id)
{
$service = Service::findOrFail($id);
return new ServiceResource($service);
}
public function getProblems()
{
$problems = Problem::all();
return ProblemResource::collection($problems);
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\SliderResource;
use App\Models\Post;
use App\Models\Slider;
class SliderController extends Controller
{
public function index()
{
$lang = request()->header('Accept-Language') ?? 'ru';
$sliders = Post::where('language', $lang)->orderBy('position')->get();
return SliderResource::collection($sliders);
}
public function show($slider_id)
{
$slider = Post::find($slider_id);
if (!$slider) {
return response()->json([
'message' => 'Slider not found'
], 404);
}
$slider->views += 1;
$slider->save();
return response()->json([
'data' => [
'id' => $slider->id,
'name' => $slider->name,
'image' => $slider->getImage(),
'description' => $slider->content,
'views' => $slider->views,
'created_at' => $slider->created_at->format('Y-m-d H:i:s'),
]
]);
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Services\BotService;
use Illuminate\Http\Request;
class SupportController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$service = new BotService();
$message = "Support: \n\nName: " . $request->input("name") . "\n" . "Phone: " . $request->input("phone") . "\n";
$service->sendSupportMessage($message);
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\UsefulInfoItemResource;
use App\Http\Resources\UsefulInfoResource;
use App\Models\UsefulInfo;
class UsefulInfoController extends Controller
{
public function index()
{
$usefulInfos = UsefulInfo::orderBy('position')->get();
return UsefulInfoResource::collection($usefulInfos);
}
public function items($id)
{
$usefulInfo = UsefulInfo::find($id);
// chech if useful info not found
if (!$usefulInfo) {
return response()->json([
'message' => 'Useful info not found'
], 404);
}
return UsefulInfoItemResource::collection($usefulInfo->items);
}
public function itemShow($id, $itemId)
{
$usefulInfo = UsefulInfo::find($id);
return new UsefulInfoItemResource($usefulInfo->items->find($itemId));
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class UserController extends Controller
{
public function me()
{
$user = getAuthUser();
return response()->json([
'data' => [
'id' => $user->id,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'middle_name' => $user->middle_name,
'language' => $user->language,
'phone' => $user->phone,
'gender' => $user->gender == 1 ? true : false
]
]);
}
public function changeLang(Request $request)
{
$validator = Validator::make($request->all(), [
'language' => 'required|string|in:ru,uz',
]);
if ($validator->fails()) {
return response()->json([
'error' => 'Validation error',
'details' => $validator->errors()
], 422);
}
$user = getAuthUser();
$user->update($request->only('language'));
return response()->json([
'data' => [
'id' => $user->id,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'middle_name' => $user->middle_name,
'language' => $user->language,
'phone' => $user->phone,
'gender' => $user->gender
]
]);
}
public function update(Request $request)
{
// validate
$request->validate([
'first_name' => 'required|string',
'last_name' => 'required|string',
'middle_name' => 'nullable|string',
'gender' => 'required|boolean',
]);
getAuthUser()->update($request->only('first_name', 'last_name', 'middle_name', 'gender'));
return response()->json([
'data' => [
'id' => getAuthUser()->id,
'first_name' => getAuthUser()->first_name,
'last_name' => getAuthUser()->last_name,
'middle_name' => getAuthUser()->middle_name,
'language' => getAuthUser()->language,
'phone' => getAuthUser()->phone,
'gender' => getAuthUser()->gender
]
]);
}
public function delete()
{
$user = getAuthUser();
// delte name
$user->first_name = null;
$user->last_name = null;
$user->middle_name = null;
$user->avatar = null;
$user->email = null;
$user->verify_code = null;
$user->birth_day = null;
$user->postal_address = null;
$user->category_id = null;
$user->notification = 0;
$user->save();
// delete
$user->delete();
return response()->json([
'message' => 'User deleted'
], 204);
}
}

View File

@@ -0,0 +1,208 @@
<?php
namespace App\Http\Controllers\Apelsin;
use App\Api\Sms;
use App\Models\Billing;
use App\Models\CommentBank;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller as ExController;
class Controller extends ExController
{
public function paymentOrder(Billing $billing)
{
return view('apelsin', compact('billing'));
}
public function payment(Request $request)
{
Log::info($request->all());
if ($request->post('orderId')) {
$billing = Billing::find($request->post('orderId'));
if ($billing->status != 'payed') {
if (!empty($billing)) {
$amount = (int) $request->post('amount');
$amount = $amount / 100;
if ($amount == $billing->amount) {
$order = Order::find($billing->order->id);
$order->update([
'payment_status' => 'payed'
]);
$billing->update([
'status' => 'payed',
'payment_system' => 'apelsin',
'transaction_id' => $request->post('transactionId')
]);
$sms = new Sms();
$message = "Quyoshli vash zakaz: {$order->id} uspeshno oplachen!";
$sms->send($order->user->phone, $message);
return response()->json([
'status' => true
]);
}
}
}
}
return response()->json([
'status' => false
]);
}
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function confirm(Request $request)
{
$sign_key = md5($request->order_number . '7Yyh5weu7zhYEbNr');
if ($sign_key == $request->sign_key) {
// Activity::create([
// 'log_name' => 'orders',
// 'description'
// ]);
$order = Order::find($request->order_number);
if (!empty($order)) {
$order->update([
'payment_status' => 'review'
]);
}
return response()->json([
'status' => true,
'back_url' => env('APP_URL') . '?order=credit'
]);
} else {
return response()->json([
'status' => false,
'message' => 'Error Sign Key'
], 403);
}
}
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function status(Request $request)
{
$sign_key = md5($request->order_number . '7Yyh5weu7zhYEbNr');
if ($sign_key === $request->sign_key) {
$order = Order::find($request->order_number);
if (!empty($order)) {
if ($request->result) {
if ($order->status == 'cancelled') {
$order->update([
'payment_status' => 'payed',
'status' => 'processing',
'archived' => false,
]);
} else {
$order->update([
'payment_status' => 'payed',
]);
}
} else {
$order->update([
'apelsin_data' => [
'status' => false,
'body' => $request->all()
],
'status' => 'cancelled',
'payment_status' => 'cancelled'
]);
}
}
return response()->json([
'status' => true,
]);
} else {
return response()->json([
'status' => false,
'message' => 'Error Sign Key'
], 403);
}
}
/**
* @param $id
* @return array
*/
public function delivered($id)
{
try {
$response = Http::withBasicAuth('AVtO_L0aN_8f234_Ssmeiq', '&*sk92jf8.1521aydd3810bx742n54kiygh2')
->post('https://alistoreback.apelsin.uz/api/loan-application/external/verdict', [
'order_number' => $id,
'status' => true
]);
} catch (\Exception $exception) {
return [
'status' => false,
'body' => $exception
];
}
$body = json_decode($response->body(), true);
if ($body['errorMessage']) {
return [
'status' => false,
'body' => $body
];
}
return [
'status' => true,
'body' => $body
];
}
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function comment(Request $request)
{
$sign_key = md5($request->order_number . '7Yyh5weu7zhYEbNr');
if ($sign_key == $request->sign_key) {
$order = Order::find($request->order_number);
if (!empty($order) && $order->payment_type == 'credit') {
$comment = $request->comment;
CommentBank::create([
'order_id' => $order->id,
'comment' => $comment
]);
}
return response()->json([
'status' => true,
], 201);
}
return response()->json([
'status' => false,
'message' => 'Error Sign Key'
], 403);
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\CustomRouteServiceProvider;
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 = CustomRouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
}

View File

@@ -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;
}

View File

@@ -0,0 +1,40 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\CustomRouteServiceProvider;
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 = CustomRouteServiceProvider::DASHBOARD;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\CustomRouteServiceProvider;
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 = CustomRouteServiceProvider::DASHBOARD;
/**
* 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, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\CustomRouteServiceProvider;
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 = CustomRouteServiceProvider::HOME;
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\CustomRouteServiceProvider;
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 = CustomRouteServiceProvider::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');
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Http\Controllers;
//use App\Helpers\Sms;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
//use LaravelSmpp\SmppService;
//use LaravelSmpp\SmppServiceInterface;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
// public function send(SmppServiceInterface $smpp)
// {
// dd($smpp->sendOne(998946404476, 'test sherali kachok'));
// }
protected function info(string $text)
{
$this->sendAlert('info', $text);
}
protected function success(string $text)
{
$this->sendAlert('success', $text);
}
protected function error(string $text)
{
$this->sendAlert('error', $text);
}
private function sendAlert(string $type, string $text)
{
request()->session()->flash($type, $text);
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Http\Controllers\Dashboard;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Auth\LoginController as DefaultLoginController;
class AuthController extends DefaultLoginController
{
public function __construct()
{
$this->middleware('guest:staff')->except('logout');
}
public function showLoginForm()
{
return view('login');
}
protected function guard()
{
return Auth::guard('staff');
}
public function username()
{
return 'username';
}
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
if ($response = $this->loggedOut($request)) {
return $response;
}
return $request->wantsJson()
? new Response('', 204)
: redirect('/');
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Http\Controllers\Dashboard\Billing;
use App\Http\Controllers\Controller as ExController;
use App\Models\Billing;
use App\Models\Currency;
use Illuminate\Http\Request;
class Controller extends ExController
{
public function index()
{
$this->authorize('view', 'billings');
$billings = Billing::latest('id')
->paginate(config(50));
$currency = Currency::latest()->first();
return view('dashboard.billing.index', compact('billings', 'currency'));
}
/**
* @param Request $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function search(Request $request)
{
$id = $request->get('query');
$billings = Billing::where('id', $id)->orWhere('transaction_id', $id)->paginate(50);
return view('dashboard.billing.index', compact('billings'));
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace App\Http\Controllers\Dashboard\Branch;
use App\Http\Controllers\Controller as BaseController;
use App\Http\Requests\Dashboard\Branch\Request;
use App\Jobs\Dashboard\Branch\Store;
use App\Jobs\Dashboard\Branch\Update;
use App\Models\Branch;
class Controller extends BaseController
{
public function index()
{
$this->authorize('view', 'branches');
$branches = Branch::latest('id')->paginate(20);
return view('dashboard.branches.index', compact('branches'));
}
public function store(Request $request)
{
if ($request->isMethod('get'))
{
$this->authorize('create', 'branches');
return view('dashboard.branches.create');
}
$this->dispatchSync(new Store($request));
$this->success(trans('admin.messages.created'));
return redirect()->route('dashboard.branches');
}
public function show(Branch $branch)
{
$this->authorize('view', 'branches');
return view('dashboard.branches.preview', compact('branch'));
}
public function update(Request $request, Branch $branch)
{
if ($request->isMethod('get'))
{
$this->authorize('update', 'branches');
return view('dashboard.branches.edit', compact('branch'));
}
$this->dispatchSync(new Update($request, $branch));
$this->success(trans('admin.messages.created'));
return redirect()->route('dashboard.branches');
}
public function destroy(Branch $branch)
{
$this->authorize('delete', 'branches');
$branch->delete();
$this->success(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,152 @@
<?php
namespace App\Http\Controllers\Dashboard\Brand;
use App\Api\ImageResize;
use App\Models\Brand;
use App\Models\Product;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\Brand\Update as UpdateRequest;
use App\Http\Requests\Dashboard\Brand\Store as StoreRequest;
use App\Jobs\Dashboard\Brand\Store as StoreJob;
use App\Jobs\Dashboard\Brand\Update as UpdateJob;
use Illuminate\Support\Facades\Storage;
class Controller extends ExController
{
protected $brands;
/**
* Controller constructor.
* @param Brend $brand
*/
public function __construct(Brand $brand)
{
$this->brands = $brand;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('view', 'brands');
$brands = $this->brands->orderBy('position')->paginate(20);
return view('dashboard.brands.index', compact('brands'));
}
/**
* @param UpdateRequest $request
* @param Brand $brand
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(UpdateRequest $request, Brand $brand)
{
if ($request->isMethod('get')) {
$this->authorize('update', 'brands');
return view('dashboard.brands.update', compact('brand'));
}
if ($request->hasFile('image')) {
if (env('FILESYSTEM_DISK') == 's3') {
// delete old image from s3
Storage::disk('s3')->delete($brand->image);
$path = $this->storeImageToS3($request->file('image'));
} else {
// detele old image
if (is_file($brand->image)) {
unlink($brand->image);
}
$path = $request->file('image')->store('uploads/brands');
}
} else {
$path = $brand->image;
}
$this->dispatchSync(UpdateJob::fromRequest($brand, $request, $path));
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.brands');
}
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'brands');
return view('dashboard.brands.store');
}
if ($request->hasFile('image')) {
$file = $request->file('image');
if (env('FILESYSTEM_DISK') == 's3') {
$path = $this->storeImageToS3($file);
} else {
$path = $file->store('uploads/brands');
}
}
$this->dispatchSync(StoreJob::fromRequest($request, $path));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.brands');
}
/**
* @param Brand $brand
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(Brand $brand)
{
$this->authorize('delete', 'brands');
if (is_file($brand->image)) {
unlink($brand->image);
}
// delete image from s3
if (env('FILESYSTEM_DISK') == 's3') {
Storage::disk('s3')->delete($brand->image);
}
Product::where('brand_id', $brand->id)->withTrashed()->update([
'brand_id' => null
]);
$brand->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
private function storeImageToS3($image): string
{
$path = '';
// first store temp file and resize it, then upload to s3
// 1 - store temp file
$tempPath = $image->store('temp', 'public');
if ($tempPath) {
$tempFilePath = storage_path('app/public/' . $tempPath);
$image = new ImageResize();
$path = $image->resize($tempPath, 322, 'brands');
// 2 - upload to s3 or keep local
if (in_array(env('FILESYSTEM_DISK'), ['s3', 'minio'])) {
Storage::disk('s3')->put($path, file_get_contents($path));
unlink($path);
}
}
return $path;
}
}

View File

@@ -0,0 +1,301 @@
<?php
namespace App\Http\Controllers\Dashboard\Category;
use App\Models\Brand;
use App\Models\Category;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\Category\Request as StoreRequest;
use App\Http\Requests\Dashboard\Category\Update as UpdateRequest;
use App\Jobs\Dashboard\Category\Store as StoreJob;
use App\Jobs\Dashboard\Category\Update as UpdateJob;
use App\Models\Characteristic;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class Controller extends ExController
{
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('view', 'categories');
$categories = Category::select('id', 'name->ru as category', 'position', 'parent_id')
->where('parent_id', null)
->with(['children' => function ($parent) {
return $parent->select('id', 'name->ru as category', 'parent_id', 'position')->orderBy('position', 'asc')->with(['children' => function ($parent) {
return $parent->select('id', 'name->ru as category', 'parent_id', 'position')->orderBy('position', 'asc');
}]);
}])->orderBy('position', 'asc')->get();
return view('dashboard.category.index', compact('categories'));
}
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('view', 'categories');
$brands = Brand::all();
$brands->map(function ($brand) {
$brand->name = $brand->name['ru'];
});
$parent_categories = Category::with('parent')->get();
return view('dashboard.category.store', compact('brands', 'parent_categories'));
}
$category = $this->dispatchSync(new StoreJob($request));
if (!empty($request->char)) {
foreach ($request->char as $char) {
Characteristic::create([
'name' => $char['name'],
'type' => $char['type'],
'category_id' => $category->id,
'filter' => $char['filter'] == 'true' ? 1 : 0
]);
}
}
$this->success(trans('admin.messages.created'));
return response()->json([
'status' => true
]);
}
/**
* @param $category
* @param UpdateRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update($category, UpdateRequest $request)
{
$category = Category::findOrFail($category);
if ($request->isMethod('get')) {
$this->authorize('update', 'categories');
$parent_categories = Category::with('parent')->whereNotIn('id', [$category->id])->get();
$brands = Brand::all();
$brands->map(function ($brand) {
$brand->name = $brand->name['ru'];
});
$category->loadMissing(['brands', 'characteristics']);
$category->brands->map(function ($brand) {
$brand->name = $brand->name['ru'];
});
return view('dashboard.category.update', compact('parent_categories', 'category', 'brands'));
}
if ($request->hasFile('image')) {
$image = $request->file('image')->store('uploads/categories', 'local');
} else {
$image = $category->image;
}
$this->dispatchSync(new UpdateJob($category, $request, $image));
if (!empty($request->char)) {
foreach ($request->char as $char) {
if ($char['id'] == null || $char['id'] == 'null') {
Characteristic::create([
'name' => $char['name'],
'type' => $char['type'],
'category_id' => $category->id,
'filter' => $char['filter'] == 'true' ? 1 : 0
]);
} else {
Characteristic::where('id', $char['id'])->update([
'name' => $char['name'],
'type' => $char['type'],
'filter' => $char['filter'] == 'true' ? 1 : 0
]);
}
}
}
if (!empty($request->deletes['char'])) {
$chars = Characteristic::whereIn('id', $request->deletes['char'])->get();
foreach ($chars as $char) {
$char->values()->detach();
// foreach ($char->values as $value) {
// $value->delete();
// }
$char->delete();
}
}
$this->success(trans('admin.messages.updated'));
return response()->json([
'status' => true
]);
}
/**
* @param Category $category
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete($category)
{
$this->authorize('delete', 'categories');
$category = Category::findOrFail($category);
if (is_file($category->image)) {
unlink($category->image);
}
// delete image from s3
if (env('FILESYSTEM_DISK') == 's3') {
Storage::disk('s3')->delete($category->image);
}
$category->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function position_save(Request $request)
{
foreach ($request->categories as $category) {
$cat = Category::find($category['id']);
$cat->parent_id = $category['parent_id'] === 'null' ? null : $category['parent_id'];
$cat->position = $category['position'];
$cat->save();
if (!empty($category['children'])) {
foreach ($category['children'] as $c) {
$cc = Category::find($c['id']);
$cc->parent_id = $c['parent_id'] === 'null' ? null : $c['parent_id'];
$cc->position = $c['position'];
$cc->save();
if (!empty($c['children'])) {
foreach ($c['children'] as $ccc) {
$cccc = Category::find($ccc['id']);
$cccc->parent_id = $ccc['parent_id'] === 'null' ? null : $ccc['parent_id'];
$cccc->position = $ccc['position'];
$cccc->save();
}
}
}
}
}
$this->info(trans('admin.messages.updated'));
return response()->json([
'status' => true
]);
}
/**
* @return array
*/
public function test()
{
$categories = Category::select('id', 'name->ru as category')
->where('parent_id', null)
->with('parents.parents.parents')->get();
$cat = $this->category($categories->toArray());
$cats = array_merge(...$cat);
return $cats;
}
/**
* @param $categories
* @return array
*/
private function category($categories)
{
return array_map(function ($cat) {
$arr = [];
if (count($cat['parents']) > 0) {
$arr[] = [
'id' => $cat['id'],
'category' => $cat['name']['ru'],
'$isDisabled' => true
];
foreach ($cat['parents'] as $parent) {
if (count($parent['parents']) > 0) {
if (count($parent['parents']) > 0) {
$arr[] = [
'id' => $parent['id'],
'category' => $parent['name']['ru'],
'$isDisabled' => true
];
foreach ($parent['parents'] as $paren) {
$arr[] = [
'id' => $paren['id'],
'category' => $paren['name']['ru'],
'$isDisabled' => false
];
}
} else {
$arr[] = [
'id' => $parent['id'],
'category' => $parent['name']['ru'],
'$isDisabled' => false
];
}
} else {
$arr[] = [
'id' => $parent['id'],
'category' => $parent['name']['ru'],
'$isDisabled' => false
];
}
}
return $arr;
} else {
$arr = [
'id' => $cat['id'],
'category' => $cat['name']['ru'],
'$isDisabled' => false
];
return $arr;
}
}, $categories);
}
/**
* @return string
*/
public function json()
{
$categories = Category::select('id', 'name', 'parent_id as parrent', 'position', 'published')->latest('id')->get();
$data = "data ='{$categories}';";
return $data;
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace App\Http\Controllers\Dashboard\City;
use App\Models\City;
use App\Models\Region;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\City\Update as UpdateRequest;
use App\Http\Requests\Dashboard\City\Store as StoreRequest;
use App\Jobs\Dashboard\City\Store as StoreJob;
use App\Jobs\Dashboard\City\Update as UpdateJob;
class Controller extends ExController
{
protected $cities;
/**
* Controller constructor.
* @param City $city
*/
public function __construct(City $city)
{
$this->cities = $city;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$this->authorize('view', 'cities');
$cities = $this->cities->latest('id')->paginate(20);
return view('dashboard.cities.index', compact('cities'));
}
/**
* @param UpdateRequest $request
* @param City $city
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
public function update(UpdateRequest $request, City $city)
{
if ($request->isMethod('get')) {
$this->authorize('update', 'cities');
$regions = Region::all();
return view('dashboard.cities.update', compact('city', 'regions'));
}
$this->dispatchSync(UpdateJob::fromRequest($city, $request));
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.cities');
}
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'cities');
$regions = Region::all();
return view('dashboard.cities.store', compact('regions'));
}
$this->dispatchSync(StoreJob::fromRequest($request));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.cities');
}
/**
* @param City $city
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(City $city)
{
$this->authorize('delete', 'cities');
$city->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Http\Controllers\Dashboard\Color;
use App\Http\Controllers\Controller as BaseController;
use App\Http\Requests\Dashboard\Color\Request;
use App\Jobs\Dashboard\Color\Store;
use App\Jobs\Dashboard\Color\Update;
use App\Models\Color;
class Controller extends BaseController
{
public function index()
{
$this->authorize('view', 'colors');
$colors = Color::latest('id')->paginate(20);
return view('dashboard.colors.index', compact('colors'));
}
public function store(Request $request)
{
if ($request->isMethod('get'))
{
$this->authorize('create', 'categories');
return view('dashboard.colors.create');
}
$this->dispatchSync(new Store($request));
$this->success(trans('admin.messages.created'));
return redirect()->route('dashboard.colors');
}
public function update(Request $request, Color $color)
{
if ($request->isMethod('get'))
{
$this->authorize('update', 'categories');
return view('dashboard.colors.update', compact('color'));
}
$this->dispatchSync(new Update($request, $color));
$this->success(trans('admin.messages.created'));
return redirect()->route('dashboard.colors');
}
public function destroy(Color $color)
{
$this->authorize('delete', 'categories');
$color->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace App\Http\Controllers\Dashboard\Comment;
use App\Models\Comment;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\Comment\Update as UpdateRequest;
use App\Jobs\Dashboard\Comment\Update as UpdateJob;
class Controller extends ExController
{
protected $comments;
/**
* Controller constructor.
* @param Comment $comment
*/
public function __construct(Comment $comment)
{
$this->comments = $comment;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$this->authorize('view', 'comments');
$comments = $this->comments->with('product')
->latest('id')->paginate(20);
return view('dashboard.comments.index', compact('comments'));
}
/**
* @param Comment $comment
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
public function update(Comment $comment)
{
$this->authorize('update', 'comments');
return view('dashboard.comments.edit', compact('comment'));
}
/**
* @param Comment $comment
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(Comment $comment)
{
$this->authorize('delete', 'comments');
$comment->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
public function publish(Comment $comment)
{
$this->authorize('update', 'comments');
$comment->update([
'publish' => true
]);
$this->info(trans('admin.messages.published'));
return redirect()->route('dashboard.comments');
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace App\Http\Controllers\Dashboard\Company;
use App\Http\Controllers\Controller as ExController;
use Illuminate\Http\Request;
use App\Models\Company;
class CompanyController extends ExController
{
public function index(Request $request)
{
$company = Company::first();
return view('dashboard.company.index', compact('company'));
}
public function update(Request $request, $companyId)
{
$company = Company::findOrFail($companyId);
$this->validate($request, [
'company_name.uz' => 'required|string',
'company_name.ru' => 'required|string',
'inn' => 'required|string',
'bank_name.uz' => 'required|string',
'bank_name.ru' => 'required|string',
'mfo' => 'required|string',
'oked' => 'required|string',
'address' => 'required|array',
'address.uz' => 'required|string',
'address.ru' => 'required|string',
'director_full_name.uz' => 'required|string',
'director_full_name.ru' => 'required|string',
'payment_account' => 'required|string',
'phone' => 'required|string',
]);
$company->update([
'company_name' => [
"uz" => $request->company_name['uz'],
"ru" => $request->company_name['ru'],
],
'inn' => $request->inn,
'bank_name' => [
"uz" => $request->bank_name['uz'],
"ru" => $request->bank_name['ru'],
],
'mfo' => $request->mfo,
'oked' => $request->oked,
'address' => [
'uz' => $request->address['uz'],
'ru' => $request->address['ru']
],
'director_full_name' => [
"uz" => $request->director_full_name['uz'],
"ru" => $request->director_full_name['ru'],
],
'payment_account' => $request->payment_account,
'phone' => $request->phone,
]);
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.companies.index');
}
}

View File

@@ -0,0 +1,136 @@
<?php
namespace App\Http\Controllers\Dashboard\Compilation;
use App\Http\Controllers\Controller as ExController;
use App\Models\Category;
use App\Models\Compilation;
use App\Models\Product;
use Illuminate\Http\Request;
use App\Http\Requests\Dashboard\Compilation\Store as StoreRequest;
use App\Http\Requests\Dashboard\Compilation\Update as UpdateRequest;
use App\Jobs\Dashboard\Compilation\Store as StoreJob;
use App\Jobs\Dashboard\Compilation\Update as UpdateJob;
class Controller extends ExController
{
protected $products;
protected $compilation;
protected $categories;
/**
* Controller constructor.
* @param Product $product
* @param Compilation $compilation
* @param Category $category
*/
public function __construct(Product $product, Compilation $compilation, Category $category)
{
$this->products = $product;
$this->compilation = $compilation;
$this->categories = $category;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('view', 'compilations');
$compilations = Compilation::orderBy('position', 'asc')->get();
return view('dashboard.compilations.index', compact('compilations'));
}
// public function store(StoreRequest $request)
// {
// if ($request->isMethod('get')) {
// $this->authorize('create', 'compilations');
//
//// $this->authorize('content-manager');
// $categories = $this->categories->where('parent_id', null)->get();
// return view('dashboard.compilations.store', compact('categories'));
// }
//
// $this->dispatchSync(new StoreJob($request));
//
// $this->success(trans('admin.messages.created'));
// return response()->json([
// 'status' => true
// ]);
// }
/**
* @param Compilation $compilation
* @param UpdateRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Compilation $compilation, UpdateRequest $request)
{
if ($request->isMethod('get')) {
// $this->authorize('content-manager');
$compilation->loadMissing(['products:id,name,poster']);
$this->authorize('update', 'compilations');
foreach ($compilation->products as $product) {
$product->poster = '/'. $product->poster;
$product->name = $product->name['ru'];
}
$categories = $this->categories->where('parent_id', false)->get();
return view('dashboard.compilations.update', compact('compilation', 'categories'));
}
$this->dispatchSync(new UpdateJob($request, $compilation));
$this->info(trans('admin.messages.updated'));
return response()->json([
'status' => true
]);
}
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function search(Request $request)
{
$query = $request->name;
$product = $this->products->published()->where('name->ru', 'like', $query . '%')->get()->map(function ($product) {
return [
'id' => $product->id,
'poster' => '/' . $product->poster,
'name' => $product->name['ru']
];
});
return response()->json([
'status' => true,
'products' => $product
]);
}
/**
* @param Compilation $compilation
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(Compilation $compilation)
{
$this->authorize('delete', 'compilations');
$compilation->delete();
$this->info(trans('admin.messages.updated'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace App\Http\Controllers\Dashboard\ContractTemplate;
use App\Http\Controllers\Controller as ExController;
use Illuminate\Http\Request;
use App\Models\ContractTemplate;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class ContractTemplateController extends ExController
{
public function index(Request $request)
{
$templates = ContractTemplate::latest('id')->paginate(30);
return view('dashboard.contract-templates.index', compact('templates'));
}
public function create()
{
return view('dashboard.contract-templates.create');
}
public function store(Request $request)
{
$this->validate($request, [
'lang' => 'required|in:uz,ru',
'type' => 'required|in:legal,physical',
'file' => 'required|file|mimes:doc,docx',
'company' => 'required|in:getgreen,sunhightech',
]);
$folder = "contract-templates";
$fileName = $request->file('file')->store($folder);
ContractTemplate::create([
'lang' => $request->lang,
'type' => $request->type,
'company' => $request->company,
'path' => $fileName,
]);
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.contract-templates.index');
}
public function edit($templateId)
{
$template = ContractTemplate::findOrFail($templateId);
return view('dashboard.contract-templates.edit', compact('template'));
}
public function update(Request $request, $templateId)
{
$template = ContractTemplate::findOrFail($templateId);
$this->validate($request, [
'file' => 'nullable|file|mimes:doc,docx',
'lang' => 'required|in:uz,ru',
'company' => 'required|in:getgreen,sunhightech',
'type' => 'required|in:legal,physical',
]);
$template->update([
'lang' => $request->lang,
'company' => $request->company,
'type' => $request->type,
]);
if ($request->hasFile('file')) {
// delete old file
if ($template->path) {
Storage::disk('public')->delete($template->path);
}
// store file to storage
$file = $request->file('file');
// with generated name
// generate name with 20 string
$fileName = Str::random(20) . '.' . $file->extension();
$file->storeAs('contract-templates', $fileName, 's3');
$template->update([
'path' => 'contract-templates/' . $fileName,
]);
}
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.contract-templates.index');
}
public function destroy($templateId)
{
$template = ContractTemplate::findOrFail($templateId);
if ($template->path) {
Storage::disk('public')->delete($template->path);
}
$template->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,235 @@
<?php
namespace App\Http\Controllers\Dashboard;
use App\Http\Controllers\Controller as ExController;
use App\Services\Dashboard\Stat\StatService;
use App\Models\User;
use App\Models\Order;
use App\Models\Billing;
use App\Models\Product;
use App\Helpers\DashboardStatic;
use Akaunting\Apexcharts\Chart;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\App;
class Controller extends ExController
{
public function index(Request $request)
{
$daysToShow = 30;
$from = $request->get('from');
$to = $request->get('to');
if (!$to) {
$to = now()->format('Y-m-d');
}
if (!$from) {
$from = now()->subDays($daysToShow)->format('Y-m-d');
}
$service = new StatService();
// Create a new chart instance
$chart = new Chart();
// Set the chart type to 'line'
$chart->setType('line');
// Define the X-axis labels (months, dates, etc.)
$chart->setLabels($service->getLabels($from, $to));
// Add a dataset to the chart (e.g., sales data)
$chart->setDataset('Orders', 'line', $service->getStatics('orders'));
$chart->setDataset('Users', 'line', $service->getStatics('users'));
$chart->setDataset('Sales', 'line', $service->getStatics('sales'));
$users = User::count();
$orders = Order::where('payment_type', '!=', 'credit')->count();
$products = Product::where('child_id', null)->count();
$billing = Billing::where('status', 'payed')->count();
$statics = [
'labels' => $this->getLabels(),
'orders_count' => $this->getStatics(),
'new_users' => $this->getUserStatics(),
'transactions' => $this->getCountTransactions(),
'sum' => $this->getAllSumStatic(),
];
return view('dashboard.index', compact(
'users',
'orders',
'products',
'billing',
'statics',
'chart'
));
}
private function getLabels()
{
$start = now()->subDays(30);
$days = [];
for ($i = 0; $i <= 30; $i++) {
$days[] = $start->copy()->addDays($i)->format('d.m');
}
return $days;
}
private function getUserStatics()
{
$users = DashboardStatic::getUserStatics();
return [
'data' => [
[
'name' => 'Пользователи',
'values' => $users
]
]
];
}
public function changeLang($lang)
{
// validate
if (!in_array($lang, ['en', 'ru', 'uz'])) {
return response()->json([
'message' => 'Language not supported'
], Response::HTTP_BAD_REQUEST);
}
session()->put('locale', $lang);
App::setLocale($lang);
return redirect()->back();
}
private function getStatics()
{
$processing = DashboardStatic::getCountProcessing();
$collect = DashboardStatic::getCountCollected();
$waiting = DashboardStatic::getCountInWay();
$closed = DashboardStatic::getCountClosed();
$cancelled = DashboardStatic::getCountCancelled();
$replacement = DashboardStatic::getCountReplacement();
$archived = DashboardStatic::getCountArchived();
return [
'data' => [
[
'name' => 'В обработке',
'values' => $processing
],
[
'name' => 'Собран',
'values' => $collect
],
[
'name' => 'Ожидает',
'values' => $waiting
],
[
'name' => 'Закрыт',
'values' => $closed
],
[
'name' => 'Отменен',
'values' => $cancelled
],
[
'name' => 'Замена',
'values' => $replacement
],
[
'name' => 'Архиве',
'values' => $archived
],
]
];
}
private function getCountTransactions()
{
$payed = DashboardStatic::getSuccessTransactions();
$waiting = DashboardStatic::getWaitingTransactions();
$refused = DashboardStatic::getRefusedTransactions();
return [
'data' => [
[
'name' => 'Оплачено',
'values' => $payed
],
[
'name' => 'В ожидания',
'values' => $waiting
],
[
'name' => 'Отказано',
'values' => $refused
],
]
];
}
private function getCountCredit()
{
$payed = DashboardStatic::getCreditPayed();
$cancelled = DashboardStatic::getCancelledCredit();
$review = DashboardStatic::getReviewCredit();
$waiting = DashboardStatic::getWaitingCredit();
return [
'data' => [
[
'name' => 'Оплачено',
'values' => $payed
],
[
'name' => 'Отказано',
'values' => $cancelled
],
[
'name' => 'Рассмотрение',
'values' => $review
],
[
'name' => 'В ожидание',
'values' => $waiting
]
]
];
}
private function getAllSumStatic()
{
return [
'data' => [
[
'name' => 'Оплачено',
'values' => []
],
[
'name' => 'Не оплачено',
'values' => []
],
[
'name' => 'Отказано',
'values' => []
],
]
];
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers\Dashboard\Currency;
use App\Http\Controllers\Controller as ExController;
use App\Models\Currency;
use Illuminate\Http\Request;
use App\Http\Requests\Dashboard\Currency\Store as StoreRequest;
use App\Jobs\Dashboard\Currency\Store as StoreJob;
class Controller extends ExController
{
protected $currency;
/**
* Controller constructor.
* @param Currency $currency
*/
public function __construct(Currency $currency)
{
$this->currency = $currency;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$this->authorize('view', 'currencies');
$currencies = $this->currency->latest('id')->limit(20)->get();
return view('dashboard.currency.index', compact('currencies'));
}
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'compilations');
return view('dashboard.currency.store');
}
$this->dispatchSync(StoreJob::fromRequest($request));
$this->success(trans('admin.messages.updated'));
return redirect()->route('dashboard.currency');
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace App\Http\Controllers\Dashboard\Feedback;
use App\Http\Controllers\Controller as ExController;
use App\Models\Feedback;
use Illuminate\Http\Request;
class Controller extends ExController
{
public function index()
{
$this->authorize('view', 'feedback');
$feedbacks = Feedback::latest('id')
->paginate(15);
return view('dashboard.feedback.index', compact('feedbacks'));
}
public function show(Feedback $feedback)
{
$this->authorize('update', 'feedback');
$feedback->update([
'viewed' => true
]);
return view('dashboard.feedback.show', compact('feedback'));
}
public function destroy(Feedback $feedback)
{
$this->authorize('delete', 'feedback');
$feedback->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace App\Http\Controllers\Dashboard\File;
use App\Models\File;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\File\Store as StoreRequest;
use App\Jobs\Dashboard\File\Store as StoreJob;
class Controller extends ExController
{
protected $files;
/**
* Controller constructor.
* @param File $file
*/
public function __construct(File $file)
{
$this->files = $file;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$this->authorize('view', 'files');
$files = $this->files->latest('id')->paginate(20);
return view('dashboard.files.index', compact('files'));
}
/**
* @param StoreRequest $request
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(StoreRequest $request)
{
$this->authorize('create', 'files');
$path = $request->file('file')->store('uploads/files');
$size = filesize($path);
$this->dispatchSync(StoreJob::fromRequest($request, $path, $size));
$this->success(trans('admin.messages.updated'));
return redirect()->back();
}
/**
* @param File $file
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(File $file)
{
$this->authorize('delete', 'files');
if (is_file($file->path)) {
unlink($file->path);
}
$file->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace App\Http\Controllers\Dashboard\Log;
use App\Http\Controllers\Controller as ExController;
use App\Models\Product;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Spatie\Activitylog\Models\Activity;
class Controller extends ExController
{
public function index(Request $request)
{
$this->authorize('view', 'logs');
$date_from = $request->date_from;
$description = $request->description;
$user_id = $request->user_id;
$log_name = $request->log_name;
$id = $request->subject_id;
$logs = Activity::where('causer_type', 'App\Models\Staff')
->with(['causer'])
->whereNotIn('log_name', ['sliders', 'billings'])
// ->whereHasMorph('subject', '*', function ($query, $type) {
// Log::info($type);
// if ($type === Product::class) {
// return $query->where('price', '>', 0);
// }
// })
->latest('id');
if (!is_null($date_from)) {
$date_from = Carbon::parse($date_from)->format('Y-m-d 00:00:01');
$date_to = Carbon::now()->format('Y-m-d 23:59:59');
$logs = $logs->whereBetween('created_at', [$date_from, $date_to]);
}
if (!is_null($description))
$logs = $logs->where('description', $description);
if (!is_null($user_id))
$logs = $logs->where('causer_id', $user_id);
if (!is_null($log_name))
$logs = $logs->where('log_name', $log_name);
if (!is_null($id))
$logs = $logs->where('subject_id', $id);
$logs = $logs->paginate(50);
return view('dashboard.logs.index', compact('logs'));
}
}

View File

@@ -0,0 +1,83 @@
<?php
namespace App\Http\Controllers\Dashboard\Measurement;
use App\Http\Controllers\Controller as ExController;
use Illuminate\Http\Request;
use App\Models\Measurement;
class MeasurementController extends ExController
{
public function index(Request $request)
{
// $this->authorize('view', 'measurements');
$measurements = Measurement::latest('id')->paginate(30);
return view('dashboard.measurements.index', compact('measurements'));
}
public function create()
{
// $this->authorize('create', 'measurements');
return view('dashboard.measurements.create');
}
public function store(Request $request)
{
// $this->authorize('create', 'measurements');
$this->validate($request, [
'name_uz' => 'required|string|max:255',
'name_ru' => 'required|string|max:255',
]);
Measurement::create([
'name' => [
'uz' => $request->name_uz,
'ru' => $request->name_ru,
],
]);
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.measurements.index');
}
public function edit(Measurement $measurement)
{
// $this->authorize('update', 'measurements');
return view('dashboard.measurements.edit', compact('measurement'));
}
public function update(Request $request, Measurement $measurement)
{
// $this->authorize('update', 'measurements');
$this->validate($request, [
'name_uz' => 'required|string|max:255',
'name_ru' => 'required|string|max:255',
]);
$measurement->update([
'name' => [
'uz' => $request->name_uz,
'ru' => $request->name_ru,
],
]);
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.measurements.index');
}
public function destroy(Measurement $measurement)
{
// $this->authorize('delete', 'measurements');
$measurement->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace App\Http\Controllers\Dashboard\Notification;
use App\Models\Notification;
use App\Models\NotificationAvailable;
use Illuminate\Http\Request;
use App\Api\Firebase;
//use App\Models\Firebase as Model;
use App\Http\Controllers\Controller as ExController;
use App\Services\Dashboard\Notification\NotificationService;
class Controller extends ExController
{
protected $firebase;
public function __construct()
{
// $this->firebase = new Firebase();
}
public function index()
{
$notifications = Notification::latest('id')->paginate(20);
return view('dashboard.notifications.index', compact('notifications'));
}
/**
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(Request $request)
{
$lang = $request->lang;
$request->validate([
'title' => 'required',
'body' => 'required',
'lang' => 'required|in:uz,ru',
]);
Notification::create([
'title' => $request->title,
'body' => $request->body,
'language' => $request->lang
]);
// Example usage
$topic = $request->lang; // Topic name (you need all devices to subscribe to this topic)
$title = $request->title;
$body = $request->body;
// Send notification to multiple devices
$service = new NotificationService();
$response = $service->sendNotificationToTopic($topic, $title, $body);
// Output response
dd($response);
return redirect()->back()->with(trans('admin.messages.created'));
}
public function notification_available()
{
$notifications = NotificationAvailable::groupBy('product_id')->select('product_id')->with('product')->selectRaw('count(id) as count')->get();
return view('dashboard.notifications.alertNotification', compact('notifications'));
}
public function notification_available_view($id)
{
$notifications = NotificationAvailable::where('product_id', $id)->get();
return view('dashboard.notifications.alertView', compact('notifications'));
}
}

View File

@@ -0,0 +1,456 @@
<?php
namespace App\Http\Controllers\Dashboard\Orders;
use App\Api\Sms;
use App\Exports\OrdersExport;
use App\Models\Branch;
use App\Models\Currency;
use App\Models\OrdersComment;
use App\Models\Product;
use App\Models\Setting;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Models\Order;
use App\Models\OrderProducts;
use App\Http\Controllers\Controller as ExController;
use App\Jobs\Dashboard\Order\Update as UpdateJob;
use App\Jobs\Dashboard\Order\Products as ProductsUpdateJob;
use App\Http\Requests\Dashboard\Order\Update as UpdateRequest;
use PDF;
use Maatwebsite\Excel\Facades\Excel;
use App\Http\Controllers\Apelsin\Controller as ApelsinController;
use App\Services\Dashboard\Order\OrderFilterService;
use Spatie\Activitylog\Models\Activity;
class Controller extends ExController
{
protected $orders;
protected $order_products;
protected $products;
protected $currency;
protected $sms;
protected $apelsin;
/**
* Controller constructor.
* @param Order $order
* @param OrderProducts $order_products
* @param Product $product
* @param Currency $currency
*/
public function __construct(Order $order, OrderProducts $order_products, Product $product, Currency $currency)
{
$this->orders = $order;
$this->products = $product;
$this->order_products = $order_products;
$this->sms = new Sms();
$this->currency = $currency->latest('id', 'desc')->limit(1)->first();
$this->apelsin = new ApelsinController();
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('view', 'orders');
$orders = $this->orders->latest('id')->where('archived', false);
$statuses = [];
$permissions = auth()->user()->role->permissions;
if (!empty($permissions['order_status']['processing']) || !empty($permissions['order_status']['collected']) || !empty($permissions['order_status']['cancelled'])) {
$statuses[] = 'processing';
}
if (!empty($permissions['order_status']['collected']) || !empty($permissions['order_status']['waiting_buyer']) || !empty($permissions['order_status']['in_way']) || !empty($permissions['order_status']['cancelled'])) {
$statuses[] = 'collected';
}
if (!empty($permissions['order_status']['waiting_buyer']) || !empty($permissions['order_status']['closed']) || !empty($permissions['order_status']['cancelled'])) {
$statuses[] = 'waiting_buyer';
}
if (!empty($permissions['order_status']['in_way']) || !empty($permissions['order_status']['closed']) || !empty($permissions['order_status']['cancelled'])) {
$statuses[] = 'in_way';
}
if (!empty($permissions['order_status']['closed']) || !empty($permissions['order_status']['cancelled']) || !empty($permissions['order_status']['replacement'])) {
$statuses[] = 'closed';
}
if (!empty($permissions['order_status']['cancelled'])) {
$statuses[] = 'cancelled';
}
if (!empty($permissions['order_status']['replacement'])) {
$statuses[] = 'replacement';
}
if (!empty($permissions['order_status']['completed'])) {
$statuses[] = 'completed';
}
// $orders = $orders->whereIn('status', $statuses)->paginate(20);
$orders = $orders->paginate(20);
return view('dashboard.orders.index', compact('orders'));
}
/**
* @param Order $order
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function view(Order $order)
{
$this->authorize('view', 'orders');
$products = $this->order_products->where('order_id', $order->id)->get();
//total = $this->order_products->getTotalPrice($order->id);
// $comments = OrdersComment::
$logs = Activity::orderBy('id', 'asc')->where('subject_type', 'App\Models\Order')->where('subject_id', $order->id)->get();
$setting = Setting::find(1);
return view('dashboard.orders.view', compact('order', 'products', 'setting', 'logs'));
}
/**
* @param Order $order
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function invoice_print(Order $order)
{
return view('invoice', compact('order'));
// $path = public_path().'/pdf';
// $pdf = PDF::loadView('invoice');
// return $pdf->download('medium.pdf');
}
/**
* @param Request $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function search(Request $request)
{
$orders = $this->orders->latest('id')->where('id', $request->get('id'))->paginate(20);
return view('dashboard.orders.index', compact('orders'));
}
/**
*
*/
public function archive($order_id)
{
$order = Order::findOrFail($order_id);
$order->archived = !$order->archived;
$order->save();
$this->info(trans('admin.messages.updated'));
return redirect()->back();
}
/**
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function mass_archived(Request $request)
{
switch ($request->input('action')) {
case "unarchive":
Order::whereIn('id', $request->order_id)->update([
'archived' => false
]);
break;
case "archived":
Order::whereIn('id', $request->order_id)->update([
'archived' => true
]);
break;
}
$this->info('Успешно перенесен в архив');
return redirect()->back();
}
/**
* @param Order $order
* @param UpdateRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Order $order, UpdateRequest $request)
{
$branches = Branch::all();
if ($request->isMethod('get')) {
$this->authorize('update', 'orders');
$order->loadMissing([
'address.city.region',
'products' => function ($product) {
return $product->select('order_id', 'product_id', 'count', 'color_id', 'size', 'discount')->with([
'product' => function ($product) {
return $product->select('id', 'name', 'price', 'price_discount', 'poster_thumb', 'color_id', 'currency');
},
'color' => function ($color) {
return $color->select('id', 'sizes', 'color_id')->with([
'color'
]);
}
]);
},
'branch:id,name'
]);
foreach ($order->products as $product) {
$product->product->price = $product->product->getPrice();
$product->price_discount = $product->product->price_discount == null ? null : $product->product->getDiscountPrice();
}
return view('dashboard.orders.update', compact('order', 'branches'));
}
//$address = Address::find($order->address_id);
$this->dispatchSync(UpdateJob::fromRequest($order, $request));
//$this->dispatchSync(AddressUpdateJob::fromRequest($address, $request));
$this->dispatchSync(new ProductsUpdateJob($order, $request));
$this->info(trans('admin.messages.updated'));
return response()->json([
'status' => true
]);
}
/**
* @param Product $product
* @return \Illuminate\Http\JsonResponse
*/
public function product(Product $product)
{
$product->loadMissing([
'childrens' => function ($child) {
return $child->select('id', 'child_id', 'color_id', 'sizes')->with([
'color'
]);
}
]);
$product->makeHidden([
'body',
'name',
'brand_id',
'child_id',
'slug',
'published',
'updated_at',
'created_at',
'deleted_at',
'poster',
'poster_thumb',
'price',
'price_discount'
]);
return response()->json([
'status' => true,
'product' => $product
]);
}
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function search_update(Request $request)
{
$query = $request->name;
$product = $this->products->where('name->ru', 'like', '%' . $query . '%')->isAvailable()->get()->map(function ($product) {
return [
'id' => $product->id,
'poster' => '/' . $product->poster,
'name' => $product->name['ru']
];
});
return response()->json([
'status' => true,
'products' => $product
]);
}
/**
* @param Product $product
* @return \Illuminate\Http\JsonResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function product_info(Product $product)
{
$this->authorize('view', 'orders');
// if ($product->currency == 'dollar') {
// $product->price = round($product->price * $this->currency->dollar, -3);
// $product->price_discount = $product->price_discount == null ? null : round($product->price_discount * $this->currency->dollar, -3);
// } else {
// $product->price = round($product->price * $this->currency->euro, -3);
// $product->price_discount = $product->price_discount == null ? null : round($product->price_discount * $this->currency->euro, -3);
// }
$product->price = $product->getPrice();
$product->price_discount = $product->price_discount == null ? null : $product->getDiscountPrice();
$product->loadMissing('childrens');
return response()->json([
'status' => true,
'product' => $product
]);
}
/**
* @param Order $order
* @param $status
* @return \Illuminate\Http\RedirectResponse
*/
public function change_status(Order $order, $status)
{
$order->status = $status;
$order->save();
$message = 'Order ' . $order->id . ' status changed to' . $status;
$this->sms->send($order->user->phone, $message);
$order->save();
$this->info(trans('admin.messages.updated'));
return redirect()->back();
}
public function changePaymentStatus(Order $order, $status)
{
$order->payment_status = $status;
$order->save();
$message = 'Order ' . $order->id . ' payment status changed to' . $status;
$this->sms->send($order->user->phone, $message);
$order->save();
$this->info(trans('admin.messages.updated'));
return redirect()->back();
}
public function filter(Request $request)
{
$filterService = new OrderFilterService($request);
$orders = $filterService->filter();
return view('dashboard.orders.index', compact('orders'));
}
public function comments(Request $request)
{
$order = Order::find($request->order_id);
switch ($request->type) {
case 'cancelled':
if (!empty(auth()->user()->role->permissions['order_status']['cancelled'])) {
$order->status = 'cancelled';
foreach ($order->products as $row) {
$product = Product::find($row->product_id);
if (!empty($product)) {
$product->count = $product->count + $row->count;
$product->save();
}
}
$message = "Quyoshli vash zakaz: {$order->id} otmenen!";
} else {
return abort(403, 'Мы от тебя не ждали :(');
}
break;
case 'replacement':
if (!empty(auth()->user()->role->permissions['order_status']['replacement'])) {
$order->status = 'replacement';
} else {
return abort(403, 'Мы от тебя не ждали :(');
}
break;
case 'closed':
if (!empty(auth()->user()->role->permissions['order_status']['closed']) || !empty(auth()->user()->role->permissions['order_status']['cancelled']) || !empty(auth()->user()->role->permissions['order_status']['replacement'])) {
$order->status = 'closed';
if ($order->payment_type == 'credit') {
$apelsin = $this->apelsin->delivered($order->id);
$order->update([
'apelsin_data' => $apelsin
]);
}
$message = "Quyoshli vash zakaz: {$order->id} zavershen!";
} else {
return abort(403, 'Мы от тебя не ждали :(');
}
break;
case 'completed':
if (!empty(auth()->user()->role->permissions['order_status']['completed'])) {
$order->status = 'completed';
if ($order->payment_type == 'credit') {
$apelsin = $this->apelsin->delivered($order->id);
$order->update([
'apelsin_data' => $apelsin
]);
}
$message = "Quyoshli vash zakaz: {$order->id} zavershen!";
} else {
abort(403, 'Мы от тебя не ждали :(');
}
break;
}
if (!empty($message)) {
$this->sms->send($order->user->phone, $message);
}
if ($request->type != 'default')
$order->save();
OrdersComment::create([
'user_id' => auth()->user()->id,
'comment' => $request->comment,
'order_id' => $request->order_id,
'type' => $request->type
]);
if ($order->payment_type == 'credit' && ($request->type == 'closed' || $request->type == 'completed')) {
if ($apelsin['status']) {
$this->info(trans('admin.messages.updated'));
} else {
$this->error('Произошла ошибка в Apelsin Credit');
}
} else {
$this->info(trans('admin.messages.updated'));
}
return redirect()->back();
}
public function export()
{
$orders = Order::all();
return Excel::download(new OrdersExport, 'reports.xlsx');
}
}

View File

@@ -0,0 +1,109 @@
<?php
namespace App\Http\Controllers\Dashboard\Page;
use App\Models\Page;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\Page\Update as UpdateRequest;
use App\Http\Requests\Dashboard\Page\Store as StoreRequest;
use App\Jobs\Dashboard\Page\Store as StoreJob;
use App\Jobs\Dashboard\Page\Update as UpdateJob;
use Illuminate\Support\Carbon;
class Controller extends ExController
{
protected $pages;
/**
* Controller constructor.
* @param Brend $page
*/
public function __construct(Page $page)
{
$this->pages = $page;
}
/**
* @param UpdateRequest $request
* @param Page $page
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(UpdateRequest $request, Page $page)
{
if ($request->isMethod('get')) {
$this->authorize('update', 'pages');
return view('dashboard.pages.edit', compact('page'));
}
$this->dispatchSync(UpdateJob::fromRequest($page, $request));
$this->info(trans('admin.messages.updated'));
return redirect()->back();
}
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'pages');
return view('dashboard.pages.create');
}
$this->dispatchSync(StoreJob::fromRequest($request));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard');
}
/**
* @param Page $page
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(Page $page)
{
$page->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function image_upload(Request $request)
{
if ($request->hasFile('file')) {
$folder = Carbon::now()->format('Y/m/d');
$path = $request->file('file')->store("uploads/posts/{$folder}");
return response()->json([
'image' => $path
]);
}
return response()->json([
'status' => false
], 403);
}
/**
* @param Page $page
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function destroy(Page $page)
{
$page->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->route('dashboard');
}
}

View File

@@ -0,0 +1,94 @@
<?php
namespace App\Http\Controllers\Dashboard\Partner;
use App\Http\Controllers\Controller as ExController;
use App\Models\Partner;
use App\Http\Requests\Dashboard\Partner\Update as UpdateRequest;
use App\Http\Requests\Dashboard\Partner\Store as StoreRequest;
use App\Jobs\Dashboard\Partner\Store as StoreJob;
use App\Jobs\Dashboard\Partner\Update as UpdateJob;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
class Controller extends ExController
{
public function index()
{
$this->authorize('view', 'partners');
$partners = Partner::orderBy('position')->paginate(20);
return view('dashboard.partners.index', compact('partners'));
}
public function create()
{
$this->authorize('create', 'partners');
return view('dashboard.partners.create');
}
public function store(StoreRequest $request)
{
if ($request->hasFile('image')) {
$path = $request->file('image')->store('uploads/partners');
}
$this->dispatchSync(StoreJob::fromRequest($request, $path));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.partners.index');
}
public function edit(Partner $partner)
{
$this->authorize('update', 'partners');
return view('dashboard.partners.edit', compact('partner'));
}
public function update(UpdateRequest $request, Partner $partner)
{
if ($request->hasFile('image')) {
if (env('FILESYSTEM_DISK') == 's3') {
// delete old image from s3
Storage::disk('s3')->delete($partner->image);
} else {
// detele old image
$imagePath = public_path($partner->image);
if (File::exists($imagePath)) {
File::delete($imagePath);
}
}
$path = $request->file('image')->store('uploads/partners');
} else {
$path = $partner->image;
}
$this->dispatchSync(UpdateJob::fromRequest($partner, $request, $path));
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.partners.index');
}
public function destroy(Partner $partner)
{
$this->authorize('delete', 'partners');
if (env('FILESYSTEM_DISK') == 's3') {
// delete old image from s3
Storage::disk('s3')->delete($partner->image);
} else {
$imagePath = public_path($partner->image);
if (File::exists($imagePath)) {
File::delete($imagePath);
}
}
$partner->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Http\Controllers\Dashboard\PartnerRequest;
use App\Http\Controllers\Controller as ExController;
use App\Models\PartnerRequest;
use Illuminate\Http\Request;
class Controller extends ExController
{
public function index()
{
$requests = PartnerRequest::latest('id')->paginate(20);
return view('dashboard.partners.requests.index', compact('requests'));
}
public function show($id)
{
$partnerRequest = PartnerRequest::findOrFail($id);
return view('dashboard.partners.requests.show', compact('partnerRequest'));
}
public function update(Request $request, $id)
{
// validate request
$request->validate([
'status' => 'required|in:approved,rejected,closed,pending'
]);
$partnerRequest = PartnerRequest::findOrFail($id);
$partnerRequest->update([
'status' => $request->status,
]);
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.partner_requests.index');
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace App\Http\Controllers\Dashboard\PaymentSystem;
use App\Http\Controllers\Controller as ExController;
use Illuminate\Http\Request;
use App\Models\PaymentSystemModel as PaymentSystem;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class PaymentSystemController extends ExController
{
public function index(Request $request)
{
$paymentSystems = PaymentSystem::latest('id')->paginate(30);
return view('dashboard.payment-systems.index', compact('paymentSystems'));
}
public function create()
{
return view('dashboard.payment-systems.create');
}
public function store(Request $request)
{
$this->validate($request, [
'title_uz' => 'required|string',
'title_ru' => 'required|string',
]);
// generate slug from title_uz
$slug = Str::slug($request->slug);
PaymentSystem::create([
'title' => [
'uz' => $request->title_uz,
'ru' => $request->title_ru,
],
'slug' => $slug,
]);
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.payment-systems.index');
}
public function edit($systemId)
{
$paymentSystem = PaymentSystem::findOrFail($systemId);
return view('dashboard.payment-systems.edit', compact('paymentSystem'));
}
public function update(Request $request, $systemId)
{
$paymentSystem = PaymentSystem::findOrFail($systemId);
$this->validate($request, [
'title_uz' => 'required|string',
'title_ru' => 'required|string',
]);
// generate slug from title_uz
$slug = Str::slug($request->slug);
$paymentSystem->update([
'title' => [
'uz' => $request->title_uz,
'ru' => $request->title_ru,
],
'slug' => $slug,
]);
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.payment-systems.index');
}
public function destroy($systemId)
{
$paymentSystem = PaymentSystem::findOrFail($systemId);
// delete related items and their logos
foreach ($paymentSystem->items as $item) {
Storage::delete($item->logo);
$item->delete();
}
$paymentSystem->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,146 @@
<?php
namespace App\Http\Controllers\Dashboard\PaymentSystem;
use App\Http\Controllers\Controller as ExController;
use App\Models\PaymentSystemItem;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class PaymentSystemItemController extends ExController
{
public function index($paymentSystemId)
{
$items = PaymentSystemItem::latest('id')->where('payment_system_id', $paymentSystemId)->get();
return view('dashboard.payment-systems.items.index', compact('items', 'paymentSystemId'));
}
public function create($paymentSystemId)
{
return view('dashboard.payment-systems.items.create', compact('paymentSystemId'));
}
public function store(Request $request, $paymentSystemId)
{
$this->validate($request, [
'title_uz' => 'required|string',
'title_ru' => 'required|string',
'description_uz' => 'nullable|string',
'description_ru' => 'nullable|string',
'logo' => 'required|image',
]);
// store logo to storage
$logo = $request->file('logo');
if (env('FILESYSTEM_DISK') == 's3') {
$folder = "uploads/payment-system-items";
$logoPath = $logo->store($folder);
} else {
$logoName = Str::random(20) . '.' . $logo->extension();
$logo->storeAs('uploads/payment-system-items', $logoName);
$logoPath = 'uploads/payment-system-items/' . $logoName;
}
// generate slug from title_uz
$slug = Str::slug($request->title_uz);
if ($request->has('description_uz') && $request->has('description_ru')) {
$description = [
'uz' => $request->description_uz,
'ru' => $request->description_ru,
];
} else {
$description = null;
}
PaymentSystemItem::create([
'title' => [
'uz' => $request->title_uz,
'ru' => $request->title_ru,
],
'payment_system_id' => $paymentSystemId,
'description' => $description,
'slug' => $slug,
'logo' => $logoPath
]);
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.payment-system-items.index', $paymentSystemId);
}
public function edit($paymentSystemId, $systemId)
{
$item = PaymentSystemItem::findOrFail($systemId);
return view('dashboard.payment-systems.items.edit', compact('item', 'paymentSystemId'));
}
public function update(Request $request, $paymentSystemId, $systemId)
{
$item = PaymentSystemItem::findOrFail($systemId);
$this->validate($request, [
'title_uz' => 'required|string',
'title_ru' => 'required|string',
'description_uz' => 'nullable|string',
'description_ru' => 'nullable|string',
'logo' => 'nullable|image',
]);
// generate slug from title_uz
$slug = Str::slug($request->title_uz);
if ($request->has('description_uz') && $request->has('description_ru')) {
$description = [
'uz' => $request->description_uz,
'ru' => $request->description_ru,
];
} else {
$description = null;
}
if ($request->hasFile('logo')) {
// delete old logo
Storage::delete($item->logo);
// store logo to storage
$logo = $request->file('logo');
// with generated name
// generate name with 20 string
$logoName = Str::random(20) . '.' . $logo->extension();
$logo->storeAs('uploads/payment-system-items', $logoName);
$logo = 'uploads/payment-system-items/' . $logoName;
} else {
$logo = $item->logo;
}
$item->update([
'title' => [
'uz' => $request->title_uz,
'ru' => $request->title_ru,
],
'payment_system_id' => $paymentSystemId,
'description' => $description,
'slug' => $slug,
'logo' => $logo,
]);
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.payment-system-items.index', $paymentSystemId);
}
public function destroy($paymentSystemId, $systemId)
{
$item = PaymentSystemItem::findOrFail($systemId);
Storage::delete($item->logo);
$item->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,153 @@
<?php
namespace App\Http\Controllers\Dashboard\Post;
use App\Http\Controllers\Controller as ExController;
use App\Models\Post;
use App\Http\Requests\Dashboard\Post\Update as UpdateRequest;
use App\Http\Requests\Dashboard\Post\Store as StoreRequest;
use App\Jobs\Dashboard\Post\Store as StoreJob;
use App\Jobs\Dashboard\Post\Update as UpdateJob;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class Controller extends ExController
{
protected $posts;
/**
* Controller constructor.
* @param Post $post
*/
public function __construct(Post $post)
{
$this->posts = $post;
}
/**
* @param $lang
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index($lang)
{
$this->authorize('view', 'posts');
$posts = $this->posts->orderBy('position')->latest('id')
->where('language', $lang)
->paginate(20);
return view('dashboard.posts.index', compact('posts', 'lang'));
}
/**
* @param UpdateRequest $request
* @param $lang
* @param Post $post
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(UpdateRequest $request, $lang, Post $post)
{
if ($request->isMethod('get')) {
$this->authorize('update', 'posts');
return view('dashboard.posts.update', compact('lang', 'post'));
}
if ($request->hasFile('image')) {
if (env('FILESYSTEM_DISK') == 's3') {
Storage::disk('s3')->delete($post->image);
} else {
if (is_file($post->image)) {
unlink($post->image);
}
}
$path = $request->file('image')->store('uploads/posts');
} else {
$path = $post->image;
}
// if ($request->has('topped')) {
// DB::table('posts')
// ->where('topped', true)
// ->where('language', $lang)
// ->update([
// 'topped' => false
// ]);
// }
$this->dispatchSync(UpdateJob::fromRequest($post, $request, $path));
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.posts', $lang);
}
/**
* @param StoreRequest $request
* @param $lang
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(StoreRequest $request, $lang)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'posts');
return view('dashboard.posts.store', compact('lang'));
}
if ($request->hasFile('image')) {
$path = $request->file('image')->store('uploads/posts');
}
if ($request->has('topped')) {
DB::table('posts')
->where('topped', true)
->where('language', $lang)
->update([
'topped' => false
]);
}
$this->dispatchSync(StoreJob::fromRequest($request, $path));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.posts', $lang);
}
/**
* @param Post $post
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(Post $post)
{
$this->authorize('delete', 'posts');
if (env('FILESYSTEM_DISK') == 's3') {
Storage::disk('s3')->delete($post->image);
} else {
if (is_file($post->image)) {
unlink($post->image);
}
}
$post->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
public function image_upload(Request $request)
{
if ($request->hasFile('file')) {
$folder = Carbon::now()->format('Y/m/d');
$path = $request->file('file')->store("uploads/posts/{$folder}");
return response()->json([
'image' => $path
]);
}
return response()->json([
'status' => false
], 403);
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace App\Http\Controllers\Dashboard\Power;
use App\Http\Controllers\Controller as ExController;
use Illuminate\Http\Request;
use App\Models\Power;
class PowerController extends ExController
{
public function index(Request $request)
{
// $this->authorize('view', 'powers');
$powers = Power::latest('id')->paginate(30);
return view('dashboard.powers.index', compact('powers'));
}
public function create()
{
// $this->authorize('create', 'powers');
return view('dashboard.powers.create');
}
public function store(Request $request)
{
// $this->authorize('create', 'powers');
$this->validate($request, [
'name_uz' => 'required|string|max:255',
'name_ru' => 'required|string|max:255',
'value' => 'required|numeric',
]);
Power::create([
'name' => [
'uz' => $request->name_uz,
'ru' => $request->name_ru,
],
'power' => $request->value,
]);
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.powers.index');
}
public function edit(Power $power)
{
// $this->authorize('update', 'powers');
return view('dashboard.powers.edit', compact('power'));
}
public function update(Request $request, Power $power)
{
// $this->authorize('update', 'powers');
$this->validate($request, [
'name_uz' => 'required|string|max:255',
'name_ru' => 'required|string|max:255',
'value' => 'required|numeric',
]);
$power->update([
'name' => [
'uz' => $request->name_uz,
'ru' => $request->name_ru,
],
'power' => $request->value,
]);
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.powers.index');
}
public function destroy(Power $power)
{
// $this->authorize('delete', 'powers');
$power->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace App\Http\Controllers\Dashboard\Problem;
use App\Http\Controllers\Controller as ExController;
use Illuminate\Http\Request;
use App\Models\Problem;
class ProblemController extends ExController
{
public function index(Request $request)
{
$problems = Problem::latest('id')->paginate(30);
return view('dashboard.problems.index', compact('problems'));
}
public function create()
{
return view('dashboard.problems.create');
}
public function store(Request $request)
{
$this->validate($request, [
'title_uz' => 'required|string|max:255',
'title_ru' => 'required|string|max:255',
]);
Problem::create([
'title' => [
'uz' => $request->title_uz,
'ru' => $request->title_ru,
],
]);
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.problems.index');
}
public function edit(Problem $problem)
{
return view('dashboard.problems.edit', compact('problem'));
}
public function update(Request $request, Problem $problem)
{
$this->validate($request, [
'title_uz' => 'required|string|max:255',
'title_ru' => 'required|string|max:255',
]);
$problem->update([
'title' => [
'uz' => $request->title_uz,
'ru' => $request->title_ru,
],
]);
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.problems.index');
}
public function destroy(Problem $problem)
{
$problem->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,621 @@
<?php
namespace App\Http\Controllers\Dashboard\Product;
use App\Exports\ProductsForPriceExport;
use App\Helpers\MassAction;
use App\Imports\MobileImport;
use App\Models\Brand;
use App\Models\Color;
use App\Models\Measurement;
use App\Models\Preview;
use App\Models\Screen;
use App\Models\Category;
use App\Models\Product;
use App\Queries\Category as CategoryQuery;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\Product\Store as StoreRequest;
use App\Http\Requests\Dashboard\Product\Update as UpdateRequest;
use App\Jobs\Dashboard\Product\Store as StoreJob;
use App\Jobs\Dashboard\Product\Child as ChildJob;
use App\Jobs\Dashboard\Product\ChildUpdate as ChildUpdateJob;
use App\Jobs\Dashboard\Product\Update as UpdateJob;
use App\Jobs\Dashboard\Product\Deletes as DeletesJob;
use Exception;
use Illuminate\Support\Facades\Date;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
class Controller extends ExController
{
protected $products;
protected $categories;
protected $brands;
protected $colors;
protected $categoryQuery;
/**
* @var MassAction
*/
private $massAction;
/**
* Controller constructor.
* @param Product $product
* @param Category $category
* @param Brand $brand
* @param Color $color
*/
public function __construct(Product $product, Category $category, Brand $brand, Color $color)
{
$this->products = $product;
$this->categories = $category;
$this->brands = $brand;
$this->colors = $color;
$this->categoryQuery = new CategoryQuery();
$this->massAction = new MassAction();
}
/**
* @param Request $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index(Request $request)
{
$this->authorize('view', 'products');
$products = $this->products->latest('id')->whereNull('child_id')->paginate($request->paginate ?? 15);
$categories = Category::whereNull('parent_id')->get();
return view('dashboard.products.index', compact('products', 'categories'));
}
/**
* @param StoreRequest $request
* @return array|\Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'products');
$categories = $this->categories->select('id', 'name->ru as category')
->where('parent_id', null)
->with(['parents' => function ($parent) {
return $parent->select('id', 'name->ru as category', 'parent_id')->with(['parents' => function ($parent) {
return $parent->select('id', 'name->ru as category', 'parent_id');
}]);
}])->get();
$brands = $this->brands->get();
$colors = $this->colors->get();
$measurement = Measurement::query()->get();
return view('dashboard.products.store', compact('categories', 'brands', 'colors', 'measurement'));
}
$product = $this->dispatchSync(StoreJob::fromRequest($request));
$product->categories()->attach([$request->getCategoryID()]);
$this->charSync($product, $request->characteristics);
$this->dispatchSync(new ChildJob($request, $product));
$this->success(trans('admin.messages.created'));
return response()->json([
'status' => true
]);
}
/**
* @param $product
* @param $char
*/
private function charSync($product, $char)
{
$sync_data = [];
if (!empty($char)) {
$ids = collect($char)->map(function ($char) {
return (int) $char['id'];
});
$product->characteristics()->detach($ids);
for ($i = 0; $i < count($char); $i++) {
if ($char[$i]['value']) {
$sync_data[$char[$i]['id']] = ['value' => $char[$i]['value']];
}
}
$product->characteristics()->attach($sync_data);
}
}
/**
* @param $id
* @return array
*/
public function characteristics($id)
{
$category = Category::find($id);
if (!empty($category->characteristics) && count($category->characteristics) > 0) {
$characteristics = $category->characteristics;
} else {
if (!empty($category->parent)) {
$characteristics = $category->parent->characteristics;
}
}
if (empty($characteristics)) {
$characteristics = $category->characteristics;
}
$characteristics->map(function ($characteristic) {
if ($characteristic->type == 'checkbox') {
$characteristic->value = false;
} else {
$characteristic->value = null;
}
});
return [
'status' => true,
'characteristics' => $characteristics
];
}
/**
* @param $categories
* @return array
*/
private function category($categories): array
{
return array_map(function ($cat) {
$arr = [];
if (count($cat['parents']) > 0) {
$arr[] = [
'id' => $cat['id'],
'category' => $cat['name']['ru'],
'$isDisabled' => true
];
foreach ($cat['parents'] as $parent) {
if (count($parent['parents']) > 0) {
if (count($parent['parents']) > 0) {
$arr[] = [
'id' => $parent['id'],
'category' => $parent['name']['ru'],
'$isDisabled' => true
];
foreach ($parent['parents'] as $paren) {
$arr[] = [
'id' => $paren['id'],
'category' => $paren['name']['ru'],
'$isDisabled' => false
];
}
} else {
$arr[] = [
'id' => $parent['id'],
'category' => $parent['name']['ru'],
'$isDisabled' => false
];
}
} else {
$arr[] = [
'id' => $parent['id'],
'category' => $parent['name']['ru'],
'$isDisabled' => false
];
}
}
return $arr;
} else {
$arr = [
'id' => $cat['id'],
'category' => $cat['name']['ru'],
'$isDisabled' => false
];
return $arr;
}
}, $categories);
}
/**
* @param Product $product
* @param UpdateRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Product $product, UpdateRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('update', 'products');
$product->loadMissing([
'childrens' => function ($child) {
return $child->select('id', 'sizes', 'color_id', 'child_id')->with([
'color' => function ($color) {
return $color->select('id', 'name', 'color');
},
'screens' => function ($screen) {
return $screen->select('id', 'name', 'size', 'path', 'product_id', 'type');
}
]);
},
'categories' => function ($categories) {
return $categories->select('id', 'name->ru as category', 'parent_id')->with(['parent' => function ($parent) {
return $parent->select('id', 'name->ru as category', 'parent_id')->with(['parents', 'parent' => function ($parent) {
return $parent->select('id', 'name->ru as category', 'parent_id')->with(['parents' => function ($parent) {
return $parent->select('id', 'name->ru as category', 'parent_id');
}]);
}, 'parents' => function ($parent) {
return $parent->select('id', 'name->ru as category', 'parent_id');
}]);
}]);
},
'characteristics'
]);
foreach ($product->childrens as $children) {
foreach ($children->screens as $screen) {
$screen->sizeText = $screen->size / 1024 . 'Kb';
if (env('FILESYSTEM_DISK') == 's3') {
$screen->url = Storage::temporaryUrl(
$screen->path,
Date::now()->addMinutes(5)
);
} else {
$screen->url = '/' . $screen->path;
}
$screen->type = "image/jpeg";
}
}
$categories = $this->categories->select('id', 'name->ru as category')
->where('parent_id', null)
->with(['parents' => function ($parent) {
return $parent->select('id', 'name->ru as category', 'parent_id')->with(['parents' => function ($parent) {
return $parent->select('id', 'name->ru as category', 'parent_id');
}]);
}])->get();
$brands = $this->brands->get();
$measurement = Measurement::query()->get();
$colors = $this->colors->get();
$product->poster = $product->getPoster();
$product->poster_thumb = $product->getPosterThumb();
$product->data_sheet = $product->getDataSheet();
return view('dashboard.products.update', compact('categories', 'brands', 'colors', 'product', 'measurement'));
}
try{
$this->dispatchSync(new UpdateJob($product, $request));
$this->dispatchSync(new ChildUpdateJob($request, $product));
}catch(Exception $e){
return Response::json([
"messages" => $e->getMessage()
]);
}
$this->charSync($product, $request->characteristics);
$this->dispatchSync(new DeletesJob($request));
$this->info(trans('admin.messages.updated'));
return response()->json([
'status' => true
]);
}
/**
* @param Product $product
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function delete(Product $product)
{
$this->authorize('delete', 'products');
// if (is_file($product->poster)) {
// unlink($product->poster);
// }
//
// if (is_file($product->poster_thumb)) {
// unlink($product->poster_thumb);
// }
//
// $screens = Screen::where('product_id', $product->id)->get();
// foreach ($screens as $screen) {
// if (is_file($screen->path)) {
// unlink($screen->path);
// }
//
// if (is_file($screen->path)) {
// unlink($screen->path_thumb);
// }
//
// $screen->delete();
// }
//
// foreach ($product->childrens as $children) {
// $screens = Screen::where('product_id', $children->id)->get();
// foreach ($screens as $screen) {
// $this->delete_screen($screen);
// }
// $children->delete();
// }
$product->delete();
$product->childrens()->delete();
$this->error(trans('admin.messages.deleted'));
return redirect()->back();
}
/**
* @param Request $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function search(Request $request)
{
$id = empty($request->get('id')) ? null : $request->get('id');
$brand = empty($request->get('brand')) ? null : $request->get('brand');
$name = empty($request->get('name')) ? null : $request->get('name');
$category = empty($request->get('category')) ? null : $request->get('category');
$in_stock = empty($request->get('in_stock')) && $request->get('in_stock') == 0 ? null : $request->get('in_stock');
$published = $request->get('published'); // ? null : $request->get('published');
$article_number = empty($request->get('article_number')) ? null : $request->get('article_number');
if ($category) {
$categoryFind = Category::find($category);
list($categoryFind, $category_id) = $this->categoryQuery->getCategoriesAndCategoryMainId($categoryFind);
} else {
$category_id = [];
}
if ($in_stock) {
$products = Product::latest('id')->searchFilter($id, $brand, $category, $published, $article_number, $category_id, $name);
if ($in_stock == 1) {
$products = $products->where('available', 1)->where('count', '>', 0);
}
} else {
$products = Product::latest('id')->searchFilter($id, $brand, $category, $published, $article_number, $category_id, $name);
if ($in_stock == 0) {
$products = $products->where('available', 0)->where('count', '>', 0)
->orWhere('available', 1)->where('count', 0)->notChilds()->searchFilter($id, $brand, $category, $published, $article_number, $category_id, $name)
->orWhere('available', 0)->where('count', 0)->notChilds()->searchFilter($id, $brand, $category, $published, $article_number, $category_id, $name);
}
}
$products = $products->paginate(10);
$categories = Category::whereNull('parent_id')->get();
return view('dashboard.products.index', compact('products', 'categories'));
}
/**
* @param Screen $screen
* @return array
* @throws \Exception
*/
public function delete_screen(Screen $screen)
{
if (is_file($screen->path)) {
unlink($screen->path);
}
if (is_file($screen->path_thumb)) {
unlink($screen->path_thumb);
}
$screen->delete();
return ['status' => true];
}
public function import(Request $request)
{
if ($request->isMethod('get')) {
$categories = Category::whereNull('parent_id')->get();
return view('dashboard.products.import', compact('categories'));
}
$request->validate([
'file' => 'required|mimes:xlsx,xls'
]);
$file = $request->file('file')->store('uploads/imports');
$excel = Excel::toArray(new MobileImport, $file);
$excel = collect($excel)->flatten(1)->map(function ($product) {
if ($product[0] != null) {
return $product;
}
})->filter(function ($value) {
return $value != null;
})->splice(1);
if ($request->category_id == 0) {
foreach ($excel as $item) {
$product = Product::find($item[0]);
if (!empty($product)) {
$product->article_number = $item[1];
$product->price = $item[3] ? $item[3] : $product->price;
$product->price_discount = $item[4] ? $item[4] : $product->price_discount;
// $product->price_credit = $item[8] ? $item[8] : $product->price_credit;
$product->count = $item[9];
$product->save();
}
}
$this->success(trans('admin.messages.created'));
return redirect()->route('dashboard.products');
}
Preview::query()->truncate();
foreach ($excel as $product) {
Preview::create([
'name' => [
'ru' => $product[0],
'uz' => $product[1],
],
'brand' => $product[2],
'price' => $product[3] ? $product[3] : 0,
'price_discount' => $product[4],
'article_number' => $product[5],
'leader_of_sales' => $product[6],
'popular' => $product[7],
'category_id' => $request->category_id,
'characteristics' => [
$product[8],
$product[9],
$product[10],
$product[11],
$product[12],
$product[13],
$product[14],
$product[15],
$product[16],
$product[17],
]
]);
}
$products = Preview::all();
$characteristics = $this->characteristics($request->category_id);
$category_id = $request->category_id;
return view('dashboard.products.preview', compact('products', 'characteristics', 'category_id'));
}
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function previewStore(Request $request)
{
$char = $this->characteristics($request->category_id);
$char = $char['characteristics'];
foreach ($request->data as $row) {
$brand = Brand::where('name->ru', $row['brand'])->first();
$brand_id = !empty($brand) ? $brand->id : null;
$product = Product::where('article_number', $row['article_number'])->first();
if (!empty($product)) {
$product->name = $row['name'];
$product->price = $row['price'];
$product->price_discount = $row['price_discount'];
$product->popular = $row['popular'];
$product->currency = 'sum';
$product->brand_id = $brand_id;
$product->leader_of_sales = $row['leader_of_sales'];
$product->slug = str_slug($row['name']['ru']);
$product->save();
} else {
$product = new Product();
$product->name = $row['name'];
$product->price = $row['price'];
$product->body = ['ru' => '', 'uz' => ''];
$product->short_body = ['ru' => '', 'uz' => ''];
$product->article_number = $row['article_number'];
$product->price_discount = $row['price_discount'];
$product->popular = $row['popular'];
$product->currency = 'sum';
$product->brand_id = $brand_id;
$product->leader_of_sales = $row['leader_of_sales'];
$product->slug = str_slug($row['name']['ru']);
$product->published = 0;
$product->save();
$product->categories()->attach([$row['category_id']]);
Product::create([
'published' => 0,
'child_id' => $product->id
]);
}
$sync_data = [];
if (!empty($char) && count($char) > 0) {
$ids = $char->map(function ($char) {
return (int) $char['id'];
});
$product->characteristics()->detach($ids);
for ($i = 0; $i < count($row['characteristics']); $i++) {
if ($char[$i]['type'] == 'checkbox') {
$value = $row['characteristics'][$i] == 1 || $row['characteristics'][$i] == true ? 'true' : 'false';
} else {
$value = $row['characteristics'][$i];
}
if ($value === null) {
$value = 'null';
}
$sync_data[$char[$i]['id']] = ['value' => $value];
}
$product->characteristics()->attach($sync_data);
}
}
$this->success(trans('admin.messages.created'));
return response()->json([
'status' => true
]);
}
public function massAction(Request $request)
{
switch ($request->input('action')) {
case "delete":
$this->massAction->massDelete($request->prod_id);
break;
case "status-deactivate":
$this->massAction->massUnpublish($request->prod_id);
break;
case "status-active":
$this->massAction->massPublish($request->prod_id);
}
$this->info(trans('admin.messages.success'));
return redirect()->back();
}
public function export()
{
return Excel::download(new ProductsForPriceExport(), 'products-export.xlsx');
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace App\Http\Controllers\Dashboard\Region;
use App\Models\Region;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\Region\Update as UpdateRequest;
use App\Http\Requests\Dashboard\Region\Store as StoreRequest;
use App\Jobs\Dashboard\Region\Store as StoreJob;
use App\Jobs\Dashboard\Region\Update as UpdateJob;
use App\Models\Power;
use App\Services\Dashboard\Region\RegionService;
class Controller extends ExController
{
protected $regions;
/**
* Controller constructor.
* @param Region $region
*/
public function __construct(Region $region)
{
$this->regions = $region;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('view', 'regions');
$regions = $this->regions->latest('id')->paginate(20);
return view('dashboard.regions.index', compact('regions'));
}
/**
* @param UpdateRequest $request
* @param Region $region
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(UpdateRequest $request, Region $region)
{
if ($request->isMethod('get')) {
$this->authorize('update', 'regions');
$powers = Power::all();
$lang = app()->getLocale();
return view('dashboard.regions.update', compact('region', 'powers', 'lang'));
}
$this->dispatchSync(UpdateJob::fromRequest($region, $request));
// update or store delivery price
if ($request->has('deliveryPrice')) {
RegionService::deliveryPrice($region, $request->deliveryPrice);
}
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.regions');
}
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'regions');
$powers = Power::all();
$lang = app()->getLocale();
return view('dashboard.regions.store', compact('powers', 'lang'));
}
$region = $this->dispatchSync(StoreJob::fromRequest($request));
// store delivery price
if ($request->has('deliveryPrice')) {
RegionService::deliveryPrice($region, $request->deliveryPrice);
}
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.regions');
}
/**
* @param Region $region
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function delete(Region $region)
{
$this->authorize('delete', 'regions');
// delete delivery price
$region->deliveryPrice()->delete();
$region->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace App\Http\Controllers\Dashboard\Role;
use App\Models\Role;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\Role\Request as UpdateRequest;
use App\Http\Requests\Dashboard\Role\Request as StoreRequest;
use App\Jobs\Dashboard\Role\Store as StoreJob;
use App\Jobs\Dashboard\Role\Update as UpdateJob;
class Controller extends ExController
{
protected $roles;
/**
* Controller constructor.
* @param Role $role
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function __construct(Role $role)
{
$this->roles = $role;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('view', 'roles');
$roles = $this->roles->latest('id')
->paginate(20);
return view('dashboard.roles.index', compact('roles'));
}
/**
* @param UpdateRequest $request
* @param Role $role
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(UpdateRequest $request, Role $role)
{
if ($request->isMethod('get')) {
$this->authorize('update', 'roles');
return view('dashboard.roles.update', compact('role'));
}
//return $request->all();
$this->dispatchSync(UpdateJob::fromRequest($role, $request));
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.roles');
}
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'roles');
return view('dashboard.roles.store');
}
$this->dispatchSync(StoreJob::fromRequest($request));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.roles');
}
/**
* @param Role $role
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(Role $role)
{
$this->authorize('delete', 'roles');
$role->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,127 @@
<?php
namespace App\Http\Controllers\Dashboard\Service;
use App\Http\Controllers\Controller as ExController;
use App\Models\Service;
use App\Http\Requests\Dashboard\Service\Update as UpdateRequest;
use App\Http\Requests\Dashboard\Service\Store as StoreRequest;
use App\Jobs\Dashboard\Service\Store as StoreJob;
use App\Jobs\Dashboard\Service\Update as UpdateJob;
use App\Models\Problem;
use App\Models\ServiceProblem;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
class Controller extends ExController
{
public function index()
{
$this->authorize('view', 'services');
$services = Service::latest('id')->paginate(20);
return view('dashboard.services.index', compact('services'));
}
public function create()
{
$this->authorize('create', 'services');
$problems = Problem::all();
return view('dashboard.services.create', compact('problems'));
}
public function store(StoreRequest $request)
{
if ($request->hasFile('image')) {
$path = $request->file('image')->store('uploads/services');
}
$service = $this->dispatchSync(StoreJob::fromRequest($request, $path));
if ($request->with_problem != null) {
foreach ($request->problems as $problem) {
ServiceProblem::create([
'service_id' => $service->id,
'problem_id' => $problem
]);
}
}
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.services.index');
}
public function edit(Service $service)
{
$this->authorize('update', 'services');
$problems = Problem::all();
return view('dashboard.services.edit', compact('service', 'problems'));
}
public function update(UpdateRequest $request, Service $service)
{
if ($request->hasFile('image')) {
if (env('FILESYSTEM_DISK') == 's3') {
$imagePath = $service->image;
Storage::disk('s3')->delete($imagePath);
} else {
$imagePath = public_path($service->image);
if (File::exists($imagePath)) {
File::delete($imagePath);
}
}
$path = $request->file('image')->store('uploads/services');
} else {
$path = $service->image;
}
$this->dispatchSync(UpdateJob::fromRequest($service, $request, $path));
$existingProblemIds = $service->problems->pluck('id')->toArray();
$newProblemIds = $request->problems ?? [];
$toDelete = array_diff($existingProblemIds, $newProblemIds);
$toAdd = array_diff($newProblemIds, $existingProblemIds);
if ($request->with_problem != null) {
foreach ($toAdd as $problem) {
ServiceProblem::create([
'service_id' => $service->id,
'problem_id' => $problem
]);
}
} else {
ServiceProblem::where('service_id', $service->id)->delete();
}
ServiceProblem::whereIn('problem_id', $toDelete)->delete();
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.services.index');
}
public function destroy(Service $service)
{
$this->authorize('delete', 'services');
if (env('FILESYSTEM_DISK') == 's3') {
$imagePath = $service->image;
Storage::disk('s3')->delete($imagePath);
} else {
$imagePath = public_path($service->image);
if (File::exists($imagePath)) {
File::delete($imagePath);
}
}
ServiceProblem::where('service_id', $service->id)->delete();
$service->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Http\Controllers\Dashboard\ServiceRequest;
use App\Http\Controllers\Controller as ExController;
use App\Models\ServiceRequest;
use Illuminate\Http\Request;
class Controller extends ExController
{
public function index()
{
$requests = ServiceRequest::latest('id')->paginate(20);
return view('dashboard.services.requests.index', compact('requests'));
}
public function show($id)
{
$serviceRequest = ServiceRequest::findOrFail($id);
return view('dashboard.services.requests.show', compact('serviceRequest'));
}
public function update(Request $request, $id)
{
// validate request
$request->validate([
'status' => 'required|in:approved,rejected,closed,pending'
]);
$serviceRequest = ServiceRequest::findOrFail($id);
$serviceRequest->update([
'status' => $request->status,
]);
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.service_requests.index');
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace App\Http\Controllers\Dashboard\Setting;
use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\Setting\Update as UpdateRequest;
use App\Jobs\Dashboard\Setting\Update as UpdateJob;
class Controller extends ExController
{
protected $setting;
/**
* Controller constructor.
* @param Setting $setting
*/
public function __construct(Setting $setting)
{
$this->setting = $setting->find(1);
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('update', 'settings');
$setting = $this->setting;
return view('dashboard.settings.index', compact('setting'));
}
/**
* @param UpdateRequest $request
* @param Setting $setting
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateRequest $request, Setting $setting)
{
$this->dispatchSync(UpdateJob::fromRequest($setting, $request));
$this->info(trans('admin.messages.updated'));
return redirect()->back();
}
public function delivery(Request $request)
{
// $this->authorize('delivery', 'settings');
Gate::check('update', 'settings');
$setting = $this->setting;
if ($request->isMethod('get')) {
return view('dashboard.settings.delivery', compact('setting'));
}
$pickup = $request->pickup == 1 ? true : false;
$delivery = $request->delivery == 1 ? true : false;
$setting->update([
'price_delivery' => $request->price_delivery,
'pickup' => $pickup,
'delivery' => $delivery,
'day_delivery' => $request->day_delivery,
'pickup_text' => '',
'other' => ''
]);
$this->info(trans('admin.messages.updated'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,110 @@
<?php
namespace App\Http\Controllers\Dashboard\Slider;
use App\Models\Slider;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\Slider\Update as UpdateRequest;
use App\Http\Requests\Dashboard\Slider\Store as StoreRequest;
use App\Jobs\Dashboard\Slider\Store as StoreJob;
use App\Jobs\Dashboard\Slider\Update as UpdateJob;
class Controller extends ExController
{
protected $sliders;
/**
* Controller constructor.
* @param Slider $slider
*/
public function __construct(Slider $slider)
{
$this->sliders = $slider;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('view', 'sliders');
$sliders = $this->sliders->orderBy('position', 'asc')->get();
return view('dashboard.sliders.index', compact('sliders'));
}
/**
* @param UpdateRequest $request
* @param Slider $slider
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(UpdateRequest $request, Slider $slider)
{
if ($request->isMethod('get')) {
$this->authorize('update', 'sliders');
return view('dashboard.sliders.update', compact('slider'));
}
if ($request->hasFile('image')) {
$path = $request->file('image')->store('uploads/sliders');
} else {
$path = $slider->image;
}
$this->dispatchSync(UpdateJob::fromRequest($slider, $request, $path));
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.sliders');
}
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'sliders');
return view('dashboard.sliders.store');
}
if ($request->hasFile('image')) {
$path = $request->file('image')->store('uploads/sliders');
}
$this->dispatchSync(StoreJob::fromRequest($request, $path));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.sliders');
}
/**
* @param Slider $slider
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(Slider $slider)
{
$this->authorize('delete', 'sliders');
if (is_file($slider->image)) {
unlink($slider->image);
}
$slider->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
public function position(Request $req)
{
foreach ($req->input('sliders') as $slider) {
Slider::find($slider['id'])->update(['position' => $slider['position']]);
}
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace App\Http\Controllers\Dashboard\SpecialOffer;
use App\Models\SpecialOffer;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\SpecialOffer\Update as UpdateRequest;
use App\Http\Requests\Dashboard\SpecialOffer\Store as StoreRequest;
use App\Jobs\Dashboard\SpecialOffer\Store as StoreJob;
use App\Jobs\Dashboard\SpecialOffer\Update as UpdateJob;
class Controller extends ExController
{
protected $specialOffers;
/**
* Controller constructor.
* @param SpecialOffer $specialOffer
*/
public function __construct(SpecialOffer $specialOffer)
{
$this->specialOffers = $specialOffer;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$this->authorize('view', 'special-offers');
$specialOffers = $this->specialOffers->latest('id')->paginate(20);
return view('dashboard.specialOffers.index', compact('specialOffers'));
}
/**
* @param UpdateRequest $request
* @param SpecialOffer $specialOffer
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
public function update(UpdateRequest $request, SpecialOffer $specialOffer)
{
if ($request->isMethod('get')) {
$this->authorize('update', 'special-offers');
return view('dashboard.specialOffers.update', compact('specialOffer'));
}
if ($request->hasFile('image')) {
$path = $request->file('image')->store('uploads/specialOffers');
} else {
$path = $specialOffer->image;
}
$this->dispatchSync(UpdateJob::fromRequest($specialOffer, $request, $path));
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.specialOffers');
}
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'special-offers');
return view('dashboard.specialOffers.store');
}
if ($request->hasFile('image')) {
$path = $request->file('image')->store('uploads/specialOffers');
}
$this->dispatchSync(StoreJob::fromRequest($request, $path));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.specialOffers');
}
/**
* @param SpecialOffer $specialOffer
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(SpecialOffer $specialOffer)
{
$this->authorize('delete', 'special-offers');
if (is_file($specialOffer->image)) {
unlink($specialOffer->image);
}
$specialOffer->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace App\Http\Controllers\Dashboard\Status;
use App\Http\Controllers\Controller as ExController;
use Illuminate\Http\Request;
use App\Models\Status;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class StatusController extends ExController
{
public function index(Request $request)
{
$statuses = Status::latest('id')->paginate(30);
return view('dashboard.statuses.index', compact('statuses'));
}
public function create()
{
return view('dashboard.statuses.create');
}
public function store(Request $request)
{
$this->validate($request, [
'slug' => 'required|string|unique:statuses',
'font_color' => 'required|string',
'bg_color' => 'required|string',
]);
Status::create([
'slug' => $request->slug,
'font_color' => $request->font_color,
'bg_color' => $request->bg_color,
]);
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.statuses.index');
}
public function edit($statusId)
{
$status = Status::findOrFail($statusId);
return view('dashboard.statuses.edit', compact('status'));
}
public function update(Request $request, $statusId)
{
$status = Status::findOrFail($statusId);
$this->validate($request, [
'slug' => 'required|string|unique:statuses,slug,' . $status->id,
'font_color' => 'required|string',
'bg_color' => 'required|string',
]);
$status->update([
'slug' => $request->slug,
'font_color' => $request->font_color,
'bg_color' => $request->bg_color,
]);
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.statuses.index');
}
public function destroy($statusId)
{
$status = Status::findOrFail($statusId);
$status->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace App\Http\Controllers\Dashboard\UsefulInfoController;
use App\Http\Controllers\Controller as ExController;
use App\Models\UsefulInfo;
use App\Http\Requests\Dashboard\UsefulInfoRequest\Update as UpdateRequest;
use App\Http\Requests\Dashboard\UsefulInfoRequest\Store as StoreRequest;
use App\Jobs\Dashboard\UsefulInfoJob\Store as StoreJob;
use App\Jobs\Dashboard\UsefulInfoJob\Update as UpdateJob;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
class Controller extends ExController
{
public function index()
{
$this->authorize('view', 'usefulinfos');
$usefulinfos = UsefulInfo::orderBy('position')->latest('id')->paginate(20);
return view('dashboard.usefulinfos.index', compact('usefulinfos'));
}
public function create()
{
$this->authorize('create', 'usefulinfos');
return view('dashboard.usefulinfos.create');
}
public function store(StoreRequest $request)
{
if ($request->hasFile('image')) {
$path = $request->file('image')->store('uploads/usefulinfos');
}
$this->dispatchSync(StoreJob::fromRequest($request, $path));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.usefulinfos.index');
}
public function edit(UsefulInfo $usefulinfo)
{
$this->authorize('update', 'usefulinfos');
return view('dashboard.usefulinfos.edit', compact('usefulinfo'));
}
public function update(UpdateRequest $request, UsefulInfo $usefulinfo)
{
if ($request->hasFile('image')) {
if (env('FILESYSTEM_DISK') == 's3') {
$imagePath = $usefulinfo->image;
Storage::disk('s3')->delete($imagePath);
} else {
$imagePath = public_path($usefulinfo->image);
if (File::exists($imagePath)) {
File::delete($imagePath);
}
}
$path = $request->file('image')->store('uploads/usefulinfos');
} else {
$path = $usefulinfo->image;
}
$this->dispatchSync(UpdateJob::fromRequest($usefulinfo, $request, $path));
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.usefulinfos.index');
}
public function destroy(UsefulInfo $usefulinfo)
{
$this->authorize('delete', 'usefulinfos');
// delete items files
foreach ($usefulinfo->items as $item) {
$filePath = public_path($item->file_url);
if (File::exists($filePath)) {
File::delete($filePath);
}
$item->delete();
}
if (env('FILESYSTEM_DISK') == 's3') {
$imagePath = $usefulinfo->image;
Storage::disk('s3')->delete($imagePath);
} else {
$imagePath = public_path($usefulinfo->image);
if (File::exists($imagePath)) {
File::delete($imagePath);
}
}
$usefulinfo->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,89 @@
<?php
namespace App\Http\Controllers\Dashboard\UsefulInfoItemController;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\UsefulInfoItemRequest\Update as UpdateRequest;
use App\Http\Requests\Dashboard\UsefulInfoItemRequest\Store as StoreRequest;
use App\Jobs\Dashboard\UsefulInfoItemJob\Store as StoreJob;
use App\Jobs\Dashboard\UsefulInfoItemJob\Update as UpdateJob;
use App\Models\UsefulInfo;
use App\Models\UsefulInfoItem;
use Illuminate\Support\Facades\File;
class Controller extends ExController
{
public function index($usefulinfo_id)
{
$this->authorize('view', 'usefulinfoitems');
$items = UsefulInfoItem::where('useful_info_id', $usefulinfo_id)
->latest('id')->paginate(20);
return view('dashboard.usefulinfos.usefulinfos_item.index', compact('items', 'usefulinfo_id'));
}
public function create($usefulinfo_id)
{
$this->authorize('create', 'usefulinfoitem');
return view('dashboard.usefulinfos.usefulinfos_item.create', compact('usefulinfo_id'));
}
public function store(StoreRequest $request, $usefulinfo_id)
{
$file_path = null;
if ($request->hasFile('file')) {
$file_path = $request->file('file')->store('uploads/usefulinfoitems');
}
$this->dispatchSync(StoreJob::fromRequest($request, $file_path, $usefulinfo_id));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.usefulinfoitems.index', $usefulinfo_id);
}
public function edit($usefulinfo_id, UsefulInfoItem $usefulinfoitem)
{
$this->authorize('update', 'usefulinfoitems');
return view('dashboard.usefulinfos.usefulinfos_item.edit', compact('usefulinfoitem', 'usefulinfo_id'));
}
public function update(UpdateRequest $request, $usefulinfo_id, UsefulInfoItem $usefulinfoitem)
{
$file_path = null;
if ($request->hasFile('file')) {
$filePath = public_path($usefulinfoitem->file_url);
if (File::exists($filePath)) {
File::delete($filePath);
}
$file_path = $request->file('file')->store('uploads/usefulinfoitems');
} else {
$file_path = $usefulinfoitem->file_url;
}
$this->dispatchSync(UpdateJob::fromRequest($usefulinfoitem, $request, $file_path));
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.usefulinfoitems.index', $usefulinfo_id);
}
public function destroy($usefulinfo_id, UsefulInfoItem $usefulinfoitem)
{
$this->authorize('delete', 'usefulinfoitems');
$filePath = public_path($usefulinfoitem->file_url);
if (File::exists($filePath)) {
File::delete($filePath);
}
$usefulinfoitem->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
}

View File

@@ -0,0 +1,164 @@
<?php
namespace App\Http\Controllers\Dashboard\User;
use App\Exports\UsersExport;
use App\Http\Requests\Dashboard\User\Create as CreateRequest;
use App\Imports\UsersImport;
use App\Jobs\Dashboard\User\Create;
use App\Models\Role;
use App\Models\Staff;
use App\Models\User;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\User\Update as UpdateRequest;
use App\Jobs\Dashboard\User\Update as UpdateJob;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
class Controller extends ExController
{
protected $users;
/**
* Controller constructor.
* @param User $user
*/
public function __construct(User $user)
{
$this->users = $user;
}
/**
* @param Request $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Exception
*/
public function index(Request $request)
{
$this->authorize('view', 'users');
$users = $this->users->latest('id');
if (!is_null($request->date_from)) {
$users = $users->filterByDate($request->date_from, $request->date_to, $request->sort_type);
}
$users = $users->search($request->search_id, $request->search_phone, $request->search_ip)->paginate(30);
return view('dashboard.users.index', compact('users'));
}
public function getStaffs()
{
$this->authorize('view', 'staffs');
$staffs = Staff::with('role')
->oldest('id')
->where('role_id', '!=', 2)
->paginate(30);
return view('dashboard.users.staffs', compact('staffs'));
}
/**
* @param Staff $staff
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function block(Staff $staff)
{
$this->authorize('update', 'staffs');
if ($staff->block === true) {
$staff->block = false;
} else {
$staff->block = true;
}
$staff->save();
$this->info(trans('admin.messages.updated'));
return redirect()->back();
}
public function store(CreateRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'staffs');
$roles = Role::whereNotIn('id', [2])->get();
return view('dashboard.users.create', compact('roles'));
}
$this->dispatchSync(new Create($request));
$this->info(trans('admin.messages.created'));
return redirect()->route('dashboard.staffs');
}
/**
* @param UpdateRequest $request
* @param Staff $staff
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(UpdateRequest $request, Staff $staff)
{
if ($request->isMethod('get')) {
$this->authorize('update', 'staffs');
$roles = Role::whereNotIn('id', [2])->get();
return view('dashboard.users.update', compact('staff', 'roles'));
}
$this->dispatchSync(new UpdateJob($staff, $request));
$this->info(trans('admin.messages.updated'));
return redirect()->route('dashboard.staffs');
}
public function import()
{
$file = '/customers.csv';
$excel = Excel::toArray(new UsersImport, $file);
$users = collect($excel)->flatten(1);
foreach ($users as $user) {
$phone = str_replace(['+', '(', ')', ' ', '-'], '', $user[8]);
$user = User::where('phone', $phone)->first();
if (empty($user)) {
if (!empty($user[8])) {
User::create([
'first_name' => !empty($user[4]) ? $user[4] : null,
'last_name' => !empty($user[5]) ? $user[5] : null,
'phone' => str_replace(['+', '(', ')', ' ', '-'], '', $user[8]),
'email' => !empty($user[7]) ? $user[7] : null,
'ip' => !empty($user[17]) ? $user[17] : null,
'role_id' => 2,
'step' => 3
]);
}
}
}
}
public function export(Request $request)
{
return (new UsersExport($request->date_from, $request->date_to, $request->search_id, $request->search_phone, $request->search_ip, $request->sort_type))
->download("users_" . now()->toDateString() . ".xlsx");
}
public static function addHours()
{
$users = User::all();
foreach ($users as $user) {
$user->update([
'created_at' => $user->created_at->addHours(5)
]);
}
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
return view('home');
}
}

View File

@@ -0,0 +1,20 @@
<?php
use App\Models\Billing;
use App\Models\Order;
use App\Api\Sms;
$billing = Billing::find($transaction->transactionable_id);
$billing->status = 'payed';
$billing->transaction_id = $transaction->system_transaction_id;
$billing->save();
$sms = new Sms();
$order = Order::find($billing->order_id);
$order->payment_status = 'payed';
$order->save();
$message = "Quyoshli vash zakaz: {$order->id} uspeshno oplachen!";
$sms->send($order->user->phone, $message);

View File

@@ -0,0 +1,8 @@
<?php
use App\Models\Order;
$order_id = $model->order_id;
Order::query()->where('id', $order_id)->update([
'payment_status' => "waiting"
]);

View File

@@ -0,0 +1,2 @@
<?php
return $response;

View File

@@ -0,0 +1,19 @@
<?php
use App\Api\Sms;
use App\Models\Billing;
use App\Models\Order;
$billing = Billing::find($transaction->transactionable_id);
$billing->status = 'refused';
$billing->save();
$sms = new Sms();
$order = Order::find($billing->order_id);
$order->status = 'cancelled';
$order->payment_status = 'cancelled';
$order->save();
$message = "Quyoshli vash zakaz: {$order->id} otmenen!";
$sms->send($order->user->phone, $message);

View File

@@ -0,0 +1,10 @@
<?php
if ($model->payment_system == 'payme') {
$amount = $amount / 100;
}
if ($model->amount == $amount) {
return true;
}
return false;

Some files were not shown because too many files have changed in this diff Show More