mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
include Account clas
This commit is contained in:
parent
56b0452d2e
commit
3ebe533fc8
@ -193,8 +193,7 @@ class LoginController extends BaseController
|
||||
}
|
||||
|
||||
$user->setCompany($user->account->default_company);
|
||||
$timeout = auth()->user()->company()->default_password_timeout;
|
||||
|
||||
$timeout = auth()->user()->company()->default_password_timeout / 60000;
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$cu = CompanyUser::query()
|
||||
@ -312,6 +311,8 @@ class LoginController extends BaseController
|
||||
|
||||
Auth::login($existing_user, true);
|
||||
$existing_user->setCompany($existing_user->account->default_company);
|
||||
$timeout = $existing_user->company()->default_password_timeout / 60000;
|
||||
Cache::put($existing_user->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$cu = CompanyUser::query()
|
||||
->where('user_id', auth()->user()->id);
|
||||
@ -322,35 +323,6 @@ class LoginController extends BaseController
|
||||
}
|
||||
|
||||
if ($user) {
|
||||
|
||||
// we are no longer accessing the permissions for gmail - email permissions here
|
||||
|
||||
// $client = new Google_Client();
|
||||
// $client->setClientId(config('ninja.auth.google.client_id'));
|
||||
// $client->setClientSecret(config('ninja.auth.google.client_secret'));
|
||||
// $client->setRedirectUri(config('ninja.app_url'));
|
||||
|
||||
// $token = false;
|
||||
|
||||
// try{
|
||||
// $token = $client->authenticate(request()->input('server_auth_code'));
|
||||
// }
|
||||
// catch(\Exception $e) {
|
||||
|
||||
// return response()
|
||||
// ->json(['message' => ctrans('texts.invalid_credentials')], 401)
|
||||
// ->header('X-App-Version', config('ninja.app_version'))
|
||||
// ->header('X-Api-Version', config('ninja.minimum_client_version'));
|
||||
|
||||
// }
|
||||
|
||||
// $refresh_token = '';
|
||||
|
||||
// if (array_key_exists('refresh_token', $token)) {
|
||||
// $refresh_token = $token['refresh_token'];
|
||||
// }
|
||||
|
||||
// $refresh_token = '';
|
||||
|
||||
$name = OAuth::splitName($google->harvestName($user));
|
||||
|
||||
@ -373,6 +345,8 @@ class LoginController extends BaseController
|
||||
|
||||
auth()->user()->email_verified_at = now();
|
||||
auth()->user()->save();
|
||||
$timeout = auth()->user()->company()->default_password_timeout / 60000;
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$ct = CompanyUser::whereUserId(auth()->user()->id);
|
||||
|
||||
|
@ -15,16 +15,36 @@ namespace App\Http\Controllers\ClientPortal;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\BillingSubscription;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class BillingSubscriptionPurchaseController extends Controller
|
||||
{
|
||||
public function index(BillingSubscription $billing_subscription)
|
||||
public function index(BillingSubscription $billing_subscription, Request $request)
|
||||
{
|
||||
if ($request->has('locale')) {
|
||||
$this->setLocale($request->query('locale'));
|
||||
}
|
||||
|
||||
return view('billing-portal.purchase', [
|
||||
'billing_subscription' => $billing_subscription,
|
||||
'hash' => Str::uuid()->toString(),
|
||||
'request_data' => $request->all(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set locale for incoming request.
|
||||
*
|
||||
* @param string $locale
|
||||
*/
|
||||
private function setLocale(string $locale): void
|
||||
{
|
||||
$record = DB::table('languages')->where('locale', $locale)->first();
|
||||
|
||||
if ($record) {
|
||||
App::setLocale($record->locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ use App\Transformers\CompanyUserTransformer;
|
||||
use App\Transformers\UserTransformer;
|
||||
use Google_Client;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class ConnectedAccountController extends BaseController
|
||||
{
|
||||
@ -111,6 +112,10 @@ class ConnectedAccountController extends BaseController
|
||||
auth()->user()->email_verified_at = now();
|
||||
auth()->user()->save();
|
||||
|
||||
$timeout = auth()->user()->company()->default_password_timeout;
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
|
||||
return $this->itemResponse(auth()->user());
|
||||
|
||||
}
|
||||
|
39
app/Http/Controllers/SubdomainController.php
Normal file
39
app/Http/Controllers/SubdomainController.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
|
||||
class SubdomainController extends BaseController
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$subdomain_exists = MultiDB::findAndSetDbByDomain(request()->input('subdomain'));
|
||||
|
||||
if($subdomain_exists)
|
||||
return response()->json(['message' => 'Domain not available'] , 401);
|
||||
|
||||
return response()->json(['message' => 'Domain available'], 200);
|
||||
}
|
||||
|
||||
}
|
@ -12,48 +12,137 @@
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Factory\ClientFactory;
|
||||
use App\Models\BillingSubscription;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Invoice;
|
||||
use App\Repositories\ClientContactRepository;
|
||||
use App\Repositories\ClientRepository;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Livewire\Component;
|
||||
|
||||
class BillingPortalPurchase extends Component
|
||||
{
|
||||
/**
|
||||
* Random hash generated by backend to handle the tracking of state.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $hash;
|
||||
|
||||
public $heading_text = 'Log in';
|
||||
/**
|
||||
* Top level text on the left side of billing page.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $heading_text;
|
||||
|
||||
|
||||
/**
|
||||
* E-mail address model for user input.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $email;
|
||||
|
||||
/**
|
||||
* Password model for user input.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $password;
|
||||
|
||||
/**
|
||||
* Instance of billing subscription.
|
||||
*
|
||||
* @var BillingSubscription
|
||||
*/
|
||||
public $billing_subscription;
|
||||
|
||||
/**
|
||||
* Instance of client contact.
|
||||
*
|
||||
* @var null|ClientContact
|
||||
*/
|
||||
public $contact;
|
||||
|
||||
/**
|
||||
* Rules for validating the form.
|
||||
*
|
||||
* @var \string[][]
|
||||
*/
|
||||
protected $rules = [
|
||||
'email' => ['required', 'email'],
|
||||
];
|
||||
|
||||
/**
|
||||
* Id for CompanyGateway record.
|
||||
*
|
||||
* @var string|integer
|
||||
*/
|
||||
public $company_gateway_id;
|
||||
|
||||
/**
|
||||
* Id for GatewayType.
|
||||
*
|
||||
* @var string|integer
|
||||
*/
|
||||
public $payment_method_id;
|
||||
|
||||
/**
|
||||
* List of steps that frontend form follows.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $steps = [
|
||||
'passed_email' => false,
|
||||
'existing_user' => false,
|
||||
'fetched_payment_methods' => false,
|
||||
'fetched_client' => false,
|
||||
'show_start_trial' => false,
|
||||
];
|
||||
|
||||
/**
|
||||
* List of payment methods fetched from client.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $methods = [];
|
||||
|
||||
/**
|
||||
* Instance of \App\Models\Invoice
|
||||
*
|
||||
* @var Invoice
|
||||
*/
|
||||
public $invoice;
|
||||
|
||||
/**
|
||||
* Coupon model for user input
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $coupon;
|
||||
|
||||
/**
|
||||
* Quantity for seats
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $quantity = 1;
|
||||
|
||||
/**
|
||||
* First-hit request data (queries, locales...).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $request_data;
|
||||
|
||||
/**
|
||||
* Handle user authentication
|
||||
*
|
||||
* @return $this|bool|void
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$this->validate();
|
||||
@ -81,6 +170,12 @@ class BillingPortalPurchase extends Component
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a blank client. Used for new customers purchasing.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Laracasts\Presenter\Exceptions\PresenterException
|
||||
*/
|
||||
protected function createBlankClient()
|
||||
{
|
||||
$company = $this->billing_subscription->company;
|
||||
@ -88,23 +183,47 @@ class BillingPortalPurchase extends Component
|
||||
|
||||
$client_repo = new ClientRepository(new ClientContactRepository());
|
||||
|
||||
$client = $client_repo->save([
|
||||
$data = [
|
||||
'name' => 'Client Name',
|
||||
'contacts' => [
|
||||
['email' => $this->email],
|
||||
]
|
||||
], ClientFactory::create($company->id, $user->id));
|
||||
],
|
||||
'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));
|
||||
|
||||
return $client->contacts->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetching payment methods from the client.
|
||||
*
|
||||
* @param ClientContact $contact
|
||||
* @return $this
|
||||
*/
|
||||
protected function getPaymentMethods(ClientContact $contact): self
|
||||
{
|
||||
if ($this->billing_subscription->trial_enabled) {
|
||||
$this->heading_text = ctrans('texts.plan_trial');
|
||||
$this->steps['show_start_trial'] = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->steps['fetched_payment_methods'] = true;
|
||||
|
||||
$this->methods = $contact->client->service()->getPaymentMethods(1000);
|
||||
|
||||
$this->heading_text = 'Pick a payment method';
|
||||
$this->heading_text = ctrans('texts.payment_methods');
|
||||
|
||||
Auth::guard('contact')->login($contact);
|
||||
|
||||
@ -113,6 +232,13 @@ class BillingPortalPurchase extends Component
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Middle method between selecting payment method &
|
||||
* submitting the from to the backend.
|
||||
*
|
||||
* @param $company_gateway_id
|
||||
* @param $gateway_type_id
|
||||
*/
|
||||
public function handleMethodSelectingEvent($company_gateway_id, $gateway_type_id)
|
||||
{
|
||||
$this->company_gateway_id = $company_gateway_id;
|
||||
@ -121,10 +247,13 @@ class BillingPortalPurchase extends Component
|
||||
$this->handleBeforePaymentEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to handle events before payments.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handleBeforePaymentEvents()
|
||||
{
|
||||
|
||||
//stubs
|
||||
$data = [
|
||||
'client_id' => $this->contact->client->id,
|
||||
'date' => now()->format('Y-m-d'),
|
||||
@ -133,7 +262,8 @@ class BillingPortalPurchase extends Component
|
||||
'client_contact_id' => $this->contact->hashed_id,
|
||||
]],
|
||||
'user_input_promo_code' => $this->coupon,
|
||||
'quantity' => 1, // Option to increase quantity
|
||||
'coupon' => $this->coupon,
|
||||
'quantity' => $this->quantity,
|
||||
];
|
||||
|
||||
$this->invoice = $this->billing_subscription
|
||||
@ -144,20 +274,49 @@ class BillingPortalPurchase extends Component
|
||||
->save();
|
||||
|
||||
Cache::put($this->hash, [
|
||||
'billing_subscription_id' => $this->billing_subscription->id,
|
||||
'email' => $this->email ?? $this->contact->email,
|
||||
'client_id' => $this->contact->client->id,
|
||||
'invoice_id' => $this->invoice->id],
|
||||
'invoice_id' => $this->invoice->id,
|
||||
'subscription_id' => $this->billing_subscription->id],
|
||||
now()->addMinutes(60)
|
||||
);
|
||||
|
||||
$this->emit('beforePaymentEventsCompleted');
|
||||
}
|
||||
|
||||
|
||||
//this isn't managed here - this is taken care of in the BS
|
||||
public function applyCouponCode()
|
||||
/**
|
||||
* Proxy method for starting the trial.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function handleTrial()
|
||||
{
|
||||
dd('Applying coupon code: ' . $this->coupon);
|
||||
return $this->billing_subscription->service()->startTrial([
|
||||
'email' => $this->email ?? $this->contact->email,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update quantity property.
|
||||
*
|
||||
* @param string $option
|
||||
* @return int
|
||||
*/
|
||||
public function updateQuantity(string $option): int
|
||||
{
|
||||
if ($this->quantity == 1 && $option == 'decrement') {
|
||||
return $this->quantity;
|
||||
}
|
||||
|
||||
// TODO: Dave review.
|
||||
if ($this->quantity >= $this->billing_subscription->max_seats_limit) {
|
||||
return $this->quantity;
|
||||
}
|
||||
|
||||
return $option == 'increment'
|
||||
? $this->quantity++
|
||||
: $this->quantity--;
|
||||
}
|
||||
|
||||
public function render()
|
||||
|
@ -59,6 +59,7 @@ class CreateCompany
|
||||
$company->enabled_modules = config('ninja.enabled_modules');
|
||||
$company->subdomain = isset($this->request['subdomain']) ? $this->request['subdomain'] : '';
|
||||
$company->custom_fields = new \stdClass;
|
||||
$company->default_password_timeout = 1800000;
|
||||
$company->save();
|
||||
|
||||
return $company;
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Mail\Engine;
|
||||
|
||||
use App\Models\Account;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Utils\Number;
|
||||
|
||||
|
@ -45,7 +45,7 @@ class SupportMessageSent extends Mailable
|
||||
|
||||
$log_file->seek(PHP_INT_MAX);
|
||||
$last_line = $log_file->key();
|
||||
$lines = new LimitIterator($log_file, $last_line - 10, $last_line);
|
||||
$lines = new LimitIterator($log_file, $last_line - 100, $last_line);
|
||||
|
||||
$log_lines = iterator_to_array($lines);
|
||||
}
|
||||
|
@ -241,7 +241,11 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
|
||||
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
|
||||
|
||||
//(new BillingSubscriptionService)->completePurchase($this->payment_hash);
|
||||
if (property_exists($this->payment_hash->data, 'billing_context')) {
|
||||
$billing_subscription = \App\Models\BillingSubscription::find($this->payment_hash->data->billing_context->billing_subscription_id);
|
||||
|
||||
(new BillingSubscriptionService($billing_subscription))->completePurchase($this->payment_hash);
|
||||
}
|
||||
|
||||
return $payment->service()->applyNumber()->save();
|
||||
}
|
||||
|
@ -100,22 +100,19 @@ class StripePaymentDriver extends BaseDriver
|
||||
// GatewayType::APPLE_PAY, // TODO:: Missing implementation
|
||||
];
|
||||
|
||||
if ($this->company_gateway->getSofortEnabled()
|
||||
&& $this->client
|
||||
if ($this->client
|
||||
&& isset($this->client->country)
|
||||
&& in_array($this->client->country->iso_3166_3, ['AUT', 'BEL', 'DEU', 'ITA', 'NLD', 'ESP'])) {
|
||||
$types[] = GatewayType::SOFORT;
|
||||
}
|
||||
|
||||
if ($this->company_gateway->getAchEnabled()
|
||||
&& $this->client
|
||||
if ($this->client
|
||||
&& isset($this->client->country)
|
||||
&& in_array($this->client->country->iso_3166_3, ['USA'])) {
|
||||
$types[] = GatewayType::BANK_TRANSFER;
|
||||
}
|
||||
|
||||
if ($this->company_gateway->getAlipayEnabled()
|
||||
&& $this->client
|
||||
if ($this->client
|
||||
&& isset($this->client->country)
|
||||
&& in_array($this->client->country->iso_3166_3, ['AUS', 'DNK', 'DEU', 'ITA', 'LUX', 'NOR', 'SVN', 'GBR', 'AUT', 'EST', 'GRC', 'JPN', 'MYS', 'PRT', 'ESP', 'USA', 'BEL', 'FIN', 'HKG', 'LVA', 'NLD', 'SGP', 'SWE', 'CAN', 'FRA', 'IRL', 'LTU', 'NZL', 'SVK', 'CHE'])) {
|
||||
$types[] = GatewayType::ALIPAY;
|
||||
|
@ -20,12 +20,14 @@ use App\Models\PaymentHash;
|
||||
use App\Models\Product;
|
||||
use App\Models\SystemLog;
|
||||
use App\Repositories\InvoiceRepository;
|
||||
use App\Utils\Traits\CleanLineItems;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
|
||||
class BillingSubscriptionService
|
||||
{
|
||||
use MakesHash;
|
||||
use CleanLineItems;
|
||||
|
||||
/** @var BillingSubscription */
|
||||
private $billing_subscription;
|
||||
@ -46,25 +48,29 @@ class BillingSubscriptionService
|
||||
|
||||
// At this point we have some state carried from the billing page
|
||||
// to this, available as $payment_hash->data->billing_context. Make something awesome ⭐
|
||||
|
||||
// create client subscription record
|
||||
|
||||
// create client subscription record
|
||||
//
|
||||
// create recurring invoice if is_recurring
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function startTrial(array $data)
|
||||
{
|
||||
// Redirects from here work just fine. Livewire will respect it.
|
||||
|
||||
// Some magic here..
|
||||
|
||||
return redirect('/trial-started');
|
||||
}
|
||||
|
||||
public function createInvoice($data): ?\App\Models\Invoice
|
||||
{
|
||||
$invoice_repo = new InvoiceRepository();
|
||||
|
||||
$data['line_items'] = $this->createLineItems($data);
|
||||
$data['line_items'] = $this->cleanItems($this->createLineItems($data));
|
||||
|
||||
/*
|
||||
If trial_enabled -> return early
|
||||
|
@ -431,7 +431,7 @@ class Design extends BaseDesign
|
||||
{
|
||||
$_variables = array_key_exists('variables', $this->context)
|
||||
? $this->context['variables']
|
||||
: ['values' => ['$entity.public_notes' => nl2br($this->entity->public_notes), '$entity.terms' => $this->entity->terms, '$entity_footer' => $this->entity->footer], 'labels' => []];
|
||||
: ['values' => ['$entity.public_notes' => $this->entity->public_notes, '$entity.terms' => $this->entity->terms, '$entity_footer' => $this->entity->footer], 'labels' => []];
|
||||
|
||||
if ($this->type == 'delivery_note') {
|
||||
return [];
|
||||
@ -443,9 +443,9 @@ class Design extends BaseDesign
|
||||
['element' => 'div', 'properties' => ['style' => 'display: flex; flex-direction: column;'], 'elements' => [
|
||||
['element' => 'p', 'content' => strtr($_variables['values']['$entity.public_notes'], $_variables), 'properties' => ['data-ref' => 'total_table-public_notes', 'style' => 'text-align: left;']],
|
||||
['element' => 'p', 'content' => '', 'properties' => ['style' => 'text-align: left; display: flex; flex-direction: column;'], 'elements' => [
|
||||
['element' => 'span', 'content' => '$entity.terms_label: ', 'properties' => ['hidden' => $this->entityVariableCheck('$entity.terms'), 'data-ref' => 'total_table-terms-label', 'style' => 'font-weight: bold; text-align: left;']],
|
||||
['element' => 'span', 'content' => '$entity.terms_label: ', 'properties' => ['hidden' => $this->entityVariableCheck('$entity.terms'), 'data-ref' => 'total_table-terms-label', 'style' => 'font-weight: bold; text-align: left; margin-top: 1rem;']],
|
||||
['element' => 'span', 'content' => strtr($_variables['values']['$entity.terms'], $_variables), 'properties' => ['data-ref' => 'total_table-terms', 'style' => 'text-align: left;']],
|
||||
['element' => 'span', 'content' => strtr($_variables['values']['$entity_footer'], $_variables), 'properties' => ['data-ref' => 'total_table-footer', 'style' => 'text-align: left;']],
|
||||
['element' => 'span', 'content' => strtr($_variables['values']['$entity_footer'], $_variables), 'properties' => ['data-ref' => 'total_table-footer', 'style' => 'text-align: left; margin-top: 1rem;']],
|
||||
]],
|
||||
['element' => 'img', 'properties' => ['hidden' => $this->client->getSetting('signature_on_pdf'), 'style' => 'max-width: 50%; height: auto;', 'src' => '$contact.signature']],
|
||||
['element' => 'div', 'properties' => ['style' => 'margin-top: 1.5rem; display: flex; align-items: flex-start;'], 'elements' => [
|
||||
|
@ -61,7 +61,7 @@ class UserTransformer extends EntityTransformer
|
||||
'last_confirmed_email_address' => (string) $user->last_confirmed_email_address ?: '',
|
||||
'google_2fa_secret' => (bool) $user->google_2fa_secret,
|
||||
'has_password' => (bool) $user->has_password,
|
||||
'oauth_user_token' => strlen($user->oauth_user_token) >=1 ? '***' : '',
|
||||
'oauth_user_token' => empty($user->oauth_user_token) ? '' : '***',
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,7 @@ class HtmlEngine
|
||||
$data['$invoice.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice2', $this->entity->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice2')];
|
||||
$data['$invoice.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice3', $this->entity->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice3')];
|
||||
$data['$invoice.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice4', $this->entity->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice4')];
|
||||
$data['$invoice.public_notes'] = ['value' => nl2br($this->entity->public_notes) ?: '', 'label' => ctrans('texts.public_notes')];
|
||||
$data['$invoice.public_notes'] = ['value' => $this->entity->public_notes ?: '', 'label' => ctrans('texts.public_notes')];
|
||||
$data['$entity.public_notes'] = &$data['$invoice.public_notes'];
|
||||
$data['$public_notes'] = &$data['$invoice.public_notes'];
|
||||
|
||||
|
2
public/css/app.css
vendored
2
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
4
public/flutter_service_worker.js
vendored
4
public/flutter_service_worker.js
vendored
@ -27,10 +27,10 @@ const RESOURCES = {
|
||||
"assets/assets/images/google-icon.png": "0f118259ce403274f407f5e982e681c3",
|
||||
"assets/fonts/MaterialIcons-Regular.otf": "1288c9e28052e028aba623321f7826ac",
|
||||
"assets/AssetManifest.json": "659dcf9d1baf3aed3ab1b9c42112bf8f",
|
||||
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "3e722fd57a6db80ee119f0e2c230ccff",
|
||||
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "174c02fc4609e8fc4389f5d21f16a296",
|
||||
"assets/FontManifest.json": "cf3c681641169319e61b61bd0277378f",
|
||||
"/": "23224b5e03519aaa87594403d54412cf",
|
||||
"main.dart.js": "1e6ec7d853ad458f61ecd490624944bc",
|
||||
"main.dart.js": "23739d5559ad1f4c23c0b72dd29078f7",
|
||||
"version.json": "b7c8971e1ab5b627fd2a4317c52b843e",
|
||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b"
|
||||
};
|
||||
|
113449
public/main.dart.js
vendored
113449
public/main.dart.js
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"/js/app.js": "/js/app.js?id=696e8203d5e8e7cf5ff5",
|
||||
"/css/app.css": "/css/app.css?id=e8d6d5e8cb60bc2f15b3",
|
||||
"/css/app.css": "/css/app.css?id=1481aa442df903f3c38b",
|
||||
"/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=a09bb529b8e1826f13b4",
|
||||
"/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=8ce8955ba775ea5f47d1",
|
||||
"/js/clients/linkify-urls.js": "/js/clients/linkify-urls.js?id=0dc8c34010d09195d2f7",
|
||||
|
@ -4177,6 +4177,7 @@ $LANG = array(
|
||||
'migration_auth_label' => 'Let\'s continue by authenticating.',
|
||||
'api_secret' => 'API secret',
|
||||
'migration_api_secret_notice' => 'You can find API_SECRET in the .env file or Invoice Ninja v5. If property is missing, leave field blank.',
|
||||
'billing_coupon_notice' => 'Your discount will be applied on the checkout.',
|
||||
'use_last_email' => 'Use last email',
|
||||
'activate_company' => 'Activate Company',
|
||||
'activate_company_help' => 'Enable emails, recurring invoices and notifications',
|
||||
@ -4200,6 +4201,7 @@ $LANG = array(
|
||||
'invoice_task_datelog' => 'Invoice Task Datelog',
|
||||
'invoice_task_datelog_help' => 'Add date details to the invoice line items',
|
||||
'promo_code' => 'Promo code',
|
||||
'recurring_invoice_issued_to' => 'Recurring invoice issued to',
|
||||
);
|
||||
|
||||
return $LANG;
|
||||
|
@ -2,7 +2,7 @@
|
||||
@section('meta_title', $billing_subscription->product->product_key)
|
||||
|
||||
@section('body')
|
||||
@livewire('billing-portal-purchase', ['billing_subscription' => $billing_subscription, 'contact' => auth('contact')->user(), 'hash' => $hash])
|
||||
@livewire('billing-portal-purchase', ['billing_subscription' => $billing_subscription, 'contact' => auth('contact')->user(), 'hash' => $hash, 'request_data' => $request_data])
|
||||
@stop
|
||||
|
||||
@push('footer')
|
||||
|
@ -10,9 +10,35 @@
|
||||
|
||||
<p class="my-6">{{ $billing_subscription->product->notes }}</p>
|
||||
|
||||
<span class="text-sm uppercase font-bold">{{ ctrans('texts.total') }}:</span>
|
||||
<span class="text-sm uppercase font-bold">{{ ctrans('texts.price') }}:</span>
|
||||
|
||||
<h1 class="text-2xl font-bold tracking-wide">{{ App\Utils\Number::formatMoney($billing_subscription->product->price, $billing_subscription->company) }}</h1>
|
||||
<div class="flex space-x-2">
|
||||
<h1 class="text-2xl font-bold tracking-wide">{{ App\Utils\Number::formatMoney($billing_subscription->product->price, $billing_subscription->company) }}</h1>
|
||||
|
||||
@if($billing_subscription->per_seat_enabled)
|
||||
<span class="text-sm">/unit</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="flex mt-4 space-x-4 items-center">
|
||||
<span class="text-sm">{{ ctrans('texts.qty') }}</span>
|
||||
<button wire:click="updateQuantity('decrement')" class="bg-gray-100 border rounded p-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="feather feather-minus">
|
||||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<button>{{ $quantity }}</button>
|
||||
<button wire:click="updateQuantity('increment')" class="bg-gray-100 border rounded p-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="feather feather-plus">
|
||||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if(auth('contact')->user())
|
||||
<a href="{{ route('client.invoices.index') }}" class="block mt-16 inline-flex items-center space-x-2">
|
||||
@ -32,14 +58,14 @@
|
||||
<div class="col-span-12 lg:col-span-6 bg-white lg:shadow-lg lg:h-screen">
|
||||
<div class="grid grid-cols-12 flex flex-col p-10 lg:mt-48 lg:ml-16">
|
||||
<div class="col-span-12 w-full lg:col-span-6">
|
||||
<h2 class="text-2xl font-bold tracking-wide">{{ $heading_text }}</h2>
|
||||
<h2 class="text-2xl font-bold tracking-wide">{{ $heading_text ?? ctrans('texts.login') }}</h2>
|
||||
@if (session()->has('message'))
|
||||
@component('portal.ninja2020.components.message')
|
||||
{{ session('message') }}
|
||||
@endcomponent
|
||||
@endif
|
||||
|
||||
@if($this->steps['fetched_payment_methods'])
|
||||
@if($steps['fetched_payment_methods'])
|
||||
<div class="flex items-center mt-4 text-sm">
|
||||
<form action="{{ route('client.payments.process', ['hash' => $hash, 'sidebar' => 'hidden']) }}"
|
||||
method="post"
|
||||
@ -67,6 +93,17 @@
|
||||
</button>
|
||||
@endforeach
|
||||
</div>
|
||||
@elseif($steps['show_start_trial'])
|
||||
<form wire:submit.prevent="handleTrial" class="mt-8">
|
||||
@csrf
|
||||
<p class="mb-4">Some text about the trial goes here. Details about the days, etc.</p>
|
||||
|
||||
|
||||
<button class="px-3 py-2 border rounded mr-4 hover:border-blue-600">
|
||||
{{ ctrans('texts.trial_call_to_action') }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@else
|
||||
<form wire:submit.prevent="authenticate" class="mt-8">
|
||||
@csrf
|
||||
@ -110,17 +147,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form wire:submit.prevent="applyCouponCode" class="mt-4">
|
||||
@csrf
|
||||
|
||||
<div class="flex items-center">
|
||||
<label class="w-full mr-2">
|
||||
<input type="text" wire:model.defer="coupon" class="input w-full m-0" />
|
||||
</label>
|
||||
|
||||
<button class="button bg-primary m-0 text-white">{{ ctrans('texts.apply') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="flex items-center mt-4">
|
||||
<label class="w-full mr-2">
|
||||
<input type="text" wire:model.lazy="coupon" class="input w-full m-0"/>
|
||||
<small class="block text-gray-900 mt-2">{{ ctrans('texts.billing_coupon_notice') }}</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -62,7 +62,7 @@
|
||||
<div>
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
{{ ctrans('texts.invoice_number_placeholder', ['invoice' => $invoice->number])}}
|
||||
- {{ ctrans('texts.paid') }}
|
||||
- {{ \App\Models\Invoice::stringStatus($invoice->status_id) }}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -24,6 +24,7 @@ Route::group(['middleware' => ['api_secret_check', 'email_db']], function () {
|
||||
});
|
||||
|
||||
Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'api/v1', 'as' => 'api.'], function () {
|
||||
Route::post('check_subdomain', 'SubdomainController@index')->name('check_subdomain');
|
||||
Route::get('ping', 'PingController@index')->name('ping');
|
||||
Route::get('health_check', 'PingController@health')->name('health_check');
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user