1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 21:22:58 +01:00
invoiceninja/app/Http/Livewire/BillingPortalPurchase.php

344 lines
8.3 KiB
PHP
Raw Normal View History

2021-03-18 01:58:10 +01:00
<?php
2021-03-18 01:53:08 +01:00
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
2021-03-18 01:58:10 +01:00
namespace App\Http\Livewire;
use App\Factory\ClientFactory;
2021-03-18 14:14:10 +01:00
use App\Models\BillingSubscription;
2021-03-18 01:58:10 +01:00
use App\Models\ClientContact;
2021-03-18 14:14:10 +01:00
use App\Models\Invoice;
2021-03-18 01:58:10 +01:00
use App\Repositories\ClientContactRepository;
use App\Repositories\ClientRepository;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
2021-03-18 01:58:10 +01:00
use Livewire\Component;
class BillingPortalPurchase extends Component
{
2021-03-18 14:14:10 +01:00
/**
* Random hash generated by backend to handle the tracking of state.
*
* @var string
*/
2021-03-18 01:58:10 +01:00
public $hash;
2021-03-18 14:14:10 +01:00
/**
* Top level text on the left side of billing page.
*
* @var string
*/
public $heading_text;
2021-03-18 01:58:10 +01:00
2021-03-18 14:14:10 +01:00
/**
* E-mail address model for user input.
*
* @var string
*/
2021-03-18 01:58:10 +01:00
public $email;
2021-03-18 14:14:10 +01:00
/**
* Password model for user input.
*
* @var string
*/
2021-03-18 01:58:10 +01:00
public $password;
2021-03-18 14:14:10 +01:00
/**
* Instance of billing subscription.
*
* @var BillingSubscription
*/
2021-03-18 01:58:10 +01:00
public $billing_subscription;
2021-03-18 14:14:10 +01:00
/**
* Instance of client contact.
*
* @var null|ClientContact
*/
2021-03-18 01:58:10 +01:00
public $contact;
2021-03-18 14:14:10 +01:00
/**
* Rules for validating the form.
*
* @var \string[][]
*/
2021-03-18 01:58:10 +01:00
protected $rules = [
'email' => ['required', 'email'],
];
2021-03-18 14:14:10 +01:00
/**
* Id for CompanyGateway record.
*
* @var string|integer
*/
2021-03-18 01:58:10 +01:00
public $company_gateway_id;
2021-03-18 14:14:10 +01:00
/**
* Id for GatewayType.
*
* @var string|integer
*/
2021-03-18 01:58:10 +01:00
public $payment_method_id;
2021-03-18 14:14:10 +01:00
/**
* List of steps that frontend form follows.
*
* @var array
*/
2021-03-18 01:58:10 +01:00
public $steps = [
'passed_email' => false,
'existing_user' => false,
'fetched_payment_methods' => false,
'fetched_client' => false,
2021-03-18 14:14:10 +01:00
'show_start_trial' => false,
2021-03-18 01:58:10 +01:00
];
2021-03-18 14:14:10 +01:00
/**
* List of payment methods fetched from client.
*
* @var array
*/
2021-03-18 01:58:10 +01:00
public $methods = [];
2021-03-18 14:14:10 +01:00
/**
* Instance of \App\Models\Invoice
*
* @var Invoice
*/
2021-03-18 01:58:10 +01:00
public $invoice;
2021-03-18 14:14:10 +01:00
/**
* Coupon model for user input
*
* @var string
*/
2021-03-18 01:58:10 +01:00
public $coupon;
2021-03-18 15:22:22 +01:00
/**
* Quantity for seats
*
* @var int
*/
public $quantity = 1;
2021-03-18 15:41:26 +01:00
/**
* First-hit request data (queries, locales...).
*
* @var array
*/
public $request_data;
2021-03-22 13:53:34 +01:00
/**
* Price of product.
*
* @var string
*/
public $price;
2021-03-18 14:14:10 +01:00
/**
* Handle user authentication
*
* @return $this|bool|void
*/
2021-03-18 01:58:10 +01:00
public function authenticate()
{
$this->validate();
$contact = ClientContact::where('email', $this->email)->first();
if ($contact && $this->steps['existing_user'] === false) {
return $this->steps['existing_user'] = true;
}
if ($contact && $this->steps['existing_user']) {
$attempt = Auth::guard('contact')->attempt(['email' => $this->email, 'password' => $this->password]);
return $attempt
? $this->getPaymentMethods($contact)
: session()->flash('message', 'These credentials do not match our records.');
}
$this->steps['existing_user'] = false;
$contact = $this->createBlankClient();
if ($contact && $contact instanceof ClientContact) {
$this->getPaymentMethods($contact);
}
}
2021-03-18 14:14:10 +01:00
/**
* Create a blank client. Used for new customers purchasing.
*
* @return mixed
* @throws \Laracasts\Presenter\Exceptions\PresenterException
*/
2021-03-18 01:58:10 +01:00
protected function createBlankClient()
{
$company = $this->billing_subscription->company;
$user = $this->billing_subscription->user;
$client_repo = new ClientRepository(new ClientContactRepository());
$data = [
2021-03-18 01:58:10 +01:00
'name' => 'Client Name',
'contacts' => [
['email' => $this->email],
],
'settings' => [],
];
if (array_key_exists('locale', $this->request_data)) {
$record = DB::table('languages')->where('locale', $this->request_data['locale'])->first();
if ($record) {
$data['settings']['language_id'] = (string)$record->id;
}
}
$client = $client_repo->save($data, ClientFactory::create($company->id, $user->id));
2021-03-18 01:58:10 +01:00
return $client->contacts->first();
}
2021-03-18 14:14:10 +01:00
/**
* Fetching payment methods from the client.
*
* @param ClientContact $contact
* @return $this
*/
2021-03-18 01:58:10 +01:00
protected function getPaymentMethods(ClientContact $contact): self
{
2021-03-18 14:14:10 +01:00
if ($this->billing_subscription->trial_enabled) {
$this->heading_text = ctrans('texts.plan_trial');
$this->steps['show_start_trial'] = true;
return $this;
}
2021-03-18 01:58:10 +01:00
$this->steps['fetched_payment_methods'] = true;
$this->methods = $contact->client->service()->getPaymentMethods(1000);
2021-03-18 14:14:10 +01:00
$this->heading_text = ctrans('texts.payment_methods');
2021-03-18 01:58:10 +01:00
Auth::guard('contact')->login($contact);
$this->contact = $contact;
return $this;
}
2021-03-18 14:14:10 +01:00
/**
* Middle method between selecting payment method &
* submitting the from to the backend.
*
* @param $company_gateway_id
* @param $gateway_type_id
*/
2021-03-18 01:58:10 +01:00
public function handleMethodSelectingEvent($company_gateway_id, $gateway_type_id)
{
$this->company_gateway_id = $company_gateway_id;
$this->payment_method_id = $gateway_type_id;
$this->handleBeforePaymentEvents();
}
2021-03-18 14:14:10 +01:00
/**
* Method to handle events before payments.
*
* @return void
*/
2021-03-18 01:58:10 +01:00
public function handleBeforePaymentEvents()
{
$data = [
'client_id' => $this->contact->client->id,
'date' => now()->format('Y-m-d'),
'invitations' => [[
'key' => '',
'client_contact_id' => $this->contact->hashed_id,
]],
'user_input_promo_code' => $this->coupon,
'coupon' => empty($this->billing_subscription->promo_code) ? '' : $this->coupon,
2021-03-18 15:22:22 +01:00
'quantity' => $this->quantity,
2021-03-18 01:58:10 +01:00
];
$this->invoice = $this->billing_subscription
->service()
->createInvoice($data)
->service()
->markSent()
->save();
Cache::put($this->hash, [
2021-03-20 23:15:26 +01:00
'billing_subscription_id' => $this->billing_subscription->id,
2021-03-18 01:58:10 +01:00
'email' => $this->email ?? $this->contact->email,
'client_id' => $this->contact->client->id,
'invoice_id' => $this->invoice->id],
2021-03-18 01:58:10 +01:00
now()->addMinutes(60)
);
$this->emit('beforePaymentEventsCompleted');
}
2021-03-18 14:14:10 +01:00
/**
* Proxy method for starting the trial.
*
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function handleTrial()
{
return $this->billing_subscription->service()->startTrial([
'email' => $this->email ?? $this->contact->email,
2021-03-22 14:03:32 +01:00
'quantity' => $this->quantity,
'contact_id' => $this->contact->id,
2021-03-18 14:14:10 +01:00
]);
}
2021-03-18 02:00:01 +01:00
2021-03-18 15:22:22 +01:00
/**
* Update quantity property.
*
* @param string $option
* @return int
*/
public function updateQuantity(string $option): int
2021-03-18 01:58:10 +01:00
{
2021-03-18 15:22:22 +01:00
if ($this->quantity == 1 && $option == 'decrement') {
return $this->quantity;
}
2021-03-22 13:32:29 +01:00
if ($this->quantity >= $this->billing_subscription->max_seats_limit && $option == 'increment') {
2021-03-18 15:22:22 +01:00
return $this->quantity;
}
2021-03-22 13:53:34 +01:00
if ($option == 'increment') {
$this->quantity++;
return $this->price = (int) $this->price + $this->billing_subscription->product->price;
}
$this->quantity--;
$this->price = (int) $this->price - $this->billing_subscription->product->price;
return 0;
2021-03-18 01:58:10 +01:00
}
public function render()
{
if ($this->contact instanceof ClientContact) {
$this->getPaymentMethods($this->contact);
}
return render('components.livewire.billing-portal-purchase');
}
}