Refactor for v3 subs

This commit is contained in:
David Bomba 2024-11-13 21:50:18 +11:00
parent 77e7cb0fde
commit df5988939b
19 changed files with 234 additions and 106 deletions

View File

@ -12,17 +12,21 @@
namespace App\Livewire\BillingPortal\Authentication; namespace App\Livewire\BillingPortal\Authentication;
use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject;
use App\Mail\Subscription\OtpCode;
use App\Models\ClientContact;
use App\Models\Subscription;
use Illuminate\Support\Facades\Cache;
use Livewire\Component; use Livewire\Component;
use App\Models\Subscription;
use App\Models\ClientContact;
use App\Utils\Traits\MakesHash;
use App\Jobs\Mail\NinjaMailerJob;
use Livewire\Attributes\Computed;
use App\Mail\Subscription\OtpCode;
use App\Jobs\Mail\NinjaMailerObject;
use Illuminate\Support\Facades\Cache;
class Login extends Component class Login extends Component
{ {
public Subscription $subscription; use MakesHash;
public string $subscription_id;
public array $context; public array $context;
@ -39,12 +43,18 @@ class Login extends Component
'initial_completed' => false, 'initial_completed' => false,
]; ];
#[Computed]
public function subscription()
{
return Subscription::find($this->decodePrimaryKey($this->subscription_id));
}
public function initial() public function initial()
{ {
$this->validateOnly('email', ['email' => 'required|bail|email:rfc|email']); $this->validateOnly('email', ['email' => 'required|bail|email:rfc|email']);
$contact = ClientContact::where('email', $this->email) $contact = ClientContact::where('email', $this->email)
->where('company_id', $this->subscription->company_id) ->where('company_id', $this->subscription()->company_id)
->first(); ->first();
if ($contact === null) { if ($contact === null) {
@ -65,7 +75,7 @@ class Login extends Component
public function withPassword() public function withPassword()
{ {
$contact = ClientContact::where('email', $this->email) $contact = ClientContact::where('email', $this->email)
->where('company_id', $this->subscription->company_id) ->where('company_id', $this->subscription()->company_id)
->first(); ->first();
if ($contact) { if ($contact) {
@ -93,9 +103,9 @@ class Login extends Component
$cc->email = $this->email; $cc->email = $this->email;
$nmo = new NinjaMailerObject(); $nmo = new NinjaMailerObject();
$nmo->mailable = new OtpCode($this->subscription->company, $this->context['contact'] ?? null, $code); $nmo->mailable = new OtpCode($this->subscription()->company, $this->context['contact'] ?? null, $code);
$nmo->company = $this->subscription->company; $nmo->company = $this->subscription()->company;
$nmo->settings = $this->subscription->company->settings; $nmo->settings = $this->subscription()->company->settings;
$nmo->to_user = $cc; $nmo->to_user = $cc;
NinjaMailerJob::dispatch($nmo); NinjaMailerJob::dispatch($nmo);
@ -124,7 +134,7 @@ class Login extends Component
} }
$contact = ClientContact::where('email', $this->email) $contact = ClientContact::where('email', $this->email)
->where('company_id', $this->subscription->company_id) ->where('company_id', $this->subscription()->company_id)
->first(); ->first();
if ($contact) { if ($contact) {
@ -147,7 +157,7 @@ class Login extends Component
$attempt = auth()->guard('contact')->attempt([ $attempt = auth()->guard('contact')->attempt([
'email' => $this->email, 'email' => $this->email,
'password' => $this->password, 'password' => $this->password,
'company_id' => $this->subscription->company_id, 'company_id' => $this->subscription()->company_id,
]); ]);
if ($attempt) { if ($attempt) {
@ -165,6 +175,7 @@ class Login extends Component
$this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user()); $this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user());
$this->dispatch('purchase.next'); $this->dispatch('purchase.next');
} }
} }
public function render(): \Illuminate\View\View public function render(): \Illuminate\View\View

View File

@ -12,14 +12,18 @@
namespace App\Livewire\BillingPortal\Authentication; namespace App\Livewire\BillingPortal\Authentication;
use Illuminate\Support\Facades\Validator;
use Livewire\Component; use Livewire\Component;
use App\Models\Subscription; use App\Models\Subscription;
use App\Models\ClientContact; use App\Models\ClientContact;
use App\Utils\Traits\MakesHash;
use Livewire\Attributes\Computed;
use Illuminate\Support\Facades\Validator;
class Register extends Component class Register extends Component
{ {
public Subscription $subscription; use MakesHash;
public string $subscription_id;
public array $context; public array $context;
@ -29,6 +33,8 @@ class Register extends Component
public ?int $otp; public ?int $otp;
public array $formData = [];
public array $state = [ public array $state = [
'initial_completed' => false, 'initial_completed' => false,
'register_form' => false, 'register_form' => false,
@ -38,12 +44,19 @@ class Register extends Component
public array $additional_fields = []; public array $additional_fields = [];
#[Computed()]
public function subscription()
{
return Subscription::find($this->decodePrimaryKey($this->subscription_id))->withoutRelations()->makeHidden(['webhook_configuration','steps']);
}
public function initial(): void public function initial(): void
{ {
$this->validateOnly('email', ['email' => 'required|bail|email:rfc']); $this->validateOnly('email', ['email' => 'required|bail|email:rfc']);
$contact = ClientContact::where('email', $this->email) $contact = ClientContact::where('email', $this->email)
->where('company_id', $this->subscription->company_id) ->where('company_id', $this->subscription()->company_id)
->first(); ->first();
if ($contact) { if ($contact) {
@ -59,13 +72,19 @@ class Register extends Component
public function register(array $data) public function register(array $data)
{ {
$data = array_merge($data, [
'country_id' => $this->formData['country_id'] ?? null,
'shipping_country_id' => $this->formData['shipping_country_id'] ?? null,
]);
$service = new ClientRegisterService( $service = new ClientRegisterService(
company: $this->subscription->company, company: $this->subscription()->company,
additional: $this->additional_fields, additional: $this->additional_fields,
); );
$rules = $service->rules(); $rules = $service->rules();
$data = Validator::make($data, $rules)->validate(); $data = Validator::make($data, $rules)->validate();
$client = $service->createClient($data); $client = $service->createClient($data);
@ -79,13 +98,13 @@ class Register extends Component
public function registerForm() public function registerForm()
{ {
$count = collect($this->subscription->company->client_registration_fields ?? []) $count = collect($this->subscription()->company->client_registration_fields ?? [])
->filter(fn ($field) => $field['required'] === true || $field['visible'] === true) ->filter(fn ($field) => $field['required'] === true || $field['visible'] === true)
->count(); ->count();
if ($count === 0) { if ($count === 0) {
$service = new ClientRegisterService( $service = new ClientRegisterService(
company: $this->subscription->company, company: $this->subscription()->company,
); );
$client = $service->createClient([]); $client = $service->createClient([]);
@ -99,9 +118,9 @@ class Register extends Component
return; return;
} }
$this->register_fields = [...collect($this->subscription->company->client_registration_fields ?? [])->toArray()]; $this->register_fields = [...collect($this->subscription()->company->client_registration_fields ?? [])->toArray()];
$first_gateway = collect($this->subscription->company->company_gateways()->withoutTrashed()->get()) $first_gateway = collect($this->subscription()->company->company_gateways()->withoutTrashed()->get())
->sortBy('sort_order') ->sortBy('sort_order')
->first(); ->first();
@ -145,6 +164,7 @@ class Register extends Component
$this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user()); $this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user());
$this->dispatch('purchase.next'); $this->dispatch('purchase.next');
} }
} }
public function render() public function render()

View File

@ -12,18 +12,22 @@
namespace App\Livewire\BillingPortal\Authentication; namespace App\Livewire\BillingPortal\Authentication;
use Illuminate\Support\Facades\Validator;
use Livewire\Component; use Livewire\Component;
use App\Models\Subscription; use App\Models\Subscription;
use App\Models\ClientContact; use App\Models\ClientContact;
use App\Utils\Traits\MakesHash;
use App\Jobs\Mail\NinjaMailerJob; use App\Jobs\Mail\NinjaMailerJob;
use Livewire\Attributes\Computed;
use App\Mail\Subscription\OtpCode; use App\Mail\Subscription\OtpCode;
use App\Jobs\Mail\NinjaMailerObject; use App\Jobs\Mail\NinjaMailerObject;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
class RegisterOrLogin extends Component class RegisterOrLogin extends Component
{ {
public Subscription $subscription; use MakesHash;
public string $subscription_id;
public array $context; public array $context;
@ -33,6 +37,8 @@ class RegisterOrLogin extends Component
public ?int $otp; public ?int $otp;
public array $formData = [];
public array $state = [ public array $state = [
'otp' => false, // Use as preference. E-mail/password or OTP. 'otp' => false, // Use as preference. E-mail/password or OTP.
'login_form' => false, 'login_form' => false,
@ -45,6 +51,12 @@ class RegisterOrLogin extends Component
public array $additional_fields = []; public array $additional_fields = [];
#[Computed]
public function subscription()
{
return Subscription::find($this->decodePrimaryKey($this->subscription_id));
}
public function initial() public function initial()
{ {
$this->validateOnly('email', ['email' => 'required|bail|email:rfc']); $this->validateOnly('email', ['email' => 'required|bail|email:rfc']);
@ -61,7 +73,7 @@ class RegisterOrLogin extends Component
public function withPassword() public function withPassword()
{ {
$contact = ClientContact::where('email', $this->email) $contact = ClientContact::where('email', $this->email)
->where('company_id', $this->subscription->company_id) ->where('company_id', $this->subscription()->company_id)
->first(); ->first();
if ($contact) { if ($contact) {
@ -82,7 +94,7 @@ class RegisterOrLogin extends Component
$attempt = auth()->guard('contact')->attempt([ $attempt = auth()->guard('contact')->attempt([
'email' => $this->email, 'email' => $this->email,
'password' => $this->password, 'password' => $this->password,
'company_id' => $this->subscription->company_id, 'company_id' => $this->subscription()->company_id,
]); ]);
if ($attempt) { if ($attempt) {
@ -95,7 +107,7 @@ class RegisterOrLogin extends Component
public function withOtp(): void public function withOtp(): void
{ {
$contact = ClientContact::where('email', $this->email) $contact = ClientContact::where('email', $this->email)
->where('company_id', $this->subscription->company_id) ->where('company_id', $this->subscription()->company_id)
->first(); ->first();
if ($contact === null) { if ($contact === null) {
@ -113,9 +125,9 @@ class RegisterOrLogin extends Component
$cc->email = $this->email; $cc->email = $this->email;
$nmo = new NinjaMailerObject(); $nmo = new NinjaMailerObject();
$nmo->mailable = new OtpCode($this->subscription->company, $this->context['contact'] ?? null, $code); $nmo->mailable = new OtpCode($this->subscription()->company, $this->context['contact'] ?? null, $code);
$nmo->company = $this->subscription->company; $nmo->company = $this->subscription()->company;
$nmo->settings = $this->subscription->company->settings; $nmo->settings = $this->subscription()->company->settings;
$nmo->to_user = $cc; $nmo->to_user = $cc;
NinjaMailerJob::dispatch($nmo); NinjaMailerJob::dispatch($nmo);
@ -143,7 +155,7 @@ class RegisterOrLogin extends Component
} }
$contact = ClientContact::where('email', $this->email) $contact = ClientContact::where('email', $this->email)
->where('company_id', $this->subscription->company_id) ->where('company_id', $this->subscription()->company_id)
->first(); ->first();
if ($contact) { if ($contact) {
@ -161,11 +173,19 @@ class RegisterOrLogin extends Component
public function register(array $data): void public function register(array $data): void
{ {
$data = array_merge($data, [
'country_id' => $this->formData['country_id'] ?? null,
'shipping_country_id' => $this->formData['shipping_country_id'] ?? null,
]);
$service = new ClientRegisterService( $service = new ClientRegisterService(
company: $this->subscription->company, company: $this->subscription()->company,
additional: $this->additional_fields, additional: $this->additional_fields,
); );
nlog($data);
$rules = $service->rules(); $rules = $service->rules();
$data = Validator::make($data, $rules)->validate(); $data = Validator::make($data, $rules)->validate();
@ -180,13 +200,13 @@ class RegisterOrLogin extends Component
public function registerForm() public function registerForm()
{ {
$count = collect($this->subscription->company->client_registration_fields ?? []) $count = collect($this->subscription()->company->client_registration_fields ?? [])
->filter(fn ($field) => $field['required'] === true || $field['visible'] === true) ->filter(fn ($field) => $field['required'] === true || $field['visible'] === true)
->count(); ->count();
if ($count === 0) { if ($count === 0) {
$service = new ClientRegisterService( $service = new ClientRegisterService(
company: $this->subscription->company, company: $this->subscription()->company,
); );
$client = $service->createClient([]); $client = $service->createClient([]);
@ -200,9 +220,9 @@ class RegisterOrLogin extends Component
return; return;
} }
$this->register_fields = [...collect($this->subscription->company->client_registration_fields ?? [])->toArray()]; $this->register_fields = [...collect($this->subscription()->company->client_registration_fields ?? [])->toArray()];
$first_gateway = collect($this->subscription->company->company_gateways()->withoutTrashed()->get()) $first_gateway = collect($this->subscription()->company->company_gateways()->withoutTrashed()->get())
->sortBy('sort_order') ->sortBy('sort_order')
->first(); ->first();
@ -242,6 +262,7 @@ class RegisterOrLogin extends Component
public function mount() public function mount()
{ {
if (auth()->guard('contact')->check()) { if (auth()->guard('contact')->check()) {
$this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user()); $this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user());
$this->dispatch('purchase.next'); $this->dispatch('purchase.next');

View File

@ -12,16 +12,26 @@
namespace App\Livewire\BillingPortal\Cart; namespace App\Livewire\BillingPortal\Cart;
use Livewire\Component;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Subscription; use App\Models\Subscription;
use Livewire\Component; use App\Utils\Traits\MakesHash;
use Livewire\Attributes\Computed;
class Cart extends Component class Cart extends Component
{ {
public Subscription $subscription; use MakesHash;
public array $context; public array $context;
public string $subscription_id;
#[Computed()]
public function subscription()
{
return Subscription::find($this->decodePrimaryKey($this->subscription_id))->withoutRelations()->makeHidden(['webhook_configuration','steps']);
}
public function handleSubmit() public function handleSubmit()
{ {
$this->dispatch('purchase.next'); $this->dispatch('purchase.next');

View File

@ -12,15 +12,25 @@
namespace App\Livewire\BillingPortal\Cart; namespace App\Livewire\BillingPortal\Cart;
use App\Models\Subscription;
use Livewire\Component; use Livewire\Component;
use App\Models\Subscription;
use App\Utils\Traits\MakesHash;
use Livewire\Attributes\Computed;
class OneTimeProducts extends Component class OneTimeProducts extends Component
{ {
public Subscription $subscription; use MakesHash;
public array $context; public array $context;
public string $subscription_id;
#[Computed()]
public function subscription()
{
return Subscription::find($this->decodePrimaryKey($this->subscription_id))->withoutRelations()->makeHidden(['webhook_configuration','steps']);
}
public function quantity($id, $value): void public function quantity($id, $value): void
{ {
$this->dispatch('purchase.context', property: "bundle.one_time_products.{$id}.quantity", value: $value); $this->dispatch('purchase.context', property: "bundle.one_time_products.{$id}.quantity", value: $value);

View File

@ -12,15 +12,22 @@
namespace App\Livewire\BillingPortal\Cart; namespace App\Livewire\BillingPortal\Cart;
use App\Models\Subscription;
use Livewire\Component; use Livewire\Component;
use App\Models\Subscription;
use Livewire\Attributes\Computed;
class OptionalOneTimeProducts extends Component class OptionalOneTimeProducts extends Component
{ {
public Subscription $subscription;
public array $context; public array $context;
public string $subscription_id;
#[Computed()]
public function subscription()
{
return Subscription::find($this->decodePrimaryKey($this->subscription_id))->withoutRelations()->makeHidden(['webhook_configuration','steps']);
}
public function quantity($id, $value): void public function quantity($id, $value): void
{ {
$this->dispatch('purchase.context', property: "bundle.optional_one_time_products.{$id}.quantity", value: $value); $this->dispatch('purchase.context', property: "bundle.optional_one_time_products.{$id}.quantity", value: $value);

View File

@ -12,15 +12,23 @@
namespace App\Livewire\BillingPortal\Cart; namespace App\Livewire\BillingPortal\Cart;
use App\Models\Subscription;
use Livewire\Component; use Livewire\Component;
use App\Models\Subscription;
use Livewire\Attributes\Computed;
class OptionalRecurringProducts extends Component class OptionalRecurringProducts extends Component
{ {
public Subscription $subscription;
public array $context; public array $context;
public string $subscription_id;
#[Computed()]
public function subscription()
{
return Subscription::find($this->decodePrimaryKey($this->subscription_id))->withoutRelations()->makeHidden(['webhook_configuration','steps']);
}
public function quantity($id, $value): void public function quantity($id, $value): void
{ {

View File

@ -12,14 +12,21 @@
namespace App\Livewire\BillingPortal\Cart; namespace App\Livewire\BillingPortal\Cart;
use App\Models\Subscription;
use Livewire\Component; use Livewire\Component;
use App\Models\Subscription;
use Livewire\Attributes\Computed;
class RecurringProducts extends Component class RecurringProducts extends Component
{ {
public array $context; public array $context;
public Subscription $subscription; public string $subscription_id;
#[Computed()]
public function subscription()
{
return Subscription::find($this->decodePrimaryKey($this->subscription_id))->withoutRelations()->makeHidden(['webhook_configuration','steps']);
}
public function quantity($id, $value): void public function quantity($id, $value): void
{ {

View File

@ -14,11 +14,14 @@ namespace App\Livewire\BillingPortal\Payments;
use Livewire\Component; use Livewire\Component;
use App\Models\Subscription; use App\Models\Subscription;
use App\Utils\Traits\MakesHash;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
class Methods extends Component class Methods extends Component
{//@todo this breaks down when the cart is in front of the login - we have no context on the user - nor their country/currency {
public Subscription $subscription; use MakesHash;
public string $subscription_id;
public array $context; public array $context;
@ -26,10 +29,17 @@ class Methods extends Component
public function mount(): void public function mount(): void
{ {
nlog($this->subscription_id);
$total = collect($this->context['products'])->sum('total_raw'); $total = collect($this->context['products'])->sum('total_raw');
$methods = auth()->guard('contact')->user()->client->service()->getPaymentMethods($total); //@todo this breaks down when the cart is in front of the login - we have no context on the user - nor their country/currency() $methods = auth()->guard('contact')->user()->client->service()->getPaymentMethods($total); //@todo this breaks down when the cart is in front of the login - we have no context on the user - nor their country/currency()
$this->methods = $methods; $this->methods = $methods;
nlog($methods);
} }
public function handleSelect(string $company_gateway_id, string $gateway_type_id) public function handleSelect(string $company_gateway_id, string $gateway_type_id)
@ -37,11 +47,13 @@ class Methods extends Component
/** @var \App\Models\ClientContact $contact */ /** @var \App\Models\ClientContact $contact */
$contact = auth()->guard('contact')->user(); $contact = auth()->guard('contact')->user();
$sub = Subscription::find($this->decodePrimaryKey($this->subscription_id));
$this->dispatch('purchase.context', property: 'client_id', value: $contact->client->hashed_id); $this->dispatch('purchase.context', property: 'client_id', value: $contact->client->hashed_id);
$this->context['client_id'] = $contact->client->hashed_id; $this->context['client_id'] = $contact->client->hashed_id;
$invoice = $this->subscription $invoice = $sub
->calc() ->calc()
->buildPurchaseInvoice($this->context) ->buildPurchaseInvoice($this->context)
->service() ->service()
@ -51,7 +63,7 @@ class Methods extends Component
->save(); ->save();
Cache::put($this->context['hash'], [ Cache::put($this->context['hash'], [
'subscription_id' => $this->subscription->hashed_id, 'subscription_id' => $sub->hashed_id,
'email' => $contact->email, 'email' => $contact->email,
'client_id' => $contact->client->hashed_id, 'client_id' => $contact->client->hashed_id,
'invoice_id' => $invoice->hashed_id, 'invoice_id' => $invoice->hashed_id,

View File

@ -19,6 +19,7 @@ use App\Livewire\BillingPortal\Authentication\RegisterOrLogin;
use App\Livewire\BillingPortal\Cart\Cart; use App\Livewire\BillingPortal\Cart\Cart;
use App\Livewire\BillingPortal\Payments\Methods; use App\Livewire\BillingPortal\Payments\Methods;
use App\Models\Subscription; use App\Models\Subscription;
use App\Utils\Traits\MakesHash;
use Livewire\Attributes\Computed; use Livewire\Attributes\Computed;
use Livewire\Attributes\On; use Livewire\Attributes\On;
use Livewire\Component; use Livewire\Component;
@ -26,7 +27,11 @@ use Illuminate\Support\Str;
class Purchase extends Component class Purchase extends Component
{ {
public Subscription $subscription; use MakesHash;
private $sub;
public string $subscription_id;
public string $db; public string $db;
@ -36,8 +41,6 @@ class Purchase extends Component
public ?string $campaign; public ?string $campaign;
//
public int $step = 0; public int $step = 0;
public string $id; public string $id;
@ -72,9 +75,6 @@ class Purchase extends Component
data_set($this->context, $property, $value); data_set($this->context, $property, $value);
// The following may not be needed, as we can pass arround $context.
// cache()->set($this->hash, $this->context);
if ($clone !== $this->context) { if ($clone !== $this->context) {
$this->id = Str::uuid(); $this->id = Str::uuid();
} }
@ -117,6 +117,13 @@ class Purchase extends Component
return "summary-{$this->id}"; return "summary-{$this->id}";
} }
#[Computed()]
public function subscription()
{
return Subscription::find($this->decodePrimaryKey($this->subscription_id))->withoutRelations()->makeHidden(['webhook_configuration','steps']);
}
public static function defaultSteps() public static function defaultSteps()
{ {
return [ return [
@ -129,8 +136,12 @@ class Purchase extends Component
{ {
$classes = collect(self::$dependencies)->mapWithKeys(fn ($dependency, $class) => [$dependency['id'] => $class])->toArray(); $classes = collect(self::$dependencies)->mapWithKeys(fn ($dependency, $class) => [$dependency['id'] => $class])->toArray();
if ($this->subscription->steps) { MultiDB::setDb($this->db);
$steps = collect(explode(',', $this->subscription->steps))
$this->sub = Subscription::find($this->decodePrimaryKey($this->subscription_id));
if ($this->sub->steps) {
$steps = collect(explode(',', $this->sub->steps))
->map(fn ($step) => $classes[$step]) ->map(fn ($step) => $classes[$step])
->toArray(); ->toArray();

View File

@ -15,18 +15,29 @@ namespace App\Livewire\BillingPortal;
use App\Models\RecurringInvoice; use App\Models\RecurringInvoice;
use App\Models\Subscription; use App\Models\Subscription;
use App\Utils\Number; use App\Utils\Number;
use App\Utils\Traits\MakesHash;
use Livewire\Attributes\Computed; use Livewire\Attributes\Computed;
use Livewire\Attributes\On; use Livewire\Attributes\On;
use Livewire\Component; use Livewire\Component;
class Summary extends Component class Summary extends Component
{ {
public Subscription $subscription; use MakesHash;
public string $subscription_id;
public array $context; public array $context;
#[Computed()]
public function subscription()
{
return Subscription::find($this->decodePrimaryKey($this->subscription_id))->withoutRelations()->makeHidden(['webhook_configuration','steps']);
}
public function mount() public function mount()
{ {
$subscription = Subscription::find($this->decodePrimaryKey($this->subscription_id));
$bundle = $this->context['bundle'] ?? [ $bundle = $this->context['bundle'] ?? [
'recurring_products' => [], 'recurring_products' => [],
'optional_recurring_products' => [], 'optional_recurring_products' => [],
@ -34,7 +45,7 @@ class Summary extends Component
'optional_one_time_products' => [], 'optional_one_time_products' => [],
]; ];
foreach ($this->subscription->service()->recurring_products() as $key => $product) { foreach ($subscription->service()->recurring_products() as $key => $product) {
$bundle['recurring_products'][$product->hashed_id] = [ $bundle['recurring_products'][$product->hashed_id] = [
'product' => $product, 'product' => $product,
'quantity' => $bundle['recurring_products'][$product->hashed_id]['quantity'] ?? 1, 'quantity' => $bundle['recurring_products'][$product->hashed_id]['quantity'] ?? 1,
@ -43,7 +54,7 @@ class Summary extends Component
$bundle['recurring_products'][$product->hashed_id]['product']['is_recurring'] = true; $bundle['recurring_products'][$product->hashed_id]['product']['is_recurring'] = true;
} }
foreach ($this->subscription->service()->products() as $key => $product) { foreach ($subscription->service()->products() as $key => $product) {
$bundle['one_time_products'][$product->hashed_id] = [ $bundle['one_time_products'][$product->hashed_id] = [
'product' => $product, 'product' => $product,
'quantity' => $bundle['one_time_products'][$product->hashed_id]['quantity'] ?? 1, 'quantity' => $bundle['one_time_products'][$product->hashed_id]['quantity'] ?? 1,
@ -52,7 +63,7 @@ class Summary extends Component
$bundle['one_time_products'][$product->hashed_id]['product']['is_recurring'] = false; $bundle['one_time_products'][$product->hashed_id]['product']['is_recurring'] = false;
} }
foreach ($this->subscription->service()->optional_recurring_products() as $key => $product) { foreach ($subscription->service()->optional_recurring_products() as $key => $product) {
$bundle['optional_recurring_products'][$product->hashed_id] = [ $bundle['optional_recurring_products'][$product->hashed_id] = [
'product' => $product, 'product' => $product,
'quantity' => $bundle['optional_recurring_products'][$product->hashed_id]['quantity'] ?? 0, 'quantity' => $bundle['optional_recurring_products'][$product->hashed_id]['quantity'] ?? 0,
@ -61,7 +72,7 @@ class Summary extends Component
$bundle['optional_recurring_products'][$product->hashed_id]['product']['is_recurring'] = true; $bundle['optional_recurring_products'][$product->hashed_id]['product']['is_recurring'] = true;
} }
foreach ($this->subscription->service()->optional_products() as $key => $product) { foreach ($subscription->service()->optional_products() as $key => $product) {
$bundle['optional_one_time_products'][$product->hashed_id] = [ $bundle['optional_one_time_products'][$product->hashed_id] = [
'product' => $product, 'product' => $product,
'quantity' => $bundle['optional_one_time_products'][$product->hashed_id]['quantity'] ?? 0, 'quantity' => $bundle['optional_one_time_products'][$product->hashed_id]['quantity'] ?? 0,
@ -91,7 +102,7 @@ class Summary extends Component
return $one_time + $one_time_optional; return $one_time + $one_time_optional;
} }
return Number::formatMoney($one_time + $one_time_optional, $this->subscription->company); return Number::formatMoney($one_time + $one_time_optional, $this->subscription()->company);
} }
@ -115,8 +126,8 @@ class Summary extends Component
return \sprintf( return \sprintf(
'%s/%s', '%s/%s',
Number::formatMoney($recurring + $recurring_optional, $this->subscription->company), Number::formatMoney($recurring + $recurring_optional, $this->subscription()->company),
RecurringInvoice::frequencyForKey($this->subscription->frequency_id ?? 0) RecurringInvoice::frequencyForKey($this->subscription()->frequency_id ?? 0)
); );
} }
@ -128,7 +139,7 @@ class Summary extends Component
$this->oneTimePurchasesTotal(raw: true), $this->oneTimePurchasesTotal(raw: true),
$this->recurringPurchasesTotal(raw: true), $this->recurringPurchasesTotal(raw: true),
])->sum(), ])->sum(),
$this->subscription->company $this->subscription()->company
); );
} }
@ -145,7 +156,7 @@ class Summary extends Component
'product_key' => $item['product']['product_key'], 'product_key' => $item['product']['product_key'],
'quantity' => $item['quantity'], 'quantity' => $item['quantity'],
'total_raw' => $item['product']['price'] * $item['quantity'], 'total_raw' => $item['product']['price'] * $item['quantity'],
'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription->frequency_id), 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription()->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription()->frequency_id),
]; ];
} }
@ -154,7 +165,7 @@ class Summary extends Component
'product_key' => $item['product']['product_key'], 'product_key' => $item['product']['product_key'],
'quantity' => $item['quantity'], 'quantity' => $item['quantity'],
'total_raw' => $item['product']['price'] * $item['quantity'], 'total_raw' => $item['product']['price'] * $item['quantity'],
'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription->frequency_id), 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription()->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription()->frequency_id),
]; ];
} }
@ -163,7 +174,7 @@ class Summary extends Component
'product_key' => $item['product']['product_key'], 'product_key' => $item['product']['product_key'],
'quantity' => $item['quantity'], 'quantity' => $item['quantity'],
'total_raw' => $item['product']['price'] * $item['quantity'], 'total_raw' => $item['product']['price'] * $item['quantity'],
'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company), 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription()->company),
]; ];
} }
@ -172,7 +183,7 @@ class Summary extends Component
'product_key' => $item['product']['product_key'], 'product_key' => $item['product']['product_key'],
'quantity' => $item['quantity'], 'quantity' => $item['quantity'],
'total_raw' => $item['product']['price'] * $item['quantity'], 'total_raw' => $item['product']['price'] * $item['quantity'],
'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company), 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription()->company),
]; ];
} }

View File

@ -11,7 +11,7 @@
for="{{ $field['key'] }}" for="{{ $field['key'] }}"
class="input-label"> class="input-label">
@if(in_array($field['key'], ['custom_value1','custom_value2','custom_value3','custom_value4'])) @if(in_array($field['key'], ['custom_value1','custom_value2','custom_value3','custom_value4']))
{{ (new App\Utils\Helpers())->makeCustomField($subscription->company->custom_fields, str_replace("custom_value","client", $field['key']))}} {{ (new App\Utils\Helpers())->makeCustomField($this->subscription->company->custom_fields, str_replace("custom_value","client", $field['key']))}}
@elseif(array_key_exists('label', $field)) @elseif(array_key_exists('label', $field))
{{ ctrans("texts.{$field['label']}") }} {{ ctrans("texts.{$field['label']}") }}
@else @else
@ -46,20 +46,22 @@
name="currency_id"> name="currency_id">
@foreach(App\Utils\TranslationHelper::getCurrencies() as $currency) @foreach(App\Utils\TranslationHelper::getCurrencies() as $currency)
<option <option
{{ $currency->id == $subscription->company->settings->currency_id ? 'selected' : null }} value="{{ $currency->id }}"> {{ $currency->id == $this->subscription->company->settings->currency_id ? 'selected' : null }} value="{{ $currency->id }}">
{{ $currency->getName() }} {{ $currency->getName() }}
</option> </option>
@endforeach @endforeach
</select> </select>
@elseif($field['key'] === 'country_id') @elseif($field['key'] === 'country_id')
<select <select
id="shipping_country" id="country_id"
class="input w-full form-select bg-white" class="input w-full form-select bg-white"
wire:change="$set('formData.country_id', $event.target.value)"
name="country_id"> name="country_id">
<option value="none"></option> <option value=""></option>
@foreach(App\Utils\TranslationHelper::getCountries() as $country) @foreach(App\Utils\TranslationHelper::getCountries() as $country)
<option <option
{{ $country == isset(auth()->user()->client->shipping_country->id) ? 'selected' : null }} value="{{ $country->id }}"> {{ isset(auth()->user()->client->country->id) && $country->id == auth()->user()->client->country->id ? 'selected' : '' }}
value="{{ $country->id }}">
{{ $country->iso_3166_2 }} {{ $country->iso_3166_2 }}
({{ $country->getName() }}) ({{ $country->getName() }})
</option> </option>
@ -67,13 +69,15 @@
</select> </select>
@elseif($field['key'] === 'shipping_country_id') @elseif($field['key'] === 'shipping_country_id')
<select <select
id="shipping_country" id="shipping_country_id"
class="input w-full form-select bg-white" class="input w-full form-select bg-white"
wire:change="$set('formData.shipping_country_id', $event.target.value)"
name="shipping_country_id"> name="shipping_country_id">
<option value="none"></option> <option value=""></option>
@foreach(App\Utils\TranslationHelper::getCountries() as $country) @foreach(App\Utils\TranslationHelper::getCountries() as $country)
<option <option
{{ $country == isset(auth()->user()->client->shipping_country->id) ? 'selected' : null }} value="{{ $country->id }}"> {{ isset(auth()->user()->client->shipping_country->id) && $country->id == auth()->user()->client->shipping_country->id ? 'selected' : '' }}
value="{{ $country->id }}">
{{ $country->iso_3166_2 }} {{ $country->iso_3166_2 }}
({{ $country->getName() }}) ({{ $country->getName() }})
</option> </option>
@ -124,15 +128,15 @@
<div class="col-span-12 md:col-span-6"> <div class="col-span-12 md:col-span-6">
<span class="inline-flex items-center" x-data="{ terms_of_service: false, privacy_policy: false }"> <span class="inline-flex items-center" x-data="{ terms_of_service: false, privacy_policy: false }">
@if(!empty($subscription->company->settings->client_portal_terms) || !empty($subscription->company->settings->client_portal_privacy_policy)) @if(!empty($this->subscription->company->settings->client_portal_terms) || !empty($this->subscription->company->settings->client_portal_privacy_policy))
<input type="checkbox" name="terms" class="form-checkbox mr-2 cursor-pointer" checked> <input type="checkbox" name="terms" class="form-checkbox mr-2 cursor-pointer" checked>
<span class="text-sm text-gray-800"> <span class="text-sm text-gray-800">
{{ ctrans('texts.i_agree_to_the') }} {{ ctrans('texts.i_agree_to_the') }}
@endif @endif
@includeWhen(!empty($subscription->company->settings->client_portal_terms), 'portal.ninja2020.auth.includes.register.popup', ['property' => 'terms_of_service', 'title' => ctrans('texts.terms_of_service'), 'content' => $subscription->company->settings->client_portal_terms]) @includeWhen(!empty($this->subscription->company->settings->client_portal_terms), 'portal.ninja2020.auth.includes.register.popup', ['property' => 'terms_of_service', 'title' => ctrans('texts.terms_of_service'), 'content' => $this->subscription->company->settings->client_portal_terms])
@includeWhen(!empty($subscription->company->settings->client_portal_privacy_policy), 'portal.ninja2020.auth.includes.register.popup', ['property' => 'privacy_policy', 'title' => ctrans('texts.privacy_policy'), 'content' => $subscription->company->settings->client_portal_privacy_policy]) @includeWhen(!empty($this->subscription->company->settings->client_portal_privacy_policy), 'portal.ninja2020.auth.includes.register.popup', ['property' => 'privacy_policy', 'title' => ctrans('texts.privacy_policy'), 'content' => $this->subscription->company->settings->client_portal_privacy_policy])
@error('terms') @error('terms')
<p class="text-red-600">{{ $message }}</p> <p class="text-red-600">{{ $message }}</p>

View File

@ -1,11 +1,11 @@
<div> <div>
<livewire:billing-portal.cart.one-time-products <livewire:billing-portal.cart.one-time-products
:subscription="$subscription" :subscription_id="$this->subscription->hashed_id"
:context="$context" :context="$context"
/> />
<livewire:billing-portal.cart.recurring-products <livewire:billing-portal.cart.recurring-products
:subscription="$subscription" :subscription_id="$this->subscription->hashed_id"
:context="$context" :context="$context"
/> />
@ -14,14 +14,13 @@
@endif @endif
<livewire:billing-portal.cart.optional-recurring-products <livewire:billing-portal.cart.optional-recurring-products
:subscription="$subscription"
:context="$context" :context="$context"
/> />
<div class="mt-10"></div> <div class="mt-10"></div>
<livewire:billing-portal.cart.optional-one-time-products <livewire:billing-portal.cart.optional-one-time-products
:subscription="$subscription" :subscription_id="$this->subscription->hashed_id"
:context="$context" :context="$context"
/> />

View File

@ -23,21 +23,21 @@
<div class="flex flex-col"> <div class="flex flex-col">
<h2 class="text-lg font-medium">{{ $product['product_key'] }}</h2> <h2 class="text-lg font-medium">{{ $product['product_key'] }}</h2>
<p class="block text-sm">{{ \App\Utils\Number::formatMoney($product['price'], $subscription['company']) }}</p> <p class="block text-sm">{{ \App\Utils\Number::formatMoney($product['price'], $this->subscription['company']) }}</p>
</div> </div>
</div> </div>
<div class="flex flex-col-reverse space-y-3"> <div class="flex flex-col-reverse space-y-3">
<div class="flex"> <div class="flex">
@if($subscription->use_inventory_management && $product['in_stock_quantity'] <= 0) @if($this->subscription->use_inventory_management && $product['in_stock_quantity'] <= 0)
<p class="text-sm font-light text-red-500 text-right mr-2 mt-2">{{ ctrans('texts.out_of_stock') }}</p> <p class="text-sm font-light text-red-500 text-right mr-2 mt-2">{{ ctrans('texts.out_of_stock') }}</p>
@else @else
<p class="text-sm font-light text-gray-700 text-right mr-2 mt-2">{{ ctrans('texts.qty') }}</p> <p class="text-sm font-light text-gray-700 text-right mr-2 mt-2">{{ ctrans('texts.qty') }}</p>
@endif @endif
<select id="{{ $product['hashed_id'] }}" wire:change="quantity($event.target.id, $event.target.value)" class="rounded-md border-gray-300 shadow-sm sm:text-sm" {{ $subscription->use_inventory_management && $product['in_stock_quantity'] < 1 ? 'disabled' : '' }}> <select id="{{ $product['hashed_id'] }}" wire:change="quantity($event.target.id, $event.target.value)" class="rounded-md border-gray-300 shadow-sm sm:text-sm" {{ $this->subscription->use_inventory_management && $product['in_stock_quantity'] < 1 ? 'disabled' : '' }}>
<option value="1" selected="selected">1</option> <option value="1" selected="selected">1</option>
@for ($i = 2; $i <= $subscription->maxQuantity($product); $i++) @for ($i = 2; $i <= $this->subscription->maxQuantity($product); $i++)
<option {{ $entry['quantity'] == $i ? 'selected' : '' }} value="{{ $i }}">{{ $i }}</option> <option {{ $entry['quantity'] == $i ? 'selected' : '' }} value="{{ $i }}">{{ $i }}</option>
@endfor @endfor
</select> </select>

View File

@ -23,7 +23,7 @@
<div class="flex flex-col"> <div class="flex flex-col">
<h2 class="text-lg font-medium">{{ $product['product_key'] }}</h2> <h2 class="text-lg font-medium">{{ $product['product_key'] }}</h2>
<p class="block text-sm">{{ \App\Utils\Number::formatMoney($product['price'], $subscription['company']) }}</p> <p class="block text-sm">{{ \App\Utils\Number::formatMoney($product['price'], $this->subscription['company']) }}</p>
</div> </div>
</div> </div>

View File

@ -23,7 +23,7 @@
<div class="flex flex-col"> <div class="flex flex-col">
<h2 class="text-lg font-medium">{{ $product['product_key'] }}</h2> <h2 class="text-lg font-medium">{{ $product['product_key'] }}</h2>
<p class="block text-sm">{{ \App\Utils\Number::formatMoney($product['price'], $subscription['company']) }} / <span class="lowercase">{{ App\Models\RecurringInvoice::frequencyForKey($subscription->frequency_id) }}</span></p> <p class="block text-sm">{{ \App\Utils\Number::formatMoney($product['price'], $this->subscription['company']) }} / <span class="lowercase">{{ App\Models\RecurringInvoice::frequencyForKey($subscription->frequency_id) }}</span></p>
</div> </div>
</div> </div>

View File

@ -23,7 +23,7 @@
<div class="flex flex-col"> <div class="flex flex-col">
<h2 class="text-lg font-medium">{{ $product['product_key'] }}</h2> <h2 class="text-lg font-medium">{{ $product['product_key'] }}</h2>
<p class="block text-sm">{{ \App\Utils\Number::formatMoney($product['price'], $subscription['company']) }} / <span class="lowercase">{{ App\Models\RecurringInvoice::frequencyForKey($subscription->frequency_id) }}</span></p> <p class="block text-sm">{{ \App\Utils\Number::formatMoney($product['price'], $this->subscription['company']) }} / <span class="lowercase">{{ App\Models\RecurringInvoice::frequencyForKey($subscription->frequency_id) }}</span></p>
</div> </div>
</div> </div>
@ -45,7 +45,7 @@
<option {{ $entry['quantity'] == '1' ? 'selected' : '' }} value="1">1</option> <option {{ $entry['quantity'] == '1' ? 'selected' : '' }} value="1">1</option>
@if($subscription->max_seats_limit > 1) @if($subscription->max_seats_limit > 1)
@for ($i = 2; $i <= ($subscription->use_inventory_management ? min($subscription->max_seats_limit,$product['in_stock_quantity']) : $subscription->max_seats_limit); $i++) @for ($i = 2; $i <= ($subscription->use_inventory_management ? min($this->subscription->max_seats_limit,$product['in_stock_quantity']) : $subscription->max_seats_limit); $i++)
<option {{ $entry['quantity'] == $i ? 'selected' : '' }} value="{{ $i }}">{{ $i }}</option> <option {{ $entry['quantity'] == $i ? 'selected' : '' }} value="{{ $i }}">{{ $i }}</option>
@endfor @endfor
@else @else

View File

@ -10,7 +10,7 @@
</div> </div>
@endif @endif
@livewire('billing-portal.purchase', ['subscription' => $subscription, 'db' => $subscription->company->db, 'hash' => $hash, 'request_data' => $request_data, 'campaign' => request()->query('campaign') ?? null]) @livewire('billing-portal.purchase', ['subscription_id' => $subscription->hashed_id, 'db' => $subscription->company->db, 'hash' => $hash, 'request_data' => $request_data, 'campaign' => request()->query('campaign') ?? null])
@stop @stop
@push('footer') @push('footer')

View File

@ -1,15 +1,12 @@
<div class="grid grid-cols-12 bg-gray-50"> <div class="grid grid-cols-12 bg-gray-50">
<div <div
@php
nlog($context);
@endphp
class="col-span-12 xl:col-span-6 bg-white flex flex-col items-center lg:h-screen" class="col-span-12 xl:col-span-6 bg-white flex flex-col items-center lg:h-screen"
> >
<div class="w-full p-10 lg:mt-24 md:max-w-xl"> <div class="w-full p-10 lg:mt-24 md:max-w-xl">
<img <img
class="h-8" class="h-8"
src="{{ $subscription->company->present()->logo }}" src="{{ $this->subscription->company->present()->logo }}"
alt="{{ $subscription->company->present()->name }}" alt="{{ $this->subscription->company->present()->name }}"
/> />
<svg id="spinner" class="animate-spin h-8 w-8 text-primary mt-10 hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"> <svg id="spinner" class="animate-spin h-8 w-8 text-primary mt-10 hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
@ -18,7 +15,7 @@
</svg> </svg>
<div class="my-10" id="container"> <div class="my-10" id="container">
@livewire($this->component, ['context' => $context, 'subscription' => $this->subscription], key($this->componentUniqueId())) @livewire($this->component, ['context' => $context, 'subscription_id' => $this->subscription->hashed_id], key($this->componentUniqueId()))
</div> </div>
</div> </div>
</div> </div>
@ -27,7 +24,7 @@
<div class="sticky top-0"> <div class="sticky top-0">
<div class="w-full p-10 lg:mt-24 md:max-w-xl"> <div class="w-full p-10 lg:mt-24 md:max-w-xl">
<div class="my-6 space-y-10 xl:ml-5"> <div class="my-6 space-y-10 xl:ml-5">
@livewire('billing-portal.summary', ['subscription' => $subscription, 'context' => $context], key($this->summaryUniqueId())) @livewire('billing-portal.summary', ['subscription_id' => $this->subscription->hashed_id, 'context' => $context], key($this->summaryUniqueId()))
</div> </div>
</div> </div>
</div> </div>