<?php
 namespace App\Services\Store; use App\Jobs\SendEmailJob; use App\Models\Client; use App\Models\ClientProduct; use App\Models\ClientProductTrial; use App\Models\Product; class TrialService { public function isEligible(?Client $client, Product $product): bool { if ($product->trial_mode === 'none') { return false; } if (! $client) { return true; } return ! ClientProductTrial::where('client_id', $client->id) ->where('product_id', $product->id) ->exists(); } public function recordTrial(Client $client, Product $product, ClientProduct $clientProduct, string $mode): ClientProductTrial { $trial = ClientProductTrial::create([ 'client_id' => $client->id, 'product_id' => $product->id, 'client_product_id' => $clientProduct->id, 'trial_mode' => $mode, 'started_at' => now(), 'ends_at' => $mode === 'free' ? $clientProduct->trial_ends_at : null, 'status' => $mode === 'paid' ? 'converted' : 'active', ]); if ($mode === 'free') { try { $clientProduct->loadMissing(['product', 'client']); $currencyCode = $client->currency?->code ?? 'USD'; SendEmailJob::dispatch( 'Trial Started', 'client_product', $clientProduct->id, [ 'CLIENT_NAME' => trim($client->first_name . ' ' . $client->last_name), 'PRODUCT_NAME' => $product->name, 'TRIAL_ENDS_AT' => $clientProduct->trial_ends_at ? $clientProduct->trial_ends_at->format('Y-m-d') : '—', 'TRIAL_DAYS' => $product->trial_period_days ?? '—', 'RECURRING_AMOUNT' => number_format((float) $clientProduct->recurring_amount, 2) . ' ' . $currencyCode, 'RECURRING_CYCLE' => $clientProduct->billingcycle ?? 'monthly', ] ); } catch (\Throwable $e) { \Log::warning('PRC-539 trial_started email gönderilemedi', [ 'client_product_id' => $clientProduct->id, 'error' => $e->getMessage(), ]); } } return $trial; } public function resolvePostTrialPeriod(Product $product, ?string $customerChoice): string { return $customerChoice ?: $product->trial_default_period ?: 'monthly'; } public function applyPaidTrialDiscount(Product $product, float $amount, ?int $periodMonths = null): float { if ($product->trial_mode !== 'paid' || ! $product->trial_paid_discount_percent) { return $amount; } if ($periodMonths !== null && ! $this->paidDiscountAppliesToPeriod($product, $periodMonths)) { return $amount; } return round($amount * (1 - (float) $product->trial_paid_discount_percent / 100), 2); } public function paidDiscountAppliesToPeriod(Product $product, int $periodMonths): bool { $allowedPeriods = $product->trial_paid_discount_periods; if ($allowedPeriods === null) { return true; } if (! is_array($allowedPeriods) || empty($allowedPeriods)) { return false; } return in_array($periodMonths, array_map('intval', $allowedPeriods), true); } } 