mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-08 20:22:42 +01:00
Added two week trial for hosted pro plan
This commit is contained in:
parent
1b740d77fc
commit
1794811f9b
@ -916,6 +916,8 @@ class AccountController extends BaseController
|
|||||||
$user->registered = true;
|
$user->registered = true;
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
|
$user->account->startTrial();
|
||||||
|
|
||||||
if (Input::get('go_pro') == 'true') {
|
if (Input::get('go_pro') == 'true') {
|
||||||
Session::set(REQUESTED_PRO_PLAN, true);
|
Session::set(REQUESTED_PRO_PLAN, true);
|
||||||
}
|
}
|
||||||
@ -980,6 +982,17 @@ class AccountController extends BaseController
|
|||||||
return Redirect::to('/settings/'.ACCOUNT_USER_DETAILS)->with('message', trans('texts.confirmation_resent'));
|
return Redirect::to('/settings/'.ACCOUNT_USER_DETAILS)->with('message', trans('texts.confirmation_resent'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function startTrial()
|
||||||
|
{
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
if ($user->isEligibleForTrial()) {
|
||||||
|
$user->account->startTrial();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect::back()->with('message', trans('texts.trial_success'));
|
||||||
|
}
|
||||||
|
|
||||||
public function redirectLegacy($section, $subSection = false)
|
public function redirectLegacy($section, $subSection = false)
|
||||||
{
|
{
|
||||||
if ($section === 'details') {
|
if ($section === 'details') {
|
||||||
|
@ -200,7 +200,11 @@ class AccountGatewayController extends BaseController
|
|||||||
if ($gatewayId == GATEWAY_DWOLLA) {
|
if ($gatewayId == GATEWAY_DWOLLA) {
|
||||||
$optional = array_merge($optional, ['key', 'secret']);
|
$optional = array_merge($optional, ['key', 'secret']);
|
||||||
} elseif ($gatewayId == GATEWAY_STRIPE) {
|
} elseif ($gatewayId == GATEWAY_STRIPE) {
|
||||||
$rules['publishable_key'] = 'required';
|
if (Utils::isNinjaDev() && Input::get('23_apiKey') == env('TEST_API_KEY')) {
|
||||||
|
// do nothing - we're unable to acceptance test with StripeJS
|
||||||
|
} else {
|
||||||
|
$rules['publishable_key'] = 'required';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($fields as $field => $details) {
|
foreach ($fields as $field => $details) {
|
||||||
|
@ -166,7 +166,7 @@ class UserController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function save($userPublicId = false)
|
public function save($userPublicId = false)
|
||||||
{
|
{
|
||||||
if (Auth::user()->account->isPro()) {
|
if (Auth::user()->isPro() && ! Auth::user()->isTrial()) {
|
||||||
$rules = [
|
$rules = [
|
||||||
'first_name' => 'required',
|
'first_name' => 'required',
|
||||||
'last_name' => 'required',
|
'last_name' => 'required',
|
||||||
|
@ -97,6 +97,7 @@ Route::group(['middleware' => 'auth'], function() {
|
|||||||
Route::resource('users', 'UserController');
|
Route::resource('users', 'UserController');
|
||||||
Route::post('users/bulk', 'UserController@bulk');
|
Route::post('users/bulk', 'UserController@bulk');
|
||||||
Route::get('send_confirmation/{user_id}', 'UserController@sendConfirmation');
|
Route::get('send_confirmation/{user_id}', 'UserController@sendConfirmation');
|
||||||
|
Route::get('start_trial', 'AccountController@startTrial');
|
||||||
Route::get('restore_user/{user_id}', 'UserController@restoreUser');
|
Route::get('restore_user/{user_id}', 'UserController@restoreUser');
|
||||||
Route::post('users/change_password', 'UserController@changePassword');
|
Route::post('users/change_password', 'UserController@changePassword');
|
||||||
Route::get('/switch_account/{user_id}', 'UserController@switchAccount');
|
Route::get('/switch_account/{user_id}', 'UserController@switchAccount');
|
||||||
@ -425,7 +426,6 @@ if (!defined('CONTACT_EMAIL')) {
|
|||||||
|
|
||||||
define('MAX_NUM_VENDORS', 100);
|
define('MAX_NUM_VENDORS', 100);
|
||||||
define('MAX_NUM_VENDORS_PRO', 20000);
|
define('MAX_NUM_VENDORS_PRO', 20000);
|
||||||
define('MAX_NUM_VENDORS_LEGACY', 500);
|
|
||||||
|
|
||||||
define('INVOICE_STATUS_DRAFT', 1);
|
define('INVOICE_STATUS_DRAFT', 1);
|
||||||
define('INVOICE_STATUS_SENT', 2);
|
define('INVOICE_STATUS_SENT', 2);
|
||||||
@ -669,9 +669,8 @@ if (Utils::isNinjaDev()) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (Auth::check() && Auth::user()->id === 1)
|
if (Utils::isNinjaDev() && Auth::check() && Auth::user()->id === 1)
|
||||||
{
|
{
|
||||||
Auth::loginUsingId(1);
|
Auth::loginUsingId(1);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
@ -72,6 +72,10 @@ class Utils
|
|||||||
|
|
||||||
public static function requireHTTPS()
|
public static function requireHTTPS()
|
||||||
{
|
{
|
||||||
|
if (Request::root() === 'http://ninja.dev') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return Utils::isNinjaProd() || (isset($_ENV['REQUIRE_HTTPS']) && $_ENV['REQUIRE_HTTPS'] == 'true');
|
return Utils::isNinjaProd() || (isset($_ENV['REQUIRE_HTTPS']) && $_ENV['REQUIRE_HTTPS'] == 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +118,11 @@ class Utils
|
|||||||
return Auth::check() && Auth::user()->isPro();
|
return Auth::check() && Auth::user()->isPro();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function isTrial()
|
||||||
|
{
|
||||||
|
return Auth::check() && Auth::user()->isTrial();
|
||||||
|
}
|
||||||
|
|
||||||
public static function isEnglish()
|
public static function isEnglish()
|
||||||
{
|
{
|
||||||
return App::getLocale() == 'en';
|
return App::getLocale() == 'en';
|
||||||
@ -961,6 +970,25 @@ class Utils
|
|||||||
return $interval->y == 0;
|
return $interval->y == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getInterval($date)
|
||||||
|
{
|
||||||
|
if (!$date || $date == '0000-00-00') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$today = new DateTime('now');
|
||||||
|
$datePaid = DateTime::createFromFormat('Y-m-d', $date);
|
||||||
|
|
||||||
|
return $today->diff($datePaid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function withinPastTwoWeeks($date)
|
||||||
|
{
|
||||||
|
$interval = Utils::getInterval($date);
|
||||||
|
|
||||||
|
return $interval && $interval->d <= 14;
|
||||||
|
}
|
||||||
|
|
||||||
public static function addHttp($url)
|
public static function addHttp($url)
|
||||||
{
|
{
|
||||||
if (!preg_match("~^(?:f|ht)tps?://~i", $url)) {
|
if (!preg_match("~^(?:f|ht)tps?://~i", $url)) {
|
||||||
|
@ -464,8 +464,21 @@ class Account extends Eloquent
|
|||||||
return $invoice;
|
return $invoice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getNumberPrefix($isQuote)
|
||||||
|
{
|
||||||
|
if ( ! $this->isPro()) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($isQuote ? $this->quote_number_prefix : $this->invoice_number_prefix) ?: '';
|
||||||
|
}
|
||||||
|
|
||||||
public function hasNumberPattern($isQuote)
|
public function hasNumberPattern($isQuote)
|
||||||
{
|
{
|
||||||
|
if ( ! $this->isPro()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $isQuote ? ($this->quote_number_pattern ? true : false) : ($this->invoice_number_pattern ? true : false);
|
return $isQuote ? ($this->quote_number_pattern ? true : false) : ($this->invoice_number_pattern ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,7 +562,7 @@ class Account extends Eloquent
|
|||||||
}
|
}
|
||||||
|
|
||||||
$counter = $this->getCounter($invoice->is_quote);
|
$counter = $this->getCounter($invoice->is_quote);
|
||||||
$prefix = $invoice->is_quote ? $this->quote_number_prefix : $this->invoice_number_prefix;
|
$prefix = $this->getNumberPrefix($invoice->is_quote);
|
||||||
$counterOffset = 0;
|
$counterOffset = 0;
|
||||||
|
|
||||||
// confirm the invoice number isn't already taken
|
// confirm the invoice number isn't already taken
|
||||||
@ -681,6 +694,16 @@ class Account extends Eloquent
|
|||||||
return $this->account_key === NINJA_ACCOUNT_KEY;
|
return $this->account_key === NINJA_ACCOUNT_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function startTrial()
|
||||||
|
{
|
||||||
|
if ( ! Utils::isNinja()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->pro_plan_trial = date_create()->format('Y-m-d');
|
||||||
|
$this->save();
|
||||||
|
}
|
||||||
|
|
||||||
public function isPro()
|
public function isPro()
|
||||||
{
|
{
|
||||||
if (!Utils::isNinjaProd()) {
|
if (!Utils::isNinjaProd()) {
|
||||||
@ -692,12 +715,50 @@ class Account extends Eloquent
|
|||||||
}
|
}
|
||||||
|
|
||||||
$datePaid = $this->pro_plan_paid;
|
$datePaid = $this->pro_plan_paid;
|
||||||
|
$trialStart = $this->pro_plan_trial;
|
||||||
|
|
||||||
if ($datePaid == NINJA_DATE) {
|
if ($datePaid == NINJA_DATE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Utils::withinPastYear($datePaid);
|
return Utils::withinPastTwoWeeks($trialStart) || Utils::withinPastYear($datePaid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isTrial()
|
||||||
|
{
|
||||||
|
if ($this->pro_plan_paid && $this->pro_plan_paid != '0000-00-00') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utils::withinPastTwoWeeks($this->pro_plan_trial);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEligibleForTrial()
|
||||||
|
{
|
||||||
|
return ! $this->pro_plan_trial || $this->pro_plan_trial == '0000-00-00';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCountTrialDaysLeft()
|
||||||
|
{
|
||||||
|
$interval = Utils::getInterval($this->pro_plan_trial);
|
||||||
|
|
||||||
|
return $interval ? 14 - $interval->d : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRenewalDate()
|
||||||
|
{
|
||||||
|
if ($this->pro_plan_paid && $this->pro_plan_paid != '0000-00-00') {
|
||||||
|
$date = DateTime::createFromFormat('Y-m-d', $this->pro_plan_paid);
|
||||||
|
$date->modify('+1 year');
|
||||||
|
$date = max($date, date_create());
|
||||||
|
} elseif ($this->isTrial()) {
|
||||||
|
$date = date_create();
|
||||||
|
$date->modify('+'.$this->getCountTrialDaysLeft().' day');
|
||||||
|
} else {
|
||||||
|
$date = date_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $date->format('Y-m-d');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isWhiteLabel()
|
public function isWhiteLabel()
|
||||||
@ -944,6 +1005,11 @@ class Account extends Eloquent
|
|||||||
return $this->isPro() && $this->pdf_email_attachment;
|
return $this->isPro() && $this->pdf_email_attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getEmailDesignId()
|
||||||
|
{
|
||||||
|
return $this->isPro() ? $this->email_design_id : EMAIL_DESIGN_PLAIN;
|
||||||
|
}
|
||||||
|
|
||||||
public function clientViewCSS(){
|
public function clientViewCSS(){
|
||||||
$css = null;
|
$css = null;
|
||||||
|
|
||||||
|
@ -107,6 +107,16 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
|||||||
return $this->account->isPro();
|
return $this->account->isPro();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isTrial()
|
||||||
|
{
|
||||||
|
return $this->account->isTrial();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEligibleForTrial()
|
||||||
|
{
|
||||||
|
return $this->account->isEligibleForTrial();
|
||||||
|
}
|
||||||
|
|
||||||
public function maxInvoiceDesignId()
|
public function maxInvoiceDesignId()
|
||||||
{
|
{
|
||||||
return $this->isPro() ? 11 : (Utils::isNinja() ? COUNT_FREE_DESIGNS : COUNT_FREE_DESIGNS_SELF_HOST);
|
return $this->isPro() ? 11 : (Utils::isNinja() ? COUNT_FREE_DESIGNS : COUNT_FREE_DESIGNS_SELF_HOST);
|
||||||
@ -153,7 +163,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
|||||||
|
|
||||||
public function getMaxNumClients()
|
public function getMaxNumClients()
|
||||||
{
|
{
|
||||||
if ($this->isPro()) {
|
if ($this->isPro() && ! $this->isTrial()) {
|
||||||
return MAX_NUM_CLIENTS_PRO;
|
return MAX_NUM_CLIENTS_PRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,14 +176,10 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
|||||||
|
|
||||||
public function getMaxNumVendors()
|
public function getMaxNumVendors()
|
||||||
{
|
{
|
||||||
if ($this->isPro()) {
|
if ($this->isPro() && ! $this->isTrial()) {
|
||||||
return MAX_NUM_VENDORS_PRO;
|
return MAX_NUM_VENDORS_PRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->id < LEGACY_CUTOFF) {
|
|
||||||
return MAX_NUM_VENDORS_LEGACY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MAX_NUM_VENDORS;
|
return MAX_NUM_VENDORS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,10 +127,10 @@ class ContactMailer extends Mailer
|
|||||||
$subject = $this->processVariables($subject, $variables);
|
$subject = $this->processVariables($subject, $variables);
|
||||||
$fromEmail = $user->email;
|
$fromEmail = $user->email;
|
||||||
|
|
||||||
if ($account->email_design_id == EMAIL_DESIGN_PLAIN) {
|
if ($account->getEmailDesignId() == EMAIL_DESIGN_PLAIN) {
|
||||||
$view = ENTITY_INVOICE;
|
$view = ENTITY_INVOICE;
|
||||||
} else {
|
} else {
|
||||||
$view = 'design' . ($account->email_design_id - 1);
|
$view = 'design' . ($account->getEmailDesignId() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->sendTo($invitation->contact->email, $fromEmail, $account->getDisplayName(), $subject, $view, $data);
|
$response = $this->sendTo($invitation->contact->email, $fromEmail, $account->getDisplayName(), $subject, $view, $data);
|
||||||
@ -189,10 +189,10 @@ class ContactMailer extends Mailer
|
|||||||
$subject = $this->processVariables($emailSubject, $variables);
|
$subject = $this->processVariables($emailSubject, $variables);
|
||||||
$data['invoice_id'] = $payment->invoice->id;
|
$data['invoice_id'] = $payment->invoice->id;
|
||||||
|
|
||||||
if ($account->email_design_id == EMAIL_DESIGN_PLAIN) {
|
if ($account->getEmailDesignId() == EMAIL_DESIGN_PLAIN) {
|
||||||
$view = 'payment_confirmation';
|
$view = 'payment_confirmation';
|
||||||
} else {
|
} else {
|
||||||
$view = 'design' . ($account->email_design_id - 1);
|
$view = 'design' . ($account->getEmailDesignId() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($user->email && $contact->email) {
|
if ($user->email && $contact->email) {
|
||||||
|
@ -119,7 +119,7 @@ class AccountRepository
|
|||||||
|
|
||||||
public function enableProPlan()
|
public function enableProPlan()
|
||||||
{
|
{
|
||||||
if (Auth::user()->isPro()) {
|
if (Auth::user()->isPro() && ! Auth::user()->isTrial()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ class AccountRepository
|
|||||||
$invoice->public_id = $publicId;
|
$invoice->public_id = $publicId;
|
||||||
$invoice->client_id = $client->id;
|
$invoice->client_id = $client->id;
|
||||||
$invoice->invoice_number = $account->getNextInvoiceNumber($invoice);
|
$invoice->invoice_number = $account->getNextInvoiceNumber($invoice);
|
||||||
$invoice->invoice_date = date_create()->format('Y-m-d');
|
$invoice->invoice_date = Auth::user()->account->getRenewalDate();
|
||||||
$invoice->amount = PRO_PLAN_PRICE;
|
$invoice->amount = PRO_PLAN_PRICE;
|
||||||
$invoice->balance = PRO_PLAN_PRICE;
|
$invoice->balance = PRO_PLAN_PRICE;
|
||||||
$invoice->save();
|
$invoice->save();
|
||||||
@ -266,6 +266,8 @@ class AccountRepository
|
|||||||
$user->first_name = $firstName;
|
$user->first_name = $firstName;
|
||||||
$user->last_name = $lastName;
|
$user->last_name = $lastName;
|
||||||
$user->registered = true;
|
$user->registered = true;
|
||||||
|
|
||||||
|
$user->account->startTrial();
|
||||||
}
|
}
|
||||||
|
|
||||||
$user->oauth_provider_id = $providerId;
|
$user->oauth_provider_id = $providerId;
|
||||||
|
@ -84,7 +84,7 @@ class InvoiceService extends BaseService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($account->auto_convert_quote) {
|
if ($account->auto_convert_quote || ! $account->isPro()) {
|
||||||
$invoice = $this->convertQuote($quote, $invitation);
|
$invoice = $this->convertQuote($quote, $invitation);
|
||||||
|
|
||||||
event(new QuoteInvitationWasApproved($quote, $invoice, $invitation));
|
event(new QuoteInvitationWasApproved($quote, $invoice, $invitation));
|
||||||
|
@ -212,20 +212,13 @@ class PaymentService extends BaseService
|
|||||||
{
|
{
|
||||||
$invoice = $invitation->invoice;
|
$invoice = $invitation->invoice;
|
||||||
|
|
||||||
// sync pro accounts
|
// enable pro plan for hosted users
|
||||||
if ($invoice->account->account_key == NINJA_ACCOUNT_KEY
|
if ($invoice->account->account_key == NINJA_ACCOUNT_KEY && $invoice->amount == PRO_PLAN_PRICE) {
|
||||||
&& $invoice->amount == PRO_PLAN_PRICE) {
|
|
||||||
$account = Account::with('users')->find($invoice->client->public_id);
|
$account = Account::with('users')->find($invoice->client->public_id);
|
||||||
if ($account->pro_plan_paid && $account->pro_plan_paid != '0000-00-00') {
|
$account->pro_plan_paid = $account->getRenewalDate();
|
||||||
$date = DateTime::createFromFormat('Y-m-d', $account->pro_plan_paid);
|
|
||||||
$date->modify('+1 year');
|
|
||||||
$date = max($date, date_create());
|
|
||||||
$account->pro_plan_paid = $date->format('Y-m-d');
|
|
||||||
} else {
|
|
||||||
$account->pro_plan_paid = date_create()->format('Y-m-d');
|
|
||||||
}
|
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
|
// sync pro accounts
|
||||||
$user = $account->users()->first();
|
$user = $account->users()->first();
|
||||||
$this->accountRepo->syncAccounts($user->id, $account->pro_plan_paid);
|
$this->accountRepo->syncAccounts($user->id, $account->pro_plan_paid);
|
||||||
}
|
}
|
||||||
|
@ -1103,7 +1103,7 @@ return array(
|
|||||||
'quote_message_button' => 'To view your quote for :amount, click the button below.',
|
'quote_message_button' => 'To view your quote for :amount, click the button below.',
|
||||||
'payment_message_button' => 'Thank you for your payment of :amount.',
|
'payment_message_button' => 'Thank you for your payment of :amount.',
|
||||||
'payment_type_direct_debit' => 'Direct Debit',
|
'payment_type_direct_debit' => 'Direct Debit',
|
||||||
'bank_accounts' => 'Bank Accounts',
|
'bank_accounts' => 'Credit Cards & Banks',
|
||||||
'add_bank_account' => 'Add Bank Account',
|
'add_bank_account' => 'Add Bank Account',
|
||||||
'setup_account' => 'Setup Account',
|
'setup_account' => 'Setup Account',
|
||||||
'import_expenses' => 'Import Expenses',
|
'import_expenses' => 'Import Expenses',
|
||||||
@ -1144,4 +1144,9 @@ return array(
|
|||||||
'enable_https' => 'We strongly recommend using HTTPS to accept credit card details online.',
|
'enable_https' => 'We strongly recommend using HTTPS to accept credit card details online.',
|
||||||
'quote_issued_to' => 'Quote issued to',
|
'quote_issued_to' => 'Quote issued to',
|
||||||
'show_currency_code' => 'Currency Code',
|
'show_currency_code' => 'Currency Code',
|
||||||
|
'trial_message' => 'Your account will receive a free two week trial of our pro plan.',
|
||||||
|
'trial_footer' => 'Your free trial lasts :count more days, :link to upgrade now.',
|
||||||
|
'trial_footer_last_day' => 'This is the last day of your free trial, :link to upgrade now.',
|
||||||
|
'trial_call_to_action' => 'Start Free Trial',
|
||||||
|
'trial_success' => 'Successfully enabled two week free pro plan trial',
|
||||||
);
|
);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
@if (Utils::isPro())
|
@if (Utils::isPro() && ! Utils::isTrial())
|
||||||
{!! Button::primary(trans('texts.add_user'))->asLinkTo(URL::to('/users/create'))->appendIcon(Icon::create('plus-sign')) !!}
|
{!! Button::primary(trans('texts.add_user'))->asLinkTo(URL::to('/users/create'))->appendIcon(Icon::create('plus-sign')) !!}
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@ -185,7 +185,7 @@
|
|||||||
window.open('{{ Utils::isNinjaDev() ? '' : NINJA_APP_URL }}/license?affiliate_key=' + affiliateKey + '&product_id=' + productId + '&return_url=' + window.location);
|
window.open('{{ Utils::isNinjaDev() ? '' : NINJA_APP_URL }}/license?affiliate_key=' + affiliateKey + '&product_id=' + productId + '&return_url=' + window.location);
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Auth::check() && !Auth::user()->isPro())
|
@if (Auth::check() && (!Auth::user()->isPro() || Auth::user()->isTrial()))
|
||||||
function submitProPlan() {
|
function submitProPlan() {
|
||||||
fbq('track', 'AddPaymentInfo');
|
fbq('track', 'AddPaymentInfo');
|
||||||
trackEvent('/account', '/submit_pro_plan/' + NINJA.proPlanFeature);
|
trackEvent('/account', '/submit_pro_plan/' + NINJA.proPlanFeature);
|
||||||
@ -382,7 +382,7 @@
|
|||||||
@if (Auth::check())
|
@if (Auth::check())
|
||||||
@if (!Auth::user()->registered)
|
@if (!Auth::user()->registered)
|
||||||
{!! Button::success(trans('texts.sign_up'))->withAttributes(array('id' => 'signUpButton', 'data-toggle'=>'modal', 'data-target'=>'#signUpModal'))->small() !!}
|
{!! Button::success(trans('texts.sign_up'))->withAttributes(array('id' => 'signUpButton', 'data-toggle'=>'modal', 'data-target'=>'#signUpModal'))->small() !!}
|
||||||
@elseif (!Auth::user()->isPro())
|
@elseif (Utils::isNinjaProd() && (!Auth::user()->isPro() || Auth::user()->isTrial()))
|
||||||
{!! Button::success(trans('texts.go_pro'))->withAttributes(array('id' => 'proPlanButton', 'onclick' => 'showProPlan("")'))->small() !!}
|
{!! Button::success(trans('texts.go_pro'))->withAttributes(array('id' => 'proPlanButton', 'onclick' => 'showProPlan("")'))->small() !!}
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
@ -599,10 +599,16 @@
|
|||||||
{{ Former::setOption('TwitterBootstrap3.labelWidths.large', 4) }}
|
{{ Former::setOption('TwitterBootstrap3.labelWidths.large', 4) }}
|
||||||
{{ Former::setOption('TwitterBootstrap3.labelWidths.small', 4) }}
|
{{ Former::setOption('TwitterBootstrap3.labelWidths.small', 4) }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-11 col-md-offset-1">
|
||||||
|
<div style="padding-top:20px;padding-bottom:10px;">{{ trans('texts.trial_message') }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!! Former::close() !!}
|
{!! Former::close() !!}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<center><div id="errorTaken" style="display:none"> <br/>{{ trans('texts.email_taken') }}</div></center>
|
<center><div id="errorTaken" style="display:none"> <br/>{{ trans('texts.email_taken') }}</div></center>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@ -655,11 +661,10 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if (Auth::check() && !Auth::user()->isPro())
|
@if (Auth::check() && (!Auth::user()->isPro() || Auth::user()->isTrial()))
|
||||||
<div class="modal fade" id="proPlanModal" tabindex="-1" role="dialog" aria-labelledby="proPlanModalLabel" aria-hidden="true">
|
<div class="modal fade" id="proPlanModal" tabindex="-1" role="dialog" aria-labelledby="proPlanModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog large-dialog">
|
<div class="modal-dialog large-dialog">
|
||||||
<div class="modal-content pro-plan-modal">
|
<div class="modal-content pro-plan-modal">
|
||||||
|
|
||||||
|
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<img onclick="hideProPlan()" class="close" src="{{ asset('images/pro_plan/close.png') }}"/>
|
<img onclick="hideProPlan()" class="close" src="{{ asset('images/pro_plan/close.png') }}"/>
|
||||||
@ -670,7 +675,11 @@
|
|||||||
<center>
|
<center>
|
||||||
<h2>{{ trans('texts.pro_plan_title') }}</h2>
|
<h2>{{ trans('texts.pro_plan_title') }}</h2>
|
||||||
<img class="img-responsive price" alt="Only $50 Per Year" src="{{ asset('images/pro_plan/price.png') }}"/>
|
<img class="img-responsive price" alt="Only $50 Per Year" src="{{ asset('images/pro_plan/price.png') }}"/>
|
||||||
<a class="button" href="#" onclick="submitProPlan()">{{ trans('texts.pro_plan_call_to_action') }}</a>
|
@if (Auth::user()->isEligibleForTrial())
|
||||||
|
<a class="button" href="{{ URL::to('start_trial') }}">{{ trans('texts.trial_call_to_action') }}</a>
|
||||||
|
@else
|
||||||
|
<a class="button" href="#" onclick="submitProPlan()">{{ trans('texts.pro_plan_call_to_action') }}</a>
|
||||||
|
@endif
|
||||||
</center>
|
</center>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
@ -694,12 +703,19 @@
|
|||||||
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{-- Per our license, please do not remove or modify this section. --}}
|
|
||||||
@if (!Utils::isNinjaProd())
|
|
||||||
</div>
|
</div>
|
||||||
<p> </p>
|
<br/>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@if (Utils::isNinjaProd())
|
||||||
|
@if (Auth::check() && Auth::user()->isTrial())
|
||||||
|
{!! trans(Auth::user()->account->getCountTrialDaysLeft() == 0 ? 'texts.trial_footer_last_day' : 'texts.trial_footer', [
|
||||||
|
'count' => Auth::user()->account->getCountTrialDaysLeft(),
|
||||||
|
'link' => '<a href="javascript:submitProPlan()">' . trans('texts.click_here') . '</a>'
|
||||||
|
]) !!}
|
||||||
|
@endif
|
||||||
|
@else
|
||||||
{{ trans('texts.powered_by') }}
|
{{ trans('texts.powered_by') }}
|
||||||
|
{{-- Per our license, please do not remove or modify this section. --}}
|
||||||
{!! link_to('https://www.invoiceninja.com/?utm_source=powered_by', 'InvoiceNinja.com', ['target' => '_blank', 'title' => 'invoiceninja.com']) !!} -
|
{!! link_to('https://www.invoiceninja.com/?utm_source=powered_by', 'InvoiceNinja.com', ['target' => '_blank', 'title' => 'invoiceninja.com']) !!} -
|
||||||
{!! link_to(RELEASES_URL, 'v' . NINJA_VERSION, ['target' => '_blank', 'title' => trans('texts.trello_roadmap')]) !!} |
|
{!! link_to(RELEASES_URL, 'v' . NINJA_VERSION, ['target' => '_blank', 'title' => trans('texts.trello_roadmap')]) !!} |
|
||||||
@if (Auth::user()->account->isWhiteLabel())
|
@if (Auth::user()->account->isWhiteLabel())
|
||||||
|
@ -215,6 +215,7 @@ function InvoiceModel(data) {
|
|||||||
self.invoice_date = ko.observable('');
|
self.invoice_date = ko.observable('');
|
||||||
self.invoice_number = ko.observable('');
|
self.invoice_number = ko.observable('');
|
||||||
self.due_date = ko.observable('');
|
self.due_date = ko.observable('');
|
||||||
|
self.recurring_due_date = ko.observable('');
|
||||||
self.start_date = ko.observable('');
|
self.start_date = ko.observable('');
|
||||||
self.end_date = ko.observable('');
|
self.end_date = ko.observable('');
|
||||||
self.last_sent_date = ko.observable('');
|
self.last_sent_date = ko.observable('');
|
||||||
|
@ -201,6 +201,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
{!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'card_number')
|
{!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'card_number')
|
||||||
|
->id('card_number')
|
||||||
->placeholder(trans('texts.card_number'))
|
->placeholder(trans('texts.card_number'))
|
||||||
->autocomplete('cc-number')
|
->autocomplete('cc-number')
|
||||||
->data_stripe('number')
|
->data_stripe('number')
|
||||||
@ -208,6 +209,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
{!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'cvv')
|
{!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'cvv')
|
||||||
|
->id('cvv')
|
||||||
->placeholder(trans('texts.cvv'))
|
->placeholder(trans('texts.cvv'))
|
||||||
->autocomplete('off')
|
->autocomplete('off')
|
||||||
->data_stripe('cvc')
|
->data_stripe('cvc')
|
||||||
@ -217,6 +219,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
{!! Former::select($accountGateway->getPublishableStripeKey() ? '' : 'expiration_month')
|
{!! Former::select($accountGateway->getPublishableStripeKey() ? '' : 'expiration_month')
|
||||||
|
->id('expiration_month')
|
||||||
->autocomplete('cc-exp-month')
|
->autocomplete('cc-exp-month')
|
||||||
->data_stripe('exp-month')
|
->data_stripe('exp-month')
|
||||||
->placeholder(trans('texts.expiration_month'))
|
->placeholder(trans('texts.expiration_month'))
|
||||||
@ -236,6 +239,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
{!! Former::select($accountGateway->getPublishableStripeKey() ? '' : 'expiration_year')
|
{!! Former::select($accountGateway->getPublishableStripeKey() ? '' : 'expiration_year')
|
||||||
|
->id('expiration_year')
|
||||||
->autocomplete('cc-exp-year')
|
->autocomplete('cc-exp-year')
|
||||||
->data_stripe('exp-year')
|
->data_stripe('exp-year')
|
||||||
->placeholder(trans('texts.expiration_year'))
|
->placeholder(trans('texts.expiration_year'))
|
||||||
|
@ -27,7 +27,9 @@ class OnlinePaymentCest
|
|||||||
$I->amOnPage('/settings/online_payments');
|
$I->amOnPage('/settings/online_payments');
|
||||||
|
|
||||||
if (strpos($I->grabFromCurrentUrl(), 'create') !== false) {
|
if (strpos($I->grabFromCurrentUrl(), 'create') !== false) {
|
||||||
$I->fillField(['name' =>'23_apiKey'], Fixtures::get('gateway_key'));
|
$I->fillField(['name' =>'23_apiKey'], Fixtures::get('secret_key'));
|
||||||
|
// Fails to load StripeJS causing "ReferenceError: Can't find variable: Stripe"
|
||||||
|
//$I->fillField(['name' =>'publishable_key'], Fixtures::get('publishable_key'));
|
||||||
$I->selectOption('#token_billing_type_id', 4);
|
$I->selectOption('#token_billing_type_id', 4);
|
||||||
$I->click('Save');
|
$I->click('Save');
|
||||||
$I->see('Successfully created gateway');
|
$I->see('Successfully created gateway');
|
||||||
@ -73,11 +75,12 @@ class OnlinePaymentCest
|
|||||||
$I->fillField(['name' => 'state'], $this->faker->state);
|
$I->fillField(['name' => 'state'], $this->faker->state);
|
||||||
$I->fillField(['name' => 'postal_code'], $this->faker->postcode);
|
$I->fillField(['name' => 'postal_code'], $this->faker->postcode);
|
||||||
$I->selectDropdown($I, 'United States', '.country-select .dropdown-toggle');
|
$I->selectDropdown($I, 'United States', '.country-select .dropdown-toggle');
|
||||||
$I->fillField(['name' => 'card_number'], '4242424242424242');
|
$I->fillField('#card_number', '4242424242424242');
|
||||||
$I->fillField(['name' => 'cvv'], '1234');
|
$I->fillField('#cvv', '1234');
|
||||||
$I->selectOption('#expiration_month', 12);
|
$I->selectOption('#expiration_month', 12);
|
||||||
$I->selectOption('#expiration_year', date('Y'));
|
$I->selectOption('#expiration_year', date('Y'));
|
||||||
$I->click('.btn-success');
|
$I->click('.btn-success');
|
||||||
|
$I->wait(3);
|
||||||
$I->see('Successfully applied payment');
|
$I->see('Successfully applied payment');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user