mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-31 06:14:35 -04:00
Support signing for invoice
This commit is contained in:
parent
fbf618a226
commit
3ccb33ec21
@ -747,12 +747,7 @@ class AccountController extends BaseController
|
|||||||
private function saveClientPortal()
|
private function saveClientPortal()
|
||||||
{
|
{
|
||||||
$account = Auth::user()->account;
|
$account = Auth::user()->account;
|
||||||
|
$account->fill(Input::all());
|
||||||
$account->enable_client_portal = !!Input::get('enable_client_portal');
|
|
||||||
$account->enable_client_portal_dashboard = !!Input::get('enable_client_portal_dashboard');
|
|
||||||
$account->enable_portal_password = !!Input::get('enable_portal_password');
|
|
||||||
$account->send_portal_password = !!Input::get('send_portal_password');
|
|
||||||
$account->enable_buy_now_buttons = !!Input::get('enable_buy_now_buttons');
|
|
||||||
|
|
||||||
// Only allowed for pro Invoice Ninja users or white labeled self-hosted users
|
// Only allowed for pro Invoice Ninja users or white labeled self-hosted users
|
||||||
if (Auth::user()->account->hasFeature(FEATURE_CLIENT_PORTAL_CSS)) {
|
if (Auth::user()->account->hasFeature(FEATURE_CLIENT_PORTAL_CSS)) {
|
||||||
|
@ -198,6 +198,19 @@ class ClientPortalController extends BaseController
|
|||||||
return $pdfString;
|
return $pdfString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function sign($invitationKey)
|
||||||
|
{
|
||||||
|
if (!$invitation = $this->invoiceRepo->findInvoiceByInvitation($invitationKey)) {
|
||||||
|
return RESULT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$invitation->signature_base64 = Input::get('signature');
|
||||||
|
$invitation->signature_date = date_create();
|
||||||
|
$invitation->save();
|
||||||
|
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
public function dashboard($contactKey = false)
|
public function dashboard($contactKey = false)
|
||||||
{
|
{
|
||||||
if ($contactKey) {
|
if ($contactKey) {
|
||||||
|
@ -218,6 +218,8 @@ class InvoiceController extends BaseController
|
|||||||
$contact->invitation_viewed = $invitation->viewed_date && $invitation->viewed_date != '0000-00-00 00:00:00' ? $invitation->viewed_date : false;
|
$contact->invitation_viewed = $invitation->viewed_date && $invitation->viewed_date != '0000-00-00 00:00:00' ? $invitation->viewed_date : false;
|
||||||
$contact->invitation_openend = $invitation->opened_date && $invitation->opened_date != '0000-00-00 00:00:00' ? $invitation->opened_date : false;
|
$contact->invitation_openend = $invitation->opened_date && $invitation->opened_date != '0000-00-00 00:00:00' ? $invitation->opened_date : false;
|
||||||
$contact->invitation_status = $contact->email_error ? false : $invitation->getStatus();
|
$contact->invitation_status = $contact->email_error ? false : $invitation->getStatus();
|
||||||
|
$contact->invitation_signature_svg = $invitation->signature_base64;
|
||||||
|
$contact->invitation_signature_date = $invitation->signature_date;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ Route::post('/get_started', 'AccountController@getStarted');
|
|||||||
Route::group(['middleware' => 'auth:client'], function() {
|
Route::group(['middleware' => 'auth:client'], function() {
|
||||||
Route::get('view/{invitation_key}', 'ClientPortalController@view');
|
Route::get('view/{invitation_key}', 'ClientPortalController@view');
|
||||||
Route::get('download/{invitation_key}', 'ClientPortalController@download');
|
Route::get('download/{invitation_key}', 'ClientPortalController@download');
|
||||||
|
Route::put('sign/{invitation_key}', 'ClientPortalController@sign');
|
||||||
Route::get('view', 'HomeController@viewLogo');
|
Route::get('view', 'HomeController@viewLogo');
|
||||||
Route::get('approve/{invitation_key}', 'QuoteController@approve');
|
Route::get('approve/{invitation_key}', 'QuoteController@approve');
|
||||||
Route::get('payment/{invitation_key}/{gateway_type?}/{source_id?}', 'OnlinePaymentController@showPayment');
|
Route::get('payment/{invitation_key}/{gateway_type?}/{source_id?}', 'OnlinePaymentController@showPayment');
|
||||||
|
@ -101,7 +101,9 @@ class Utils
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return \App\Models\Account::first()->hasFeature(FEATURE_WHITE_LABEL);
|
$account = \App\Models\Account::first();
|
||||||
|
|
||||||
|
return $account && $account->hasFeature(FEATURE_WHITE_LABEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getResllerType()
|
public static function getResllerType()
|
||||||
|
@ -70,6 +70,15 @@ class Account extends Eloquent
|
|||||||
'include_item_taxes_inline',
|
'include_item_taxes_inline',
|
||||||
'start_of_week',
|
'start_of_week',
|
||||||
'financial_year_start',
|
'financial_year_start',
|
||||||
|
'enable_client_portal',
|
||||||
|
'enable_client_portal_dashboard',
|
||||||
|
'enable_portal_password',
|
||||||
|
'send_portal_password',
|
||||||
|
'enable_buy_now_buttons',
|
||||||
|
'show_accept_invoice_terms',
|
||||||
|
'show_accept_quote_terms',
|
||||||
|
'require_invoice_signature',
|
||||||
|
'require_quote_signature',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1861,6 +1870,29 @@ class Account extends Eloquent
|
|||||||
|
|
||||||
return $this->enabled_modules & static::$modules[$entityType];
|
return $this->enabled_modules & static::$modules[$entityType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function showAuthenticatePanel($invoice)
|
||||||
|
{
|
||||||
|
return $this->showAcceptTerms($invoice) || $this->showSignature($invoice);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function showAcceptTerms($invoice)
|
||||||
|
{
|
||||||
|
if ( ! $this->isPro() || ! $invoice->terms) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $invoice->is_quote ? $this->show_accept_quote_terms : $this->show_accept_invoice_terms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function showSignature($invoice)
|
||||||
|
{
|
||||||
|
if ( ! $this->isPro()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $invoice->is_quote ? $this->require_quote_signature : $this->require_invoice_signature;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Account::updated(function ($account)
|
Account::updated(function ($account)
|
||||||
|
@ -31,7 +31,8 @@
|
|||||||
"dropzone": "~4.3.0",
|
"dropzone": "~4.3.0",
|
||||||
"nouislider": "~8.5.1",
|
"nouislider": "~8.5.1",
|
||||||
"bootstrap-daterangepicker": "~2.1.24",
|
"bootstrap-daterangepicker": "~2.1.24",
|
||||||
"sweetalert2": "^5.3.8"
|
"sweetalert2": "^5.3.8",
|
||||||
|
"jSignature": "brinley/jSignature#^2.1.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"jquery": "~1.11"
|
"jquery": "~1.11"
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddInvoiceSignature extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('invitations', function($table)
|
||||||
|
{
|
||||||
|
$table->text('signature_base64')->nullable();
|
||||||
|
$table->timestamp('signature_date')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('companies', function($table)
|
||||||
|
{
|
||||||
|
$table->string('utm_source')->nullable();
|
||||||
|
$table->string('utm_medium')->nullable();
|
||||||
|
$table->string('utm_campaign')->nullable();
|
||||||
|
$table->string('utm_term')->nullable();
|
||||||
|
$table->string('utm_content')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('payment_methods', function($table)
|
||||||
|
{
|
||||||
|
$table->dropForeign('payment_methods_account_gateway_token_id_foreign');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('payment_methods', function($table)
|
||||||
|
{
|
||||||
|
$table->foreign('account_gateway_token_id')->references('id')->on('account_gateway_tokens')->onDelete('cascade');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('payments', function($table)
|
||||||
|
{
|
||||||
|
$table->dropForeign('payments_payment_method_id_foreign');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('payments', function($table)
|
||||||
|
{
|
||||||
|
$table->foreign('payment_method_id')->references('id')->on('payment_methods')->onDelete('cascade');;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('invitations', function($table)
|
||||||
|
{
|
||||||
|
$table->dropColumn('signature_base64');
|
||||||
|
$table->dropColumn('signature_date');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('companies', function($table)
|
||||||
|
{
|
||||||
|
$table->dropColumn('utm_source');
|
||||||
|
$table->dropColumn('utm_medium');
|
||||||
|
$table->dropColumn('utm_campaign');
|
||||||
|
$table->dropColumn('utm_term');
|
||||||
|
$table->dropColumn('utm_content');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -80,6 +80,10 @@ elixir(function(mix) {
|
|||||||
bowerDir + '/bootstrap-daterangepicker/daterangepicker.js'
|
bowerDir + '/bootstrap-daterangepicker/daterangepicker.js'
|
||||||
], 'public/js/daterangepicker.min.js');
|
], 'public/js/daterangepicker.min.js');
|
||||||
|
|
||||||
|
mix.scripts([
|
||||||
|
bowerDir + '/jSignature/libs/jSignature.min.js'
|
||||||
|
], 'public/js/jSignature.min.js');
|
||||||
|
|
||||||
mix.scripts([
|
mix.scripts([
|
||||||
bowerDir + '/jquery/dist/jquery.js',
|
bowerDir + '/jquery/dist/jquery.js',
|
||||||
bowerDir + '/jquery-ui/jquery-ui.js',
|
bowerDir + '/jquery-ui/jquery-ui.js',
|
||||||
|
4
public/css/built.css
vendored
4
public/css/built.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
public/css/built.public.css
vendored
4
public/css/built.public.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
public/js/jSignature.min.js
vendored
Normal file
2
public/js/jSignature.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/js/jSignature.min.js.map
Normal file
1
public/js/jSignature.min.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -2175,6 +2175,19 @@ $LANG = array(
|
|||||||
'created_by' => 'Created by :name',
|
'created_by' => 'Created by :name',
|
||||||
'modules' => 'Modules',
|
'modules' => 'Modules',
|
||||||
'financial_year_start' => 'First Month of the Year',
|
'financial_year_start' => 'First Month of the Year',
|
||||||
|
'authentication' => 'Authentication',
|
||||||
|
'checkbox' => 'Checkbox',
|
||||||
|
'invoice_signature' => 'Signature',
|
||||||
|
'show_accept_invoice_terms' => 'Invoice Terms Checkbox',
|
||||||
|
'show_accept_invoice_terms_help' => 'Require client to confirm that they accept the invoice terms.',
|
||||||
|
'show_accept_quote_terms' => 'Quote Terms Checkbox',
|
||||||
|
'show_accept_quote_terms_help' => 'Require client to confirm that they accept the quote terms.',
|
||||||
|
'require_invoice_signature' => 'Invoice Signature',
|
||||||
|
'require_invoice_signature_help' => 'Require client to provide their signature.',
|
||||||
|
'require_quote_signature' => 'Quote Signature',
|
||||||
|
'require_quote_signature_help' => 'Require client to provide their signature.',
|
||||||
|
'i_agree' => 'I Agree To The Terms & Conditions',
|
||||||
|
'sign_here' => 'Please sign here:',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@
|
|||||||
{!! Former::populateField('enable_portal_password', intval($enable_portal_password)) !!}
|
{!! Former::populateField('enable_portal_password', intval($enable_portal_password)) !!}
|
||||||
{!! Former::populateField('send_portal_password', intval($send_portal_password)) !!}
|
{!! Former::populateField('send_portal_password', intval($send_portal_password)) !!}
|
||||||
{!! Former::populateField('enable_buy_now_buttons', intval($account->enable_buy_now_buttons)) !!}
|
{!! Former::populateField('enable_buy_now_buttons', intval($account->enable_buy_now_buttons)) !!}
|
||||||
|
{!! Former::populateField('show_accept_invoice_terms', intval($account->show_accept_invoice_terms)) !!}
|
||||||
|
{!! Former::populateField('show_accept_quote_terms', intval($account->show_accept_quote_terms)) !!}
|
||||||
|
{!! Former::populateField('require_invoice_signature', intval($account->require_invoice_signature)) !!}
|
||||||
|
{!! Former::populateField('require_quote_signature', intval($account->require_quote_signature)) !!}
|
||||||
|
|
||||||
@if (!Utils::isNinja() && !Auth::user()->account->hasFeature(FEATURE_WHITE_LABEL))
|
@if (!Utils::isNinja() && !Auth::user()->account->hasFeature(FEATURE_WHITE_LABEL))
|
||||||
<div class="alert alert-warning" style="font-size:larger;">
|
<div class="alert alert-warning" style="font-size:larger;">
|
||||||
@ -61,20 +65,71 @@
|
|||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">{!! trans('texts.security') !!}</h3>
|
<h3 class="panel-title">{!! trans('texts.authentication') !!}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="col-md-10 col-md-offset-1">
|
<div role="tabpanel">
|
||||||
{!! Former::checkbox('enable_portal_password')
|
<ul class="nav nav-tabs" role="tablist" style="border: none">
|
||||||
->text(trans('texts.enable'))
|
<li role="presentation" class="active"><a href="#password" aria-controls="password" role="tab" data-toggle="tab">{{ trans('texts.password') }}</a></li>
|
||||||
->help(trans('texts.enable_portal_password_help'))
|
<li role="presentation"><a href="#checkbox" aria-controls="checkbox" role="tab" data-toggle="tab">{{ trans('texts.checkbox') }}</a></li>
|
||||||
->label(trans('texts.enable_portal_password')) !!}
|
<li role="presentation"><a href="#signature" aria-controls="signature" role="tab" data-toggle="tab">{{ trans('texts.invoice_signature') }}</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-10 col-md-offset-1">
|
<div class="tab-content">
|
||||||
{!! Former::checkbox('send_portal_password')
|
<div role="tabpanel" class="tab-pane active" id="password">
|
||||||
->text(trans('texts.enable'))
|
<div class="panel-body">
|
||||||
->help(trans('texts.send_portal_password_help'))
|
<div class="row">
|
||||||
->label(trans('texts.send_portal_password')) !!}
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
{!! Former::checkbox('enable_portal_password')
|
||||||
|
->text(trans('texts.enable'))
|
||||||
|
->help(trans('texts.enable_portal_password_help'))
|
||||||
|
->label(trans('texts.enable_portal_password')) !!}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
{!! Former::checkbox('send_portal_password')
|
||||||
|
->text(trans('texts.enable'))
|
||||||
|
->help(trans('texts.send_portal_password_help'))
|
||||||
|
->label(trans('texts.send_portal_password')) !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div role="tabpanel" class="tab-pane" id="checkbox">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
{!! Former::checkbox('show_accept_invoice_terms')
|
||||||
|
->text(trans('texts.enable'))
|
||||||
|
->help(trans('texts.show_accept_invoice_terms_help'))
|
||||||
|
->label(trans('texts.show_accept_invoice_terms')) !!}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
{!! Former::checkbox('show_accept_quote_terms')
|
||||||
|
->text(trans('texts.enable'))
|
||||||
|
->help(trans('texts.show_accept_quote_terms_help'))
|
||||||
|
->label(trans('texts.show_accept_quote_terms')) !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div role="tabpanel" class="tab-pane" id="signature">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
{!! Former::checkbox('require_invoice_signature')
|
||||||
|
->text(trans('texts.enable'))
|
||||||
|
->help(trans('texts.require_invoice_signature_help'))
|
||||||
|
->label(trans('texts.require_invoice_signature')) !!}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
{!! Former::checkbox('require_quote_signature')
|
||||||
|
->text(trans('texts.enable'))
|
||||||
|
->help(trans('texts.require_quote_signature_help'))
|
||||||
|
->label(trans('texts.require_quote_signature')) !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -120,11 +120,13 @@
|
|||||||
<span data-bind="visible: !$root.invoice().is_recurring()">
|
<span data-bind="visible: !$root.invoice().is_recurring()">
|
||||||
<span data-bind="html: $data.view_as_recipient"></span>
|
<span data-bind="html: $data.view_as_recipient"></span>
|
||||||
@if (Utils::isConfirmed())
|
@if (Utils::isConfirmed())
|
||||||
<span style="vertical-align:text-top;color:red" class="fa fa-exclamation-triangle"
|
<span style="vertical-align:text-top;color:red" class="fa fa-exclamation-triangle"
|
||||||
data-bind="visible: $data.email_error, tooltip: {title: $data.email_error}"></span>
|
data-bind="visible: $data.email_error, tooltip: {title: $data.email_error}"></span>
|
||||||
<span style="vertical-align:text-top" class="glyphicon glyphicon-info-sign"
|
<span style="vertical-align:text-top" class="fa fa-info-circle"
|
||||||
data-bind="visible: $data.invitation_status, tooltip: {title: $data.invitation_status, html: true},
|
data-bind="visible: $data.invitation_status, tooltip: {title: $data.invitation_status, html: true},
|
||||||
style: {color: $data.info_color}"></span>
|
style: {color: $data.info_color}"></span>
|
||||||
|
<span style="vertical-align:text-top" class="fa fa-user-circle"
|
||||||
|
data-bind="visible: $data.invitation_signature_svg, tooltip: {title: '', html: true}"></span>
|
||||||
@endif
|
@endif
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
@ -563,7 +565,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<p> </p>
|
<p> </p>
|
||||||
|
|
||||||
@if (Auth::user()->account->live_preview))
|
@if (Auth::user()->account->live_preview)
|
||||||
@include('invoices.pdf', ['account' => Auth::user()->account])
|
@include('invoices.pdf', ['account' => Auth::user()->account])
|
||||||
@else
|
@else
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
@ -596,6 +596,8 @@ function ContactModel(data) {
|
|||||||
self.invitation_openend = ko.observable(false);
|
self.invitation_openend = ko.observable(false);
|
||||||
self.invitation_viewed = ko.observable(false);
|
self.invitation_viewed = ko.observable(false);
|
||||||
self.email_error = ko.observable('');
|
self.email_error = ko.observable('');
|
||||||
|
self.invitation_signature_svg = ko.observable('');
|
||||||
|
self.invitation_signature_date = ko.observable('');
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
ko.mapping.fromJS(data, {}, this);
|
ko.mapping.fromJS(data, {}, this);
|
||||||
|
@ -6,20 +6,31 @@
|
|||||||
@include('money_script')
|
@include('money_script')
|
||||||
|
|
||||||
@foreach ($invoice->client->account->getFontFolders() as $font)
|
@foreach ($invoice->client->account->getFontFolders() as $font)
|
||||||
<script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
<script src="{{ asset('pdf.built.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script>
|
<script src="{{ asset('pdf.built.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script>
|
||||||
|
|
||||||
|
@if ($account->showSignature($invoice))
|
||||||
|
<script src="{{ asset('js/jSignature.min.js') }}"></script>
|
||||||
|
@endif
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
background-color: #f8f8f8;
|
background-color: #f8f8f8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.dropdown-menu li a{
|
.dropdown-menu li a{
|
||||||
overflow:hidden;
|
overflow:hidden;
|
||||||
margin-top:5px;
|
margin-top:5px;
|
||||||
margin-bottom:5px;
|
margin-bottom:5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#signature {
|
||||||
|
border: 2px dotted black;
|
||||||
|
background-color:lightgrey;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@if (!empty($transactionToken) && $accountGateway->gateway_id == GATEWAY_BRAINTREE)
|
@if (!empty($transactionToken) && $accountGateway->gateway_id == GATEWAY_BRAINTREE)
|
||||||
@ -99,7 +110,7 @@
|
|||||||
@if (!empty($partialView))
|
@if (!empty($partialView))
|
||||||
@include($partialView)
|
@include($partialView)
|
||||||
@else
|
@else
|
||||||
<div class="pull-right" style="text-align:right">
|
<div id="paymentButtons" class="pull-right" style="text-align:right">
|
||||||
@if ($invoice->isQuote())
|
@if ($invoice->isQuote())
|
||||||
{!! Button::normal(trans('texts.download_pdf'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!}
|
{!! Button::normal(trans('texts.download_pdf'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!}
|
||||||
@if ($showApprove)
|
@if ($showApprove)
|
||||||
@ -191,6 +202,33 @@
|
|||||||
@else
|
@else
|
||||||
refreshPDF();
|
refreshPDF();
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@if ($account->showAuthenticatePanel($invoice))
|
||||||
|
$('#paymentButtons a').on('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
window.pendingPaymentHref = $(this).attr('href');
|
||||||
|
@if ($account->showSignature($invoice))
|
||||||
|
if (window.pendingPaymentInit) {
|
||||||
|
$("#signature").jSignature('reset');
|
||||||
|
}
|
||||||
|
@endif
|
||||||
|
@if ($account->showAcceptTerms($invoice))
|
||||||
|
$('#termsCheckbox').attr('checked', false);
|
||||||
|
@endif
|
||||||
|
$('#authenticationModal').modal('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
@if ($account->showSignature($invoice))
|
||||||
|
$('#authenticationModal').on('shown.bs.modal', function () {
|
||||||
|
if ( ! window.pendingPaymentInit) {
|
||||||
|
window.pendingPaymentInit = true;
|
||||||
|
$("#signature").jSignature().bind('change', function(e) {
|
||||||
|
setModalPayNowEnabled();
|
||||||
|
});;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
@endif
|
||||||
|
@endif
|
||||||
});
|
});
|
||||||
|
|
||||||
function onDownloadClick() {
|
function onDownloadClick() {
|
||||||
@ -203,6 +241,48 @@
|
|||||||
$('#customGatewayModal').modal('show');
|
$('#customGatewayModal').modal('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onModalPayNowClick() {
|
||||||
|
@if ($account->showSignature($invoice))
|
||||||
|
var data = {
|
||||||
|
signature: $('#signature').jSignature('getData', 'svgbase64')[1]
|
||||||
|
};
|
||||||
|
$.ajax({
|
||||||
|
url: "{{ URL::to('sign/' . $invitation->invitation_key) }}",
|
||||||
|
type: 'PUT',
|
||||||
|
data: data,
|
||||||
|
success: function(response) {
|
||||||
|
redirectToPayment();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
@else
|
||||||
|
redirectToPayment();
|
||||||
|
@endif
|
||||||
|
}
|
||||||
|
|
||||||
|
function redirectToPayment() {
|
||||||
|
$('#authenticationModal').modal('hide');
|
||||||
|
location.href = window.pendingPaymentHref;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setModalPayNowEnabled() {
|
||||||
|
var disabled = false;
|
||||||
|
|
||||||
|
@if ($account->showAcceptTerms($invoice))
|
||||||
|
if ( ! $('#termsCheckbox').is(':checked')) {
|
||||||
|
disabled = true;
|
||||||
|
}
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($account->showSignature($invoice))
|
||||||
|
if ( ! $('#signature').jSignature('isModified')) {
|
||||||
|
disabled = true;
|
||||||
|
}
|
||||||
|
@endif
|
||||||
|
|
||||||
|
$('#modalPayNowButton').attr('disabled', disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@include('invoices.pdf', ['account' => $invoice->client->account, 'viewPDF' => true])
|
@include('invoices.pdf', ['account' => $invoice->client->account, 'viewPDF' => true])
|
||||||
@ -232,4 +312,42 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@if ($account->showAuthenticatePanel($invoice))
|
||||||
|
<div class="modal fade" id="authenticationModal" tabindex="-1" role="dialog" aria-labelledby="authenticationModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h4 class="modal-title"> </h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="well">
|
||||||
|
{!! nl2br(e($invoice->terms)) !!}
|
||||||
|
</div>
|
||||||
|
@if ($account->showSignature($invoice))
|
||||||
|
<div>
|
||||||
|
{{ trans('texts.sign_here') }}
|
||||||
|
</div>
|
||||||
|
<div id="signature"></div><br/>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
@if ($account->showAcceptTerms($invoice))
|
||||||
|
<div class="pull-left">
|
||||||
|
<label for="termsCheckbox" style="font-weight:normal">
|
||||||
|
<input id="termsCheckbox" type="checkbox" onclick="setModalPayNowEnabled()"/>
|
||||||
|
{{ trans('texts.i_agree') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
<button id="modalPayNowButton" type="button" class="btn btn-success" onclick="onModalPayNowClick()" disabled="">{{ trans('texts.pay_now') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
@stop
|
@stop
|
||||||
|
Loading…
x
Reference in New Issue
Block a user