From 4a749d5868345eee69e4af2c696896d2e8209ea9 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 25 Feb 2016 20:34:23 +0200 Subject: [PATCH] Improvements to custom designer --- app/Http/Controllers/AccountController.php | 16 ++++++ app/Models/Account.php | 2 +- public/built.js | 54 +++++++++++++++++-- public/js/pdf.pdfmake.js | 20 +++++-- public/js/script.js | 35 ++++++++++++ resources/lang/da/texts.php | 3 +- resources/lang/de/texts.php | 3 +- resources/lang/en/texts.php | 3 +- resources/lang/es/texts.php | 3 +- resources/lang/es_ES/texts.php | 3 +- resources/lang/fr/texts.php | 3 +- resources/lang/fr_CA/texts.php | 3 +- resources/lang/it/texts.php | 3 +- resources/lang/lt/texts.php | 3 +- resources/lang/nb_NO/texts.php | 3 +- resources/lang/nl/texts.php | 3 +- resources/lang/pt_BR/texts.php | 3 +- resources/lang/sv/texts.php | 3 +- .../views/accounts/customize_design.blade.php | 18 ++++++- resources/views/master.blade.php | 2 +- 20 files changed, 147 insertions(+), 39 deletions(-) diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 6c0f59a3ba91..90b6ef930b3a 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -15,6 +15,7 @@ use Response; use Request; use App\Models\Affiliate; use App\Models\License; +use App\Models\Invoice; use App\Models\User; use App\Models\Account; use App\Models\Gateway; @@ -393,6 +394,21 @@ class AccountController extends BaseController if ($section == ACCOUNT_CUSTOMIZE_DESIGN) { $data['customDesign'] = ($account->custom_design && !$design) ? $account->custom_design : $design; + + // sample invoice to help determine variables + $invoice = Invoice::scope() + ->with('client', 'account') + ->where('is_quote', '=', false) + ->where('is_recurring', '=', false) + ->first(); + + if ($invoice) { + $invoice->hidePrivateFields(); + unset($invoice->account); + unset($invoice->invoice_items); + unset($invoice->client->contacts); + $data['sampleInvoice'] = $invoice; + } } return View::make("accounts.{$section}", $data); diff --git a/app/Models/Account.php b/app/Models/Account.php index d3f64bb2eec0..b729f46ffb50 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -439,7 +439,7 @@ class Account extends Eloquent return $height; } - public function createInvoice($entityType, $clientId = null) + public function createInvoice($entityType = ENTITY_INVOICE, $clientId = null) { $invoice = Invoice::createNew(); diff --git a/public/built.js b/public/built.js index 81952805cb58..1d94fa1247a6 100644 --- a/public/built.js +++ b/public/built.js @@ -30833,6 +30833,11 @@ function truncate(str, length) { return (str && str.length > length) ? (str.substr(0, length-1) + '...') : str; } +// http://stackoverflow.com/questions/280634/endswith-in-javascript +function endsWith(str, suffix) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; +} + // http://codeaid.net/javascript/convert-seconds-to-hours-minutes-and-seconds-%28javascript%29 function secondsToTime(secs) { @@ -30865,6 +30870,11 @@ function toSnakeCase(str) { return str.replace(/([A-Z])/g, function($1){return "_"+$1.toLowerCase();}); } +// https://coderwall.com/p/iprsng/convert-snake-case-to-camelcase +function snakeToCamel(s){ + return s.replace(/_([a-z])/g, function (g) { return g[1].toUpperCase(); }); +} + function getDescendantProp(obj, desc) { var arr = desc.split("."); while(arr.length && (obj = obj[arr.shift()])); @@ -30873,6 +30883,7 @@ function getDescendantProp(obj, desc) { function doubleDollarSign(str) { if (!str) return ''; + if (!str.replace) return str; return str.replace(/\$/g, '\$\$\$'); } @@ -30906,6 +30917,29 @@ function loadImages(selector) { }); } +// http://stackoverflow.com/questions/4810841/how-can-i-pretty-print-json-using-javascript +function prettyJson(json) { + if (typeof json != 'string') { + json = JSON.stringify(json, undefined, 2); + } + json = json.replace(/&/g, '&').replace(//g, '>'); + return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { + var cls = 'number'; + if (/^"/.test(match)) { + if (/:$/.test(match)) { + cls = 'key'; + } else { + cls = 'string'; + } + } else if (/true|false/.test(match)) { + cls = 'boolean'; + } else if (/null/.test(match)) { + cls = 'null'; + } + match = snakeToCamel(match); + return '' + match + ''; + }); +} var NINJA = NINJA || {}; NINJA.TEMPLATES = { @@ -31117,18 +31151,28 @@ NINJA.decodeJavascript = function(invoice, javascript) } // search/replace values - var regExp = new RegExp('"\\$[\\\w\\\.]*?Value"', 'g'); + var regExp = new RegExp('"\\$[a-z][\\\w\\\.]*?[Value]?"', 'g'); var matches = javascript.match(regExp); - + if (matches) { for (var i=0; i= 0) { + continue; + } + + // legacy style had 'Value' at the end + if (endsWith(match, 'Value"')) { + field = match.substring(2, match.indexOf('Value')); + } else { + field = match.substring(2, match.length - 1); + } field = toSnakeCase(field); - + var value = getDescendantProp(invoice, field) || ' '; value = doubleDollarSign(value); - javascript = javascript.replace(match, '"'+value+'"'); } } diff --git a/public/js/pdf.pdfmake.js b/public/js/pdf.pdfmake.js index 58ddd24d2db7..a5b9ca681515 100644 --- a/public/js/pdf.pdfmake.js +++ b/public/js/pdf.pdfmake.js @@ -209,18 +209,28 @@ NINJA.decodeJavascript = function(invoice, javascript) } // search/replace values - var regExp = new RegExp('"\\$[\\\w\\\.]*?Value"', 'g'); + var regExp = new RegExp('"\\$[a-z][\\\w\\\.]*?[Value]?"', 'g'); var matches = javascript.match(regExp); - + if (matches) { for (var i=0; i= 0) { + continue; + } + + // legacy style had 'Value' at the end + if (endsWith(match, 'Value"')) { + field = match.substring(2, match.indexOf('Value')); + } else { + field = match.substring(2, match.length - 1); + } field = toSnakeCase(field); - + var value = getDescendantProp(invoice, field) || ' '; value = doubleDollarSign(value); - javascript = javascript.replace(match, '"'+value+'"'); } } diff --git a/public/js/script.js b/public/js/script.js index 2dc527f6d3d4..6167b8ff05f2 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -961,6 +961,11 @@ function truncate(str, length) { return (str && str.length > length) ? (str.substr(0, length-1) + '...') : str; } +// http://stackoverflow.com/questions/280634/endswith-in-javascript +function endsWith(str, suffix) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; +} + // http://codeaid.net/javascript/convert-seconds-to-hours-minutes-and-seconds-%28javascript%29 function secondsToTime(secs) { @@ -993,6 +998,11 @@ function toSnakeCase(str) { return str.replace(/([A-Z])/g, function($1){return "_"+$1.toLowerCase();}); } +// https://coderwall.com/p/iprsng/convert-snake-case-to-camelcase +function snakeToCamel(s){ + return s.replace(/_([a-z])/g, function (g) { return g[1].toUpperCase(); }); +} + function getDescendantProp(obj, desc) { var arr = desc.split("."); while(arr.length && (obj = obj[arr.shift()])); @@ -1001,6 +1011,7 @@ function getDescendantProp(obj, desc) { function doubleDollarSign(str) { if (!str) return ''; + if (!str.replace) return str; return str.replace(/\$/g, '\$\$\$'); } @@ -1033,3 +1044,27 @@ function loadImages(selector) { $(item).attr('data-src', src); }); } + +// http://stackoverflow.com/questions/4810841/how-can-i-pretty-print-json-using-javascript +function prettyJson(json) { + if (typeof json != 'string') { + json = JSON.stringify(json, undefined, 2); + } + json = json.replace(/&/g, '&').replace(//g, '>'); + return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { + var cls = 'number'; + if (/^"/.test(match)) { + if (/:$/.test(match)) { + cls = 'key'; + } else { + cls = 'string'; + } + } else if (/true|false/.test(match)) { + cls = 'boolean'; + } else if (/null/.test(match)) { + cls = 'null'; + } + match = snakeToCamel(match); + return '' + match + ''; + }); +} \ No newline at end of file diff --git a/resources/lang/da/texts.php b/resources/lang/da/texts.php index c4522aca3b94..35a559ac6ade 100644 --- a/resources/lang/da/texts.php +++ b/resources/lang/da/texts.php @@ -747,8 +747,7 @@ return array( 'primary_user' => 'Primær bruger', 'help' => 'Hjælp', 'customize_help' => '

Vi bruger pdfmake til at definere faktura design felter. pdfmake legeplads giver en god mulighed for at se biblioteket i aktion.

-

Du kan tilgå alle faktura felter ved at tilføje Value til slutningen. For eksempel viser $invoiceNumberValue fakturanummeret.

-

For at tilgå under indstillingerne ved hjælp af dot notation. For eksempel kan man for at vise klient navnet bruge $client.nameValue.

+

For at tilgå under indstillingerne ved hjælp af dot notation. For eksempel kan man for at vise klient navnet bruge $client.name.

Hvis du mangler svar på nogen spørgsmål så post et spørgsmål i vores support forum.

', 'invoice_due_date' => 'Due Date', diff --git a/resources/lang/de/texts.php b/resources/lang/de/texts.php index 5fea0bf82b63..3c2ec0580feb 100644 --- a/resources/lang/de/texts.php +++ b/resources/lang/de/texts.php @@ -747,8 +747,7 @@ return array( 'primary_user' => 'Primärer Benutzer', 'help' => 'Hilfe', 'customize_help' => '

Wir benutzen zur deklarativen Definition der Rechnungsdesigns pdfmake. Der pdfmake playground bietet Gelegenheit die Bibliothek in Aktion zu sehen.

-

Man kann jedes Rechnungsfeld nutzen, in dem man Value hinten anhängt. Zum Beispiel zeigt $invoiceNumberValue die Rechnungsnummer.

-

Mit der dot notation kann auf Kind-Eigenschaften zugegriffen werden. Für den Kundennamen kann man zum Beispiel $client.nameValue benutzen.

+

Mit der dot notation kann auf Kind-Eigenschaften zugegriffen werden. Für den Kundennamen kann man zum Beispiel $client.name benutzen.

Wenn du Hilfe brauchst schreibe uns gern im Support Forum (Englisch).

', 'invoice_due_date' => 'Fällig am', diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index d98821b83fee..2b4a9cd872d1 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -655,8 +655,7 @@ $LANG = array( 'primary_user' => 'Primary User', 'help' => 'Help', 'customize_help' => '

We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.

-

You can access any invoice field by adding Value to the end. For example $invoiceNumberValue displays the invoice number.

-

To access a child property using dot notation. For example to show the client name you could use $client.nameValue.

+

To access a child property using dot notation. For example to show the client name you could use $client.name.

If you need help figuring something out post a question to our support forum.

', 'invoice_due_date' => 'Due Date', 'quote_due_date' => 'Valid Until', diff --git a/resources/lang/es/texts.php b/resources/lang/es/texts.php index 5639fff40824..1b1f27947c46 100644 --- a/resources/lang/es/texts.php +++ b/resources/lang/es/texts.php @@ -725,8 +725,7 @@ return array( 'primary_user' => 'Usuario Primario', 'help' => 'Ayuda', 'customize_help' => '

Nosotros usamos pdfmake para definir los diseños de las facturas de manera declarativa. El playground de pdfmake es una excelente manera de ver a la librería en acción.

-

Puedes acceder cualquier campo de una factura agregando Value al final. Por ejemplo, $invoiceNumberValue muestra el número de factura.

-

Para acceder a una propiedad hija usando notación de punto.Por ejemplo, para mostrar el nombre de un cliente se puede usar $client.nameValue.

+

Para acceder a una propiedad hija usando notación de punto.Por ejemplo, para mostrar el nombre de un cliente se puede usar $client.name.

Si necesitas ayuda entendiendo algo puede preguntar en nuestro foro de soporte.

', 'invoice_due_date' => 'Fecha de Vencimiento', diff --git a/resources/lang/es_ES/texts.php b/resources/lang/es_ES/texts.php index 6640183cf610..4e29075d559a 100644 --- a/resources/lang/es_ES/texts.php +++ b/resources/lang/es_ES/texts.php @@ -746,8 +746,7 @@ return array( 'primary_user' => 'Usuario Principal', 'help' => 'Ayuda', 'customize_help' => '

We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.

-

You can access any invoice field by adding Value to the end. For example $invoiceNumberValue displays the invoice number.

-

To access a child property using dot notation. For example to show the client name you could use $client.nameValue.

+

To access a child property using dot notation. For example to show the client name you could use $client.name.

If you need help figuring something out post a question to our support forum.

', 'invoice_due_date' => 'Fecha de Pago', diff --git a/resources/lang/fr/texts.php b/resources/lang/fr/texts.php index f14abbe158a0..1572eb219137 100644 --- a/resources/lang/fr/texts.php +++ b/resources/lang/fr/texts.php @@ -738,8 +738,7 @@ return array( 'primary_user' => 'Utilisateur principal', 'help' => 'Aide', 'customize_help' => '

Nous utilisons pdfmake pour définir le design des factures. Le bac à sable de pdfmake est une bonne façon de voir cette bibliothèque en action.

-

Vous pouvez accéder à n\'importe quel champ de facture en ajoutant Value à la fin. Par exemple $invoiceNumberValue affiche le numéro de facture.

-

Pour accéder à une propriété héritée avec la notation par point. Par exemple pour montrer le nom du client vous pouvez utiliser $client.nameValue.

+

Pour accéder à une propriété héritée avec la notation par point. Par exemple pour montrer le nom du client vous pouvez utiliser $client.name.

Si vous avez besoin d\'aide pour comprendre quelque chose envoyez une question à notre forum de support.

', 'invoice_due_date' => 'Date limite', diff --git a/resources/lang/fr_CA/texts.php b/resources/lang/fr_CA/texts.php index f5deda9deda3..946fac0696ed 100644 --- a/resources/lang/fr_CA/texts.php +++ b/resources/lang/fr_CA/texts.php @@ -741,8 +741,7 @@ return array( 'primary_user' => 'Utilisateur principal', 'help' => 'Aide', 'customize_help' => '

Nous utilisons pdfmake pour définir le design des factures de façon déclarative. L\'environnement pdfmake permet de voir la librairie en action.

-

Vous pouvez accéder à n\'importe quel champ de facture en ajoutant Value à la fin. Par exemple $invoiceNumberValue affiche le numéro de facture.

-

Pour accéder à une propriété enfant en utilisant la notation par point. Par exemple $client.nameValueaffiche le nom du client.

+

Pour accéder à une propriété enfant en utilisant la notation par point. Par exemple $client.nameaffiche le nom du client.

Si vous avez besoin d\'aide à cet effet, n\'hésitez pas à publier une question sur notre forum d\'aide (en anglais).

', 'invoice_due_date' => 'Échéance', diff --git a/resources/lang/it/texts.php b/resources/lang/it/texts.php index 3af6cf341634..5c358ae62627 100644 --- a/resources/lang/it/texts.php +++ b/resources/lang/it/texts.php @@ -743,8 +743,7 @@ return array( 'primary_user' => 'Primary User', 'help' => 'Help', 'customize_help' => '

We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.

-

You can access any invoice field by adding Value to the end. For example $invoiceNumberValue displays the invoice number.

-

To access a child property using dot notation. For example to show the client name you could use $client.nameValue.

+

To access a child property using dot notation. For example to show the client name you could use $client.name.

If you need help figuring something out post a question to our support forum.

', 'invoice_due_date' => 'Due Date', diff --git a/resources/lang/lt/texts.php b/resources/lang/lt/texts.php index 1da6b841fd11..4dc55e9e5e4f 100644 --- a/resources/lang/lt/texts.php +++ b/resources/lang/lt/texts.php @@ -750,8 +750,7 @@ return array( 'primary_user' => 'Primary User', 'help' => 'Help', 'customize_help' => '

We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.

-

You can access any invoice field by adding Value to the end. For example $invoiceNumberValue displays the invoice number.

-

To access a child property using dot notation. For example to show the client name you could use $client.nameValue.

+

To access a child property using dot notation. For example to show the client name you could use $client.name.

If you need help figuring something out post a question to our support forum.

', 'invoice_due_date' => 'Due Date', diff --git a/resources/lang/nb_NO/texts.php b/resources/lang/nb_NO/texts.php index e232d9fa4b17..875df81d4639 100644 --- a/resources/lang/nb_NO/texts.php +++ b/resources/lang/nb_NO/texts.php @@ -746,8 +746,7 @@ return array( 'primary_user' => 'Hovedbruker', 'help' => 'Hjelp', 'customize_help' => '

Vi bruker pdfmake for å definere faktura designene deklarativt. Pdfmake playground gir en flott måte å se biblioteket i aksjon.

-

Du kan få tilgang til hvilket som helst faktura felt ved å legge til Value i slutten. For eksempel $invoiceNumberValue viser faktura nummeret.

-

For å få tilgang til et underelementet ved bruk av prikk notasjon. For eksempel for å vise klientens navn, kan du bruke $client.nameValue.

+

For å få tilgang til et underelementet ved bruk av prikk notasjon. For eksempel for å vise klientens navn, kan du bruke $client.name.

Om du trenger hjelp til å finne ut noe, poster et spørsmål til vårt brukerforum.

', 'invoice_due_date' => 'Tidsfrist', diff --git a/resources/lang/nl/texts.php b/resources/lang/nl/texts.php index e1f3f40c162e..9794f7c0089b 100644 --- a/resources/lang/nl/texts.php +++ b/resources/lang/nl/texts.php @@ -741,8 +741,7 @@ return array( 'primary_user' => 'Primaire gebruiker', 'help' => 'Help', 'customize_help' => '

We gebruiken pdfmake om de factuur ontwerpen declaratief te definieren. De pdfmake playground is een interessante manier om de library in actie te zien.

-

Je kan elk factuur veld gebruiken door Veld toe te voegen op het einde. Bijvoorbeeld $invoiceNumberValue toont de factuur nummer.

-

Gebruik dot notatie om een "kind eigenschap" te gebruiken. Bijvoorbeeld voor de klant naam te tonen gebruik je $client.nameValue.

+

Gebruik dot notatie om een "kind eigenschap" te gebruiken. Bijvoorbeeld voor de klant naam te tonen gebruik je $client.name.

Als je ergens hulp bij nodig hebt, post dan een vraag op ons support forum.

', 'invoice_due_date' => 'Vervaldatum', diff --git a/resources/lang/pt_BR/texts.php b/resources/lang/pt_BR/texts.php index 0c2d7d915fee..731be8bbbdc6 100644 --- a/resources/lang/pt_BR/texts.php +++ b/resources/lang/pt_BR/texts.php @@ -739,8 +739,7 @@ return array( 'primary_user' => 'Usuário Principal', 'help' => 'Ajuda', 'customize_help' => '

We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.

-

You can access any invoice field by adding Value to the end. For example $invoiceNumberValue displays the invoice number.

-

To access a child property using dot notation. For example to show the client name you could use $client.nameValue.

+

To access a child property using dot notation. For example to show the client name you could use $client.name.

If you need help figuring something out post a question to our support forum.

', 'invoice_due_date' => 'Data de vencimento', diff --git a/resources/lang/sv/texts.php b/resources/lang/sv/texts.php index 41f51c2c8ac3..8f72d9bb40d3 100644 --- a/resources/lang/sv/texts.php +++ b/resources/lang/sv/texts.php @@ -745,8 +745,7 @@ return array( 'primary_user' => 'Primary User', 'help' => 'Help', 'customize_help' => '

We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.

-

You can access any invoice field by adding Value to the end. For example $invoiceNumberValue displays the invoice number.

-

To access a child property using dot notation. For example to show the client name you could use $client.nameValue.

+

To access a child property using dot notation. For example to show the client name you could use $client.name.

If you need help figuring something out post a question to our support forum.

', 'invoice_due_date' => 'Due Date', diff --git a/resources/views/accounts/customize_design.blade.php b/resources/views/accounts/customize_design.blade.php index f4ffa9b215a9..a1860e97ed72 100644 --- a/resources/views/accounts/customize_design.blade.php +++ b/resources/views/accounts/customize_design.blade.php @@ -22,6 +22,14 @@ background: #FFFFFF !important; } + /* http://stackoverflow.com/questions/4810841/how-can-i-pretty-print-json-using-javascript */ + pre {outline: 1px solid #ccc; padding: 5px; margin: 5px; } + .string { color: green; } + .number { color: darkorange; } + .boolean { color: blue; } + .null { color: magenta; } + .key { color: red; } + @stop @@ -140,8 +148,14 @@ target = target.substring(1); // strip leading # loadEditor(target); }); - + refreshPDF(true); + + @if (isset($sampleInvoice) && $sampleInvoice) + var sample = {!! $sampleInvoice->toJSON() !!} + console.log(sample); + $('#sampleData').show().html(prettyJson(sample)); + @endif }); @@ -206,6 +220,8 @@
{!! trans('texts.customize_help') !!} + +