mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-08 12:12:48 +01:00
Enabled customizing invoice designs
This commit is contained in:
parent
48b73e7e22
commit
35d794b36f
28
.gitignore
vendored
28
.gitignore
vendored
@ -13,18 +13,26 @@
|
||||
/bootstrap/environment.php
|
||||
/vendor
|
||||
/node_modules
|
||||
.env
|
||||
/.DS_Store
|
||||
/Thumbs.db
|
||||
.env.development.php
|
||||
.env.php
|
||||
.idea
|
||||
.project
|
||||
error_log
|
||||
public/error_log
|
||||
/.env
|
||||
/.env.development.php
|
||||
/.env.php
|
||||
|
||||
/error_log
|
||||
/auth.json
|
||||
/public/error_log
|
||||
|
||||
/ninja.sublime-project
|
||||
/ninja.sublime-workspace
|
||||
auth.json
|
||||
/.phpstorm.meta.php
|
||||
/_ide_helper.php
|
||||
/.idea
|
||||
/.project
|
||||
|
||||
.phpstorm.meta.php
|
||||
_ide_helper.php
|
||||
/public/js/templates/business.js
|
||||
/public/js/templates/creative.js
|
||||
/public/js/templates/elegant.js
|
||||
/public/js/templates/hipster.js
|
||||
/public/js/templates/photo.js
|
||||
/public/js/templates/playful.js
|
@ -195,9 +195,11 @@ class AccountController extends BaseController
|
||||
'title' => trans('texts.invoice_settings'),
|
||||
];
|
||||
|
||||
if ($subSection == ACCOUNT_INVOICE_DESIGN) {
|
||||
if ($subSection == ACCOUNT_INVOICE_DESIGN
|
||||
|| $subSection == ACCOUNT_CUSTOMIZE_DESIGN) {
|
||||
$invoice = new stdClass();
|
||||
$client = new stdClass();
|
||||
$contact = new stdClass();
|
||||
$invoiceItem = new stdClass();
|
||||
|
||||
$client->name = 'Sample Client';
|
||||
@ -208,11 +210,17 @@ class AccountController extends BaseController
|
||||
$client->work_phone = '';
|
||||
$client->work_email = '';
|
||||
|
||||
$invoice->invoice_number = Auth::user()->account->getNextInvoiceNumber();
|
||||
$invoice->invoice_number = $account->getNextInvoiceNumber();
|
||||
$invoice->invoice_date = date_create()->format('Y-m-d');
|
||||
$invoice->account = json_decode(Auth::user()->account->toJson());
|
||||
$invoice->account = json_decode($account->toJson());
|
||||
$invoice->amount = $invoice->balance = 100;
|
||||
|
||||
$invoice->terms = $account->invoice_terms;
|
||||
$invoice->invoice_footer = $account->invoice_footer;
|
||||
|
||||
$contact->email = 'contact@gmail.com';
|
||||
$client->contacts = [$contact];
|
||||
|
||||
$invoiceItem->cost = 100;
|
||||
$invoiceItem->qty = 1;
|
||||
$invoiceItem->notes = 'Notes';
|
||||
@ -221,15 +229,28 @@ class AccountController extends BaseController
|
||||
$invoice->client = $client;
|
||||
$invoice->invoice_items = [$invoiceItem];
|
||||
|
||||
$data['account'] = $account;
|
||||
$data['invoice'] = $invoice;
|
||||
$data['invoiceDesigns'] = InvoiceDesign::availableDesigns();
|
||||
$data['invoiceLabels'] = json_decode($account->invoice_labels) ?: [];
|
||||
$data['title'] = trans('texts.invoice_design');
|
||||
$data['invoiceDesigns'] = InvoiceDesign::availableDesigns($subSection == ACCOUNT_CUSTOMIZE_DESIGN);
|
||||
|
||||
$design = false;
|
||||
foreach ($data['invoiceDesigns'] as $item) {
|
||||
if ($item->id == $account->invoice_design_id) {
|
||||
$design = $item->javascript;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($subSection == ACCOUNT_CUSTOMIZE_DESIGN) {
|
||||
$data['customDesign'] = $account->custom_design ?: $design;
|
||||
}
|
||||
} else if ($subSection == ACCOUNT_EMAIL_TEMPLATES) {
|
||||
$data['invoiceEmail'] = $account->getEmailTemplate(ENTITY_INVOICE);
|
||||
$data['quoteEmail'] = $account->getEmailTemplate(ENTITY_QUOTE);
|
||||
$data['paymentEmail'] = $account->getEmailTemplate(ENTITY_PAYMENT);
|
||||
$data['emailFooter'] = $account->getEmailFooter();
|
||||
$data['emailFooter'] = $account->getEmailFooter();
|
||||
$data['title'] = trans('texts.email_templates');
|
||||
} else if ($subSection == ACCOUNT_USER_MANAGEMENT) {
|
||||
$data['title'] = trans('texts.users_and_tokens');
|
||||
@ -263,6 +284,8 @@ class AccountController extends BaseController
|
||||
return AccountController::saveInvoiceSettings();
|
||||
} elseif ($subSection == ACCOUNT_INVOICE_DESIGN) {
|
||||
return AccountController::saveInvoiceDesign();
|
||||
} elseif ($subSection == ACCOUNT_CUSTOMIZE_DESIGN) {
|
||||
return AccountController::saveCustomizeDesign();
|
||||
} elseif ($subSection == ACCOUNT_EMAIL_TEMPLATES) {
|
||||
return AccountController::saveEmailTemplates();
|
||||
}
|
||||
@ -271,6 +294,24 @@ class AccountController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
private function saveCustomizeDesign() {
|
||||
if (Auth::user()->account->isPro()) {
|
||||
$account = Auth::user()->account;
|
||||
$account->custom_design = Input::get('custom_design');
|
||||
$account->invoice_design_id = CUSTOM_DESIGN;
|
||||
|
||||
if (!$account->utf8_invoices) {
|
||||
$account->utf8_invoices = true;
|
||||
}
|
||||
|
||||
$account->save();
|
||||
|
||||
Session::flash('message', trans('texts.updated_settings'));
|
||||
}
|
||||
|
||||
return Redirect::to('company/advanced_settings/customize_design');
|
||||
}
|
||||
|
||||
private function saveEmailTemplates()
|
||||
{
|
||||
if (Auth::user()->account->isPro()) {
|
||||
|
@ -213,6 +213,10 @@ class InvoiceController extends BaseController
|
||||
$invoice->due_date = Utils::fromSqlDate($invoice->due_date);
|
||||
$invoice->is_pro = $account->isPro();
|
||||
|
||||
if ($invoice->invoice_design_id == CUSTOM_DESIGN) {
|
||||
$invoice->invoice_design->javascript = $account->custom_design;
|
||||
}
|
||||
|
||||
$contact = $invitation->contact;
|
||||
$contact->setVisible([
|
||||
'first_name',
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Routes
|
||||
@ -247,6 +246,8 @@ define('ACCOUNT_USER_MANAGEMENT', 'user_management');
|
||||
define('ACCOUNT_DATA_VISUALIZATIONS', 'data_visualizations');
|
||||
define('ACCOUNT_EMAIL_TEMPLATES', 'email_templates');
|
||||
define('ACCOUNT_TOKEN_MANAGEMENT', 'token_management');
|
||||
define('ACCOUNT_CUSTOMIZE_DESIGN', 'customize_design');
|
||||
|
||||
|
||||
define('ACTIVITY_TYPE_CREATE_CLIENT', 1);
|
||||
define('ACTIVITY_TYPE_ARCHIVE_CLIENT', 2);
|
||||
@ -300,6 +301,7 @@ define('INVOICE_STATUS_PARTIAL', 4);
|
||||
define('INVOICE_STATUS_PAID', 5);
|
||||
|
||||
define('PAYMENT_TYPE_CREDIT', 1);
|
||||
define('CUSTOM_DESIGN', 11);
|
||||
|
||||
define('FREQUENCY_WEEKLY', 1);
|
||||
define('FREQUENCY_TWO_WEEKS', 2);
|
||||
|
@ -12,6 +12,10 @@ class Account extends Eloquent
|
||||
use SoftDeletes;
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
protected $casts = [
|
||||
'utf8_invoice' => 'boolean',
|
||||
];
|
||||
|
||||
public function users()
|
||||
{
|
||||
return $this->hasMany('App\Models\User');
|
||||
@ -261,6 +265,8 @@ class Account extends Eloquent
|
||||
'rate',
|
||||
'hours',
|
||||
'balance',
|
||||
'from',
|
||||
'to',
|
||||
];
|
||||
|
||||
foreach ($fields as $field) {
|
||||
|
@ -2,20 +2,30 @@
|
||||
|
||||
use Eloquent;
|
||||
use Auth;
|
||||
use App\Models\InvoiceDesign;
|
||||
|
||||
class InvoiceDesign extends Eloquent
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
public function scopeAvailableDesigns($query)
|
||||
public function scopeAvailableDesigns($query, $utf8 = false)
|
||||
{
|
||||
$designs = $query->where('id', '<=', \Auth::user()->maxInvoiceDesignId())->orderBy('id')->get();
|
||||
$account = Auth::user()->account;
|
||||
$designs = $query->where('id', '<=', Auth::user()->maxInvoiceDesignId())->orderBy('id')->get();
|
||||
|
||||
foreach ($designs as $design) {
|
||||
foreach ($designs as $design) {
|
||||
$fileName = public_path(strtolower("js/templates/{$design->name}.js"));
|
||||
if (Auth::user()->account->utf8_invoices && file_exists($fileName)) {
|
||||
if (($utf8 || Auth::user()->account->utf8_invoices) && file_exists($fileName)) {
|
||||
$design->javascript = file_get_contents($fileName);
|
||||
}
|
||||
|
||||
if ($design->id == CUSTOM_DESIGN) {
|
||||
if ($account->utf8_invoices && $account->custom_design) {
|
||||
$design->javascript = $account->custom_design;
|
||||
} else {
|
||||
$designs->pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $designs;
|
||||
|
@ -100,7 +100,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||
|
||||
public function maxInvoiceDesignId()
|
||||
{
|
||||
return $this->isPro() ? 10 : COUNT_FREE_DESIGNS;
|
||||
return $this->isPro() ? 11 : COUNT_FREE_DESIGNS;
|
||||
}
|
||||
|
||||
public function getDisplayName()
|
||||
|
@ -20,7 +20,8 @@
|
||||
"d3": "3.4.11",
|
||||
"handsontable": "*",
|
||||
"pdfmake": "*",
|
||||
"moment": "*"
|
||||
"moment": "*",
|
||||
"jsoneditor": "*"
|
||||
},
|
||||
"resolutions": {
|
||||
"jquery": "~1.11"
|
||||
|
36
database/migrations/2015_07_19_081332_add_custom_design.php
Normal file
36
database/migrations/2015_07_19_081332_add_custom_design.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddCustomDesign extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('accounts', function($table)
|
||||
{
|
||||
$table->text('custom_design')->nullable();
|
||||
});
|
||||
|
||||
DB::table('invoice_designs')->insert(['id' => CUSTOM_DESIGN, 'name' => 'Custom']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('accounts', function($table)
|
||||
{
|
||||
$table->dropColumn('custom_design');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
1
public/css/jsoneditor.min.css
vendored
Normal file
1
public/css/jsoneditor.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -31644,33 +31644,51 @@ var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
|
||||
|
||||
|
||||
var invoiceOld;
|
||||
var refreshTimer;
|
||||
function generatePDF(invoice, javascript, force, cb) {
|
||||
if (!invoice || !javascript) {
|
||||
return;
|
||||
}
|
||||
console.log('== generatePDF - force: %s', force);
|
||||
if (force || !invoiceOld) {
|
||||
refreshTimer = null;
|
||||
} else {
|
||||
if (refreshTimer) {
|
||||
clearTimeout(refreshTimer);
|
||||
}
|
||||
refreshTimer = setTimeout(function() {
|
||||
generatePDF(invoice, javascript, true, cb);
|
||||
}, 500);
|
||||
return;
|
||||
}
|
||||
|
||||
invoice = calculateAmounts(invoice);
|
||||
var a = copyInvoice(invoice);
|
||||
var b = copyInvoice(invoiceOld);
|
||||
var a = copyObject(invoice);
|
||||
var b = copyObject(invoiceOld);
|
||||
if (!force && _.isEqual(a, b)) {
|
||||
return;
|
||||
}
|
||||
pdfmakeMarker = "//pdfmake";
|
||||
invoiceOld = invoice;
|
||||
report_id = invoice.invoice_design_id;
|
||||
pdfmakeMarker = "{";
|
||||
if(javascript.slice(0, pdfmakeMarker.length) === pdfmakeMarker) {
|
||||
doc = GetPdfMake(invoice, javascript, cb);
|
||||
//doc.getDataUrl(cb);
|
||||
} else {
|
||||
doc = GetPdf(invoice, javascript);
|
||||
doc.getDataUrl = function(cb) {
|
||||
cb( this.output("datauristring"));
|
||||
};
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
doc.getDataUrl(cb);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
function copyInvoice(orig) {
|
||||
function copyObject(orig) {
|
||||
if (!orig) return false;
|
||||
var copy = JSON.stringify(orig);
|
||||
var copy = JSON.parse(copy);
|
||||
return copy;
|
||||
return JSON.parse(JSON.stringify(orig));
|
||||
}
|
||||
|
||||
|
||||
@ -33213,73 +33231,63 @@ function twoDigits(value) {
|
||||
}
|
||||
var NINJA = NINJA || {};
|
||||
|
||||
function GetPdfMake(invoice, javascript, callback) {
|
||||
var account = invoice.account;
|
||||
var baseDD = {
|
||||
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?processVariables(invoice.invoice_footer):"", margin: [40, 0]}]
|
||||
if (!invoice.is_pro && logoImages.imageLogo1) {
|
||||
f.push({
|
||||
image: logoImages.imageLogo1,
|
||||
width: 150,
|
||||
margin: [40,0]
|
||||
});
|
||||
}
|
||||
return f;
|
||||
},
|
||||
NINJA.TEMPLATES = {
|
||||
CLEAN: "1",
|
||||
BOLD:"2",
|
||||
MODERN: "3",
|
||||
NORMAL:"4",
|
||||
BUSINESS:"5",
|
||||
CREATIVE:"6",
|
||||
ELEGANT:"7",
|
||||
HIPSTER:"8",
|
||||
PLAYFUL:"9",
|
||||
PHOTO:"10"
|
||||
};
|
||||
|
||||
};
|
||||
function GetPdfMake(invoice, javascript, callback) {
|
||||
//console.log("== GetPdfMake.. ");
|
||||
//console.log(javascript);
|
||||
|
||||
eval(javascript);
|
||||
dd = $.extend(true, baseDD, dd);
|
||||
javascript = NINJA.decodeJavascript(invoice, javascript);
|
||||
|
||||
/*
|
||||
pdfMake.fonts = {
|
||||
wqy: {
|
||||
normal: 'wqy.ttf',
|
||||
bold: 'wqy.ttf',
|
||||
italics: 'wqy.ttf',
|
||||
bolditalics: 'wqy.ttf'
|
||||
function jsonCallBack(key, val) {
|
||||
if ((val+'').indexOf('$borderTopAndBottom') === 0) {
|
||||
var parts = val.split(':');
|
||||
return function (i, node) {
|
||||
return (i === 0 || i === node.table.body.length) ? parseFloat(parts[1]) : 0;
|
||||
};
|
||||
} else if ((val+'').indexOf('$borderNone') === 0) {
|
||||
return function (i, node) {
|
||||
return 0;
|
||||
};
|
||||
} else if ((val+'').indexOf('$borderNotTop') === 0) {
|
||||
var parts = val.split(':');
|
||||
return function (i, node) {
|
||||
return i === 0 ? 0 : parseFloat(parts[1]);
|
||||
};
|
||||
} else if ((val+'').indexOf('$padding') === 0) {
|
||||
var parts = val.split(':');
|
||||
return function (i, node) {
|
||||
return parseInt(parts[1], 10);
|
||||
};
|
||||
} else if ((val+'').indexOf('$primaryColor') === 0) {
|
||||
var parts = val.split(':');
|
||||
return NINJA.primaryColor || parts[1];
|
||||
} else if ((val+'').indexOf('$secondaryColor') === 0) {
|
||||
var parts = val.split(':');
|
||||
return NINJA.secondaryColor || parts[1];
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
//console.log(javascript);
|
||||
var dd = JSON.parse(javascript, jsonCallBack);
|
||||
//console.log(JSON.stringify(dd));
|
||||
|
||||
/*
|
||||
pdfMake.fonts = {
|
||||
NotoSansCJKsc: {
|
||||
normal: 'NotoSansCJKsc-Regular.ttf',
|
||||
bold: 'NotoSansCJKsc-Medium.ttf',
|
||||
italics: 'NotoSansCJKsc-Italic.ttf',
|
||||
bolditalics: 'NotoSansCJKsc-Italic.ttf'
|
||||
},
|
||||
var fonts = {
|
||||
Roboto: {
|
||||
normal: 'Roboto-Regular.ttf',
|
||||
bold: 'Roboto-Medium.ttf',
|
||||
@ -33296,30 +33304,82 @@ function GetPdfMake(invoice, javascript, callback) {
|
||||
return doc;
|
||||
}
|
||||
|
||||
NINJA.decodeJavascript = function(invoice, javascript)
|
||||
{
|
||||
var account = invoice.account;
|
||||
var blankImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=';
|
||||
|
||||
var json = {
|
||||
'accountName': account.name || ' ',
|
||||
'accountLogo': window.accountLogo || blankImage,
|
||||
'accountDetails': NINJA.accountDetails(invoice),
|
||||
'accountAddress': NINJA.accountAddress(invoice),
|
||||
'invoiceDetails': NINJA.invoiceDetails(invoice),
|
||||
'invoiceDetailsHeight': NINJA.invoiceDetails(invoice).length * 22,
|
||||
'invoiceLineItems': NINJA.invoiceLines(invoice),
|
||||
'invoiceLineItemColumns': NINJA.invoiceColumns(invoice),
|
||||
'clientDetails': NINJA.clientDetails(invoice),
|
||||
'notesAndTerms': NINJA.notesAndTerms(invoice),
|
||||
'subtotals': NINJA.subtotals(invoice),
|
||||
'subtotalsHeight': NINJA.subtotals(invoice).length * 22,
|
||||
'subtotalsWithoutBalance': NINJA.subtotals(invoice, true),
|
||||
'balanceDue': formatMoney(invoice.balance_amount, invoice.client.currency_id),
|
||||
'balanceDueLabel': invoiceLabels.balance_due,
|
||||
'invoiceFooter': account.invoice_footer || ' ',
|
||||
'entityType': invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice,
|
||||
'entityTypeUpper': (invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice).toUpperCase(),
|
||||
'yourInvoice': invoiceLabels.your_invoice,
|
||||
'yourInvoiceUpper': invoiceLabels.your_invoice.toUpperCase(),
|
||||
'invoiceIssuedTo': invoiceLabels.invoice_issued_to + ':',
|
||||
'fontSize': NINJA.fontSize,
|
||||
'fontSizeLarger': NINJA.fontSize + 1,
|
||||
'fontSizeLargest': NINJA.fontSize + 2,
|
||||
}
|
||||
|
||||
for (var key in json) {
|
||||
var regExp = new RegExp('"\\$'+key+'"', 'g');
|
||||
var val = JSON.stringify(json[key]);
|
||||
javascript = javascript.replace(regExp, val);
|
||||
}
|
||||
|
||||
return javascript;
|
||||
}
|
||||
|
||||
NINJA.notesAndTerms = function(invoice)
|
||||
{
|
||||
var text = [];
|
||||
var data = [];
|
||||
|
||||
if (invoice.public_notes) {
|
||||
text.push({text:processVariables(invoice.public_notes), style:'notes'});
|
||||
data.push({text:invoice.public_notes, style: ['notes']});
|
||||
data.push({text:' '});
|
||||
}
|
||||
|
||||
if (invoice.terms) {
|
||||
text.push({text:invoiceLabels.terms, style:'termsLabel'});
|
||||
text.push({text:processVariables(invoice.terms), style:'terms'});
|
||||
data.push({text:invoiceLabels.terms, style: ['bold']});
|
||||
data.push({text:invoice.terms, style: ['terms']});
|
||||
}
|
||||
|
||||
return text;
|
||||
return NINJA.prepareDataList(data, 'notesAndTerms');
|
||||
}
|
||||
|
||||
NINJA.invoiceColumns = function(invoice)
|
||||
{
|
||||
if (invoice.has_taxes) {
|
||||
return ["15%", "*", "auto", "auto", "auto", "15%"];
|
||||
} else {
|
||||
return ["15%", "*", "auto", "auto", "15%"]
|
||||
}
|
||||
}
|
||||
|
||||
NINJA.invoiceLines = function(invoice) {
|
||||
var grid = [
|
||||
[
|
||||
{text: invoiceLabels.item, style: 'tableHeader'},
|
||||
{text: invoiceLabels.description, style: 'tableHeader'},
|
||||
{text: invoiceLabels.unit_cost, style: 'tableHeader'},
|
||||
{text: invoiceLabels.quantity, style: 'tableHeader'},
|
||||
{text: invoice.has_taxes?invoiceLabels.tax:'', style: 'tableHeader'},
|
||||
{text: invoiceLabels.line_total, style: 'tableHeader'}
|
||||
{text: invoiceLabels.item, style: ['tableHeader', 'itemTableHeader']},
|
||||
{text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']},
|
||||
{text: invoiceLabels.unit_cost, style: ['tableHeader', 'costTableHeader']},
|
||||
{text: invoiceLabels.quantity, style: ['tableHeader', 'qtyTableHeader']},
|
||||
{text: invoice.has_taxes ? invoiceLabels.tax : '', style: ['tableHeader', 'taxTableHeader']},
|
||||
{text: invoiceLabels.line_total, style: ['tableHeader', 'lineTotalTableHeader']}
|
||||
]
|
||||
];
|
||||
|
||||
@ -33329,23 +33389,27 @@ NINJA.invoiceLines = function(invoice) {
|
||||
var hideQuantity = invoice.account.hide_quantity == '1';
|
||||
|
||||
for (var i = 0; i < invoice.invoice_items.length; i++) {
|
||||
|
||||
var row = [];
|
||||
var item = invoice.invoice_items[i];
|
||||
var cost = formatMoney(item.cost, currencyId, true);
|
||||
var qty = NINJA.parseFloat(item.qty) ? roundToTwo(NINJA.parseFloat(item.qty)) + '' : '';
|
||||
var notes = item.notes;
|
||||
var productKey = item.product_key;
|
||||
var tax = "";
|
||||
var tax = '';
|
||||
|
||||
if (item.tax && parseFloat(item.tax.rate)) {
|
||||
tax = parseFloat(item.tax.rate);
|
||||
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||||
tax = parseFloat(item.tax_rate);
|
||||
}
|
||||
|
||||
|
||||
// show at most one blank line
|
||||
if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) {
|
||||
//if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) {
|
||||
if ((!cost || cost == '0.00') && !notes && !productKey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
shownItem = true;
|
||||
|
||||
// process date variables
|
||||
@ -33363,140 +33427,166 @@ NINJA.invoiceLines = function(invoice) {
|
||||
}
|
||||
lineTotal = formatMoney(lineTotal, currencyId);
|
||||
|
||||
rowStyle = i%2===0?'odd':'even';
|
||||
rowStyle = (i % 2 == 0) ? 'odd' : 'even';
|
||||
|
||||
row.push({style:["productKey", rowStyle], text:productKey || ' '}); // product key can be blank when selecting from a datalist
|
||||
row.push({style:["notes", rowStyle], text:notes || ' '});
|
||||
row.push({style:["cost", rowStyle], text:cost});
|
||||
row.push({style:["quantity", rowStyle], text:qty || ' '});
|
||||
|
||||
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};
|
||||
if (invoice.has_taxes) {
|
||||
row.push({style:["tax", rowStyle], text: tax+'' || ''});
|
||||
}
|
||||
|
||||
row.push({style:["lineTotal", rowStyle], text:lineTotal || ' '});
|
||||
|
||||
grid.push(row);
|
||||
}
|
||||
|
||||
return grid;
|
||||
return NINJA.prepareDataTable(grid, 'invoiceItems');
|
||||
}
|
||||
|
||||
NINJA.subtotals = function(invoice)
|
||||
NINJA.subtotals = function(invoice, removeBalance)
|
||||
{
|
||||
if (!invoice) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = [
|
||||
[invoiceLabels.subtotal, formatMoney(invoice.subtotal_amount, invoice.client.currency_id)],
|
||||
];
|
||||
var account = invoice.account;
|
||||
var data = [];
|
||||
data.push([{text: invoiceLabels.subtotal}, {text: formatMoney(invoice.subtotal_amount, invoice.client.currency_id)}]);
|
||||
|
||||
if(invoice.discount_amount != 0) {
|
||||
data.push([invoiceLabels.discount, formatMoney(invoice.discount_amount, invoice.client.currency_id)]);
|
||||
if (invoice.discount_amount != 0) {
|
||||
data.push([{text: invoiceLabels.discount}, {text: formatMoney(invoice.discount_amount, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') {
|
||||
data.push([invoiceLabels.custom_invoice_label1, formatMoney(invoice.custom_value1, invoice.client.currency_id)]);
|
||||
data.push([{text: account.custom_invoice_label1}, {text: formatMoney(invoice.custom_value1, invoice.client.currency_id)}]);
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') {
|
||||
data.push([invoiceLabels.custom_invoice_label2, formatMoney(invoice.custom_value2, invoice.client.currency_id)]);
|
||||
data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
if(invoice.tax && invoice.tax.name || invoice.tax_name) {
|
||||
data.push([invoiceLabels.tax, formatMoney(invoice.tax_amount, invoice.client.currency_id)]);
|
||||
if (invoice.tax && invoice.tax.name || invoice.tax_name) {
|
||||
data.push([{text: invoiceLabels.tax}, {text: formatMoney(invoice.tax_amount, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
data.push([invoiceLabels.custom_invoice_label1, formatMoney(invoice.custom_value1, invoice.client.currency_id)]);
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
data.push([{text: account.custom_invoice_label1}, {text: formatMoney(invoice.custom_value1, invoice.client.currency_id)}]);
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') {
|
||||
data.push([invoiceLabels.custom_invoice_label2, formatMoney(invoice.custom_value2, invoice.client.currency_id)]);
|
||||
}
|
||||
|
||||
var paid = invoice.amount - invoice.balance;
|
||||
if (invoice.account.hide_paid_to_date != '1' || paid) {
|
||||
data.push([invoiceLabels.paid_to_date, formatMoney(paid, invoice.client.currency_id)]);
|
||||
}
|
||||
|
||||
data.push([{text:invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due, style:'balanceDueLabel'},
|
||||
{text:formatMoney(invoice.balance_amount, invoice.client.currency_id), style:'balanceDueValue'}]);
|
||||
return data;
|
||||
}
|
||||
|
||||
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'});
|
||||
if(account.vat_number) data.push({text:account.vat_number, style:'accountDetails'});
|
||||
if(account.work_email) data.push({text:account.work_email, style:'accountDetails'});
|
||||
if(account.work_phone) data.push({text:account.work_phone, style:'accountDetails'});
|
||||
return data;
|
||||
}
|
||||
|
||||
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();
|
||||
data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]);
|
||||
}
|
||||
var data = [];
|
||||
if(account.address1) data.push({text:account.address1, style:'accountDetails'});
|
||||
if(account.address2) data.push({text:account.address2, style:'accountDetails'});
|
||||
if(address) data.push({text:address, style:'accountDetails'});
|
||||
if(account.country) data.push({text:account.country.name, style: 'accountDetails'});
|
||||
if(account.custom_label1 && account.custom_value1) data.push({text:account.custom_label1 +' '+ account.custom_value1, style: 'accountDetails'});
|
||||
if(account.custom_label2 && account.custom_value2) data.push({text:account.custom_label2 +' '+ account.custom_value2, style: 'accountDetails'});
|
||||
return data;
|
||||
|
||||
var paid = invoice.amount - invoice.balance;
|
||||
if (invoice.account.hide_paid_to_date != '1' || paid) {
|
||||
data.push([{text:invoiceLabels.paid_to_date}, {text:formatMoney(paid, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
if (!removeBalance) {
|
||||
data.push([
|
||||
{text:invoice.is_quote ? invoiceLabels.balance_due : invoiceLabels.balance_due, style:['balanceDueLabel']},
|
||||
{text:formatMoney(invoice.balance_amount, invoice.client.currency_id), style:['balanceDue']}
|
||||
]);
|
||||
}
|
||||
|
||||
//return data;
|
||||
return NINJA.prepareDataPairs(data, 'subtotals');
|
||||
}
|
||||
|
||||
NINJA.accountDetails = function(invoice) {
|
||||
var account = invoice.account;
|
||||
var data = [
|
||||
{text:account.name, style: ['accountName']},
|
||||
{text:account.id_number},
|
||||
{text:account.vat_number},
|
||||
{text:account.work_email},
|
||||
{text:account.work_phone}
|
||||
];
|
||||
return NINJA.prepareDataList(data, 'accountDetails');
|
||||
}
|
||||
|
||||
NINJA.accountAddress = function(invoice) {
|
||||
var account = invoice.account;
|
||||
var cityStatePostal = '';
|
||||
if (account.city || account.state || account.postal_code) {
|
||||
cityStatePostal = ((account.city ? account.city + ', ' : '') + account.state + ' ' + account.postal_code).trim();
|
||||
}
|
||||
|
||||
var data = [
|
||||
{text: account.address1},
|
||||
{text: account.address2},
|
||||
{text: cityStatePostal},
|
||||
{text: account.country ? account.country.name : ''}
|
||||
];
|
||||
|
||||
return NINJA.prepareDataList(data, 'accountAddress');
|
||||
}
|
||||
|
||||
NINJA.invoiceDetails = function(invoice) {
|
||||
|
||||
var data = [
|
||||
[
|
||||
invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number,
|
||||
{style: 'bold', text: invoice.invoice_number},
|
||||
{text: (invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number), style: ['invoiceNumberLabel']},
|
||||
{text: invoice.invoice_number, style: ['invoiceNumber']}
|
||||
],
|
||||
[
|
||||
invoice.is_quote ? invoiceLabels.quote_date : invoiceLabels.invoice_date,
|
||||
invoice.invoice_date,
|
||||
{text: invoiceLabels.po_number},
|
||||
{text: invoice.po_number}
|
||||
],
|
||||
[
|
||||
invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due,
|
||||
formatMoney(invoice.balance_amount, invoice.client.currency_id),
|
||||
{text: invoiceLabels.invoice_date},
|
||||
{text: invoice.invoice_date}
|
||||
],
|
||||
[
|
||||
{text: invoiceLabels.due_date},
|
||||
{text: invoice.due_date}
|
||||
]
|
||||
];
|
||||
|
||||
return data;
|
||||
if (NINJA.parseFloat(invoice.balance) < NINJA.parseFloat(invoice.amount)) {
|
||||
data.push([
|
||||
{text: invoiceLabels.total},
|
||||
{text: formatMoney(invoice.amount, invoice.client.currency_id)}
|
||||
]);
|
||||
}
|
||||
|
||||
if (NINJA.parseFloat(invoice.partial)) {
|
||||
data.push([
|
||||
{text: invoiceLabels.balance},
|
||||
{text: formatMoney(invoice.total_amount, invoice.client.currency_id)}
|
||||
]);
|
||||
}
|
||||
|
||||
data.push([
|
||||
{text: invoiceLabels.balance_due},
|
||||
{text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style: ['invoiceDetailBalanceDue']}
|
||||
])
|
||||
|
||||
return NINJA.prepareDataPairs(data, 'invoiceDetails');
|
||||
}
|
||||
|
||||
NINJA.clientDetails = function(invoice) {
|
||||
NINJA.clientDetails = function(invoice) {
|
||||
var client = invoice.client;
|
||||
var data;
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
var contact = client.contacts[0];
|
||||
var clientName = client.name || (contact.first_name || contact.last_name ? (contact.first_name + ' ' + contact.last_name) : contact.email);
|
||||
var clientEmail = client.contacts[0].email == clientName ? '' : client.contacts[0].email;
|
||||
|
||||
var fields = [
|
||||
getClientDisplayName(client),
|
||||
client.id_number,
|
||||
client.vat_number,
|
||||
concatStrings(client.address1, client.address2),
|
||||
concatStrings(client.city, client.state, client.postal_code),
|
||||
client.country ? client.country.name : false,
|
||||
invoice.contact && getClientDisplayName(client) != invoice.contact.email ? invoice.contact.email : false,
|
||||
invoice.client.custom_value1 ? invoice.account['custom_client_label1'] + ' ' + invoice.client.custom_value1 : false,
|
||||
invoice.client.custom_value2 ? invoice.account['custom_client_label2'] + ' ' + invoice.client.custom_value2 : false,
|
||||
data = [
|
||||
{text:clientName || ' ', style: ['clientName']},
|
||||
{text:client.address1},
|
||||
{text:concatStrings(client.city, client.state, client.postal_code)},
|
||||
{text:client.country ? client.country.name : ''},
|
||||
{text:clientEmail}
|
||||
];
|
||||
|
||||
var data = [];
|
||||
for (var i=0; i<fields.length; i++) {
|
||||
var field = fields[i];
|
||||
if (!field) {
|
||||
continue;
|
||||
}
|
||||
data.push([field]);
|
||||
}
|
||||
if (!data.length) {
|
||||
data.push(['']);
|
||||
}
|
||||
return data;
|
||||
return NINJA.prepareDataList(data, 'clientDetails');
|
||||
}
|
||||
|
||||
|
||||
NINJA.getPrimaryColor = function(defaultColor) {
|
||||
return NINJA.primaryColor ? NINJA.primaryColor : defaultColor;
|
||||
}
|
||||
@ -33505,6 +33595,62 @@ NINJA.getSecondaryColor = function(defaultColor) {
|
||||
return NINJA.primaryColor ? NINJA.secondaryColor : defaultColor;
|
||||
}
|
||||
|
||||
NINJA.getEntityLabel = function(invoice) {
|
||||
return invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice;
|
||||
// remove blanks and add section style to all elements
|
||||
NINJA.prepareDataList = function(oldData, section) {
|
||||
var newData = [];
|
||||
for (var i=0; i<oldData.length; i++) {
|
||||
var item = NINJA.processItem(oldData[i], section);
|
||||
if (item.text) {
|
||||
newData.push(item);
|
||||
}
|
||||
}
|
||||
return newData;
|
||||
}
|
||||
|
||||
NINJA.prepareDataTable = function(oldData, section) {
|
||||
var newData = [];
|
||||
for (var i=0; i<oldData.length; i++) {
|
||||
var row = oldData[i];
|
||||
var newRow = [];
|
||||
for (var j=0; j<row.length; j++) {
|
||||
var item = NINJA.processItem(row[j], section);
|
||||
if (item.text) {
|
||||
newRow.push(item);
|
||||
}
|
||||
}
|
||||
if (newRow.length) {
|
||||
newData.push(newRow);
|
||||
}
|
||||
}
|
||||
return newData;
|
||||
}
|
||||
|
||||
NINJA.prepareDataPairs = function(oldData, section) {
|
||||
var newData = [];
|
||||
for (var i=0; i<oldData.length; i++) {
|
||||
var row = oldData[i];
|
||||
var isBlank = false;
|
||||
for (var j=0; j<row.length; j++) {
|
||||
var item = NINJA.processItem(row[j], section);
|
||||
if (!item.text) {
|
||||
isBlank = true;
|
||||
}
|
||||
if (j == 1) {
|
||||
NINJA.processItem(row[j], section + "Value");
|
||||
}
|
||||
}
|
||||
if (!isBlank) {
|
||||
newData.push(oldData[i]);
|
||||
}
|
||||
}
|
||||
return newData;
|
||||
}
|
||||
|
||||
NINJA.processItem = function(item, section) {
|
||||
if (item.style && item.style instanceof Array) {
|
||||
item.style.push(section);
|
||||
} else {
|
||||
item.style = [section];
|
||||
}
|
||||
return item;
|
||||
}
|
44
public/js/jsoneditor.min.js
vendored
Normal file
44
public/js/jsoneditor.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,72 +1,62 @@
|
||||
var NINJA = NINJA || {};
|
||||
|
||||
function GetPdfMake(invoice, javascript, callback) {
|
||||
var account = invoice.account;
|
||||
var baseDD = {
|
||||
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?processVariables(invoice.invoice_footer):"", margin: [40, 0]}]
|
||||
if (!invoice.is_pro && logoImages.imageLogo1) {
|
||||
f.push({
|
||||
image: logoImages.imageLogo1,
|
||||
width: 150,
|
||||
margin: [40,0]
|
||||
});
|
||||
}
|
||||
return f;
|
||||
},
|
||||
NINJA.TEMPLATES = {
|
||||
CLEAN: "1",
|
||||
BOLD:"2",
|
||||
MODERN: "3",
|
||||
NORMAL:"4",
|
||||
BUSINESS:"5",
|
||||
CREATIVE:"6",
|
||||
ELEGANT:"7",
|
||||
HIPSTER:"8",
|
||||
PLAYFUL:"9",
|
||||
PHOTO:"10"
|
||||
};
|
||||
|
||||
};
|
||||
function GetPdfMake(invoice, javascript, callback) {
|
||||
//console.log("== GetPdfMake.. ");
|
||||
//console.log(javascript);
|
||||
|
||||
eval(javascript);
|
||||
dd = $.extend(true, baseDD, dd);
|
||||
javascript = NINJA.decodeJavascript(invoice, javascript);
|
||||
|
||||
/*
|
||||
pdfMake.fonts = {
|
||||
wqy: {
|
||||
normal: 'wqy.ttf',
|
||||
bold: 'wqy.ttf',
|
||||
italics: 'wqy.ttf',
|
||||
bolditalics: 'wqy.ttf'
|
||||
function jsonCallBack(key, val) {
|
||||
if ((val+'').indexOf('$borderTopAndBottom') === 0) {
|
||||
var parts = val.split(':');
|
||||
return function (i, node) {
|
||||
return (i === 0 || i === node.table.body.length) ? parseFloat(parts[1]) : 0;
|
||||
};
|
||||
} else if ((val+'').indexOf('$borderNone') === 0) {
|
||||
return function (i, node) {
|
||||
return 0;
|
||||
};
|
||||
} else if ((val+'').indexOf('$borderNotTop') === 0) {
|
||||
var parts = val.split(':');
|
||||
return function (i, node) {
|
||||
return i === 0 ? 0 : parseFloat(parts[1]);
|
||||
};
|
||||
} else if ((val+'').indexOf('$padding') === 0) {
|
||||
var parts = val.split(':');
|
||||
return function (i, node) {
|
||||
return parseInt(parts[1], 10);
|
||||
};
|
||||
} else if ((val+'').indexOf('$primaryColor') === 0) {
|
||||
var parts = val.split(':');
|
||||
return NINJA.primaryColor || parts[1];
|
||||
} else if ((val+'').indexOf('$secondaryColor') === 0) {
|
||||
var parts = val.split(':');
|
||||
return NINJA.secondaryColor || parts[1];
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
//console.log(javascript);
|
||||
var dd = JSON.parse(javascript, jsonCallBack);
|
||||
//console.log(JSON.stringify(dd));
|
||||
|
||||
/*
|
||||
pdfMake.fonts = {
|
||||
NotoSansCJKsc: {
|
||||
normal: 'NotoSansCJKsc-Regular.ttf',
|
||||
bold: 'NotoSansCJKsc-Medium.ttf',
|
||||
italics: 'NotoSansCJKsc-Italic.ttf',
|
||||
bolditalics: 'NotoSansCJKsc-Italic.ttf'
|
||||
},
|
||||
var fonts = {
|
||||
Roboto: {
|
||||
normal: 'Roboto-Regular.ttf',
|
||||
bold: 'Roboto-Medium.ttf',
|
||||
@ -83,30 +73,82 @@ function GetPdfMake(invoice, javascript, callback) {
|
||||
return doc;
|
||||
}
|
||||
|
||||
NINJA.decodeJavascript = function(invoice, javascript)
|
||||
{
|
||||
var account = invoice.account;
|
||||
var blankImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=';
|
||||
|
||||
var json = {
|
||||
'accountName': account.name || ' ',
|
||||
'accountLogo': window.accountLogo || blankImage,
|
||||
'accountDetails': NINJA.accountDetails(invoice),
|
||||
'accountAddress': NINJA.accountAddress(invoice),
|
||||
'invoiceDetails': NINJA.invoiceDetails(invoice),
|
||||
'invoiceDetailsHeight': NINJA.invoiceDetails(invoice).length * 22,
|
||||
'invoiceLineItems': NINJA.invoiceLines(invoice),
|
||||
'invoiceLineItemColumns': NINJA.invoiceColumns(invoice),
|
||||
'clientDetails': NINJA.clientDetails(invoice),
|
||||
'notesAndTerms': NINJA.notesAndTerms(invoice),
|
||||
'subtotals': NINJA.subtotals(invoice),
|
||||
'subtotalsHeight': NINJA.subtotals(invoice).length * 22,
|
||||
'subtotalsWithoutBalance': NINJA.subtotals(invoice, true),
|
||||
'balanceDue': formatMoney(invoice.balance_amount, invoice.client.currency_id),
|
||||
'balanceDueLabel': invoiceLabels.balance_due,
|
||||
'invoiceFooter': account.invoice_footer || ' ',
|
||||
'entityType': invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice,
|
||||
'entityTypeUpper': (invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice).toUpperCase(),
|
||||
'yourInvoice': invoiceLabels.your_invoice,
|
||||
'yourInvoiceUpper': invoiceLabels.your_invoice.toUpperCase(),
|
||||
'invoiceIssuedTo': invoiceLabels.invoice_issued_to + ':',
|
||||
'fontSize': NINJA.fontSize,
|
||||
'fontSizeLarger': NINJA.fontSize + 1,
|
||||
'fontSizeLargest': NINJA.fontSize + 2,
|
||||
}
|
||||
|
||||
for (var key in json) {
|
||||
var regExp = new RegExp('"\\$'+key+'"', 'g');
|
||||
var val = JSON.stringify(json[key]);
|
||||
javascript = javascript.replace(regExp, val);
|
||||
}
|
||||
|
||||
return javascript;
|
||||
}
|
||||
|
||||
NINJA.notesAndTerms = function(invoice)
|
||||
{
|
||||
var text = [];
|
||||
var data = [];
|
||||
|
||||
if (invoice.public_notes) {
|
||||
text.push({text:processVariables(invoice.public_notes), style:'notes'});
|
||||
data.push({text:invoice.public_notes, style: ['notes']});
|
||||
data.push({text:' '});
|
||||
}
|
||||
|
||||
if (invoice.terms) {
|
||||
text.push({text:invoiceLabels.terms, style:'termsLabel'});
|
||||
text.push({text:processVariables(invoice.terms), style:'terms'});
|
||||
data.push({text:invoiceLabels.terms, style: ['bold']});
|
||||
data.push({text:invoice.terms, style: ['terms']});
|
||||
}
|
||||
|
||||
return text;
|
||||
return NINJA.prepareDataList(data, 'notesAndTerms');
|
||||
}
|
||||
|
||||
NINJA.invoiceColumns = function(invoice)
|
||||
{
|
||||
if (invoice.has_taxes) {
|
||||
return ["15%", "*", "auto", "auto", "auto", "15%"];
|
||||
} else {
|
||||
return ["15%", "*", "auto", "auto", "15%"]
|
||||
}
|
||||
}
|
||||
|
||||
NINJA.invoiceLines = function(invoice) {
|
||||
var grid = [
|
||||
[
|
||||
{text: invoiceLabels.item, style: 'tableHeader'},
|
||||
{text: invoiceLabels.description, style: 'tableHeader'},
|
||||
{text: invoiceLabels.unit_cost, style: 'tableHeader'},
|
||||
{text: invoiceLabels.quantity, style: 'tableHeader'},
|
||||
{text: invoice.has_taxes?invoiceLabels.tax:'', style: 'tableHeader'},
|
||||
{text: invoiceLabels.line_total, style: 'tableHeader'}
|
||||
{text: invoiceLabels.item, style: ['tableHeader', 'itemTableHeader']},
|
||||
{text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']},
|
||||
{text: invoiceLabels.unit_cost, style: ['tableHeader', 'costTableHeader']},
|
||||
{text: invoiceLabels.quantity, style: ['tableHeader', 'qtyTableHeader']},
|
||||
{text: invoice.has_taxes ? invoiceLabels.tax : '', style: ['tableHeader', 'taxTableHeader']},
|
||||
{text: invoiceLabels.line_total, style: ['tableHeader', 'lineTotalTableHeader']}
|
||||
]
|
||||
];
|
||||
|
||||
@ -116,23 +158,27 @@ NINJA.invoiceLines = function(invoice) {
|
||||
var hideQuantity = invoice.account.hide_quantity == '1';
|
||||
|
||||
for (var i = 0; i < invoice.invoice_items.length; i++) {
|
||||
|
||||
var row = [];
|
||||
var item = invoice.invoice_items[i];
|
||||
var cost = formatMoney(item.cost, currencyId, true);
|
||||
var qty = NINJA.parseFloat(item.qty) ? roundToTwo(NINJA.parseFloat(item.qty)) + '' : '';
|
||||
var notes = item.notes;
|
||||
var productKey = item.product_key;
|
||||
var tax = "";
|
||||
var tax = '';
|
||||
|
||||
if (item.tax && parseFloat(item.tax.rate)) {
|
||||
tax = parseFloat(item.tax.rate);
|
||||
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||||
tax = parseFloat(item.tax_rate);
|
||||
}
|
||||
|
||||
|
||||
// show at most one blank line
|
||||
if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) {
|
||||
//if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) {
|
||||
if ((!cost || cost == '0.00') && !notes && !productKey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
shownItem = true;
|
||||
|
||||
// process date variables
|
||||
@ -150,140 +196,166 @@ NINJA.invoiceLines = function(invoice) {
|
||||
}
|
||||
lineTotal = formatMoney(lineTotal, currencyId);
|
||||
|
||||
rowStyle = i%2===0?'odd':'even';
|
||||
rowStyle = (i % 2 == 0) ? 'odd' : 'even';
|
||||
|
||||
row.push({style:["productKey", rowStyle], text:productKey || ' '}); // product key can be blank when selecting from a datalist
|
||||
row.push({style:["notes", rowStyle], text:notes || ' '});
|
||||
row.push({style:["cost", rowStyle], text:cost});
|
||||
row.push({style:["quantity", rowStyle], text:qty || ' '});
|
||||
|
||||
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};
|
||||
if (invoice.has_taxes) {
|
||||
row.push({style:["tax", rowStyle], text: tax+'' || ''});
|
||||
}
|
||||
|
||||
row.push({style:["lineTotal", rowStyle], text:lineTotal || ' '});
|
||||
|
||||
grid.push(row);
|
||||
}
|
||||
|
||||
return grid;
|
||||
return NINJA.prepareDataTable(grid, 'invoiceItems');
|
||||
}
|
||||
|
||||
NINJA.subtotals = function(invoice)
|
||||
NINJA.subtotals = function(invoice, removeBalance)
|
||||
{
|
||||
if (!invoice) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = [
|
||||
[invoiceLabels.subtotal, formatMoney(invoice.subtotal_amount, invoice.client.currency_id)],
|
||||
];
|
||||
var account = invoice.account;
|
||||
var data = [];
|
||||
data.push([{text: invoiceLabels.subtotal}, {text: formatMoney(invoice.subtotal_amount, invoice.client.currency_id)}]);
|
||||
|
||||
if(invoice.discount_amount != 0) {
|
||||
data.push([invoiceLabels.discount, formatMoney(invoice.discount_amount, invoice.client.currency_id)]);
|
||||
if (invoice.discount_amount != 0) {
|
||||
data.push([{text: invoiceLabels.discount}, {text: formatMoney(invoice.discount_amount, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') {
|
||||
data.push([invoiceLabels.custom_invoice_label1, formatMoney(invoice.custom_value1, invoice.client.currency_id)]);
|
||||
data.push([{text: account.custom_invoice_label1}, {text: formatMoney(invoice.custom_value1, invoice.client.currency_id)}]);
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') {
|
||||
data.push([invoiceLabels.custom_invoice_label2, formatMoney(invoice.custom_value2, invoice.client.currency_id)]);
|
||||
data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
if(invoice.tax && invoice.tax.name || invoice.tax_name) {
|
||||
data.push([invoiceLabels.tax, formatMoney(invoice.tax_amount, invoice.client.currency_id)]);
|
||||
if (invoice.tax && invoice.tax.name || invoice.tax_name) {
|
||||
data.push([{text: invoiceLabels.tax}, {text: formatMoney(invoice.tax_amount, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
data.push([invoiceLabels.custom_invoice_label1, formatMoney(invoice.custom_value1, invoice.client.currency_id)]);
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
data.push([{text: account.custom_invoice_label1}, {text: formatMoney(invoice.custom_value1, invoice.client.currency_id)}]);
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') {
|
||||
data.push([invoiceLabels.custom_invoice_label2, formatMoney(invoice.custom_value2, invoice.client.currency_id)]);
|
||||
}
|
||||
|
||||
var paid = invoice.amount - invoice.balance;
|
||||
if (invoice.account.hide_paid_to_date != '1' || paid) {
|
||||
data.push([invoiceLabels.paid_to_date, formatMoney(paid, invoice.client.currency_id)]);
|
||||
}
|
||||
|
||||
data.push([{text:invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due, style:'balanceDueLabel'},
|
||||
{text:formatMoney(invoice.balance_amount, invoice.client.currency_id), style:'balanceDueValue'}]);
|
||||
return data;
|
||||
}
|
||||
|
||||
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'});
|
||||
if(account.vat_number) data.push({text:account.vat_number, style:'accountDetails'});
|
||||
if(account.work_email) data.push({text:account.work_email, style:'accountDetails'});
|
||||
if(account.work_phone) data.push({text:account.work_phone, style:'accountDetails'});
|
||||
return data;
|
||||
}
|
||||
|
||||
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();
|
||||
data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]);
|
||||
}
|
||||
var data = [];
|
||||
if(account.address1) data.push({text:account.address1, style:'accountDetails'});
|
||||
if(account.address2) data.push({text:account.address2, style:'accountDetails'});
|
||||
if(address) data.push({text:address, style:'accountDetails'});
|
||||
if(account.country) data.push({text:account.country.name, style: 'accountDetails'});
|
||||
if(account.custom_label1 && account.custom_value1) data.push({text:account.custom_label1 +' '+ account.custom_value1, style: 'accountDetails'});
|
||||
if(account.custom_label2 && account.custom_value2) data.push({text:account.custom_label2 +' '+ account.custom_value2, style: 'accountDetails'});
|
||||
return data;
|
||||
|
||||
var paid = invoice.amount - invoice.balance;
|
||||
if (invoice.account.hide_paid_to_date != '1' || paid) {
|
||||
data.push([{text:invoiceLabels.paid_to_date}, {text:formatMoney(paid, invoice.client.currency_id)}]);
|
||||
}
|
||||
|
||||
if (!removeBalance) {
|
||||
data.push([
|
||||
{text:invoice.is_quote ? invoiceLabels.balance_due : invoiceLabels.balance_due, style:['balanceDueLabel']},
|
||||
{text:formatMoney(invoice.balance_amount, invoice.client.currency_id), style:['balanceDue']}
|
||||
]);
|
||||
}
|
||||
|
||||
//return data;
|
||||
return NINJA.prepareDataPairs(data, 'subtotals');
|
||||
}
|
||||
|
||||
NINJA.accountDetails = function(invoice) {
|
||||
var account = invoice.account;
|
||||
var data = [
|
||||
{text:account.name, style: ['accountName']},
|
||||
{text:account.id_number},
|
||||
{text:account.vat_number},
|
||||
{text:account.work_email},
|
||||
{text:account.work_phone}
|
||||
];
|
||||
return NINJA.prepareDataList(data, 'accountDetails');
|
||||
}
|
||||
|
||||
NINJA.accountAddress = function(invoice) {
|
||||
var account = invoice.account;
|
||||
var cityStatePostal = '';
|
||||
if (account.city || account.state || account.postal_code) {
|
||||
cityStatePostal = ((account.city ? account.city + ', ' : '') + account.state + ' ' + account.postal_code).trim();
|
||||
}
|
||||
|
||||
var data = [
|
||||
{text: account.address1},
|
||||
{text: account.address2},
|
||||
{text: cityStatePostal},
|
||||
{text: account.country ? account.country.name : ''}
|
||||
];
|
||||
|
||||
return NINJA.prepareDataList(data, 'accountAddress');
|
||||
}
|
||||
|
||||
NINJA.invoiceDetails = function(invoice) {
|
||||
|
||||
var data = [
|
||||
[
|
||||
invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number,
|
||||
{style: 'bold', text: invoice.invoice_number},
|
||||
{text: (invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number), style: ['invoiceNumberLabel']},
|
||||
{text: invoice.invoice_number, style: ['invoiceNumber']}
|
||||
],
|
||||
[
|
||||
invoice.is_quote ? invoiceLabels.quote_date : invoiceLabels.invoice_date,
|
||||
invoice.invoice_date,
|
||||
{text: invoiceLabels.po_number},
|
||||
{text: invoice.po_number}
|
||||
],
|
||||
[
|
||||
invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due,
|
||||
formatMoney(invoice.balance_amount, invoice.client.currency_id),
|
||||
{text: invoiceLabels.invoice_date},
|
||||
{text: invoice.invoice_date}
|
||||
],
|
||||
[
|
||||
{text: invoiceLabels.due_date},
|
||||
{text: invoice.due_date}
|
||||
]
|
||||
];
|
||||
|
||||
return data;
|
||||
if (NINJA.parseFloat(invoice.balance) < NINJA.parseFloat(invoice.amount)) {
|
||||
data.push([
|
||||
{text: invoiceLabels.total},
|
||||
{text: formatMoney(invoice.amount, invoice.client.currency_id)}
|
||||
]);
|
||||
}
|
||||
|
||||
if (NINJA.parseFloat(invoice.partial)) {
|
||||
data.push([
|
||||
{text: invoiceLabels.balance},
|
||||
{text: formatMoney(invoice.total_amount, invoice.client.currency_id)}
|
||||
]);
|
||||
}
|
||||
|
||||
data.push([
|
||||
{text: invoiceLabels.balance_due},
|
||||
{text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style: ['invoiceDetailBalanceDue']}
|
||||
])
|
||||
|
||||
return NINJA.prepareDataPairs(data, 'invoiceDetails');
|
||||
}
|
||||
|
||||
NINJA.clientDetails = function(invoice) {
|
||||
NINJA.clientDetails = function(invoice) {
|
||||
var client = invoice.client;
|
||||
var data;
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
var contact = client.contacts[0];
|
||||
var clientName = client.name || (contact.first_name || contact.last_name ? (contact.first_name + ' ' + contact.last_name) : contact.email);
|
||||
var clientEmail = client.contacts[0].email == clientName ? '' : client.contacts[0].email;
|
||||
|
||||
var fields = [
|
||||
getClientDisplayName(client),
|
||||
client.id_number,
|
||||
client.vat_number,
|
||||
concatStrings(client.address1, client.address2),
|
||||
concatStrings(client.city, client.state, client.postal_code),
|
||||
client.country ? client.country.name : false,
|
||||
invoice.contact && getClientDisplayName(client) != invoice.contact.email ? invoice.contact.email : false,
|
||||
invoice.client.custom_value1 ? invoice.account['custom_client_label1'] + ' ' + invoice.client.custom_value1 : false,
|
||||
invoice.client.custom_value2 ? invoice.account['custom_client_label2'] + ' ' + invoice.client.custom_value2 : false,
|
||||
data = [
|
||||
{text:clientName || ' ', style: ['clientName']},
|
||||
{text:client.address1},
|
||||
{text:concatStrings(client.city, client.state, client.postal_code)},
|
||||
{text:client.country ? client.country.name : ''},
|
||||
{text:clientEmail}
|
||||
];
|
||||
|
||||
var data = [];
|
||||
for (var i=0; i<fields.length; i++) {
|
||||
var field = fields[i];
|
||||
if (!field) {
|
||||
continue;
|
||||
}
|
||||
data.push([field]);
|
||||
}
|
||||
if (!data.length) {
|
||||
data.push(['']);
|
||||
}
|
||||
return data;
|
||||
return NINJA.prepareDataList(data, 'clientDetails');
|
||||
}
|
||||
|
||||
|
||||
NINJA.getPrimaryColor = function(defaultColor) {
|
||||
return NINJA.primaryColor ? NINJA.primaryColor : defaultColor;
|
||||
}
|
||||
@ -292,6 +364,62 @@ NINJA.getSecondaryColor = function(defaultColor) {
|
||||
return NINJA.primaryColor ? NINJA.secondaryColor : defaultColor;
|
||||
}
|
||||
|
||||
NINJA.getEntityLabel = function(invoice) {
|
||||
return invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice;
|
||||
// remove blanks and add section style to all elements
|
||||
NINJA.prepareDataList = function(oldData, section) {
|
||||
var newData = [];
|
||||
for (var i=0; i<oldData.length; i++) {
|
||||
var item = NINJA.processItem(oldData[i], section);
|
||||
if (item.text) {
|
||||
newData.push(item);
|
||||
}
|
||||
}
|
||||
return newData;
|
||||
}
|
||||
|
||||
NINJA.prepareDataTable = function(oldData, section) {
|
||||
var newData = [];
|
||||
for (var i=0; i<oldData.length; i++) {
|
||||
var row = oldData[i];
|
||||
var newRow = [];
|
||||
for (var j=0; j<row.length; j++) {
|
||||
var item = NINJA.processItem(row[j], section);
|
||||
if (item.text) {
|
||||
newRow.push(item);
|
||||
}
|
||||
}
|
||||
if (newRow.length) {
|
||||
newData.push(newRow);
|
||||
}
|
||||
}
|
||||
return newData;
|
||||
}
|
||||
|
||||
NINJA.prepareDataPairs = function(oldData, section) {
|
||||
var newData = [];
|
||||
for (var i=0; i<oldData.length; i++) {
|
||||
var row = oldData[i];
|
||||
var isBlank = false;
|
||||
for (var j=0; j<row.length; j++) {
|
||||
var item = NINJA.processItem(row[j], section);
|
||||
if (!item.text) {
|
||||
isBlank = true;
|
||||
}
|
||||
if (j == 1) {
|
||||
NINJA.processItem(row[j], section + "Value");
|
||||
}
|
||||
}
|
||||
if (!isBlank) {
|
||||
newData.push(oldData[i]);
|
||||
}
|
||||
}
|
||||
return newData;
|
||||
}
|
||||
|
||||
NINJA.processItem = function(item, section) {
|
||||
if (item.style && item.style instanceof Array) {
|
||||
item.style.push(section);
|
||||
} else {
|
||||
item.style = [section];
|
||||
}
|
||||
return item;
|
||||
}
|
@ -8,33 +8,51 @@ var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
|
||||
|
||||
|
||||
var invoiceOld;
|
||||
var refreshTimer;
|
||||
function generatePDF(invoice, javascript, force, cb) {
|
||||
if (!invoice || !javascript) {
|
||||
return;
|
||||
}
|
||||
console.log('== generatePDF - force: %s', force);
|
||||
if (force || !invoiceOld) {
|
||||
refreshTimer = null;
|
||||
} else {
|
||||
if (refreshTimer) {
|
||||
clearTimeout(refreshTimer);
|
||||
}
|
||||
refreshTimer = setTimeout(function() {
|
||||
generatePDF(invoice, javascript, true, cb);
|
||||
}, 500);
|
||||
return;
|
||||
}
|
||||
|
||||
invoice = calculateAmounts(invoice);
|
||||
var a = copyInvoice(invoice);
|
||||
var b = copyInvoice(invoiceOld);
|
||||
var a = copyObject(invoice);
|
||||
var b = copyObject(invoiceOld);
|
||||
if (!force && _.isEqual(a, b)) {
|
||||
return;
|
||||
}
|
||||
pdfmakeMarker = "//pdfmake";
|
||||
invoiceOld = invoice;
|
||||
report_id = invoice.invoice_design_id;
|
||||
pdfmakeMarker = "{";
|
||||
if(javascript.slice(0, pdfmakeMarker.length) === pdfmakeMarker) {
|
||||
doc = GetPdfMake(invoice, javascript, cb);
|
||||
//doc.getDataUrl(cb);
|
||||
} else {
|
||||
doc = GetPdf(invoice, javascript);
|
||||
doc.getDataUrl = function(cb) {
|
||||
cb( this.output("datauristring"));
|
||||
};
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
doc.getDataUrl(cb);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
function copyInvoice(orig) {
|
||||
function copyObject(orig) {
|
||||
if (!orig) return false;
|
||||
var copy = JSON.stringify(orig);
|
||||
var copy = JSON.parse(copy);
|
||||
return copy;
|
||||
return JSON.parse(JSON.stringify(orig));
|
||||
}
|
||||
|
||||
|
||||
|
188
public/js/templates/bold.js
Normal file
188
public/js/templates/bold.js
Normal file
@ -0,0 +1,188 @@
|
||||
{
|
||||
"content": [
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"image": "$accountLogo",
|
||||
"width": 80,
|
||||
"margin": [60, -40, 0, 0]
|
||||
},
|
||||
{
|
||||
"width": 300,
|
||||
"stack": [
|
||||
{"text":"$yourInvoiceUpper", "style": "yourInvoice"},
|
||||
"$clientDetails"
|
||||
],
|
||||
"margin": [-32, 150, 0, 0]
|
||||
},
|
||||
{
|
||||
"canvas": [
|
||||
{
|
||||
"type": "rect",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 225,
|
||||
"h": 80,
|
||||
"r":0,
|
||||
"lineWidth": 1,
|
||||
"color": "#36a399"
|
||||
}
|
||||
],
|
||||
"width":10,
|
||||
"margin":[-10,150,0,0]
|
||||
},
|
||||
{
|
||||
"table": {
|
||||
"body": "$invoiceDetails"
|
||||
},
|
||||
"layout": "noBorders",
|
||||
"margin": [0, 160, 0, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"style": "invoiceLineItemsTable",
|
||||
"table": {
|
||||
"headerRows": 1,
|
||||
"widths": ["15%", "*", "auto", "auto", "auto"],
|
||||
"body": "$invoiceLineItems"
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$borderNone",
|
||||
"vLineWidth": "$borderNone",
|
||||
"paddingLeft": "$padding:8",
|
||||
"paddingRight": "$padding:8",
|
||||
"paddingTop": "$padding:14",
|
||||
"paddingBottom": "$padding:14"
|
||||
}
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"width": 46,
|
||||
"text": " "
|
||||
},
|
||||
"$notesAndTerms",
|
||||
{
|
||||
"table": {
|
||||
"widths": ["*", "*"],
|
||||
"body": "$subtotals"
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$borderNone",
|
||||
"vLineWidth": "$borderNone",
|
||||
"paddingLeft": "$padding:8",
|
||||
"paddingRight": "$padding:8",
|
||||
"paddingTop": "$padding:4",
|
||||
"paddingBottom": "$padding:4"
|
||||
}
|
||||
}]
|
||||
}
|
||||
],
|
||||
"footer": [
|
||||
{"canvas": [{ "type": "line", "x1": 0, "y1": 0, "x2": 600, "y2": 0,"lineWidth": 100,"lineColor":"#2e2b2b"}]},
|
||||
{
|
||||
"text": "$invoiceFooter",
|
||||
"margin": [40, -20, 40, 0],
|
||||
"alignment": "left",
|
||||
"color": "#FFFFFF"
|
||||
}
|
||||
],
|
||||
"header": [
|
||||
{"canvas": [{ "type": "line", "x1": 0, "y1": 0, "x2": 50, "y2":0,"lineWidth": 200,"lineColor":"#2e2b2b"}],"width":100,"margin":[0,0,0,0]},
|
||||
{"canvas": [{ "type": "line", "x1": 0, "y1": 0, "x2": 150, "y2":0,"lineWidth": 60,"lineColor":"#2e2b2b"}],"width":100,"margin":[0,0,0,0]},
|
||||
{"canvas": [{ "type": "line", "x1": 149, "y1": 0, "x2": 600, "y2":0,"lineWidth": 200,"lineColor":"#2e2b2b"}],"width":10,"margin":[0,0,0,0]},
|
||||
{
|
||||
"stack": "$accountDetails",
|
||||
"margin": [380, 16, 0, 0]
|
||||
}
|
||||
],
|
||||
"defaultStyle": {
|
||||
"fontSize": "$fontSize",
|
||||
"margin": [8, 4, 8, 4]
|
||||
},
|
||||
"styles": {
|
||||
"primaryColor":{
|
||||
"color": "$primaryColor:#299CC2"
|
||||
},
|
||||
"accountName": {
|
||||
"margin": [4, 2, 4, 2],
|
||||
"color": "$primaryColor:#299CC2"
|
||||
},
|
||||
"accountDetails": {
|
||||
"margin": [4, 2, 4, 2],
|
||||
"color": "#AAA9A9"
|
||||
},
|
||||
"odd": {
|
||||
"fillColor": "#ebebeb",
|
||||
"margin": [0,0,0,0]
|
||||
},
|
||||
"productKey": {
|
||||
"color": "$primaryColor:#299CC2"
|
||||
},
|
||||
"balanceDueLabel": {
|
||||
"fontSize": "$fontSizeLargest",
|
||||
"bold": true
|
||||
},
|
||||
"balanceDue": {
|
||||
"fontSize": "$fontSizeLargest",
|
||||
"color": "$primaryColor:#299CC2",
|
||||
"bold": true
|
||||
},
|
||||
"invoiceDetails": {
|
||||
"color": "#ffffff"
|
||||
},
|
||||
"invoiceNumber": {
|
||||
"bold": true
|
||||
},
|
||||
"itemTableHeader": {
|
||||
"margin": [40,0,0,0]
|
||||
},
|
||||
"totalTableHeader": {
|
||||
"margin": [0,0,40,0]
|
||||
},
|
||||
"tableHeader": {
|
||||
"fontSize": 12,
|
||||
"bold": true
|
||||
},
|
||||
"productKey": {
|
||||
"color": "$primaryColor:#299CC2",
|
||||
"margin": [40,0,0,0],
|
||||
"bold": true
|
||||
},
|
||||
"yourInvoice": {
|
||||
"bold": true,
|
||||
"fontSize": 14,
|
||||
"color": "#36a399",
|
||||
"margin": [0,0,0,8]
|
||||
},
|
||||
"invoiceLineItemsTable": {
|
||||
"margin": [0, 16, 0, 16]
|
||||
},
|
||||
"clientName": {
|
||||
"bold": true
|
||||
},
|
||||
"cost": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"quantity": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"tax": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"lineTotal": {
|
||||
"alignment": "right",
|
||||
"margin": [0,0,40,0]
|
||||
},
|
||||
"subtotals": {
|
||||
"alignment": "right",
|
||||
"margin": [0,0,40,0]
|
||||
},
|
||||
"termsLabel": {
|
||||
"bold": true,
|
||||
"margin": [0, 10, 0, 4]
|
||||
}
|
||||
},
|
||||
"pageMargins": [0, 80, 0, 40]
|
||||
}
|
@ -1,162 +1,173 @@
|
||||
//pdfmake
|
||||
|
||||
/*
|
||||
var dd = {
|
||||
content: 'wqy中文wqy',
|
||||
defaultStyle: {
|
||||
font: 'wqy'
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
var dd = {
|
||||
content: [
|
||||
{
|
||||
columns: [
|
||||
[
|
||||
invoice.image?
|
||||
{
|
||||
"content": [{
|
||||
"columns": [
|
||||
{
|
||||
image: invoice.image,
|
||||
fit: [150, 80]
|
||||
}:""
|
||||
],
|
||||
{
|
||||
stack: NINJA.accountDetails(account)
|
||||
},
|
||||
{
|
||||
stack: NINJA.accountAddress(account)
|
||||
}
|
||||
"image": "$accountLogo",
|
||||
"width": 100
|
||||
},
|
||||
{
|
||||
"stack": "$accountDetails",
|
||||
"margin": [80, 0, 0, 0]
|
||||
},
|
||||
{
|
||||
"stack": "$accountAddress"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text:(NINJA.getEntityLabel(invoice)).toUpperCase(),
|
||||
margin: [8, 70, 8, 16],
|
||||
style: 'primaryColor',
|
||||
fontSize: NINJA.fontSize + 2
|
||||
"text": "$entityTypeUpper",
|
||||
"margin": [8, 50, 8, 5],
|
||||
"style": "entityTypeLabel"
|
||||
|
||||
},
|
||||
{
|
||||
table: {
|
||||
headerRows: 1,
|
||||
widths: ['auto', 'auto', '*'],
|
||||
body: [
|
||||
"table": {
|
||||
"headerRows": 1,
|
||||
"widths": ["auto", "auto", "*"],
|
||||
"body": [
|
||||
[
|
||||
{
|
||||
table: {
|
||||
body: NINJA.invoiceDetails(invoice),
|
||||
"table": {
|
||||
"body": "$invoiceDetails"
|
||||
},
|
||||
layout: 'noBorders',
|
||||
"margin": [0, 4, 12, 4],
|
||||
"layout": "noBorders"
|
||||
},
|
||||
{
|
||||
table: {
|
||||
body: NINJA.clientDetails(invoice),
|
||||
},
|
||||
layout: 'noBorders',
|
||||
},
|
||||
''
|
||||
"stack": "$clientDetails"
|
||||
},
|
||||
{
|
||||
"text": ""
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
layout: {
|
||||
hLineWidth: function (i, node) {
|
||||
return (i === 0 || i === node.table.body.length) ? .5 : 0;
|
||||
},
|
||||
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; }
|
||||
"layout": {
|
||||
"hLineWidth": "$borderTopAndBottom:.5",
|
||||
"vLineWidth": "$borderNone",
|
||||
"hLineColor": "#D8D8D8",
|
||||
"paddingLeft": "$padding:8",
|
||||
"paddingRight": "$padding:8",
|
||||
"paddingTop": "$padding:4",
|
||||
"paddingBottom": "$padding:4"
|
||||
}
|
||||
},
|
||||
'\n',
|
||||
{
|
||||
table: {
|
||||
headerRows: 1,
|
||||
widths: ['15%', '*', 'auto', 'auto', 'auto', 'auto'],
|
||||
body: NINJA.invoiceLines(invoice),
|
||||
"style": "invoiceLineItemsTable",
|
||||
"table": {
|
||||
"headerRows": 1,
|
||||
"widths": "$invoiceLineItemColumns",
|
||||
"body": "$invoiceLineItems"
|
||||
},
|
||||
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; }
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$borderNotTop:.5",
|
||||
"vLineWidth": "$borderNone",
|
||||
"hLineColor": "#D8D8D8",
|
||||
"paddingLeft": "$padding:8",
|
||||
"paddingRight": "$padding:8",
|
||||
"paddingTop": "$padding:14",
|
||||
"paddingBottom": "$padding:14"
|
||||
}
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
"$notesAndTerms",
|
||||
{
|
||||
"table": {
|
||||
"widths": ["*", "*"],
|
||||
"body": "$subtotals"
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$borderNone",
|
||||
"vLineWidth": "$borderNone",
|
||||
"paddingLeft": "$padding:8",
|
||||
"paddingRight": "$padding:8",
|
||||
"paddingTop": "$padding:4",
|
||||
"paddingBottom": "$padding:4"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
],
|
||||
|
||||
defaultStyle: {
|
||||
//font: 'arialuni',
|
||||
fontSize: NINJA.fontSize,
|
||||
margin: [8, 4, 8, 4]
|
||||
"defaultStyle": {
|
||||
"fontSize": "$fontSize",
|
||||
"margin": [8, 4, 8, 4]
|
||||
},
|
||||
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')
|
||||
},
|
||||
"footer": {
|
||||
"text": "$invoiceFooter",
|
||||
"margin": [40, -20, 40, 0],
|
||||
"alignment": "left"
|
||||
},
|
||||
pageMargins: [40, 40, 40, 40],
|
||||
};
|
||||
"styles": {
|
||||
"entityTypeLabel": {
|
||||
"fontSize": "$fontSizeLargest",
|
||||
"color": "$primaryColor:#299CC2"
|
||||
},
|
||||
"primaryColor":{
|
||||
"color": "$primaryColor:#299CC2"
|
||||
},
|
||||
"accountName": {
|
||||
"color": "$primaryColor:#299CC2",
|
||||
"bold": true
|
||||
},
|
||||
"accountDetails": {
|
||||
"margin": [0, 2, 0, 2]
|
||||
},
|
||||
"clientDetails": {
|
||||
"margin": [0, 2, 0, 2]
|
||||
},
|
||||
"notesAndTerms": {
|
||||
"margin": [0, 2, 0, 2]
|
||||
},
|
||||
"accountAddress": {
|
||||
"margin": [0, 2, 0, 2]
|
||||
},
|
||||
"odd": {
|
||||
"fillColor": "#fbfbfb"
|
||||
},
|
||||
"productKey": {
|
||||
"color": "$primaryColor:#299CC2",
|
||||
"bold": true
|
||||
},
|
||||
"balanceDueLabel": {
|
||||
"fontSize": "$fontSizeLargest"
|
||||
},
|
||||
"balanceDue": {
|
||||
"fontSize": "$fontSizeLargest",
|
||||
"color": "$primaryColor:#299CC2"
|
||||
},
|
||||
"invoiceNumber": {
|
||||
"bold": true
|
||||
},
|
||||
"tableHeader": {
|
||||
"bold": true,
|
||||
"fontSize": "$fontSizeLargest"
|
||||
},
|
||||
"invoiceLineItemsTable": {
|
||||
"margin": [0, 16, 0, 16]
|
||||
},
|
||||
"clientName": {
|
||||
"bold": true
|
||||
},
|
||||
"cost": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"quantity": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"tax": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"lineTotal": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"subtotals": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"termsLabel": {
|
||||
"bold": true,
|
||||
"margin": [0, 10, 0, 4]
|
||||
}
|
||||
},
|
||||
"pageMargins": [40, 40, 40, 40]
|
||||
}
|
220
public/js/templates/modern.js
Normal file
220
public/js/templates/modern.js
Normal file
@ -0,0 +1,220 @@
|
||||
{
|
||||
"content": [
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"image": "$accountLogo",
|
||||
"width": 80,
|
||||
"margin": [0, 60, 0, 30]
|
||||
},
|
||||
{
|
||||
"stack": "$clientDetails",
|
||||
"margin": [260, 80, 0, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"canvas": [{ "type": "rect", "x": 0, "y": 0, "w": 515, "h": 26, "r":0, "lineWidth": 1, "color":"#403d3d"}],"width":10,"margin":[0,25,0,-30]},
|
||||
{
|
||||
"style": "invoiceLineItemsTable",
|
||||
"table": {
|
||||
"headerRows": 1,
|
||||
"widths": ["15%", "*", "auto", "auto", "auto"],
|
||||
"body": "$invoiceLineItems"
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$borderNotTop:.5",
|
||||
"vLineWidth": "$borderNone",
|
||||
"hLineColor": "#888888",
|
||||
"paddingLeft": "$padding:8",
|
||||
"paddingRight": "$padding:8",
|
||||
"paddingTop": "$padding:8",
|
||||
"paddingBottom": "$padding:8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
"$notesAndTerms",
|
||||
{
|
||||
"table": {
|
||||
"widths": ["*", "*"],
|
||||
"body": "$subtotalsWithoutBalance"
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$borderNone",
|
||||
"vLineWidth": "$borderNone",
|
||||
"paddingLeft": "$padding:8",
|
||||
"paddingRight": "$padding:8",
|
||||
"paddingTop": "$padding:4",
|
||||
"paddingBottom": "$padding:4"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"canvas": [
|
||||
{
|
||||
"type": "rect",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 515,
|
||||
"h": 26,
|
||||
"r": 0,
|
||||
"lineWidth": 1,
|
||||
"color": "#403d3d"
|
||||
}
|
||||
],
|
||||
"width": 10,
|
||||
"margin": [
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "$balanceDueLabel",
|
||||
"style": "balanceDueLabel",
|
||||
"margin": [0, 16, 0, 0],
|
||||
"width": 370
|
||||
},
|
||||
{
|
||||
"text": "$balanceDue",
|
||||
"style": "balanceDue",
|
||||
"margin": [0, 16, 8, 0]
|
||||
}
|
||||
]
|
||||
} ],
|
||||
"footer": [
|
||||
{
|
||||
"canvas": [
|
||||
{
|
||||
"type": "line", "x1": 0, "y1": 0, "x2": 600, "y2": 0,"lineWidth": 100,"lineColor":"#f26621"
|
||||
}]
|
||||
,"width":10
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"text": "$invoiceFooter",
|
||||
"margin": [40, -30, 40, 0],
|
||||
"alignment": "left",
|
||||
"color": "#FFFFFF",
|
||||
"width": 350
|
||||
},
|
||||
{
|
||||
"stack": "$accountDetails",
|
||||
"margin": [0, -40, 0, 0],
|
||||
"width": "*"
|
||||
},
|
||||
{
|
||||
"stack": "$accountAddress",
|
||||
"margin": [0, -40, 0, 0],
|
||||
"width": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"header": [
|
||||
{
|
||||
"canvas": [{ "type": "line", "x1": 0, "y1": 0, "x2": 600, "y2": 0,"lineWidth": 200,"lineColor":"#f26621"}],"width":10
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"text": "$accountName", "bold": true,"fontSize":30,"color":"#ffffff","margin":[40,20,0,0],"width":350
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"width": 300,
|
||||
"table": {
|
||||
"body": "$invoiceDetails"
|
||||
},
|
||||
"layout": "noBorders",
|
||||
"margin": [400, -40, 0, 0]
|
||||
}
|
||||
],
|
||||
"defaultStyle": {
|
||||
"fontSize": "$fontSize",
|
||||
"margin": [8, 4, 8, 4]
|
||||
},
|
||||
"styles": {
|
||||
"primaryColor":{
|
||||
"color": "$primaryColor:#299CC2"
|
||||
},
|
||||
"accountName": {
|
||||
"margin": [4, 2, 4, 2],
|
||||
"color": "$primaryColor:#299CC2"
|
||||
},
|
||||
"accountDetails": {
|
||||
"margin": [4, 2, 4, 2],
|
||||
"color": "#FFFFFF"
|
||||
},
|
||||
"accountAddress": {
|
||||
"margin": [4, 2, 4, 2],
|
||||
"color": "#FFFFFF"
|
||||
},
|
||||
"clientDetails": {
|
||||
"margin": [0, 2, 4, 2]
|
||||
},
|
||||
"invoiceDetails": {
|
||||
"color": "#FFFFFF"
|
||||
},
|
||||
"invoiceLineItemsTable": {
|
||||
"margin": [0, 0, 0, 16]
|
||||
},
|
||||
"productKey": {
|
||||
"bold": true
|
||||
},
|
||||
"clientName": {
|
||||
"bold": true
|
||||
},
|
||||
"tableHeader": {
|
||||
"bold": true,
|
||||
"color": "#FFFFFF",
|
||||
"fontSize": "$fontSizeLargest"
|
||||
},
|
||||
"balanceDueLabel": {
|
||||
"fontSize": "$fontSizeLargest",
|
||||
"color":"#FFFFFF",
|
||||
"alignment":"right",
|
||||
"bold": true
|
||||
},
|
||||
"balanceDue": {
|
||||
"fontSize": "$fontSizeLargest",
|
||||
"color":"#FFFFFF",
|
||||
"bold": true,
|
||||
"alignment":"right"
|
||||
},
|
||||
"cost": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"quantity": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"tax": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"lineTotal": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"subtotals": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"termsLabel": {
|
||||
"bold": true,
|
||||
"margin": [0, 10, 0, 4]
|
||||
},
|
||||
"invoiceNumberLabel": {
|
||||
"bold": true
|
||||
},
|
||||
"invoiceNumber": {
|
||||
"bold": true
|
||||
}
|
||||
|
||||
},
|
||||
"pageMargins": [40, 80, 40, 50]
|
||||
}
|
133
public/js/templates/plain.js
Normal file
133
public/js/templates/plain.js
Normal file
@ -0,0 +1,133 @@
|
||||
{
|
||||
"content": [
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"stack": "$accountDetails"
|
||||
},
|
||||
{
|
||||
"stack": "$accountAddress"
|
||||
},
|
||||
[
|
||||
{
|
||||
"image": "$accountLogo",
|
||||
"width": 100
|
||||
}
|
||||
]
|
||||
]},
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"width": 340,
|
||||
"stack": "$clientDetails",
|
||||
"margin": [0,40,0,0]
|
||||
},
|
||||
{
|
||||
"canvas": [{ "type": "rect", "x": 0, "y": 0, "w": 175, "h": 15, "r":0, "lineWidth": 1, "color":"#e6e6e6"}],
|
||||
"width":10,
|
||||
"margin":[0,70,0,0]
|
||||
},
|
||||
{
|
||||
"width":200,
|
||||
"table": {
|
||||
"body": "$invoiceDetails"
|
||||
},
|
||||
"layout": "noBorders",
|
||||
"margin":[0,40,0,0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"canvas": [{ "type": "rect", "x": 0, "y": 0, "w": 515, "h": 25,"r":0, "lineWidth": 1,"color":"#e6e6e6"}],"width":10,"margin":[0,30,0,-43]
|
||||
},
|
||||
{
|
||||
"style": "invoiceLineItemsTable",
|
||||
"table": {
|
||||
"headerRows": 1,
|
||||
"widths": "$invoiceLineItemColumns",
|
||||
"body": "$invoiceLineItems"
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$borderNotTop:1",
|
||||
"vLineWidth": "$borderNone",
|
||||
"hLineColor": "#e6e6e6",
|
||||
"paddingLeft": "$padding:8",
|
||||
"paddingRight": "$padding:8",
|
||||
"paddingTop": "$padding:8",
|
||||
"paddingBottom": "$padding:8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"columns": [
|
||||
"$notesAndTerms",
|
||||
{
|
||||
"canvas": [{ "type": "rect", "x": -360, "y": 0, "w": 200, "h": 20,"r":0, "lineWidth": 2, "color":"#e6e6e6","lineColor":"#e6e6e6"}],"width":10,"margin":[420,37,0,0]
|
||||
},
|
||||
{
|
||||
"style": "subtotals",
|
||||
"table": {
|
||||
"widths": ["*", "*"],
|
||||
"body": "$subtotals"
|
||||
},
|
||||
"layout": {
|
||||
"hLineWidth": "$borderNone",
|
||||
"vLineWidth": "$borderNone",
|
||||
"paddingLeft": "$padding:8",
|
||||
"paddingRight": "$padding:8",
|
||||
"paddingTop": "$padding:4",
|
||||
"paddingBottom": "$padding:4"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"footer": {
|
||||
"text": "$invoiceFooter",
|
||||
"margin": [40, -40, 40, 0],
|
||||
"alignment": "left"
|
||||
},
|
||||
"defaultStyle": {
|
||||
"fontSize": "$fontSize",
|
||||
"margin": [8, 4, 8, 4]
|
||||
},
|
||||
"styles": {
|
||||
"primaryColor":{
|
||||
"color": "$primaryColor:#299CC2"
|
||||
},
|
||||
"accountDetails": {
|
||||
"margin": [0, 2, 0, 1]
|
||||
},
|
||||
"accountAddress": {
|
||||
"margin": [0, 2, 0, 1]
|
||||
},
|
||||
"clientDetails": {
|
||||
"margin": [0, 2, 0, 1]
|
||||
},
|
||||
"tableHeader": {
|
||||
"bold": true
|
||||
},
|
||||
"invoiceLineItemsTable": {
|
||||
"margin": [0, 16, 0, 16]
|
||||
},
|
||||
"cost": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"quantity": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"tax": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"lineTotal": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"subtotals": {
|
||||
"alignment": "right"
|
||||
},
|
||||
"termsLabel": {
|
||||
"bold": true,
|
||||
"margin": [0, 10, 0, 4]
|
||||
}
|
||||
},
|
||||
"pageMargins": [40, 40, 40, 40]
|
||||
}
|
@ -70,4 +70,5 @@ If you'd like to translate the site please use [caouecs/Laravel4-long](https://g
|
||||
* [jashkenas/underscore](https://github.com/jashkenas/underscore) - JavaScript's utility _ belt
|
||||
* [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) - List of languages for Laravel4
|
||||
* [bgrins/spectrum](https://github.com/bgrins/spectrum) - The No Hassle JavaScript Colorpicker
|
||||
* [lokesh/lightbox2](https://github.com/lokesh/lightbox2/) - The original lightbox script
|
||||
* [lokesh/lightbox2](https://github.com/lokesh/lightbox2/) - The original lightbox script
|
||||
* [josdejong/jsoneditor](https://github.com/josdejong/jsoneditor/) - A web-based tool to view, edit and format JSON
|
@ -599,7 +599,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -724,6 +724,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
|
||||
|
@ -590,7 +590,6 @@ return array(
|
||||
'less_fields' => 'Weniger Felder',
|
||||
'client_name' => 'Kundenname',
|
||||
'pdf_settings' => 'PDF Einstellungen',
|
||||
'utf8_invoices' => 'Cyrillic Unterstützung <sup>Beta</sup>',
|
||||
'product_settings' => 'Produkt Einstellungen',
|
||||
'auto_wrap' => 'Automatischer Zeilenumbruch',
|
||||
'duplicate_post' => 'Achtung: Die vorherige Seite wurde zweimal abgeschickt. Das zweite Abschicken wurde ignoriert.',
|
||||
@ -715,6 +714,22 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
|
||||
);
|
@ -40,8 +40,8 @@ return array(
|
||||
'taxes' => 'Taxes',
|
||||
'tax' => 'Tax',
|
||||
'item' => 'Item',
|
||||
'description' => 'Description',
|
||||
'unit_cost' => 'Unit Cost',
|
||||
'description' => 'Description',
|
||||
'unit_cost' => 'Cost',
|
||||
'quantity' => 'Quantity',
|
||||
'line_total' => 'Line Total',
|
||||
'subtotal' => 'Subtotal',
|
||||
@ -401,9 +401,9 @@ return array(
|
||||
|
||||
'invoice_fields' => 'Invoice Fields',
|
||||
'invoice_options' => 'Invoice Options',
|
||||
'hide_quantity' => 'Hide quantity',
|
||||
'hide_quantity' => 'Hide Quantity',
|
||||
'hide_quantity_help' => 'If your line items quantities are always 1, then you can declutter invoices by no longer displaying this field.',
|
||||
'hide_paid_to_date' => 'Hide paid to date',
|
||||
'hide_paid_to_date' => 'Hide Paid to Date',
|
||||
'hide_paid_to_date_help' => 'Only display the "Paid to Date" area on your invoices once a payment has been received.',
|
||||
|
||||
'charge_taxes' => 'Charge taxes',
|
||||
@ -597,7 +597,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -722,5 +722,21 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
);
|
||||
|
||||
|
@ -569,7 +569,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -694,6 +694,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
);
|
@ -598,7 +598,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -723,6 +723,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
|
||||
|
@ -590,7 +590,7 @@ return array(
|
||||
'less_fields' => 'Moins de champs',
|
||||
'client_name' => 'Nom du client',
|
||||
'pdf_settings' => 'Réglages PDF',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Réglages du produit',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -715,6 +715,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
|
||||
|
@ -590,7 +590,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -716,6 +716,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
);
|
||||
|
@ -592,7 +592,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -718,6 +718,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
|
||||
|
@ -600,7 +600,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -725,6 +725,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
|
||||
|
@ -598,7 +598,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -723,6 +723,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
|
||||
|
@ -593,7 +593,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -718,6 +718,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
|
||||
|
@ -593,7 +593,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -718,6 +718,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
);
|
||||
|
@ -596,7 +596,7 @@ return array(
|
||||
'less_fields' => 'Less Fields',
|
||||
'client_name' => 'Client Name',
|
||||
'pdf_settings' => 'PDF Settings',
|
||||
'utf8_invoices' => 'Cyrillic Support <sup>Beta</sup>',
|
||||
'utf8_invoices' => 'New PDF Engine <sup>Beta</sup>',
|
||||
'product_settings' => 'Product Settings',
|
||||
'auto_wrap' => 'Auto Line Wrap',
|
||||
'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.',
|
||||
@ -721,6 +721,20 @@ return array(
|
||||
'add_to_invoice' => 'Add to invoice :invoice',
|
||||
'create_new_invoice' => 'Create new invoice',
|
||||
'task_errors' => 'Please correct any overlapping times',
|
||||
'from' => 'From',
|
||||
'to' => 'To',
|
||||
'font_size' => 'Font Size',
|
||||
'primary_color' => 'Primary Color',
|
||||
'secondary_color' => 'Secondary Color',
|
||||
'customize_design' => 'Customize Design',
|
||||
|
||||
'content' => 'Content',
|
||||
'styles' => 'Styles',
|
||||
'defaults' => 'Defaults',
|
||||
'margins' => 'Margins',
|
||||
'header' => 'Header',
|
||||
'footer' => 'Footer',
|
||||
'custom' => 'Custom',
|
||||
|
||||
|
||||
|
||||
|
175
resources/views/accounts/customize_design.blade.php
Normal file
175
resources/views/accounts/customize_design.blade.php
Normal file
@ -0,0 +1,175 @@
|
||||
@extends('accounts.nav')
|
||||
|
||||
@section('head')
|
||||
@parent
|
||||
|
||||
<script src="{{ asset('js/pdf_viewer.js') }}" type="text/javascript"></script>
|
||||
<script src="{{ asset('js/compatibility.js') }}" type="text/javascript"></script>
|
||||
|
||||
<link href="{{ asset('css/jsoneditor.min.css') }}" rel="stylesheet" type="text/css">
|
||||
<script src="{{ asset('js/jsoneditor.min.js') }}" type="text/javascript"></script>
|
||||
|
||||
<script src="{{ asset('js/pdfmake.min.js') }}" type="text/javascript"></script>
|
||||
<script src="{{ asset('js/vfs_fonts.js') }}" type="text/javascript"></script>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
select.form-control {
|
||||
background: #FFFFFF !important;
|
||||
margin-right: 12px;
|
||||
}
|
||||
table {
|
||||
background: #FFFFFF !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
@parent
|
||||
@include('accounts.nav_advanced')
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
var invoiceDesigns = {!! $invoiceDesigns !!};
|
||||
var invoice = {!! json_encode($invoice) !!};
|
||||
var sections = ['content', 'styles', 'defaultStyle', 'pageMargins', 'header', 'footer'];
|
||||
var customDesign = origCustomDesign = {!! $customDesign !!};
|
||||
|
||||
function getPDFString(cb, force) {
|
||||
invoice.is_pro = {!! Auth::user()->isPro() ? 'true' : 'false' !!};
|
||||
invoice.account.hide_quantity = {!! Auth::user()->account->hide_quantity ? 'true' : 'false' !!};
|
||||
invoice.account.hide_paid_to_date = {!! Auth::user()->account->hide_paid_to_date ? 'true' : 'false' !!};
|
||||
invoice.invoice_design_id = {!! Auth::user()->account->invoice_design_id !!};
|
||||
|
||||
NINJA.primaryColor = '{!! Auth::user()->account->primary_color !!}';
|
||||
NINJA.secondaryColor = '{!! Auth::user()->account->secondary_color !!}';
|
||||
NINJA.fontSize = {!! Auth::user()->account->font_size !!};
|
||||
|
||||
generatePDF(invoice, getDesignJavascript(), force, cb);
|
||||
}
|
||||
|
||||
function getDesignJavascript() {
|
||||
var id = $('#invoice_design_id').val();
|
||||
if (id == '-1') {
|
||||
showMoreDesigns();
|
||||
$('#invoice_design_id').val(1);
|
||||
return invoiceDesigns[0].javascript;
|
||||
} else {
|
||||
return JSON.stringify(customDesign);
|
||||
}
|
||||
}
|
||||
|
||||
function loadEditor(section)
|
||||
{
|
||||
editorSection = section;
|
||||
editor.set(customDesign[section]);
|
||||
editor.expandAll();
|
||||
}
|
||||
|
||||
function saveEditor(data)
|
||||
{
|
||||
setTimeout(function() {
|
||||
customDesign[editorSection] = editor.get();
|
||||
refreshPDF();
|
||||
}, 100)
|
||||
}
|
||||
|
||||
function onSelectChange()
|
||||
{
|
||||
var id = $('#invoice_design_id').val();
|
||||
|
||||
if (parseInt(id)) {
|
||||
customDesign = JSON.parse(invoiceDesigns[id-1].javascript);
|
||||
} else {
|
||||
customDesign = origCustomDesign;
|
||||
}
|
||||
|
||||
loadEditor(editorSection);
|
||||
refreshPDF(true);
|
||||
}
|
||||
|
||||
function submitForm()
|
||||
{
|
||||
$('#custom_design').val(JSON.stringify(customDesign));
|
||||
$('form.warn-on-exit').submit();
|
||||
}
|
||||
|
||||
$(function() {
|
||||
refreshPDF(true);
|
||||
|
||||
var container = document.getElementById("jsoneditor");
|
||||
var options = {
|
||||
mode: 'form',
|
||||
modes: ['form', 'code'],
|
||||
error: function (err) {
|
||||
console.error(err.toString());
|
||||
},
|
||||
change: function() {
|
||||
saveEditor();
|
||||
}
|
||||
};
|
||||
window.editor = new JSONEditor(container, options);
|
||||
loadEditor('content');
|
||||
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
var target = $(e.target).attr("href") // activated tab
|
||||
target = target.substring(1); // strip leading #
|
||||
loadEditor(target);
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
|
||||
{!! Former::open()->addClass('warn-on-exit')->onchange('refreshPDF()') !!}
|
||||
{!! Former::populateField('invoice_design_id', $account->invoice_design_id) !!}
|
||||
|
||||
<div style="display:none">
|
||||
{!! Former::text('custom_design') !!}
|
||||
</div>
|
||||
|
||||
|
||||
<div role="tabpanel">
|
||||
<ul class="nav nav-tabs" role="tablist" style="border: none">
|
||||
<li role="presentation" class="active"><a href="#content" aria-controls="content" role="tab" data-toggle="tab">{{ trans('texts.content') }}</a></li>
|
||||
<li role="presentation"><a href="#styles" aria-controls="styles" role="tab" data-toggle="tab">{{ trans('texts.styles') }}</a></li>
|
||||
<li role="presentation"><a href="#defaultStyle" aria-controls="defaultStyle" role="tab" data-toggle="tab">{{ trans('texts.defaults') }}</a></li>
|
||||
<li role="presentation"><a href="#pageMargins" aria-controls="margins" role="tab" data-toggle="tab">{{ trans('texts.margins') }}</a></li>
|
||||
<li role="presentation"><a href="#header" aria-controls="header" role="tab" data-toggle="tab">{{ trans('texts.header') }}</a></li>
|
||||
<li role="presentation"><a href="#footer" aria-controls="footer" role="tab" data-toggle="tab">{{ trans('texts.footer') }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="jsoneditor" style="width: 550px; height: 743px;"></div>
|
||||
|
||||
<p> </p>
|
||||
|
||||
{!! Former::actions(
|
||||
Former::select('invoice_design_id')->style('display:inline;width:120px')->fromQuery($invoiceDesigns, 'name', 'id')->onchange('onSelectChange()')->raw(),
|
||||
Button::success(trans('texts.save'))->withAttributes(['onclick' => 'submitForm()'])->large()->appendIcon(Icon::create('floppy-disk'))
|
||||
) !!}
|
||||
|
||||
@if (!Auth::user()->isPro())
|
||||
<script>
|
||||
$(function() {
|
||||
$('form.warn-on-exit input').prop('disabled', true);
|
||||
});
|
||||
</script>
|
||||
@endif
|
||||
|
||||
{!! Former::close() !!}
|
||||
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
|
||||
@include('invoices.pdf', ['account' => Auth::user()->account, 'pdfHeight' => 800])
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
@ -27,8 +27,9 @@
|
||||
showMoreDesigns();
|
||||
$('#invoice_design_id').val(1);
|
||||
return invoiceDesigns[0].javascript;
|
||||
} else {
|
||||
return invoiceDesigns[id-1].javascript;
|
||||
} else {
|
||||
var design = _.find(invoiceDesigns, function(design){ return design.id == id});
|
||||
return design ? design.javascript : '';
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,8 +56,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
doc = generatePDF(invoice, getDesignJavascript(), true);
|
||||
doc.getDataUrl(cb);
|
||||
generatePDF(invoice, getDesignJavascript(), true, cb);
|
||||
}
|
||||
|
||||
$(function() {
|
||||
@ -109,6 +109,10 @@
|
||||
{!! Former::text('primary_color') !!}
|
||||
{!! Former::text('secondary_color') !!}
|
||||
|
||||
{!! Former::actions(
|
||||
Button::primary(trans('texts.customize_design'))->small()->asLinkTo(URL::to('/company/advanced_settings/customize_design'))
|
||||
) !!}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
{!! HTML::nav_link('company/products', 'product_library') !!}
|
||||
{!! HTML::nav_link('company/notifications', 'notifications') !!}
|
||||
{!! HTML::nav_link('company/import_export', 'import_export', 'company/import_map') !!}
|
||||
{!! HTML::nav_link('company/advanced_settings/invoice_settings', 'advanced_settings', '*/advanced_settings/*') !!}
|
||||
{!! HTML::nav_link('company/advanced_settings/invoice_design', 'advanced_settings', '*/advanced_settings/*') !!}
|
||||
</ul>
|
||||
|
||||
<br/>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<ul class="nav nav-tabs nav nav-justified">
|
||||
{!! HTML::nav_link('company/advanced_settings/invoice_settings', 'invoice_settings') !!}
|
||||
{!! HTML::nav_link('company/advanced_settings/invoice_design', 'invoice_design') !!}
|
||||
{!! HTML::nav_link('company/advanced_settings/invoice_settings', 'invoice_settings') !!}
|
||||
{!! HTML::nav_link('company/advanced_settings/email_templates', 'email_templates') !!}
|
||||
{!! HTML::nav_link('company/advanced_settings/charts_and_reports', 'charts_and_reports') !!}
|
||||
{!! HTML::nav_link('company/advanced_settings/user_management', 'users_and_tokens') !!}
|
||||
|
@ -446,7 +446,7 @@
|
||||
<li>{!! link_to('company/products', uctrans('texts.product_library')) !!}</li>
|
||||
<li>{!! link_to('company/notifications', uctrans('texts.notifications')) !!}</li>
|
||||
<li>{!! link_to('company/import_export', uctrans('texts.import_export')) !!}</li>
|
||||
<li><a href="{{ url('company/advanced_settings/invoice_settings') }}">{!! uctrans('texts.advanced_settings') . Utils::getProLabel(ACCOUNT_ADVANCED_SETTINGS) !!}</a></li>
|
||||
<li><a href="{{ url('company/advanced_settings/invoice_design') }}">{!! uctrans('texts.advanced_settings') . Utils::getProLabel(ACCOUNT_ADVANCED_SETTINGS) !!}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -67,7 +67,7 @@
|
||||
<div data-bind="with: client">
|
||||
<div style="display:none" class="form-group" data-bind="visible: contacts().length > 0 && (contacts()[0].email() || contacts()[0].first_name()), foreach: contacts">
|
||||
<div class="col-lg-8 col-lg-offset-4">
|
||||
<label class="checkbox" data-bind="attr: {for: $index() + '_check'}" onclick="refreshPDF()">
|
||||
<label class="checkbox" data-bind="attr: {for: $index() + '_check'}" onclick="refreshPDF(true)">
|
||||
<input type="checkbox" value="1" data-bind="checked: send_invoice, attr: {id: $index() + '_check'}">
|
||||
<span data-bind="html: email.display"/>
|
||||
</label>
|
||||
@ -325,9 +325,9 @@
|
||||
|
||||
|
||||
@if (!Utils::isPro() || \App\Models\InvoiceDesign::count() == COUNT_FREE_DESIGNS)
|
||||
{!! Former::select('invoice_design_id')->style('display:'.($account->utf8_invoices ? 'none' : 'inline').';width:150px;background-color:white !important')->raw()->fromQuery($invoiceDesigns, 'name', 'id')->data_bind("value: invoice_design_id")->addOption(trans('texts.more_designs') . '...', '-1') !!}
|
||||
{!! Former::select('invoice_design_id')->style('display:inline;width:150px;background-color:white !important')->raw()->fromQuery($invoiceDesigns, 'name', 'id')->data_bind("value: invoice_design_id")->addOption(trans('texts.more_designs') . '...', '-1') !!}
|
||||
@else
|
||||
{!! Former::select('invoice_design_id')->style('display:'.($account->utf8_invoices ? 'none' : 'inline').';width:150px;background-color:white !important')->raw()->fromQuery($invoiceDesigns, 'name', 'id')->data_bind("value: invoice_design_id") !!}
|
||||
{!! Former::select('invoice_design_id')->style('display:inline;width:150px;background-color:white !important')->raw()->fromQuery($invoiceDesigns, 'name', 'id')->data_bind("value: invoice_design_id") !!}
|
||||
@endif
|
||||
|
||||
{!! Button::primary(trans('texts.download_pdf'))->withAttributes(array('onclick' => 'onDownloadClick()'))->appendIcon(Icon::create('download-alt')) !!}
|
||||
@ -485,10 +485,10 @@
|
||||
<tr data-bind="event: { mouseover: showActions, mouseout: hideActions }">
|
||||
<td style="width:30px" class="hide-border"></td>
|
||||
<td style="width:60px">
|
||||
<input onkeyup="onTaxRateChange()" data-bind="value: name, valueUpdate: 'afterkeydown'" class="form-control" onchange="refreshPDF()"//>
|
||||
<input onkeyup="onTaxRateChange()" data-bind="value: name, valueUpdate: 'afterkeydown'" class="form-control" onchange="refreshPDF(true)"//>
|
||||
</td>
|
||||
<td style="width:60px">
|
||||
<input onkeyup="onTaxRateChange()" data-bind="value: prettyRate, valueUpdate: 'afterkeydown'" style="text-align: right" class="form-control" onchange="refreshPDF()"//>
|
||||
<input onkeyup="onTaxRateChange()" data-bind="value: prettyRate, valueUpdate: 'afterkeydown'" style="text-align: right" class="form-control" onchange="refreshPDF(true)"//>
|
||||
</td>
|
||||
<td style="width:30px; cursor:pointer" class="hide-border td-icon">
|
||||
<i style="width:12px;" data-bind="click: $root.removeTaxRate, visible: actionsVisible() && !isEmpty()" class="fa fa-minus-circle redlink" title="Remove item"/>
|
||||
@ -589,7 +589,7 @@
|
||||
model.loadClient($.parseJSON(ko.toJSON(new ClientModel())));
|
||||
model.invoice().client().country = false;
|
||||
}
|
||||
refreshPDF();
|
||||
refreshPDF(true);
|
||||
});
|
||||
|
||||
// If no clients exists show the client form when clicking on the client select input
|
||||
@ -601,7 +601,7 @@
|
||||
|
||||
$('#invoice_footer, #terms, #public_notes, #invoice_number, #invoice_date, #due_date, #po_number, #discount, #currency_id, #invoice_design_id, #recurring, #is_amount_discount, #partial').change(function() {
|
||||
setTimeout(function() {
|
||||
refreshPDF();
|
||||
refreshPDF(true);
|
||||
}, 1);
|
||||
});
|
||||
|
||||
@ -616,7 +616,7 @@
|
||||
}).on('hidden.bs.modal', function () {
|
||||
if (model.clientBackup) {
|
||||
model.loadClient(model.clientBackup);
|
||||
refreshPDF();
|
||||
refreshPDF(true);
|
||||
}
|
||||
})
|
||||
|
||||
@ -639,7 +639,7 @@
|
||||
@if ($client)
|
||||
$input.trigger('change');
|
||||
@else
|
||||
refreshPDF();
|
||||
refreshPDF(true);
|
||||
@endif
|
||||
|
||||
var client = model.invoice().client();
|
||||
@ -655,7 +655,7 @@
|
||||
function applyComboboxListeners() {
|
||||
var selectorStr = '.invoice-table input, .invoice-table select, .invoice-table textarea';
|
||||
$(selectorStr).off('blur').on('blur', function() {
|
||||
refreshPDF();
|
||||
refreshPDF(true);
|
||||
});
|
||||
|
||||
$('textarea').on('keyup focus', function(e) {
|
||||
@ -711,14 +711,11 @@
|
||||
return invoice;
|
||||
}
|
||||
|
||||
function getPDFString(cb) {
|
||||
function getPDFString(cb, force) {
|
||||
var invoice = createInvoiceModel();
|
||||
var design = getDesignJavascript();
|
||||
if (!design) return;
|
||||
doc = generatePDF(invoice, design, false);
|
||||
if (!doc) return;
|
||||
//return doc.output('datauristring');
|
||||
doc.getDataUrl(cb);
|
||||
generatePDF(invoice, design, force, cb);
|
||||
}
|
||||
|
||||
function getDesignJavascript() {
|
||||
@ -728,7 +725,8 @@
|
||||
model.invoice().invoice_design_id(1);
|
||||
return invoiceDesigns[0].javascript;
|
||||
} else {
|
||||
return invoiceDesigns[id-1].javascript;
|
||||
var design = _.find(invoiceDesigns, function(design){ return design.id == id});
|
||||
return design ? design.javascript : '';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1091,7 +1089,7 @@
|
||||
$('#emailError').css( "display", "none" );
|
||||
//$('.client_select input.form-control').focus();
|
||||
|
||||
refreshPDF();
|
||||
refreshPDF(true);
|
||||
model.clientBackup = false;
|
||||
$('#clientModal').modal('hide');
|
||||
}
|
||||
@ -1143,7 +1141,7 @@
|
||||
self.invoice_items = ko.observableArray();
|
||||
self.amount = ko.observable(0);
|
||||
self.balance = ko.observable(0);
|
||||
self.invoice_design_id = ko.observable({{ $account->utf8_invoices ? 1 : $account->invoice_design_id }});
|
||||
self.invoice_design_id = ko.observable({{ $account->invoice_design_id }});
|
||||
self.partial = ko.observable(0);
|
||||
self.has_tasks = ko.observable(false);
|
||||
|
||||
@ -1252,7 +1250,7 @@
|
||||
|
||||
self.removeItem = function(item) {
|
||||
self.invoice_items.remove(item);
|
||||
refreshPDF();
|
||||
refreshPDF(true);
|
||||
}
|
||||
|
||||
|
||||
@ -1368,7 +1366,7 @@
|
||||
});
|
||||
|
||||
self.onDragged = function(item) {
|
||||
refreshPDF();
|
||||
refreshPDF(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,7 @@
|
||||
invoiceDesign = invoiceDesigns[0];
|
||||
}
|
||||
|
||||
doc = generatePDF(invoice, invoiceDesign.javascript, true);
|
||||
doc.getDataUrl(cb);
|
||||
generatePDF(invoice, invoiceDesign.javascript, true, cb);
|
||||
}
|
||||
|
||||
$(function() {
|
||||
|
@ -63,12 +63,11 @@
|
||||
logoImages.imageLogoHeight3 = 81/2;
|
||||
|
||||
@if (file_exists($account->getLogoPath()))
|
||||
window.accountLogo = "{{ HTML::image_data($account->getLogoPath()) }}";
|
||||
if (window.invoice) {
|
||||
invoice.image = "{{ HTML::image_data($account->getLogoPath()) }}";
|
||||
invoice.image = window.accountLogo;
|
||||
invoice.imageWidth = {{ $account->getLogoWidth() }};
|
||||
invoice.imageHeight = {{ $account->getLogoHeight() }};
|
||||
} else {
|
||||
window.accountLogo = "{{ HTML::image_data($account->getLogoPath()) }}";
|
||||
}
|
||||
@endif
|
||||
|
||||
@ -87,8 +86,8 @@
|
||||
var isRefreshing = false;
|
||||
var needsRefresh = false;
|
||||
|
||||
function refreshPDF() {
|
||||
getPDFString(refreshPDFCB);
|
||||
function refreshPDF(force) {
|
||||
getPDFString(refreshPDFCB, force);
|
||||
}
|
||||
|
||||
function refreshPDFCB(string) {
|
||||
|
@ -53,8 +53,7 @@
|
||||
invoice.contact = {!! $contact->toJson() !!};
|
||||
|
||||
function getPDFString(cb) {
|
||||
doc = generatePDF(invoice, invoice.invoice_design.javascript);
|
||||
doc.getDataUrl(cb);
|
||||
generatePDF(invoice, invoice.invoice_design.javascript, true, cb);
|
||||
}
|
||||
|
||||
$(function() {
|
||||
|
Loading…
Reference in New Issue
Block a user