Working on pdfmake

This commit is contained in:
Hillel Coren 2015-05-22 10:22:24 +03:00
parent 0ffd13f864
commit 33d139adf5
8 changed files with 365 additions and 253 deletions

View File

@ -331,6 +331,9 @@ class AccountController extends BaseController
$account->primary_color = Input::get('primary_color');
$account->secondary_color = Input::get('secondary_color');
$account->invoice_design_id = Input::get('invoice_design_id');
if (Input::has('font_size')) {
$account->font_size = intval(Input::get('font_size'));
}
$account->save();
Session::flash('message', trans('texts.updated_settings'));

View File

@ -279,6 +279,7 @@ define('MAX_NUM_CLIENTS', 500);
define('MAX_NUM_CLIENTS_PRO', 20000);
define('MAX_NUM_USERS', 20);
define('MAX_SUBDOMAIN_LENGTH', 30);
define('DEFAULT_FONT_SIZE', 9);
define('INVOICE_STATUS_DRAFT', 1);
define('INVOICE_STATUS_SENT', 2);

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddFontSize extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->smallInteger('font_size')->default(DEFAULT_FONT_SIZE);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('font_size');
});
}
}

View File

@ -33068,14 +33068,56 @@ function roundToTwo(num, toString) {
function truncate(str, length) {
return (str && str.length > length) ? (str.substr(0, length-1) + '...') : str;
}
var NINJA = NINJA || {};
function GetPdfMake(invoice, javascript, callback) {
var account = invoice.account;
var baseDD = {
pageMargins: [40, 40, 40, 40]
pageMargins: [40, 40, 40, 40],
styles: {
bold: {
bold: true
},
cost: {
alignment: 'right'
},
quantity: {
alignment: 'right'
},
tax: {
alignment: 'right'
},
lineTotal: {
alignment: 'right'
},
right: {
alignment: 'right'
},
subtotals: {
alignment: 'right'
},
termsLabel: {
bold: true,
margin: [0, 10, 0, 4]
}
},
footer: function(){
f = [{ text:invoice.invoice_footer?invoice.invoice_footer:"", margin: [40, 0]}]
if (!invoice.is_pro && logoImages.imageLogo1) {
f.push({
image: logoImages.imageLogo1,
width: 150,
margin: [40,0]
});
}
return f;
},
};
eval(javascript);
dd = _.extend(dd, baseDD);
eval(javascript);
dd = $.extend(true, baseDD, dd);
/*
var fonts = {
Roboto: {
@ -33093,7 +33135,8 @@ function GetPdfMake(invoice, javascript, callback) {
};
return doc;
}
function notesAndTerms(invoice)
NINJA.notesAndTerms = function(invoice)
{
var text = [];
if (invoice.public_notes) {
@ -33108,7 +33151,7 @@ function notesAndTerms(invoice)
return text;
}
function invoiceLines(invoice) {
NINJA.invoiceLines = function(invoice) {
var grid = [
[
{text: invoiceLabels.item, style: 'tableHeader'},
@ -33139,42 +33182,43 @@ function invoiceLines(invoice) {
tax = parseFloat(item.tax_rate);
}
// show at most one blank line
if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) {
continue;
}
shownItem = true;
// show at most one blank line
if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) {
continue;
}
shownItem = true;
// process date variables
if (invoice.is_recurring) {
notes = processVariables(notes);
productKey = processVariables(productKey);
}
// process date variables
if (invoice.is_recurring) {
notes = processVariables(notes);
productKey = processVariables(productKey);
}
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (tax) {
lineTotal += lineTotal * tax / 100;
}
if (lineTotal) {
total += lineTotal;
}
lineTotal = formatMoney(lineTotal, currencyId);
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (tax) {
lineTotal += lineTotal * tax / 100;
}
if (lineTotal) {
total += lineTotal;
}
lineTotal = formatMoney(lineTotal, currencyId);
rowStyle = i%2===0?'odd':'even';
rowStyle = i%2===0?'odd':'even';
row[0] = {style:["productKey", rowStyle], text:productKey};
row[1] = {style:["notes", rowStyle], text:notes};
row[2] = {style:["cost", rowStyle], text:cost};
row[3] = {style:["quantity", rowStyle], text:qty};
row[4] = {style:["tax", rowStyle], text:""+tax};
row[5] = {style:["lineTotal", rowStyle], text:lineTotal};
row[0] = {style:["productKey", rowStyle], text:productKey};
row[1] = {style:["notes", rowStyle], text:notes};
row[2] = {style:["cost", rowStyle], text:cost};
row[3] = {style:["quantity", rowStyle], text:qty};
row[4] = {style:["tax", rowStyle], text:""+tax};
row[5] = {style:["lineTotal", rowStyle], text:lineTotal};
grid.push(row);
}
return grid;
grid.push(row);
}
return grid;
}
function subtotals(invoice)
NINJA.subtotals = function(invoice)
{
if (!invoice) {
return;
@ -33216,7 +33260,7 @@ function subtotals(invoice)
return data;
}
function accountDetails(account) {
NINJA.accountDetails = function(account) {
var data = [];
if(account.name) data.push({text:account.name, style:'accountName'});
if(account.id_number) data.push({text:account.id_number, style:'accountDetails'});
@ -33226,7 +33270,7 @@ function accountDetails(account) {
return data;
}
function accountAddress(account) {
NINJA.accountAddress = function(account) {
var address = '';
if (account.city || account.state || account.postal_code) {
address = ((account.city ? account.city + ', ' : '') + account.state + ' ' + account.postal_code).trim();
@ -33239,7 +33283,7 @@ function accountAddress(account) {
return data;
}
function invoiceDetails(invoice) {
NINJA.invoiceDetails = function(invoice) {
var data = [
[
invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number,
@ -33258,7 +33302,7 @@ function invoiceDetails(invoice) {
return data;
}
function clientDetails(invoice) {
NINJA.clientDetails = function(invoice) {
var client = invoice.client;
if (!client) {
return;
@ -33282,16 +33326,23 @@ function clientDetails(invoice) {
if (!field) {
continue;
}
data.push(field);
}
data.push([field]);
}
if (!data.length) {
data.push(['']);
}
return data;
}
function primaryColor( defaultColor) {
return NINJA.primaryColor?NINJA.primaryColor:defaultColor;
NINJA.getPrimaryColor = function(defaultColor) {
return NINJA.primaryColor ? NINJA.primaryColor : defaultColor;
}
function secondaryColor( defaultColor) {
return NINJA.primaryColor?NINJA.secondaryColor:defaultColor;
NINJA.getSecondaryColor = function(defaultColor) {
return NINJA.primaryColor ? NINJA.secondaryColor : defaultColor;
}
NINJA.getEntityLabel = function(invoice) {
return invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice;
}

View File

@ -1,11 +1,53 @@
var NINJA = NINJA || {};
function GetPdfMake(invoice, javascript, callback) {
var account = invoice.account;
var baseDD = {
pageMargins: [40, 40, 40, 40]
pageMargins: [40, 40, 40, 40],
styles: {
bold: {
bold: true
},
cost: {
alignment: 'right'
},
quantity: {
alignment: 'right'
},
tax: {
alignment: 'right'
},
lineTotal: {
alignment: 'right'
},
right: {
alignment: 'right'
},
subtotals: {
alignment: 'right'
},
termsLabel: {
bold: true,
margin: [0, 10, 0, 4]
}
},
footer: function(){
f = [{ text:invoice.invoice_footer?invoice.invoice_footer:"", margin: [40, 0]}]
if (!invoice.is_pro && logoImages.imageLogo1) {
f.push({
image: logoImages.imageLogo1,
width: 150,
margin: [40,0]
});
}
return f;
},
};
eval(javascript);
dd = _.extend(dd, baseDD);
eval(javascript);
dd = $.extend(true, baseDD, dd);
/*
var fonts = {
Roboto: {
@ -23,7 +65,8 @@ function GetPdfMake(invoice, javascript, callback) {
};
return doc;
}
function notesAndTerms(invoice)
NINJA.notesAndTerms = function(invoice)
{
var text = [];
if (invoice.public_notes) {
@ -38,7 +81,7 @@ function notesAndTerms(invoice)
return text;
}
function invoiceLines(invoice) {
NINJA.invoiceLines = function(invoice) {
var grid = [
[
{text: invoiceLabels.item, style: 'tableHeader'},
@ -69,42 +112,43 @@ function invoiceLines(invoice) {
tax = parseFloat(item.tax_rate);
}
// show at most one blank line
if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) {
continue;
}
shownItem = true;
// show at most one blank line
if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) {
continue;
}
shownItem = true;
// process date variables
if (invoice.is_recurring) {
notes = processVariables(notes);
productKey = processVariables(productKey);
}
// process date variables
if (invoice.is_recurring) {
notes = processVariables(notes);
productKey = processVariables(productKey);
}
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (tax) {
lineTotal += lineTotal * tax / 100;
}
if (lineTotal) {
total += lineTotal;
}
lineTotal = formatMoney(lineTotal, currencyId);
var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty));
if (tax) {
lineTotal += lineTotal * tax / 100;
}
if (lineTotal) {
total += lineTotal;
}
lineTotal = formatMoney(lineTotal, currencyId);
rowStyle = i%2===0?'odd':'even';
rowStyle = i%2===0?'odd':'even';
row[0] = {style:["productKey", rowStyle], text:productKey};
row[1] = {style:["notes", rowStyle], text:notes};
row[2] = {style:["cost", rowStyle], text:cost};
row[3] = {style:["quantity", rowStyle], text:qty};
row[4] = {style:["tax", rowStyle], text:""+tax};
row[5] = {style:["lineTotal", rowStyle], text:lineTotal};
row[0] = {style:["productKey", rowStyle], text:productKey};
row[1] = {style:["notes", rowStyle], text:notes};
row[2] = {style:["cost", rowStyle], text:cost};
row[3] = {style:["quantity", rowStyle], text:qty};
row[4] = {style:["tax", rowStyle], text:""+tax};
row[5] = {style:["lineTotal", rowStyle], text:lineTotal};
grid.push(row);
}
return grid;
grid.push(row);
}
return grid;
}
function subtotals(invoice)
NINJA.subtotals = function(invoice)
{
if (!invoice) {
return;
@ -146,7 +190,7 @@ function subtotals(invoice)
return data;
}
function accountDetails(account) {
NINJA.accountDetails = function(account) {
var data = [];
if(account.name) data.push({text:account.name, style:'accountName'});
if(account.id_number) data.push({text:account.id_number, style:'accountDetails'});
@ -156,7 +200,7 @@ function accountDetails(account) {
return data;
}
function accountAddress(account) {
NINJA.accountAddress = function(account) {
var address = '';
if (account.city || account.state || account.postal_code) {
address = ((account.city ? account.city + ', ' : '') + account.state + ' ' + account.postal_code).trim();
@ -169,7 +213,7 @@ function accountAddress(account) {
return data;
}
function invoiceDetails(invoice) {
NINJA.invoiceDetails = function(invoice) {
var data = [
[
invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number,
@ -188,7 +232,7 @@ function invoiceDetails(invoice) {
return data;
}
function clientDetails(invoice) {
NINJA.clientDetails = function(invoice) {
var client = invoice.client;
if (!client) {
return;
@ -212,16 +256,23 @@ function clientDetails(invoice) {
if (!field) {
continue;
}
data.push(field);
}
data.push([field]);
}
if (!data.length) {
data.push(['']);
}
return data;
}
function primaryColor( defaultColor) {
return NINJA.primaryColor?NINJA.primaryColor:defaultColor;
NINJA.getPrimaryColor = function(defaultColor) {
return NINJA.primaryColor ? NINJA.primaryColor : defaultColor;
}
function secondaryColor( defaultColor) {
return NINJA.primaryColor?NINJA.secondaryColor:defaultColor;
NINJA.getSecondaryColor = function(defaultColor) {
return NINJA.primaryColor ? NINJA.secondaryColor : defaultColor;
}
NINJA.getEntityLabel = function(invoice) {
return invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice;
}

View File

@ -1,187 +1,151 @@
//pdfmake
var dd = {
content: [
content: [
{
columns: [
columns: [
[
invoice.image?
{
image: invoice.image,
fit: [150, 80]
}:""
invoice.image?
{
image: invoice.image,
fit: [150, 80]
}:""
],
{
stack: accountDetails(account)
stack: NINJA.accountDetails(account)
},
{
stack: accountAddress(account)
stack: NINJA.accountAddress(account)
}
]
]
},
{
text:(invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice).toUpperCase(),
margin: [8, 70, 8, 16],
style: 'primaryColor',
fontSize: 11
text:(NINJA.getEntityLabel(invoice)).toUpperCase(),
margin: [8, 70, 8, 16],
style: 'primaryColor',
fontSize: NINJA.fontSize + 2
},
{
table: {
headerRows: 1,
widths: ['auto', 'auto', '*'],
body: [[
{
table: {
body: invoiceDetails(invoice),
},
layout: 'noBorders',
},
clientDetails(invoice),
''
]]
},
layout: {
hLineWidth: function (i, node) {
return (i === 0 || i === node.table.body.length) ? .5 : 0;
table: {
headerRows: 1,
widths: ['auto', 'auto', '*'],
body: [
[
{
table: {
body: NINJA.invoiceDetails(invoice),
},
layout: 'noBorders',
},
{
table: {
body: NINJA.clientDetails(invoice),
},
layout: 'noBorders',
},
''
]
]
},
vLineWidth: function (i, node) {
return 0;
},
hLineColor: function (i, node) {
return '#D8D8D8';
},
paddingLeft: function(i, node) { return 8; },
paddingRight: function(i, node) { return 8; },
paddingTop: function(i, node) { return 4; },
paddingBottom: function(i, node) { return 4; }
}
},
'\n',
{
table: {
headerRows: 1,
widths: ['15%', '*', 'auto', 'auto', 'auto', 'auto'],
body:invoiceLines(invoice),
},
layout: {
hLineWidth: function (i, node) {
return i === 0 ? 0 : .5;
},
vLineWidth: function (i, node) {
return 0;
},
hLineColor: function (i, node) {
return '#D8D8D8';
},
paddingLeft: function(i, node) { return 8; },
paddingRight: function(i, node) { return 8; },
paddingTop: function(i, node) { return 8; },
paddingBottom: function(i, node) { return 8; }
},
},
'\n',
{
columns: [
notesAndTerms(invoice),
{
style: 'subtotals',
table: {
widths: ['*', '*'],
body: subtotals(invoice),
},
layout: {
layout: {
hLineWidth: function (i, node) {
return 0;
return (i === 0 || i === node.table.body.length) ? .5 : 0;
},
vLineWidth: function (i, node) {
return 0;
return 0;
},
hLineColor: function (i, node) {
return '#D8D8D8';
},
paddingLeft: function(i, node) { return 8; },
paddingRight: function(i, node) { return 8; },
paddingTop: function(i, node) { return 4; },
paddingBottom: function(i, node) { return 4; }
},
paddingBottom: function(i, node) { return 4; }
}
]
},
],
'\n',
{
table: {
headerRows: 1,
widths: ['15%', '*', 'auto', 'auto', 'auto', 'auto'],
body: NINJA.invoiceLines(invoice),
},
layout: {
hLineWidth: function (i, node) {
return i === 0 ? 0 : .5;
},
vLineWidth: function (i, node) {
return 0;
},
hLineColor: function (i, node) {
return '#D8D8D8';
},
paddingLeft: function(i, node) { return 8; },
paddingRight: function(i, node) { return 8; },
paddingTop: function(i, node) { return 8; },
paddingBottom: function(i, node) { return 8; }
},
},
'\n',
{
columns: [
NINJA.notesAndTerms(invoice),
{
style: 'subtotals',
table: {
widths: ['*', '*'],
body: NINJA.subtotals(invoice),
},
layout: {
hLineWidth: function (i, node) {
return 0;
},
vLineWidth: function (i, node) {
return 0;
},
paddingLeft: function(i, node) { return 8; },
paddingRight: function(i, node) { return 8; },
paddingTop: function(i, node) { return 4; },
paddingBottom: function(i, node) { return 4; }
},
}
]
},
],
footer: function(){
f = [{ text:invoice.invoice_footer?invoice.invoice_footer:"", margin: [40, 0]}]
if (!invoice.is_pro && logoImages.imageLogo1) {
f.push({
image: logoImages.imageLogo1,
width: 150,
margin: [40,0]
});
}
return f;
},
defaultStyle: {
//font: 'Roboto',
fontSize: 9,
margin: [8, 4, 8, 4]
},
styles: {
primaryColor:{
color: primaryColor('#299CC2')
defaultStyle: {
fontSize: NINJA.fontSize,
margin: [8, 4, 8, 4]
},
accountName: {
margin: [4, 2, 4, 2],
color:primaryColor('#299CC2')
styles: {
primaryColor:{
color: NINJA.getPrimaryColor('#299CC2')
},
accountName: {
margin: [4, 2, 4, 2],
color: NINJA.getPrimaryColor('#299CC2')
},
accountDetails: {
margin: [4, 2, 4, 2],
color: '#AAA9A9'
},
even: {
},
odd: {
fillColor:'#F4F4F4'
},
productKey: {
color: NINJA.getPrimaryColor('#299CC2')
},
tableHeader: {
bold: true
},
balanceDueLabel: {
fontSize: NINJA.fontSize + 2
},
balanceDueValue: {
fontSize: NINJA.fontSize + 2,
color: NINJA.getPrimaryColor('#299CC2')
},
},
accountDetails: {
margin: [4, 2, 4, 2],
color: '#AAA9A9'
},
bold: {
bold: true
},
even: {
},
odd: {
fillColor:'#F4F4F4'
},
productKey: {
color:primaryColor('#299CC2')
},
cost: {
alignment: 'right'
},
quantity: {
alignment: 'right'
},
tax: {
alignment: 'right'
},
lineTotal: {
alignment: 'right'
},
right: {
alignment: 'right'
},
subtotals: {
alignment: 'right'
},
tableHeader: {
bold: true
},
balanceDueLabel: {
fontSize: 11
},
balanceDueValue: {
fontSize: 11,
color:primaryColor('#299CC2')
},
notes: {
},
terms: {
},
termsLabel: {
bold: true,
fontSize: 10,
margin: [0, 10, 0, 4]
}
}
pageMargins: [40, 40, 40, 40],
};

View File

@ -40,6 +40,7 @@
NINJA.primaryColor = $('#primary_color').val();
NINJA.secondaryColor = $('#secondary_color').val();
NINJA.fontSize = parseInt($('#font_size').val());
doc = generatePDF(invoice, getDesignJavascript(), true);
doc.getDataUrl(cb);
@ -80,15 +81,18 @@
@if (!Utils::isPro() || \App\Models\InvoiceDesign::count() == COUNT_FREE_DESIGNS)
{!! Former::select('invoice_design_id')->style('display:inline;width:120px')->fromQuery($invoiceDesigns, 'name', 'id')->addOption(trans('texts.more_designs') . '...', '-1') !!}
{!! Former::select('invoice_design_id')->style('display:inline;width:120px')->fromQuery($invoiceDesigns, 'name', 'id')->addOption(trans('texts.more_designs') . '...', '-1') !!}
@else
{!! Former::select('invoice_design_id')->style('display:inline;width:120px')->fromQuery($invoiceDesigns, 'name', 'id') !!}
@endif
@if (Auth::user()->account->utf8_invoices)
{!! Former::text('font_size')->type('number')->min('0')->step('1')->style('width:120px') !!}
@endif
{!! Former::text('primary_color') !!}
{!! Former::text('secondary_color') !!}
</div>
</div>

View File

@ -5,17 +5,21 @@
for (var i=0; i<currencies.length; i++) {
var currency = currencies[i];
currencyMap[currency.id] = currency;
}
}
var NINJA = NINJA || {};
@if (Auth::check())
NINJA.primaryColor = "{{ Auth::user()->account->primary_color }}";
NINJA.secondaryColor = "{{ Auth::user()->account->secondary_color }}";
NINJA.fontSize = {{ Auth::user()->account->font_size ?: DEFAULT_FONT_SIZE }};
@endif
NINJA.parseFloat = function(str) {
if (!str) return '';
str = (str+'').replace(/[^0-9\.\-]/g, '');
return window.parseFloat(str);
}
function formatMoney(value, currency_id, hide_symbol) {
value = NINJA.parseFloat(value);
if (!currency_id) currency_id = {{ Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY) }};