diff --git a/app/Designs/Designer.php b/app/Designs/Designer.php
index 70feff34a623..f54986bbde6b 100644
--- a/app/Designs/Designer.php
+++ b/app/Designs/Designer.php
@@ -107,7 +107,7 @@ class Designer
'
;
- $signature = '
'; /** @wip */
+ $signature = '
';
$logo = '';
if (!$this->entity->user->account->isPaid()) {
diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php
index 9511dce9c179..ae856a240f31 100644
--- a/app/Http/Controllers/ClientPortal/PaymentController.php
+++ b/app/Http/Controllers/ClientPortal/PaymentController.php
@@ -14,6 +14,7 @@ namespace App\Http\Controllers\ClientPortal;
use App\Filters\PaymentFilters;
use App\Http\Controllers\Controller;
+use App\Jobs\Invoice\InjectSignature;
use App\Models\CompanyGateway;
use App\Models\Invoice;
use App\Models\Payment;
@@ -90,9 +91,14 @@ class PaymentController extends Controller
$invoices->map(function ($invoice) {
$invoice->balance = Number::formatMoney($invoice->balance, $invoice->client);
$invoice->due_date = $this->formatDate($invoice->due_date, $invoice->client->date_format());
+
return $invoice;
});
+ $invoices->each(function ($invoice) {
+ InjectSignature::dispatch($invoice, request()->signature);
+ });
+
$payment_methods = auth()->user()->client->getPaymentMethods($amount);
$gateway = CompanyGateway::find(request()->input('company_gateway_id'));
@@ -110,7 +116,6 @@ class PaymentController extends Controller
'hashed_ids' => request()->invoices,
];
-
return $gateway->driver(auth()->user()->client)->processPaymentView($data);
}
diff --git a/app/Jobs/Invoice/InjectSignature.php b/app/Jobs/Invoice/InjectSignature.php
new file mode 100644
index 000000000000..5e2f7636425e
--- /dev/null
+++ b/app/Jobs/Invoice/InjectSignature.php
@@ -0,0 +1,56 @@
+invoice = $invoice;
+
+ $this->signature = $signature;
+ }
+
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $invitation = $this->invoice->invitations->whereNotNull('signature_base64')->first();
+
+ if (!$invitation) {
+ return;
+ }
+
+ $invitation->signature_base64 = $this->signature;
+ $invitation->save();
+
+ CreateInvoicePdf::dispatch($invitation);
+ }
+}
diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php
index 7b43cb973267..337c170d45ea 100644
--- a/app/Utils/HtmlEngine.php
+++ b/app/Utils/HtmlEngine.php
@@ -301,7 +301,7 @@ class HtmlEngine
$data['$task.tax_name2'] = ['value' => '', 'label' => ctrans('texts.tax')];
$data['$task.tax_name3'] = ['value' => '', 'label' => ctrans('texts.tax')];
$data['$task.line_total'] = ['value' => '', 'label' => ctrans('texts.line_total')];
- //$data['$contact.signature']
+ $data['$contact.signature'] = ['value' => $this->invitation->signature_base64, 'label' => ctrans('texts.signature')];
// $data['custom_label1'] = ['value' => '', 'label' => ctrans('texts.')];
// $data['custom_label2'] = ['value' => '', 'label' => ctrans('texts.')];
diff --git a/public/js/clients/invoices/payment.js b/public/js/clients/invoices/payment.js
index 9503f46e3c32..178e93627541 100644
--- a/public/js/clients/invoices/payment.js
+++ b/public/js/clients/invoices/payment.js
@@ -1,2 +1,2 @@
/*! For license information please see payment.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=3)}({3:function(e,t,n){e.exports=n("FuOr")},FuOr:function(e,t){function n(e,t){for(var n=0;n {
- this.termsAccepted = true;
- this.submitForm();
- });
+ document
+ .getElementById("accept-terms-button")
+ .addEventListener("click", () => {
+ this.termsAccepted = true;
+ this.submitForm();
+ });
}
if (!this.shouldDisplaySignature && this.shouldDisplayTerms) {
this.displaySignature();
- document.getElementById('signature-next-step').addEventListener('click', () => {
- this.submitForm();
- });
+ document
+ .getElementById("signature-next-step")
+ .addEventListener("click", () => {
+ document.querySelector('input[name="signature"').value = this.signaturePad.toDataURL();
+ this.submitForm();
+ });
}
if (this.shouldDisplaySignature && this.shouldDisplayTerms) {
this.displaySignature();
- document.getElementById('signature-next-step').addEventListener('click', () => {
- this.displayTerms();
+ document
+ .getElementById("signature-next-step")
+ .addEventListener("click", () => {
+ this.displayTerms();
- document.getElementById('accept-terms-button').addEventListener('click', () => {
- this.termsAccepted = true;
- this.submitForm();
+ 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) {
@@ -55,28 +67,38 @@ class Payment {
}
submitForm() {
- document.getElementById('payment-form').submit();
+ document.getElementById("payment-form").submit();
}
displayTerms() {
- let displayTermsModal = document.getElementById('displayTermsModal');
- displayTermsModal.removeAttribute('style');
+ let displayTermsModal = document.getElementById("displayTermsModal");
+ displayTermsModal.removeAttribute("style");
}
displaySignature() {
- let displaySignatureModal = document.getElementById('displaySignatureModal');
- displaySignatureModal.removeAttribute('style');
+ 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;
}
handle() {
- document.querySelectorAll('.dropdown-gateway-button').forEach((element) => {
- element.addEventListener('click', () => this.handleMethodSelect(element));
- });
+ document
+ .querySelectorAll(".dropdown-gateway-button")
+ .forEach(element => {
+ element.addEventListener("click", () =>
+ this.handleMethodSelect(element)
+ );
+ });
}
}
@@ -84,10 +106,6 @@ const signature = document.querySelector(
'meta[name="require-invoice-signature"]'
).content;
-const terms = document.querySelector(
- 'meta[name="show-invoice-terms"]'
-).content;
+const terms = document.querySelector('meta[name="show-invoice-terms"]').content;
new Payment(Boolean(+signature), Boolean(+terms)).handle();
-
-
diff --git a/resources/views/portal/ninja2020/invoices/includes/signature.blade.php b/resources/views/portal/ninja2020/invoices/includes/signature.blade.php
index 3da52cec874d..a1a84a41668e 100644
--- a/resources/views/portal/ninja2020/invoices/includes/signature.blade.php
+++ b/resources/views/portal/ninja2020/invoices/includes/signature.blade.php
@@ -27,7 +27,7 @@
diff --git a/resources/views/portal/ninja2020/invoices/payment.blade.php b/resources/views/portal/ninja2020/invoices/payment.blade.php
index 2ec7ca61933a..443ebde9ea93 100644
--- a/resources/views/portal/ninja2020/invoices/payment.blade.php
+++ b/resources/views/portal/ninja2020/invoices/payment.blade.php
@@ -16,6 +16,7 @@
@endforeach
+