Files
boursecu_server/app/Http/Controllers/Site/ReportController.php
T

683 lines
25 KiB
PHP

<?php
namespace App\Http\Controllers\Site;
use App\Http\Controllers\Admin\PriceController;
use App\Http\Controllers\Controller;
use App\Mail\YourMailableClass;
use App\Models\Cnt;
use App\Models\Setting;
use App\Models\ConfigStatic;
use App\Models\Customer;
use App\Services\LimanService;
use App\Models\Price;
use App\Models\PriceCandle;
use App\Models\PriceTrigger;
use App\Models\Product;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Mail;
use Morilog\Jalali\Jalalian;
use App\Http\Controllers\Admin\ProductController;
class ReportController extends Controller
{
public function candleChart()
{
$candle = PriceCandle::select(["start",
"high",
"low",
"end",
"date_at"])->whereDate('date_at', '<=', date("Y-m-d"))
->whereDate('date_at', '>', Carbon::now()->subDays(30)->format("Y-m-d"))
->get()->toArray();
$a = [];
foreach ($candle as $c) {
$create['date'] = $c["date_at"];
unset($c["date_at"]);
$create['candle'] = array_values($c);
$a[] = array_values($create);
}
return response()->json($a);
}
public function updatePrise()
{
// $difference = config('fee.single');
$difference = Setting::where('key', 'fee_single')->first()->value;
$lastPrice = Price::latest()->first();
$PriceTriggers = PriceTrigger::where("is_active", true)->get();
foreach ($PriceTriggers as $PriceTrigger) {
$priseGold = $PriceTrigger->dirction == 1
? $lastPrice->price - $difference
: ($PriceTrigger->dirction == 2 ? $lastPrice->price + $difference : $lastPrice->price);
if (eval('return $priseGold ' . $PriceTrigger->price_condition . ' $PriceTrigger->target_price;')) {
$customer = Customer::find($PriceTrigger->customer_id);
$message = "قیمت طلا به " . number_format($priseGold, -1) . " در هر گرم رسید\n" .$this->Config('name_fa');
if ($PriceTrigger->action == 'email') {
Mail::to("$customer->email")->send(new YourMailableClass($message, '', '', '', ''));
} elseif ($PriceTrigger->action == 'sms') {
$this->send($customer->mobile, $message);
}
$PriceTrigger->is_active = false;
$PriceTrigger->triggered_at = Carbon::now();
$PriceTrigger->save();
}
}
return response()->json();
}
public function upDownPrice()
{
$difference = Setting::where('key', 'fee_single')->first()->value;
$today = Carbon::now()->format("Y-m-d");
$prises = Price::where('date_at', $today)->get("price");
$minP = 0; // Initialize to the highest possible value
$maxP = 0; // Initialize to the lowest possible value
foreach ($prises as $p) {
// Initialize $minP to the first price if it's null
if ($minP == 0 || $p->price < $minP) {
$minP = $p->price;
}
// Initialize $maxP to the first price if it's null
if ($maxP == 0 || $p->price > $maxP) {
$maxP = $p->price;
}
}
if (count($prises) === 0) {
$price = Price::orderBy('id', 'desc')->first();
$priceValue = $price->price;
return ['sell' => $priceValue - $difference, 'buy' => $priceValue + $difference];
} else {
// Assuming $minP and $maxP are defined elsewhere in your code
return ['sell' => $minP - $difference, 'buy' => $maxP + $difference];
}
// return $prises;
// $add_sell_price = config('add_sell_price.major');
// $price = PriceCandle::whereDate('date_at',)->first();
// $price_price = Price::orderBy('id','desc')->first();
}
public function lastPrice()
{
$closed = false;
$goldir_price = 0;
$liman_price = 0;
$tgn = 0;
$pr_price = 0;
$open_buy = true;
$open_sell = true;
$liman_open_buy = false;
$liman_open_sell = false;
$priceSource = null;
$priceValue = 0;
$toBool = function ($value) {
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
};
/*
|--------------------------------------------------------------------------
| بستن قیمت طبق منطق قبلی
|--------------------------------------------------------------------------
*/
if ($this->Config('close_price') == 'true') {
$startDay = $this->Config('startDay');
[$startHour, $startMinute] = explode(':', $startDay);
$endDay = $this->Config('endDay');
[$endHour, $endMinute] = explode(':', $endDay);
$current = Carbon::now();
$start = Carbon::today()->setTime((int) $startHour, (int) $startMinute);
$end = Carbon::today()->setTime((int) $endHour, (int) $endMinute);
if (!$current->between($start, $end)) {
Cnt::where('key', 'app_closed')->update(['value' => "true"]);
Cnt::where('key', 'goldir_closed')->update(['value' => "true"]);
Cnt::where('key', 'liman_closed')->update(['value' => "true"]);
return [
'sell' => 0,
'buy' => 0,
'price_last' => 0,
'price' => 0,
'main_product' => 0,
'taban_gohar' => 0,
'goldir' => 0,
'liman' => 0,
'closed' => true,
'time' => now()->format('H:i:s'),
];
}
Cnt::where('key', 'app_closed')->update(['value' => "false"]);
Cnt::where('key', 'goldir_closed')->update(['value' => "false"]);
Cnt::where('key', 'liman_closed')->update(['value' => "false"]);
}
/*
|--------------------------------------------------------------------------
| Settings
|--------------------------------------------------------------------------
*/
$settings = Setting::whereIn('key', [
'fee_single',
'goldir_price',
'tabanGohar_price',
'main_product_price',
'buy_fee',
'sell_fee',
])->get();
$settingsMap = $settings->pluck('value', 'key');
$taban_gohar_price = $settingsMap->get('tabanGohar_price');
$difference = (float) $settingsMap->get('fee_single', 0);
$gold_ir_price = $settingsMap->get('goldir_price');
$main_product_price = $settingsMap->get('main_product_price');
$diff_buy = (float) $settingsMap->get('buy_fee', $difference);
$diff_sell = (float) $settingsMap->get('sell_fee', $difference);
$liman_price_enabled = $toBool($this->Config('liman_price'));
\Log::info('LAST_PRICE DEBUG START', [
'file' => __FILE__,
'close_price' => $this->Config('close_price'),
'liman_price_raw' => $this->Config('liman_price'),
'liman_price_enabled' => $liman_price_enabled,
'liman_product_id' => $this->Config('liman_product_id'),
'liman_base_url' => $this->Config('liman_base_url'),
'liman_token_exists' => (bool) Setting::where('key', 'liman_token')->value('value'),
]);
/*
|--------------------------------------------------------------------------
| Montpar / Liman - اولویت اول
|--------------------------------------------------------------------------
*/
if ($liman_price_enabled && !$closed) {
try {
$limanBaseUrl = rtrim($this->Config('liman_base_url') ?: 'https://montpar.ir', '/');
$limanProductId = (int) ($this->Config('liman_product_id') ?: 25);
$liman = app(LimanService::class)->productList();
\Log::info('PROVIDER FIRST RESPONSE', [
'base_url' => $limanBaseUrl,
'product_id' => $limanProductId,
'type' => gettype($liman),
'message' => is_array($liman) ? ($liman['message'] ?? null) : null,
'available_ids' => is_array($liman) ? collect($liman)->pluck('id')->values()->all() : null,
]);
if (isset($liman['message'])) {
throw new \Exception('Provider message: ' . $liman['message']);
}
$collection = collect($liman);
$lpLiman = $collection->firstWhere('id', $limanProductId);
\Log::info('PROVIDER PRODUCT PICKED', [
'base_url' => $limanBaseUrl,
'liman_product_id' => $limanProductId,
'found' => (bool) $lpLiman,
'has_sub_agent' => $lpLiman && isset($lpLiman['sub_agent']),
'open_buy' => $lpLiman['open_buy'] ?? null,
'open_sell' => $lpLiman['open_sell'] ?? null,
'buy_gram' => $lpLiman['sub_agent']['rate_buy_gram_price'] ?? null,
'sell_gram' => $lpLiman['sub_agent']['rate_sell_gram_price'] ?? null,
]);
if (!$lpLiman) {
throw new \Exception("Provider product not found. product_id={$limanProductId}");
}
if (!isset($lpLiman['sub_agent'])) {
throw new \Exception("Provider product has no sub_agent. product_id={$limanProductId}");
}
$buy = (float) ($lpLiman['sub_agent']['rate_buy_gram_price'] ?? 0);
$sell = (float) ($lpLiman['sub_agent']['rate_sell_gram_price'] ?? 0);
if ($buy <= 0 || $sell <= 0) {
throw new \Exception("Provider invalid gram price. buy={$buy}, sell={$sell}");
}
$customPrice = [];
$customPrice['price'] = ($buy + $sell) / 2;
$customPrice['diff'] = ($buy - $sell) / 2;
Cnt::where('key', 'liman_price')->update([
'value' => (float) $customPrice['price']
]);
Cnt::where('key', 'liman_diff')->update([
'value' => (float) $customPrice['diff']
]);
Cnt::where('key', 'liman_mazaneh')->update([
'value' => ((float) $customPrice['price'] * 4.331802)
]);
Cnt::where('key', 'liman_truly_buy_mazaneh')->update([
'value' => $lpLiman['sub_agent']['rate_buy_price'] ?? 0
]);
Cnt::where('key', 'liman_truly_sell_mazaneh')->update([
'value' => $lpLiman['sub_agent']['rate_sell_price'] ?? 0
]);
Cnt::where('key', 'log')->update([
'value' => json_encode($lpLiman, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
]);
$liman_open_sell = $toBool($lpLiman['open_sell'] ?? false);
$liman_open_buy = $toBool($lpLiman['open_buy'] ?? false);
Cnt::where('key', 'liman_open_sell')->update([
'value' => $liman_open_sell ? "true" : "false"
]);
Cnt::where('key', 'liman_open_buy')->update([
'value' => $liman_open_buy ? "true" : "false"
]);
if ($liman_open_sell || $liman_open_buy) {
$liman_price = (int) $customPrice['price'];
}
Cnt::where('key', 'liman_closed')->update([
'value' => $liman_price == 0 ? "true" : "false"
]);
\Log::info('PROVIDER PRICE SUCCESS', [
'base_url' => $limanBaseUrl,
'liman_product_id' => $limanProductId,
'liman_price' => $liman_price,
'liman_diff' => $customPrice['diff'],
'open_buy' => $liman_open_buy,
'open_sell' => $liman_open_sell,
]);
} catch (\Throwable $e) {
$liman_price = 0;
\Log::error('PROVIDER PRICE ERROR', [
'base_url' => $limanBaseUrl ?? null,
'message' => $e->getMessage(),
'liman_product_id' => $limanProductId ?? null,
'liman_response' => $liman ?? null,
]);
Cnt::where('key', 'liman_closed')->update([
'value' => "true"
]);
}
}
/*
|--------------------------------------------------------------------------
| Goldir
|--------------------------------------------------------------------------
*/
if ($gold_ir_price == 'true' && !$closed) {
try {
$goldir = Http::timeout(7)
->withOptions([
'curl' => [
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
CURLOPT_TCP_FASTOPEN => 1,
]
])
->withoutVerifying()
->withToken(Cnt::where('key', 'goldir')->value('value'))
->get('https://gold.ir/server/customer/product/list')
->json();
if ((isset($goldir['message']) && $goldir['message'] == 'no authorised') || $goldir == null) {
$cnt = new Cnt();
$goldir = Http::timeout(2)
->withToken($cnt->goldir_login())
->get('https://gold.ir/server/customer/product/list')
->json();
}
$collection = collect($goldir);
$lpGoldir = $collection->firstWhere('id', 40);
if ($lpGoldir && isset($lpGoldir['sub_agent'])) {
$buy = (float) $lpGoldir['sub_agent']['rate_buy_gram_price'];
$sell = (float) $lpGoldir['sub_agent']['rate_sell_gram_price'];
$customPrice = [];
$customPrice['price'] = (ceil($buy) + ceil($sell)) / 2;
$customPrice['diff'] = (ceil($buy) - ceil($sell)) / 2;
Cnt::where('key', 'goldir_price')->update([
'value' => (float) $customPrice['price']
]);
Cnt::where('key', 'goldir_diff')->update([
'value' => (float) $customPrice['diff']
]);
Cnt::where('key', 'goldir_mazaneh')->update([
'value' => ((float) $customPrice['price'] * 4.331802)
]);
Cnt::where('key', 'goldir_truly_buy_mazaneh')->update([
'value' => $lpGoldir['sub_agent']['rate_buy_price']
]);
Cnt::where('key', 'goldir_truly_sell_mazaneh')->update([
'value' => $lpGoldir['sub_agent']['rate_sell_price']
]);
Cnt::where('key', 'log')->update([
'value' => json_encode($goldir, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
]);
$open_sell = $toBool($lpGoldir['open_sell'] ?? false);
$open_buy = $toBool($lpGoldir['open_buy'] ?? false);
Cnt::where('key', 'goldir_open_sell')->update([
'value' => $open_sell ? "true" : "false"
]);
Cnt::where('key', 'goldir_open_buy')->update([
'value' => $open_buy ? "true" : "false"
]);
if ($open_sell || $open_buy) {
$goldir_price = (int) $customPrice['price'];
}
}
Cnt::where('key', 'goldir_closed')->update([
'value' => $goldir_price == 0 ? "true" : "false"
]);
} catch (\Throwable $e) {
$goldir_price = 0;
Cnt::where('key', 'goldir_closed')->update([
'value' => "true"
]);
}
}
/*
|--------------------------------------------------------------------------
| Main Product
|--------------------------------------------------------------------------
*/
if ($main_product_price == 'true' && !$closed) {
$main_product_id = Cnt::where('key', 'main_product')->value('value');
$pr_product = Product::find($main_product_id);
if ($pr_product) {
$pr_price = (float) $pr_product['price'] + (float) $pr_product['price_profit'];
}
}
/*
|--------------------------------------------------------------------------
| Taban Gohar
|--------------------------------------------------------------------------
*/
if ($taban_gohar_price == 'true' && !$closed) {
try {
$taban_gohar = Http::withOptions([
'curl' => [
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
CURLOPT_TCP_FASTOPEN => 1,
]
])
->withoutVerifying()
->timeout(2)
->get('https://tabangohar.com/GheymatKhan/prices_in_table.html')
->json();
$tgn = (int) $taban_gohar['c'] * 10;
} catch (\Throwable $e) {
$tgn = 0;
}
}
/*
|--------------------------------------------------------------------------
| انتخاب قیمت اصلی
| اولویت:
| Liman/Montpar -> Goldir -> Taban Gohar -> Main Product
|--------------------------------------------------------------------------
*/
if ($liman_price_enabled && ($liman_price ?? 0) !== 0 && !$closed) {
$priceValue = (int) $liman_price;
$priceSource = 'liman';
} elseif ($gold_ir_price == 'true' && ($goldir_price ?? 0) !== 0 && !$closed) {
$priceValue = (int) $goldir_price;
$priceSource = 'goldir';
} elseif ($taban_gohar_price == 'true' && ($tgn ?? 0) !== 0 && !$closed) {
$priceValue = $tgn;
$priceSource = 'taban_gohar';
} elseif ($main_product_price == 'true' && ($pr_price ?? 0) !== 0 && !$closed) {
$priceValue = $pr_price;
$priceSource = 'main_product';
} else {
$priceValue = 0;
$priceSource = null;
}
/*
|--------------------------------------------------------------------------
| اگر هیچ منبعی قیمت نداد، قیمت قبلی دیتابیس را برنگردان
|--------------------------------------------------------------------------
*/
if ($priceValue <= 0) {
\Log::warning('LAST_PRICE NO SOURCE PRICE', [
'liman_price' => $liman_price,
'goldir_price' => $goldir_price,
'taban_gohar' => $tgn,
'main_product' => $pr_price,
'price_source' => $priceSource,
]);
return [
'sell' => 0,
'buy' => 0,
'price_last' => 0,
'price' => 0,
'main_product' => $pr_price ?? 0,
'taban_gohar' => $tgn ?? 0,
'goldir' => $goldir_price ?? 0,
'liman' => $liman_price ?? 0,
'closed' => true,
'time' => now(),
];
}
/*
|--------------------------------------------------------------------------
| ذخیره قیمت
|--------------------------------------------------------------------------
*/
$lastPrice = Price::latest()->first();
if (
!$closed &&
(!$lastPrice || (float) $lastPrice->price != (float) $priceValue) &&
$priceValue > 30000000
) {
$price = new Price();
$price->price = $priceValue;
$price->time_at = Carbon::now()->toTimeString();
$price->date_at = Carbon::now()->toDateString();
$price->save();
$this->updatePrise();
$candle = PriceCandle::whereDate('date_at', date("Y-m-d"))->first();
if (!is_null($candle)) {
$candle->end = $priceValue;
if ($priceValue < $candle->low) {
$candle->low = $priceValue;
} elseif ($priceValue > $candle->high) {
$candle->high = $priceValue;
}
$candle->save();
} else {
PriceCandle::create([
"start" => $priceValue,
"end" => $priceValue,
"high" => $priceValue,
"low" => $priceValue,
"date_at" => date("Y-m-d")
]);
}
}
/*
|--------------------------------------------------------------------------
| محاسبه sell / buy با همان priceValue همین اجرای فعلی
|--------------------------------------------------------------------------
*/
if ($priceSource === 'liman') {
$liman_profit = (float) Cnt::where('key', 'liman_diff')->value('value');
$final_buy_diff = $diff_buy + $liman_profit;
$final_sell_diff = $diff_sell + $liman_profit;
$sell = $liman_open_sell
? ceil($priceValue - $final_sell_diff)
: 0;
$buy = $liman_open_buy
? ceil($priceValue + $final_buy_diff)
: 0;
$priceLast = ceil($priceValue + $final_buy_diff);
} else {
if ($priceSource === 'goldir' && $goldir_price !== 0) {
$goldir_profit = (float) Cnt::where('key', 'goldir_diff')->value('value');
$difference = $goldir_profit;
}
$sell = $open_sell
? ceil($priceValue - $difference)
: 0;
$buy = $open_buy
? ceil($priceValue + $difference)
: 0;
$priceLast = ceil($priceValue + $difference);
}
return [
'sell' => $sell,
'buy' => $buy,
'price_last' => $priceLast,
'price' => $priceValue,
'main_product' => $pr_price ?? 0,
'taban_gohar' => $tgn ?? 0,
'goldir' => $goldir_price ?? 0,
'liman' => $liman_price ?? 0,
'closed' => false,
'time' => now(),
];
}
public function check()
{
$service = Http::
withHeaders([
'accept' => 'application/json',
'Authorization' => 'Bearer ohxsrbjagqvbt0glaygt'
])->get('https://studio.persianapi.com/index.php/web-service/common/gold-currency-coin?format=json&limit=30&page=1')
->json();
$list = [];
if (isset($service['result'])) {
foreach ($service['result'] as $item) {
if ($item['key'] == 137120 || $item['key'] == 137119) {
$list[] = $item;
if ($item['key'] == 137120) {
(new PriceController())->store(new Request(["price" => $item['price']]));
}
}
}
Cnt::where('key', 'price')->update(['value_json' => $list]);
}
}
public function test()
{
$a = '{{12, 23, {4, 0, {1}, {1}}}, 0, {1}}';
$b = str_split($a);
$c = [];
$str = "";
foreach ($b as $item) {
if ($item != " ") {
print_r($item);
print_r('++');
if ($item == ',' || $item == '}') {
if (!in_array($c[count($c) - 1], ['{', '}'])) {
$c[count($c) - 1] += (int)$str;
print_r((int)$str);
print_r('^^');
} else {
$c[] = $str;
print_r($c);
print_r('&&');
}
$str = "";
} elseif (in_array($item, ['{', '}'])) {
$c[] = $item;
print_r($c);
print_r('**');
} else {
$str .= $item;
print_r($str);
print_r('@@');
}
}
}
dd($c);
$d = [];
$e = [];
foreach ($c as $item) {
if ($item == '}') {
print_r($d[count($d) - 1]);
print_r('***');
$e[] = $d[count($d) - 1];
} else {
$d[] = $item;
print_r($d);
print_r('-----');
}
}
dd($e);
}
}