Enable gated multi-level referral profit and harden chat/SMS notify paths.
Honor enable_customer_level_profit for order referral payouts, and tighten support-chat webhook/SMS plus SuperAdmin SMS panel sync settings. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -259,7 +259,7 @@ class SingleOrderController extends Controller
|
||||
report($e);
|
||||
}
|
||||
}
|
||||
// $response['reward'] = $this->give_order_reward($data, $wallet, $wallet_interface);
|
||||
$response['reward'] = $this->give_order_reward($data, $wallet, $wallet_interface);
|
||||
if ((int) $data['direction'] === 1 && $customer) {
|
||||
$referrer = Customer::where('referral_id', $customer->referral_to_id)->first();
|
||||
if (!empty($referrer) && $referrer->first_buy_order == 1 && $customer->first_buy_order !== 1) {
|
||||
@@ -810,64 +810,97 @@ class SingleOrderController extends Controller
|
||||
|
||||
private function give_order_reward(&$data, $wallet, $wallet_interface)
|
||||
{
|
||||
if (!app(\App\Services\ConfigService::class)->getBool('enable_customer_level_profit', false)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$serviceCharge = (float) ($data['order']['service_charge'] ?? 0);
|
||||
if ($serviceCharge <= 0) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$data['aCustomers'] = [];
|
||||
$i = 0;
|
||||
$data['aCustomers'][$i] = Customer::findOrFail($data['customer_id']);
|
||||
while ($data['aCustomers'][$i + 1] = Customer::where('referral_id', $data['aCustomers'][$i]->referral_to_id)->first()) {
|
||||
if ($data['aCustomers'][$i + 1]->profit_amount_by_lvl) {
|
||||
$levels = json_decode(str_replace(['{', '}'], ['[', ']'], $data['aCustomers'][$i + 1]->profit_amount_by_lvl), true);
|
||||
foreach ($levels as $level) {
|
||||
if ($level[0] == $i + 1) {
|
||||
// [$level[1],$data['aCustomers'][$i+1]];
|
||||
|
||||
if ($this->Config('has_page_earn_money') == true) {
|
||||
$gift_for_invite = ($data['order']['service_charge'] * $level[1]) / 100;
|
||||
$profit_receiver = $data['aCustomers'][$i + 1]->id;
|
||||
$profit_sender = $data['aCustomers'][0]->id;
|
||||
$Withdraw = Withdraw::create([
|
||||
'user_id' => $profit_sender,
|
||||
'customer_id' => $profit_receiver,
|
||||
"cash" => 0,
|
||||
"gold" => $gift_for_invite,
|
||||
'sts' => 9,
|
||||
]);
|
||||
$wallet_interface = new WalletInterface($profit_receiver, 2);
|
||||
new TransactionInterface($wallet_interface, $_inp = [
|
||||
"cash" => 0,
|
||||
"gold" => $gift_for_invite,
|
||||
'expire_at' => now(),
|
||||
'active' => true,
|
||||
'withdraw_id' => $Withdraw->id,
|
||||
'start_at' => now(),
|
||||
], 9, true, false);
|
||||
$transaction = Transaction::where('customer_id', $profit_receiver)->latest()->first();
|
||||
TransactionsAdmin::create([
|
||||
'customer_id' => $profit_sender,
|
||||
'customer_to_id' => $profit_receiver,
|
||||
'user_id' => $profit_sender,
|
||||
'order_id' => $data['order']['id'],
|
||||
'wallet' => null, // یا مقدار مناسب دیگری
|
||||
'transaction_id' => $transaction->id,
|
||||
'cash' => 0,
|
||||
'note' => ' سود بابت سفارش',
|
||||
'type' => 1, // یا مقدار مناسب دیگری
|
||||
'gold' => $gift_for_invite,
|
||||
'balance_cash' => 0, // یا مقدار مناسب دیگری
|
||||
'balance_gold' => $gift_for_invite, // مقدار صحیح برای `balance_gold`
|
||||
'withdraw_id' => $Withdraw->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
$levels = $this->parseProfitAmountByLevel($data['aCustomers'][$i + 1]->profit_amount_by_lvl);
|
||||
foreach ($levels as $levelRow) {
|
||||
$levelNo = (int) ($levelRow['level'] ?? $levelRow[0] ?? 0);
|
||||
$percent = (float) ($levelRow['present'] ?? $levelRow[1] ?? 0);
|
||||
if ($levelNo !== ($i + 1) || $percent <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$gift_for_invite = ($serviceCharge * $percent) / 100;
|
||||
if ($gift_for_invite <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$profit_receiver = $data['aCustomers'][$i + 1]->id;
|
||||
$profit_sender = $data['aCustomers'][0]->id;
|
||||
$Withdraw = Withdraw::create([
|
||||
'user_id' => $profit_sender,
|
||||
'customer_id' => $profit_receiver,
|
||||
'cash' => 0,
|
||||
'gold' => $gift_for_invite,
|
||||
'sts' => 9,
|
||||
]);
|
||||
$wallet_interface = new WalletInterface($profit_receiver, 2);
|
||||
new TransactionInterface($wallet_interface, [
|
||||
'cash' => 0,
|
||||
'gold' => $gift_for_invite,
|
||||
'expire_at' => now(),
|
||||
'active' => true,
|
||||
'withdraw_id' => $Withdraw->id,
|
||||
'start_at' => now(),
|
||||
], 9, true, false);
|
||||
$transaction = Transaction::where('customer_id', $profit_receiver)->latest()->first();
|
||||
TransactionsAdmin::create([
|
||||
'customer_id' => $profit_sender,
|
||||
'customer_to_id' => $profit_receiver,
|
||||
'user_id' => $profit_sender,
|
||||
'order_id' => $data['order']['id'],
|
||||
'wallet' => null,
|
||||
'transaction_id' => $transaction->id,
|
||||
'cash' => 0,
|
||||
'note' => ' سود بابت سفارش',
|
||||
'type' => 1,
|
||||
'gold' => $gift_for_invite,
|
||||
'balance_cash' => 0,
|
||||
'balance_gold' => $gift_for_invite,
|
||||
'withdraw_id' => $Withdraw->id,
|
||||
]);
|
||||
}
|
||||
if ($i == 100) break;
|
||||
$i++; // برای جلوگیری از حلقه بینهایت
|
||||
if ($i == 100) {
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/** @return list<array{level?:int,present?:float}|array{0:int,1:float}> */
|
||||
private function parseProfitAmountByLevel(mixed $raw): array
|
||||
{
|
||||
if (is_array($raw)) {
|
||||
return $raw;
|
||||
}
|
||||
if (!is_string($raw) || trim($raw) === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
$decoded = json_decode($raw, true);
|
||||
if (is_array($decoded)) {
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
// فرمت قدیمی: رشته شبیه {1,5},{2,2}
|
||||
$legacy = json_decode(str_replace(['{', '}'], ['[', ']'], $raw), true);
|
||||
|
||||
return is_array($legacy) ? $legacy : [];
|
||||
}
|
||||
|
||||
private function sendTransactionNotifications(array $data, string $transactionType)
|
||||
{
|
||||
$customer = Customer::findOrFail($data['customer_id']);
|
||||
@@ -880,8 +913,9 @@ class SingleOrderController extends Controller
|
||||
$totalPrice = $data['total_price'] ?? ($data['payment_amount'] ?? 0);
|
||||
$subjectTitle = $this->transactionSubjectTitle($data);
|
||||
|
||||
$amountLabel = self::formatSmsGoldWeight($amount);
|
||||
$message = "کاربر {$customer->name} با شماره موبایل {$customer->mobile} اقدام به $transactionType {$subjectTitle} به مقدار " .
|
||||
"{$amount} گرم به مبلغ " . number_format($totalPrice) .
|
||||
"{$amountLabel} گرم به مبلغ " . number_format($totalPrice) .
|
||||
" ریال کرد. با تشکر، $companyName";
|
||||
if (self::isSmsNotifEnabled('sms_notif_order_admin')) {
|
||||
User::where('send_sms', 1)->get()->each(function ($admin) use ($message) {
|
||||
@@ -895,9 +929,10 @@ class SingleOrderController extends Controller
|
||||
$balanceLabel = self::metalTypeLabel();
|
||||
$goldBalance = $wallet ? ($wallet->gold ?? 0) : 0;
|
||||
$cashBalance = $wallet ? ($wallet->cash ?? 0) : 0;
|
||||
$customerMessage = "$companyName\n$transactionType {$subjectTitle}\nگرم: {$amount}\n" .
|
||||
$goldBalanceLabel = self::formatSmsGoldWeight($goldBalance);
|
||||
$customerMessage = "$companyName\n$transactionType {$subjectTitle}\nگرم: {$amountLabel}\n" .
|
||||
"مبلغ کل: " . number_format($totalPrice) . "\n\n" .
|
||||
"موجودی {$balanceLabel}: {$goldBalance}\n" .
|
||||
"موجودی {$balanceLabel}: {$goldBalanceLabel}\n" .
|
||||
"مانده ریالی: " . number_format($cashBalance) . "\n" .
|
||||
self::publicSiteUrl(request());
|
||||
|
||||
@@ -1036,7 +1071,7 @@ class SingleOrderController extends Controller
|
||||
$userMobile = $customer->mobile; // User's mobile number
|
||||
$userName = $customer->name; // User's name
|
||||
$chargedAmount = $data['total_price']; // Total price in Rial
|
||||
$chargedAmountGold = $data['amount']; // Amount of gold
|
||||
$chargedAmountGold = self::formatSmsGoldWeight($data['amount']); // Amount of gold
|
||||
|
||||
// Company name
|
||||
$companyName = $this->Config('name_fa'); // Company name from configuration
|
||||
@@ -1055,15 +1090,16 @@ class SingleOrderController extends Controller
|
||||
->main()
|
||||
->first();
|
||||
$companyurl = self::publicSiteUrl(request());
|
||||
$weight = $data['amount'];
|
||||
$weight = (float) $data['amount'];
|
||||
$weightLabel = self::formatSmsGoldWeight($weight);
|
||||
$totalAmount = $data['total_price'];
|
||||
$pricePerGram = $weight > 0 ? $totalAmount / $weight : 0;
|
||||
$goldBalance = $mainWallet->gold ?? 0;
|
||||
$goldBalance = self::formatSmsGoldWeight($mainWallet->gold ?? 0);
|
||||
$remainingBalance = $mainWallet->cash ?? 0;
|
||||
|
||||
$message = "$companyName\n";
|
||||
$message .= "خرید آبشده\n";
|
||||
$message .= "گرم: $weight\n";
|
||||
$message .= "گرم: $weightLabel\n";
|
||||
$message .= "قیمت گرم: " . number_format($pricePerGram) . "\n";
|
||||
$message .= "مبلغ کل: " . number_format($totalAmount) . "\n\n";
|
||||
$message .= "موجودی طلایی: $goldBalance\n";
|
||||
@@ -1110,6 +1146,28 @@ class SingleOrderController extends Controller
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* مقدار ضربشونده در قیمت واحد برای مبلغ سفارش.
|
||||
* قیمت فرمولی = قیمت هر عدد (وزن داخل فرمول است) → فقط تعداد.
|
||||
* بقیه = تعداد × وزن واحد محصول.
|
||||
*/
|
||||
private function resolveProductOrderPricingAmount(Product|array|null $product, float $number): float
|
||||
{
|
||||
if ($product instanceof Product && FormulaPriceService::isEnabled($product)) {
|
||||
return $number;
|
||||
}
|
||||
|
||||
if (is_array($product) && ! empty($product['price_formula_enabled'])) {
|
||||
return $number;
|
||||
}
|
||||
|
||||
$unitAmount = $product instanceof Product
|
||||
? (float) ($product->amount ?? 0)
|
||||
: (float) (is_array($product) ? ($product['amount'] ?? 0) : 0);
|
||||
|
||||
return $number * $unitAmount;
|
||||
}
|
||||
|
||||
private function assertMinimumSellCash(array $data): void
|
||||
{
|
||||
$minSell = Setting::where('key', 'minimum_sell')->where('is_active', 1)->first();
|
||||
|
||||
Reference in New Issue
Block a user