mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 13:12:50 +01:00
Merge pull request #4322 from beganovich/v5-display-signature-and-terms-on-quotes
(v5) Display signatures & accepting terms for invoices & quotes
This commit is contained in:
commit
f81526af2d
@ -170,8 +170,8 @@ class PaymentController extends Controller
|
||||
|
||||
});
|
||||
|
||||
if ((bool) $request->signature) {
|
||||
$invoices->each(function ($invoice) {
|
||||
if (request()->has('signature') && !is_null(request()->signature) && !empty(request()->signature)) {
|
||||
$invoices->each(function ($invoice) use ($request) {
|
||||
InjectSignature::dispatch($invoice, $request->signature);
|
||||
});
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use App\Events\Quote\QuoteWasApproved;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ClientPortal\ProcessQuotesInBulkRequest;
|
||||
use App\Http\Requests\ClientPortal\ShowQuoteRequest;
|
||||
use App\Jobs\Invoice\InjectSignature;
|
||||
use App\Models\Company;
|
||||
use App\Models\Quote;
|
||||
use App\Utils\Ninja;
|
||||
@ -111,6 +112,10 @@ class QuoteController extends Controller
|
||||
foreach ($quotes as $quote) {
|
||||
$quote->service()->approve(auth()->user())->save();
|
||||
event(new QuoteWasApproved(auth('contact')->user(), $quote, $quote->company, Ninja::eventVars()));
|
||||
|
||||
if (request()->has('signature') && !is_null(request()->signature) && !empty(request()->signature)) {
|
||||
InjectSignature::dispatch($quote, request()->signature);
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()
|
||||
|
@ -15,9 +15,9 @@ class InjectSignature implements ShouldQueue
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var App\Models\Invoice
|
||||
* @var App\Models\Invoice|App\Models\Quote
|
||||
*/
|
||||
public $invoice;
|
||||
public $entity;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@ -27,12 +27,12 @@ class InjectSignature implements ShouldQueue
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param Invoice $invoice
|
||||
* @param $entity
|
||||
* @param string $signature
|
||||
*/
|
||||
public function __construct(Invoice $invoice, string $signature)
|
||||
public function __construct($entity, string $signature)
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
$this->entity = $entity;
|
||||
|
||||
$this->signature = $signature;
|
||||
}
|
||||
@ -44,7 +44,7 @@ class InjectSignature implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$invitation = $this->invoice->invitations->whereNotNull('signature_base64')->first();
|
||||
$invitation = $this->entity->invitations->whereNotNull('signature_base64')->first();
|
||||
|
||||
if (! $invitation) {
|
||||
return;
|
||||
|
2
public/js/clients/quotes/approve.js
vendored
2
public/js/clients/quotes/approve.js
vendored
@ -1,2 +1,2 @@
|
||||
/*! For license information please see approve.js.LICENSE.txt */
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=10)}({10:function(e,t,n){e.exports=n("WuMn")},WuMn:function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var r=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.shouldDisplaySignature=t}var t,r,o;return t=e,(r=[{key:"submitForm",value:function(){document.getElementById("approve-form").submit()}},{key:"displaySignature",value:function(){document.getElementById("displaySignatureModal").removeAttribute("style"),new SignaturePad(document.getElementById("signature-pad"),{backgroundColor:"rgb(240,240,240)",penColor:"rgb(0, 0, 0)"})}},{key:"handle",value:function(){var e=this;document.getElementById("approve-button").addEventListener("click",(function(){e.shouldDisplaySignature&&(e.displaySignature(),document.getElementById("signature-next-step").addEventListener("click",(function(){e.submitForm()}))),e.shouldDisplaySignature||e.submitForm()}))}}])&&n(t.prototype,r),o&&n(t,o),e}(),o=document.querySelector('meta[name="require-quote-signature"]').content;new r(Boolean(+o)).handle()}});
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var u=t[r]={i:r,l:!1,exports:{}};return e[r].call(u.exports,u,u.exports,n),u.l=!0,u.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var u in e)n.d(r,u,function(t){return e[t]}.bind(null,u));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=10)}({10:function(e,t,n){e.exports=n("WuMn")},WuMn:function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var r=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.shouldDisplaySignature=t,this.shouldDisplayTerms=n,this.termsAccepted=!1}var t,r,u;return t=e,(r=[{key:"submitForm",value:function(){document.getElementById("approve-form").submit()}},{key:"displaySignature",value:function(){document.getElementById("displaySignatureModal").removeAttribute("style");var e=new SignaturePad(document.getElementById("signature-pad"),{penColor:"rgb(0, 0, 0)"});this.signaturePad=e}},{key:"displayTerms",value:function(){document.getElementById("displayTermsModal").removeAttribute("style")}},{key:"handle",value:function(){var e=this;document.getElementById("approve-button").addEventListener("click",(function(){e.shouldDisplaySignature&&e.shouldDisplayTerms&&(e.displaySignature(),document.getElementById("signature-next-step").addEventListener("click",(function(){e.displayTerms(),document.getElementById("accept-terms-button").addEventListener("click",(function(){document.querySelector('input[name="signature"').value=e.signaturePad.toDataURL(),e.termsAccepted=!0,e.submitForm()}))}))),e.shouldDisplaySignature&&!e.shouldDisplayTerms&&(e.displaySignature(),document.getElementById("signature-next-step").addEventListener("click",(function(){document.querySelector('input[name="signature"').value=e.signaturePad.toDataURL(),e.submitForm()}))),!e.shouldDisplaySignature&&e.shouldDisplayTerms&&(e.displayTerms(),document.getElementById("accept-terms-button").addEventListener("click",(function(){e.termsAccepted=!0,e.submitForm()}))),e.shouldDisplaySignature||e.shouldDisplayTerms||e.submitForm()}))}}])&&n(t.prototype,r),u&&n(t,u),e}(),u=document.querySelector('meta[name="require-quote-signature"]').content,o=document.querySelector('meta[name="show-quote-terms"]').content;new r(Boolean(+u),Boolean(+o)).handle()}});
|
@ -12,7 +12,7 @@
|
||||
"/js/clients/payments/stripe-credit-card.js": "/js/clients/payments/stripe-credit-card.js?id=f4659d26a26d2f408397",
|
||||
"/js/clients/payments/stripe-sofort.js": "/js/clients/payments/stripe-sofort.js?id=7f5b13e34c75e63c015e",
|
||||
"/js/clients/quotes/action-selectors.js": "/js/clients/quotes/action-selectors.js?id=1b8f9325aa6e8595e7fa",
|
||||
"/js/clients/quotes/approve.js": "/js/clients/quotes/approve.js?id=9cdbe50bab63dc1dd520",
|
||||
"/js/clients/quotes/approve.js": "/js/clients/quotes/approve.js?id=85bcae0a646882e56b12",
|
||||
"/js/clients/shared/multiple-downloads.js": "/js/clients/shared/multiple-downloads.js?id=5c35d28cf0a3286e7c45",
|
||||
"/js/clients/shared/pdf.js": "/js/clients/shared/pdf.js?id=fa54bb4229aba6b0817c",
|
||||
"/js/setup/setup.js": "/js/setup/setup.js?id=f42b2dee6575623822c2",
|
||||
|
92
resources/js/clients/quotes/approve.js
vendored
92
resources/js/clients/quotes/approve.js
vendored
@ -9,8 +9,10 @@
|
||||
*/
|
||||
|
||||
class Approve {
|
||||
constructor(displaySignature) {
|
||||
constructor(displaySignature, displayTerms) {
|
||||
this.shouldDisplaySignature = displaySignature;
|
||||
this.shouldDisplayTerms = displayTerms;
|
||||
this.termsAccepted = false;
|
||||
}
|
||||
|
||||
submitForm() {
|
||||
@ -18,34 +20,84 @@ class Approve {
|
||||
}
|
||||
|
||||
displaySignature() {
|
||||
let displaySignatureModal = document.getElementById('displaySignatureModal');
|
||||
let displaySignatureModal = document.getElementById(
|
||||
'displaySignatureModal'
|
||||
);
|
||||
displaySignatureModal.removeAttribute('style');
|
||||
|
||||
const signaturePad = new SignaturePad(document.getElementById('signature-pad'), {
|
||||
backgroundColor: 'rgb(240,240,240)',
|
||||
penColor: 'rgb(0, 0, 0)'
|
||||
});
|
||||
const signaturePad = new SignaturePad(
|
||||
document.getElementById('signature-pad'),
|
||||
{
|
||||
penColor: 'rgb(0, 0, 0)',
|
||||
}
|
||||
);
|
||||
|
||||
this.signaturePad = signaturePad;
|
||||
}
|
||||
|
||||
displayTerms() {
|
||||
let displayTermsModal = document.getElementById("displayTermsModal");
|
||||
displayTermsModal.removeAttribute("style");
|
||||
}
|
||||
|
||||
handle() {
|
||||
document.getElementById('approve-button').addEventListener('click', () => {
|
||||
if (this.shouldDisplaySignature) {
|
||||
this.displaySignature();
|
||||
document
|
||||
.getElementById('approve-button')
|
||||
.addEventListener('click', () => {
|
||||
if (this.shouldDisplaySignature && this.shouldDisplayTerms) {
|
||||
this.displaySignature();
|
||||
|
||||
document.getElementById('signature-next-step').addEventListener('click', () => {
|
||||
document
|
||||
.getElementById('signature-next-step')
|
||||
.addEventListener('click', () => {
|
||||
this.displayTerms();
|
||||
|
||||
document
|
||||
.getElementById('accept-terms-button')
|
||||
.addEventListener('click', () => {
|
||||
document.querySelector(
|
||||
'input[name="signature"'
|
||||
).value = this.signaturePad.toDataURL();
|
||||
this.termsAccepted = true;
|
||||
this.submitForm();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (this.shouldDisplaySignature && !this.shouldDisplayTerms) {
|
||||
this.displaySignature();
|
||||
|
||||
document
|
||||
.getElementById('signature-next-step')
|
||||
.addEventListener('click', () => {
|
||||
document.querySelector(
|
||||
'input[name="signature"'
|
||||
).value = this.signaturePad.toDataURL();
|
||||
this.submitForm();
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.shouldDisplaySignature && this.shouldDisplayTerms) {
|
||||
this.displayTerms();
|
||||
|
||||
document
|
||||
.getElementById('accept-terms-button')
|
||||
.addEventListener('click', () => {
|
||||
this.termsAccepted = true;
|
||||
this.submitForm();
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.shouldDisplaySignature && !this.shouldDisplayTerms) {
|
||||
this.submitForm();
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.shouldDisplaySignature) this.submitForm();
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const signature = document.querySelector(
|
||||
'meta[name="require-quote-signature"]'
|
||||
).content;
|
||||
|
||||
new Approve(Boolean(+signature)).handle();
|
||||
const signature = document.querySelector('meta[name="require-quote-signature"]')
|
||||
.content;
|
||||
|
||||
const terms = document.querySelector('meta[name="show-quote-terms"]').content;
|
||||
|
||||
new Approve(Boolean(+signature), Boolean(+terms)).handle();
|
||||
|
@ -3303,4 +3303,6 @@ return [
|
||||
'activity_65' => ':user emailed reminder 3 for invoice :invoice to :contact',
|
||||
'activity_66' => ':user emailed reminder endless for invoice :invoice to :contact',
|
||||
|
||||
'by_clicking_next_you_accept_terms' => 'By clicking "Next step" you accept terms.',
|
||||
'not_specified' => 'Not specified',
|
||||
];
|
||||
|
@ -1,24 +1,13 @@
|
||||
<div style="display: none;" id="displaySignatureModal"
|
||||
class="fixed bottom-0 inset-x-0 px-4 pb-4 sm:inset-0 sm:flex sm:items-center sm:justify-center">
|
||||
<div x-show="open" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200"
|
||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
|
||||
class="fixed inset-0 transition-opacity">
|
||||
<div style="display: none;" id="displaySignatureModal" class="fixed bottom-0 inset-x-0 px-4 pb-4 sm:inset-0 sm:flex sm:items-center sm:justify-center">
|
||||
<div x-show="open" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 transition-opacity">
|
||||
<div class="absolute inset-0 bg-gray-500 opacity-75"></div>
|
||||
</div>
|
||||
|
||||
<div x-show="open" x-transition:enter="ease-out duration-300"
|
||||
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" x-transition:leave="ease-in duration-200"
|
||||
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
||||
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
class="bg-white rounded-lg px-4 pt-5 pb-4 overflow-hidden shadow-xl transform transition-all sm:max-w-lg sm:w-full sm:p-6">
|
||||
<div x-show="open" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100" x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" class="bg-white rounded-lg px-4 pt-5 pb-4 overflow-hidden shadow-xl transform transition-all sm:max-w-lg sm:w-full sm:p-6">
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div
|
||||
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<svg class="h-6 w-6 text-red-600" stroke="currentColor" fill="none" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||
@ -34,11 +23,15 @@
|
||||
</div>
|
||||
<div class="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
||||
<div class="flex w-full rounded-md shadow-sm sm:ml-3 sm:w-auto">
|
||||
<button type="button" class="button button-primary bg-primary" id="signature-next-step"
|
||||
@click="document.getElementById('displaySignatureModal').style.display = 'none';">
|
||||
<button type="button" id="signature-next-step" class="button button-primary bg-primary" @click="document.getElementById('displaySignatureModal').style.display = 'none';">
|
||||
{{ ctrans('texts.next_step') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-3 flex w-full rounded-md shadow-sm sm:mt-0 sm:w-auto">
|
||||
<button @click="document.getElementById('displaySignatureModal').style.display = 'none';" type="button" class="button button-secondary">
|
||||
{{ ctrans('texts.close') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,46 +1,38 @@
|
||||
<div style="display: none;" id="displayTermsModal"
|
||||
class="fixed bottom-0 inset-x-0 px-4 pb-4 sm:inset-0 sm:flex sm:items-center sm:justify-center">
|
||||
<div x-show="open" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200"
|
||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
|
||||
class="fixed inset-0 transition-opacity">
|
||||
<div style="display: none;" id="displayTermsModal" class="fixed bottom-0 inset-x-0 px-4 pb-4 sm:inset-0 sm:flex sm:items-center sm:justify-center">
|
||||
<div x-show="open" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 transition-opacity">
|
||||
<div class="absolute inset-0 bg-gray-500 opacity-75"></div>
|
||||
</div>
|
||||
|
||||
<div x-show="open" x-transition:enter="ease-out duration-300"
|
||||
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" x-transition:leave="ease-in duration-200"
|
||||
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
||||
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
class="bg-white rounded-lg px-4 pt-5 pb-4 overflow-hidden shadow-xl transform transition-all sm:max-w-lg sm:w-full sm:p-6">
|
||||
<div x-show="open" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100" x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" class="bg-white rounded-lg px-4 pt-5 pb-4 overflow-hidden shadow-xl transform transition-all sm:max-w-lg sm:w-full sm:p-6">
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div
|
||||
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<svg class="h-6 w-6 text-red-600" stroke="currentColor" fill="none" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
<h3 class="text-xl leading-6 font-medium text-gray-900">
|
||||
{{ ctrans('texts.terms') }}
|
||||
</h3>
|
||||
<div class="mt-2">
|
||||
<p class="text-sm leading-5 text-gray-500">
|
||||
{!! $invoice->terms !!}
|
||||
</p>
|
||||
<div class="mt-4">
|
||||
@foreach($entities as $entity)
|
||||
<div class="mb-4">
|
||||
<h4 class="leading-6 font-medium text-gray-900">{{ $entity_type }} {{ $entity->number }}:</h4>
|
||||
@if($entity->terms)
|
||||
<p class="text-sm leading-5 text-gray-500">{!! $entity->terms !!}</p>
|
||||
@else
|
||||
<i class="text-sm leading-5 text-gray-500">{{ ctrans('texts.not_specified') }}</i>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
<p class="mt-4 block text-sm text-gray-900">{{ ctrans('texts.by_clicking_next_you_accept_terms') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
||||
<div class="flex w-full rounded-md shadow-sm sm:ml-3 sm:w-auto">
|
||||
<button type="button" id="accept-terms-button" class="button button-primary bg-primary">
|
||||
{{ ctrans('texts.agree_to_terms', ['terms' => trans('texts.invoice_terms')]) }}
|
||||
{{ ctrans('texts.next_step') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-3 flex w-full rounded-md shadow-sm sm:mt-0 sm:w-auto">
|
||||
<button @click="document.getElementById('displayTermsModal').style.display = 'none';" type="button"
|
||||
class="button button-secondary">
|
||||
<button @click="document.getElementById('displayTermsModal').style.display = 'none';" type="button" class="button button-secondary">
|
||||
{{ ctrans('texts.close') }}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -143,7 +143,7 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@include('portal.ninja2020.invoices.includes.terms')
|
||||
@include('portal.ninja2020.invoices.includes.terms', ['entities' => $invoices, 'entity_type' => ctrans('texts.invoice')])
|
||||
@include('portal.ninja2020.invoices.includes.signature')
|
||||
|
||||
@endsection
|
||||
|
@ -2,7 +2,8 @@
|
||||
@section('meta_title', ctrans('texts.approve'))
|
||||
|
||||
@push('head')
|
||||
<meta name="require-quote-signature" content="{{ $settings->require_invoice_signature ? true : false }}">
|
||||
<meta name="show-quote-terms" content="{{ $settings->show_accept_quote_terms ? true : false }}">
|
||||
<meta name="require-quote-signature" content="{{ $settings->require_quote_signature ? true : false }}">
|
||||
<script src="https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js"></script>
|
||||
@endpush
|
||||
|
||||
@ -14,7 +15,9 @@
|
||||
@foreach($quotes as $quote)
|
||||
<input type="hidden" name="quotes[]" value="{{ $quote->hashed_id }}">
|
||||
@endforeach
|
||||
<input type="hidden" name="signature">
|
||||
</form>
|
||||
|
||||
<div class="container mx-auto">
|
||||
<div class="grid grid-cols-6 gap-4">
|
||||
<div class="col-span-6 md:col-start-2 md:col-span-4">
|
||||
@ -78,6 +81,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('portal.ninja2020.invoices.includes.terms', ['entities' => $quotes, 'entity_type' => ctrans('texts.quote')])
|
||||
@include('portal.ninja2020.invoices.includes.signature')
|
||||
@endsection
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user