This commit is contained in:
David Bomba 2016-01-09 11:13:23 +11:00
parent 7beeb78126
commit e792e66aaa
35 changed files with 315 additions and 60 deletions

View File

@ -2,6 +2,39 @@ module.exports = function(grunt) {
grunt.initConfig({ grunt.initConfig({
pkg: grunt.file.readJSON('package.json'), pkg: grunt.file.readJSON('package.json'),
dump_dir: (function() {
var out = {};
grunt.file.expand({ filter: 'isDirectory'}, 'public/fonts/invoice-fonts/*').forEach(function(path) {
var fontName = /[^/]*$/.exec(path)[0],
files = {},
license='';
// Add license text
grunt.file.expand({ filter: 'isFile'}, path+'/*.txt').forEach(function(path) {
var licenseText = grunt.file.read(path);
// Fix anything that could escape from the comment
licenseText = licenseText.replace(/\*\//g,'*\\/');
license += "/*\n"+licenseText+"\n*/";
});
// Create files list
files['public/js/vfs_fonts/'+fontName+'.js'] = [path+'/*.ttf'];
out[fontName] = {
options: {
pre: license+'window.ninjaFontVfs=window.ninjaFontVfs||{};window.ninjaFontVfs.'+fontName+'=',
rootPath: path+'/'
},
files: files
};
});
// Return the computed object
return out;
}()),
concat: { concat: {
options: { options: {
process: function(src, filepath) { process: function(src, filepath) {
@ -145,7 +178,8 @@ module.exports = function(grunt) {
}); });
grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-dump-dir');
grunt.registerTask('default', ['concat']); grunt.registerTask('default', ['dump_dir', 'concat']);
}; };

View File

@ -347,14 +347,15 @@ class AccountController extends BaseController
$invoice->client = $client; $invoice->client = $client;
$invoice->invoice_items = [$invoiceItem]; $invoice->invoice_items = [$invoiceItem];
$data['account'] = $account; $data['account'] = $account;
$data['invoice'] = $invoice; $data['invoice'] = $invoice;
$data['invoiceLabels'] = json_decode($account->invoice_labels) ?: []; $data['invoiceLabels'] = json_decode($account->invoice_labels) ?: [];
$data['title'] = trans('texts.invoice_design'); $data['title'] = trans('texts.invoice_design');
$data['invoiceDesigns'] = InvoiceDesign::getDesigns(); $data['invoiceDesigns'] = InvoiceDesign::getDesigns();
$data['invoiceFonts'] = Cache::get('fonts');
$data['section'] = $section; $data['section'] = $section;
$design = false; $design = false;
foreach ($data['invoiceDesigns'] as $item) { foreach ($data['invoiceDesigns'] as $item) {
if ($item->id == $account->invoice_design_id) { if ($item->id == $account->invoice_design_id) {
@ -689,10 +690,12 @@ class AccountController extends BaseController
$account = Auth::user()->account; $account = Auth::user()->account;
$account->hide_quantity = Input::get('hide_quantity') ? true : false; $account->hide_quantity = Input::get('hide_quantity') ? true : false;
$account->hide_paid_to_date = Input::get('hide_paid_to_date') ? true : false; $account->hide_paid_to_date = Input::get('hide_paid_to_date') ? true : false;
$account->header_font_id = Input::get('header_font_id');
$account->body_font_id = Input::get('body_font_id');
$account->primary_color = Input::get('primary_color'); $account->primary_color = Input::get('primary_color');
$account->secondary_color = Input::get('secondary_color'); $account->secondary_color = Input::get('secondary_color');
$account->invoice_design_id = Input::get('invoice_design_id'); $account->invoice_design_id = Input::get('invoice_design_id');
if (Input::has('font_size')) { if (Input::has('font_size')) {
$account->font_size = intval(Input::get('font_size')); $account->font_size = intval(Input::get('font_size'));
} }

View File

@ -104,6 +104,7 @@ class InvoiceController extends BaseController
'error' => trans('texts.invoice_not_found'), 'error' => trans('texts.invoice_not_found'),
'hideHeader' => true, 'hideHeader' => true,
'clientViewCSS' => $account->clientViewCSS(), 'clientViewCSS' => $account->clientViewCSS(),
'clientFontUrl' => $account->getFontsUrl(),
]); ]);
} }
@ -123,6 +124,7 @@ class InvoiceController extends BaseController
$invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date); $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date);
$invoice->due_date = Utils::fromSqlDate($invoice->due_date); $invoice->due_date = Utils::fromSqlDate($invoice->due_date);
$invoice->is_pro = $account->isPro(); $invoice->is_pro = $account->isPro();
$invoice->invoice_fonts = $account->getFontsData();
if ($invoice->invoice_design_id == CUSTOM_DESIGN) { if ($invoice->invoice_design_id == CUSTOM_DESIGN) {
$invoice->invoice_design->javascript = $account->custom_design; $invoice->invoice_design->javascript = $account->custom_design;
@ -156,6 +158,7 @@ class InvoiceController extends BaseController
'hideLogo' => $account->isWhiteLabel(), 'hideLogo' => $account->isWhiteLabel(),
'hideHeader' => $account->isNinjaAccount(), 'hideHeader' => $account->isNinjaAccount(),
'clientViewCSS' => $account->clientViewCSS(), 'clientViewCSS' => $account->clientViewCSS(),
'clientFontUrl' => $account->getFontsUrl(),
'invoice' => $invoice->hidePrivateFields(), 'invoice' => $invoice->hidePrivateFields(),
'invitation' => $invitation, 'invitation' => $invitation,
'invoiceLabels' => $account->getInvoiceLabels(), 'invoiceLabels' => $account->getInvoiceLabels(),
@ -417,6 +420,7 @@ class InvoiceController extends BaseController
'paymentTerms' => Cache::get('paymentTerms'), 'paymentTerms' => Cache::get('paymentTerms'),
'industries' => Cache::get('industries'), 'industries' => Cache::get('industries'),
'invoiceDesigns' => InvoiceDesign::getDesigns(), 'invoiceDesigns' => InvoiceDesign::getDesigns(),
'invoiceFonts' => Cache::get('fonts'),
'frequencies' => array( 'frequencies' => array(
1 => 'Weekly', 1 => 'Weekly',
2 => 'Two weeks', 2 => 'Two weeks',
@ -639,6 +643,7 @@ class InvoiceController extends BaseController
'versionsJson' => json_encode($versionsJson), 'versionsJson' => json_encode($versionsJson),
'versionsSelect' => $versionsSelect, 'versionsSelect' => $versionsSelect,
'invoiceDesigns' => InvoiceDesign::getDesigns(), 'invoiceDesigns' => InvoiceDesign::getDesigns(),
'invoiceFonts' => Cache::get('fonts'),
]; ];
return View::make('invoices.history', $data); return View::make('invoices.history', $data);

View File

@ -178,6 +178,7 @@ class PaymentController extends BaseController
'hideLogo' => $account->isWhiteLabel(), 'hideLogo' => $account->isWhiteLabel(),
'hideHeader' => $account->isNinjaAccount(), 'hideHeader' => $account->isNinjaAccount(),
'clientViewCSS' => $account->clientViewCSS(), 'clientViewCSS' => $account->clientViewCSS(),
'clientFontUrl' => $account->getFontsUrl(),
'showAddress' => $accountGateway->show_address, 'showAddress' => $accountGateway->show_address,
]; ];

View File

@ -38,6 +38,7 @@ class PublicClientController extends BaseController
'client' => $client, 'client' => $client,
'hideLogo' => $account->isWhiteLabel(), 'hideLogo' => $account->isWhiteLabel(),
'clientViewCSS' => $account->clientViewCSS(), 'clientViewCSS' => $account->clientViewCSS(),
'clientFontUrl' => $account->getFontsUrl(),
]; ];
return response()->view('invited.dashboard', $data); return response()->view('invited.dashboard', $data);
@ -83,6 +84,7 @@ class PublicClientController extends BaseController
'color' => $color, 'color' => $color,
'hideLogo' => $account->isWhiteLabel(), 'hideLogo' => $account->isWhiteLabel(),
'clientViewCSS' => $account->clientViewCSS(), 'clientViewCSS' => $account->clientViewCSS(),
'clientFontUrl' => $account->getFontsUrl(),
'title' => trans('texts.invoices'), 'title' => trans('texts.invoices'),
'entityType' => ENTITY_INVOICE, 'entityType' => ENTITY_INVOICE,
'columns' => Utils::trans(['invoice_number', 'invoice_date', 'invoice_total', 'balance_due', 'due_date']), 'columns' => Utils::trans(['invoice_number', 'invoice_date', 'invoice_total', 'balance_due', 'due_date']),
@ -113,6 +115,7 @@ class PublicClientController extends BaseController
'color' => $color, 'color' => $color,
'hideLogo' => $account->isWhiteLabel(), 'hideLogo' => $account->isWhiteLabel(),
'clientViewCSS' => $account->clientViewCSS(), 'clientViewCSS' => $account->clientViewCSS(),
'clientFontUrl' => $account->getFontsUrl(),
'entityType' => ENTITY_PAYMENT, 'entityType' => ENTITY_PAYMENT,
'title' => trans('texts.payments'), 'title' => trans('texts.payments'),
'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date']) 'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date'])
@ -149,6 +152,7 @@ class PublicClientController extends BaseController
'color' => $color, 'color' => $color,
'hideLogo' => $account->isWhiteLabel(), 'hideLogo' => $account->isWhiteLabel(),
'clientViewCSS' => $account->clientViewCSS(), 'clientViewCSS' => $account->clientViewCSS(),
'clientFontUrl' => $account->getFontsUrl(),
'title' => trans('texts.quotes'), 'title' => trans('texts.quotes'),
'entityType' => ENTITY_QUOTE, 'entityType' => ENTITY_QUOTE,
'columns' => Utils::trans(['quote_number', 'quote_date', 'quote_total', 'due_date']), 'columns' => Utils::trans(['quote_number', 'quote_date', 'quote_total', 'due_date']),
@ -173,6 +177,7 @@ class PublicClientController extends BaseController
'error' => trans('texts.invoice_not_found'), 'error' => trans('texts.invoice_not_found'),
'hideHeader' => true, 'hideHeader' => true,
'clientViewCSS' => $account->clientViewCSS(), 'clientViewCSS' => $account->clientViewCSS(),
'clientFontUrl' => $account->getFontsUrl(),
]); ]);
} }

View File

@ -118,6 +118,7 @@ class QuoteController extends BaseController
'languages' => Cache::get('languages'), 'languages' => Cache::get('languages'),
'industries' => Cache::get('industries'), 'industries' => Cache::get('industries'),
'invoiceDesigns' => InvoiceDesign::getDesigns(), 'invoiceDesigns' => InvoiceDesign::getDesigns(),
'invoiceFonts' => Cache::get('fonts'),
'invoiceLabels' => Auth::user()->account->getInvoiceLabels(), 'invoiceLabels' => Auth::user()->account->getInvoiceLabels(),
'isRecurring' => false, 'isRecurring' => false,
]; ];

View File

@ -156,7 +156,11 @@ class StartupCheck
if (Input::has('clear_cache') || !Cache::has($name)) { if (Input::has('clear_cache') || !Cache::has($name)) {
if ($name == 'paymentTerms') { if ($name == 'paymentTerms') {
$orderBy = 'num_days'; $orderBy = 'num_days';
}
else if ($name == 'fonts') {
$orderBy = 'sort_order';
} elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries'])) { } elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries'])) {
$orderBy = 'name'; $orderBy = 'name';
} else { } else {
$orderBy = 'id'; $orderBy = 'id';

View File

@ -337,6 +337,8 @@ if (!defined('CONTACT_EMAIL')) {
define('MAX_LOGO_FILE_SIZE', 200); // KB define('MAX_LOGO_FILE_SIZE', 200); // KB
define('MAX_FAILED_LOGINS', 10); define('MAX_FAILED_LOGINS', 10);
define('DEFAULT_FONT_SIZE', 9); define('DEFAULT_FONT_SIZE', 9);
define('DEFAULT_HEADER_FONT', 1);// Roboto
define('DEFAULT_BODY_FONT', 1);// Roboto
define('DEFAULT_SEND_RECURRING_HOUR', 8); define('DEFAULT_SEND_RECURRING_HOUR', 8);
define('IMPORT_CSV', 'CSV'); define('IMPORT_CSV', 'CSV');
@ -537,6 +539,7 @@ if (!defined('CONTACT_EMAIL')) {
'invoiceStatus' => 'App\Models\InvoiceStatus', 'invoiceStatus' => 'App\Models\InvoiceStatus',
'frequencies' => 'App\Models\Frequency', 'frequencies' => 'App\Models\Frequency',
'gateways' => 'App\Models\Gateway', 'gateways' => 'App\Models\Gateway',
'fonts' => 'App\Models\Font',
]; ];
define('CACHED_TABLES', serialize($cachedTables)); define('CACHED_TABLES', serialize($cachedTables));

View File

@ -377,7 +377,10 @@ class Utils
$format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT); $format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT);
$dateTime = DateTime::createFromFormat($format, $date); $dateTime = DateTime::createFromFormat($format, $date);
return $formatResult ? $dateTime->format('Y-m-d') : $dateTime; if(!$dateTime)
return $date;
else
return $formatResult ? $dateTime->format('Y-m-d') : $dateTime;
} }
public static function fromSqlDate($date, $formatResult = true) public static function fromSqlDate($date, $formatResult = true)

View File

@ -20,6 +20,7 @@ class Account extends Eloquent
protected $presenter = 'App\Ninja\Presenters\AccountPresenter'; protected $presenter = 'App\Ninja\Presenters\AccountPresenter';
protected $dates = ['deleted_at']; protected $dates = ['deleted_at'];
protected $hidden = ['ip']; protected $hidden = ['ip'];
public $fonts_obj = null;
public static $basicSettings = [ public static $basicSettings = [
ACCOUNT_COMPANY_DETAILS, ACCOUNT_COMPANY_DETAILS,
@ -876,11 +877,94 @@ class Account extends Eloquent
} }
public function clientViewCSS(){ public function clientViewCSS(){
if ((Utils::isNinja() && $this->isPro()) || $this->isWhiteLabel()) { $css = null;
return $this->client_view_css;
if ($this->isPro()) {
$bodyFont = $this->getBodyFontCss();
$headerFont = $this->getHeaderFontCss();
$css = 'body{'.$bodyFont.'}';
if ($headerFont != $bodyFont) {
$css .= 'h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{'.$headerFont.'}';
}
if ((Utils::isNinja() && $this->isPro()) || $this->isWhiteLabel()) {
// For self-hosted users, a white-label license is required for custom CSS
$css .= $this->client_view_css;
}
} }
return null; return $css;
}
public function getFontsUrl($protocol = ''){
if ($this->isPro()){
$bodyFont = $this->body_font_id;
$headerFont = $this->header_font_id;
}
else{
$bodyFont = DEFAULT_BODY_FONT;
$headerFont = DEFAULT_HEADER_FONT;
}
$bodyFontSettings = Utils::getFromCache($bodyFont, 'fonts');
$google_fonts = array($bodyFontSettings['google_font']);
if($headerFont != $bodyFont){
$headerFontSettings = Utils::getFromCache($headerFont, 'fonts');
$google_fonts[] = $headerFontSettings['google_font'];
}
return ($protocol?$protocol.':':'').'//fonts.googleapis.com/css?family='.implode('|',$google_fonts);
}
public function getHeaderFontName(){
return Utils::getFromCache($this->header_font_id, 'fonts')['name'];
}
public function getBodyFontName(){
return Utils::getFromCache($this->body_font_id, 'fonts')['name'];
}
public function getHeaderFontCss($include_weight = true){
$font_data = Utils::getFromCache($this->header_font_id, 'fonts');
$css = 'font-family:'.$font_data['css_stack'].';';
if($include_weight){
$css .= 'font-weight:'.$font_data['css_weight'].';';
}
return $css;
}
public function getBodyFontCss($include_weight = true){
$font_data = Utils::getFromCache($this->body_font_id, 'fonts');
$css = 'font-family:'.$font_data['css_stack'].';';
if($include_weight){
$css .= 'font-weight:'.$font_data['css_weight'].';';
}
return $css;
}
public function getFonts(){
return array_unique(array($this->header_font_id, $this->body_font_id));
}
public function getFontsData(){
$data = array();
foreach($this->getFonts() as $font){
$data[] = Utils::getFromCache($font, 'fonts');
}
return $data;
}
public function getFontFolders(){
return array_map(function($item){return $item['folder'];}, $this->getFontsData());
} }
} }

View File

@ -353,6 +353,7 @@ class Invoice extends EntityModel implements BalanceAffecting
'account', 'account',
'invoice_design', 'invoice_design',
'invoice_design_id', 'invoice_design_id',
'invoice_fonts',
'is_pro', 'is_pro',
'is_quote', 'is_quote',
'custom_value1', 'custom_value1',

View File

@ -16,6 +16,7 @@ class DatabaseSeeder extends Seeder {
$this->call('ConstantsSeeder'); $this->call('ConstantsSeeder');
$this->call('CountriesSeeder'); $this->call('CountriesSeeder');
$this->call('PaymentLibrariesSeeder'); $this->call('PaymentLibrariesSeeder');
$this->call('FontsSeeder');
} }
} }

View File

@ -122,6 +122,8 @@ class PaymentLibrariesSeeder extends Seeder
['name' => 'Netherlands Antillean Guilder', 'code' => 'ANG', 'symbol' => 'ANG ', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], ['name' => 'Netherlands Antillean Guilder', 'code' => 'ANG', 'symbol' => 'ANG ', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','],
['name' => 'Trinidad and Tobago Dollar', 'code' => 'TTD', 'symbol' => 'TT$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Trinidad and Tobago Dollar', 'code' => 'TTD', 'symbol' => 'TT$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
['name' => 'East Caribbean Dollar', 'code' => 'XCD', 'symbol' => 'EC$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'East Caribbean Dollar', 'code' => 'XCD', 'symbol' => 'EC$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
['name' => 'Ghanaian Cedi', 'code' => 'GHS', 'symbol' => 'GHS ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
['name' => 'Bulgarian Lev', 'code' => 'BGN', 'symbol' => 'BGN ', 'precision' => '2', 'thousand_separator' => ' ', 'decimal_separator' => '.'],
]; ];
foreach ($currencies as $currency) { foreach ($currencies as $currency) {

View File

@ -1,13 +1,14 @@
{ {
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"gulp": "^3.8.8",
"laravel-elixir": "*",
"grunt": "~0.4.4", "grunt": "~0.4.4",
"grunt-contrib-concat": "~0.4.0",
"grunt-contrib-jshint": "~0.6.3", "grunt-contrib-jshint": "~0.6.3",
"grunt-contrib-nodeunit": "~0.2.0", "grunt-contrib-nodeunit": "~0.2.0",
"grunt-contrib-uglify": "~0.2.2", "grunt-contrib-uglify": "~0.2.2",
"grunt-contrib-concat": "~0.4.0" "grunt-dump-dir": "^0.1.2",
"gulp": "^3.8.8",
"laravel-elixir": "*"
}, },
"dependencies": { "dependencies": {
"grunt-dump-dir": "^0.1.2" "grunt-dump-dir": "^0.1.2"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -90,16 +90,30 @@ function GetPdfMake(invoice, javascript, callback) {
} }
} }
/*
var fonts = {
Roboto: { pdfMake.fonts = {}
normal: 'Roboto-Regular.ttf', fonts = window.invoiceFonts || invoice.invoice_fonts;
bold: 'Roboto-Medium.ttf',
italics: 'Roboto-Italic.ttf', // Add only the loaded fonts
bolditalics: 'Roboto-Italic.ttf' $.each(fonts, function(i,font){
}, addFont(font);
}; });
*/
function addFont(font){
if(window.ninjaFontVfs[font.folder]){
pdfMake.fonts[font.name] = {
normal: font.folder+'/'+font.normal,
italics: font.folder+'/'+font.italics,
bold: font.folder+'/'+font.bold,
bolditalics: font.folder+'/'+font.bolditalics
}
}
}
if(!dd.defaultStyle)dd.defaultStyle = {font:NINJA.bodyFont};
else if(!dd.defaultStyle.font)dd.defaultStyle.font = NINJA.bodyFont;
doc = pdfMake.createPdf(dd); doc = pdfMake.createPdf(dd);
doc.save = function(fileName) { doc.save = function(fileName) {
@ -141,6 +155,8 @@ NINJA.decodeJavascript = function(invoice, javascript)
'fontSizeLarger': NINJA.fontSize + 1, 'fontSizeLarger': NINJA.fontSize + 1,
'fontSizeLargest': NINJA.fontSize + 2, 'fontSizeLargest': NINJA.fontSize + 2,
'fontSizeSmaller': NINJA.fontSize - 1, 'fontSizeSmaller': NINJA.fontSize - 1,
'bodyFont': NINJA.bodyFont,
'headerFont': NINJA.headerFont,
} }
for (var key in json) { for (var key in json) {

File diff suppressed because one or more lines are too long

View File

@ -976,8 +976,7 @@ return array(
'custom_account_fields_helps' => 'Add a label and value to the company details section of the PDF.', 'custom_account_fields_helps' => 'Add a label and value to the company details section of the PDF.',
'custom_invoice_fields_helps' => 'Add a text input to the invoice create/edit page and display the label and value on the PDF.', 'custom_invoice_fields_helps' => 'Add a text input to the invoice create/edit page and display the label and value on the PDF.',
'custom_invoice_charges_helps' => 'Add a text input to the invoice create/edit page and include the charge in the invoice subtotals.', 'custom_invoice_charges_helps' => 'Add a text input to the invoice create/edit page and include the charge in the invoice subtotals.',
'color_help' => 'Note: the primary color is also used in the client portal and custom email designs.',
'token_expired' => 'Validation token was expired. Please try again.', 'token_expired' => 'Validation token was expired. Please try again.',
'invoice_link' => 'Invoice Link', 'invoice_link' => 'Invoice Link',
'button_confirmation_message' => 'Click to confirm your email address.', 'button_confirmation_message' => 'Click to confirm your email address.',
@ -1026,4 +1025,10 @@ return array(
'thursday' => 'Thursday', 'thursday' => 'Thursday',
'friday' => 'Friday', 'friday' => 'Friday',
'saturday' => 'Saturday', 'saturday' => 'Saturday',
);
// Fonts
'header_font_id' => 'Header Font',
'body_font_id' => 'Body Font',
'color_font_help' => 'Note: the primary color and fonts are also used in the client portal and custom email designs.',
);

View File

@ -7,7 +7,9 @@
<link href="{{ asset('css/jsoneditor.min.css') }}" rel="stylesheet" type="text/css"> <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/jsoneditor.min.js') }}" type="text/javascript"></script>
@foreach ($account->getFontFolders() as $font)
<script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script>
@endforeach
<script src="{{ asset('js/pdf.built.js') }}" type="text/javascript"></script> <script src="{{ asset('js/pdf.built.js') }}" type="text/javascript"></script>
<style type="text/css"> <style type="text/css">
@ -29,6 +31,7 @@
<script> <script>
var invoiceDesigns = {!! $invoiceDesigns !!}; var invoiceDesigns = {!! $invoiceDesigns !!};
var invoiceFonts = {!! $invoiceFonts !!};
var invoice = {!! json_encode($invoice) !!}; var invoice = {!! json_encode($invoice) !!};
var sections = ['content', 'styles', 'defaultStyle', 'pageMargins', 'header', 'footer']; var sections = ['content', 'styles', 'defaultStyle', 'pageMargins', 'header', 'footer'];
var customDesign = origCustomDesign = {!! $customDesign ?: 'JSON.parse(invoiceDesigns[0].javascript);' !!}; var customDesign = origCustomDesign = {!! $customDesign ?: 'JSON.parse(invoiceDesigns[0].javascript);' !!};
@ -42,6 +45,8 @@
NINJA.primaryColor = '{!! Auth::user()->account->primary_color !!}'; NINJA.primaryColor = '{!! Auth::user()->account->primary_color !!}';
NINJA.secondaryColor = '{!! Auth::user()->account->secondary_color !!}'; NINJA.secondaryColor = '{!! Auth::user()->account->secondary_color !!}';
NINJA.fontSize = {!! Auth::user()->account->font_size !!}; NINJA.fontSize = {!! Auth::user()->account->font_size !!};
NINJA.headerFont = {!! json_encode(Auth::user()->account->getHeaderFontName()) !!};
NINJA.bodyFont = {!! json_encode(Auth::user()->account->getBodyFontName()) !!};
generatePDF(invoice, getDesignJavascript(), force, cb); generatePDF(invoice, getDesignJavascript(), force, cb);
} }
@ -118,7 +123,6 @@
$(function() { $(function() {
clearError(); clearError();
refreshPDF(true);
var container = document.getElementById("jsoneditor"); var container = document.getElementById("jsoneditor");
var options = { var options = {
@ -130,12 +134,14 @@
}; };
window.editor = new JSONEditor(container, options); window.editor = new JSONEditor(container, options);
loadEditor('content'); loadEditor('content');
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var target = $(e.target).attr("href") // activated tab var target = $(e.target).attr("href") // activated tab
target = target.substring(1); // strip leading # target = target.substring(1); // strip leading #
loadEditor(target); loadEditor(target);
}); });
refreshPDF(true);
}); });
</script> </script>

View File

@ -4,7 +4,10 @@
@parent @parent
@include('money_script') @include('money_script')
<script src="{{ asset('js/pdf.built.js') }}" type="text/javascript"></script> @foreach ($account->getFontFolders() as $font)
<script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script>
@endforeach
<script src="{{ asset('js/pdf.built.js') }}" type="text/javascript"></script>
@stop @stop
@ -14,6 +17,7 @@
<script> <script>
var invoiceDesigns = {!! $invoiceDesigns !!}; var invoiceDesigns = {!! $invoiceDesigns !!};
var invoiceFonts = {!! $invoiceFonts !!};
var invoice = {!! json_encode($invoice) !!}; var invoice = {!! json_encode($invoice) !!};
function getDesignJavascript() { function getDesignJavascript() {
@ -21,13 +25,24 @@
if (id == '-1') { if (id == '-1') {
showMoreDesigns(); showMoreDesigns();
$('#invoice_design_id').val(1); $('#invoice_design_id').val(1);
return invoiceDesigns[0].javascript; return invoiceDesigns[0].javascript;
} else { } else {
var design = _.find(invoiceDesigns, function(design){ return design.id == id}); var design = _.find(invoiceDesigns, function(design){ return design.id == id});
return design ? design.javascript : ''; return design ? design.javascript : '';
} }
} }
function loadFont(fontId){
var fontFolder = '';
$.each(window.invoiceFonts, function(i, font){
if(font.id==fontId)fontFolder=font.folder;
});
if(!window.ninjaFontVfs[fontFolder]){
window.loadingFonts = true;
jQuery.getScript({!! json_encode(asset('js/vfs_fonts/%s.js')) !!}.replace('%s', fontFolder), function(){window.loadingFonts=false;ninjaLoadFontVfs();refreshPDF()})
}
}
function getPDFString(cb) { function getPDFString(cb) {
invoice.is_pro = {!! Auth::user()->isPro() ? 'true' : 'false' !!}; invoice.is_pro = {!! Auth::user()->isPro() ? 'true' : 'false' !!};
invoice.account.hide_quantity = $('#hide_quantity').is(":checked"); invoice.account.hide_quantity = $('#hide_quantity').is(":checked");
@ -37,6 +52,8 @@
NINJA.primaryColor = $('#primary_color').val(); NINJA.primaryColor = $('#primary_color').val();
NINJA.secondaryColor = $('#secondary_color').val(); NINJA.secondaryColor = $('#secondary_color').val();
NINJA.fontSize = parseInt($('#font_size').val()); NINJA.fontSize = parseInt($('#font_size').val());
NINJA.headerFont = $('#header_font_id option:selected').text();
NINJA.bodyFont = $('#body_font_id option:selected').text();
var fields = ['item', 'description', 'unit_cost', 'quantity', 'line_total', 'terms']; var fields = ['item', 'description', 'unit_cost', 'quantity', 'line_total', 'terms'];
invoiceLabels.old = {}; invoiceLabels.old = {};
@ -66,7 +83,10 @@
$('#primary_color').spectrum(options); $('#primary_color').spectrum(options);
$('#secondary_color').spectrum(options); $('#secondary_color').spectrum(options);
$('#header_font_id').change(function(){loadFont($('#header_font_id').val())});
$('#body_font_id').change(function(){loadFont($('#body_font_id').val())});
refreshPDF(); refreshPDF();
}); });
@ -76,7 +96,7 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
{!! Former::open()->addClass('warn-on-exit')->onchange('refreshPDF()') !!} {!! Former::open()->addClass('warn-on-exit')->onchange('if(!window.loadingFonts)refreshPDF()') !!}
{!! Former::populate($account) !!} {!! Former::populate($account) !!}
{!! Former::populateField('hide_quantity', intval($account->hide_quantity)) !!} {!! Former::populateField('hide_quantity', intval($account->hide_quantity)) !!}
{!! Former::populateField('hide_paid_to_date', intval($account->hide_paid_to_date)) !!} {!! Former::populateField('hide_paid_to_date', intval($account->hide_paid_to_date)) !!}
@ -112,6 +132,12 @@
->style('display:inline; width:300px') ->style('display:inline; width:300px')
->fromQuery($invoiceDesigns, 'name', 'id') !!} ->fromQuery($invoiceDesigns, 'name', 'id') !!}
@endif @endif
{!! Former::select('header_font_id')
->style('display:inline; width:300px')
->fromQuery($invoiceFonts, 'name', 'id') !!}
{!! Former::select('body_font_id')
->style('display:inline; width:300px')
->fromQuery($invoiceFonts, 'name', 'id') !!}
{!! Former::text('font_size') {!! Former::text('font_size')
->style('width:300px') ->style('width:300px')
@ -121,7 +147,7 @@
{!! Former::text('primary_color') !!} {!! Former::text('primary_color') !!}
{!! Former::text('secondary_color') {!! Former::text('secondary_color')
->help('<br/>'.trans('texts.color_help')) !!} ->help('<br/>'.trans('texts.color_font_help')) !!}
</div> </div>
</div> </div>

View File

@ -7,7 +7,7 @@
@stop @stop
@section('body') @section('body')
<h2>{{ trans('texts.confirmation_header') }}</h2> <h2 style="{!! $account->getheaderFontCss() !!}">{{ trans('texts.confirmation_header') }}</h2>
<div> <div>
{{ $invitationMessage . trans('texts.button_confirmation_message') }} {{ $invitationMessage . trans('texts.button_confirmation_message') }}
</div> </div>

View File

@ -46,7 +46,7 @@
</tr> </tr>
<tr> <tr>
<td class="content" style="border-collapse: collapse;"> <td class="content" style="border-collapse: collapse;">
<div style="font-size: 18px; margin: 42px 40px 42px; padding: 0;">{!! $body !!}</div> <div style="font-size: 18px; margin: 42px 40px 42px; padding: 0; max-width: 520px;">{!! $body !!}</div>
</td> </td>
</tr> </tr>
@stop @stop

View File

@ -46,7 +46,7 @@
</tr> </tr>
<tr> <tr>
<td class="content" style="border-collapse: collapse;"> <td class="content" style="border-collapse: collapse;">
<div style="font-size: 18px; margin: 42px 40px 42px; padding: 0;">{!! $body !!}</div> <div style="font-size: 18px; margin: 42px 40px 42px; padding: 0; max-width: 520px;">{!! $body !!}</div>
</td> </td>
</tr> </tr>
@stop @stop

View File

@ -2,9 +2,11 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" lang="{{ App::getLocale() }}"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" lang="{{ App::getLocale() }}">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!--[if !mso]><!-- -->
<link href="{{ $account->getFontsUrl('http') }}" rel="stylesheet" type="text/css" />
<!--<![endif]-->
</head> </head>
<body style="min-height: 700px; color: #000000;{!! $account->getBodyFontCss() !!}font-size: 12px; -webkit-text-size-adjust: none; -ms-text-size-adjust: none; background: #F4F5F5; margin: 0; padding: 0;"
<body style="min-height: 700px; color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 12px; -webkit-text-size-adjust: none; -ms-text-size-adjust: none; background: #F4F5F5; margin: 0; padding: 0;"
alink="#FF0000" link="#FF0000" bgcolor="#F4F5F5" text="#000000" yahoo="fix"> alink="#FF0000" link="#FF0000" bgcolor="#F4F5F5" text="#000000" yahoo="fix">
@yield('markup') @yield('markup')
@ -48,7 +50,7 @@
} }
</style> </style>
<div id="body_style" style="min-height: 700px; color: #2E2B2B; font-family: Helvetica, sans-serif; font-size: 16px; <div id="body_style" style="min-height: 700px;{!! $account->getBodyFontCss() !!}color: #2E2B2B; font-size: 16px;
background: #F4F5F5; padding: 0px 15px;"> background: #F4F5F5; padding: 0px 15px;">
<table cellpadding="0" cellspacing="0" border="0" bgcolor="#FFFFFF" width="600" align="center"> <table cellpadding="0" cellspacing="0" border="0" bgcolor="#FFFFFF" width="600" align="center">

View File

@ -3,6 +3,7 @@
@section('head') @section('head')
<link href="//fonts.googleapis.com/css?family=Roboto:400,700,900,100|Roboto+Slab:400,300,700&subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link href="{{ asset('css/built.css') }}?no_cache={{ NINJA_VERSION }}" rel="stylesheet" type="text/css"/> <link href="{{ asset('css/built.css') }}?no_cache={{ NINJA_VERSION }}" rel="stylesheet" type="text/css"/>
<style type="text/css"> <style type="text/css">

View File

@ -4,6 +4,9 @@
@parent @parent
@include('money_script') @include('money_script')
@foreach ($account->getFontFolders() as $font)
<script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script>
@endforeach
<script src="{{ asset('js/pdf.built.js') }}" type="text/javascript"></script> <script src="{{ asset('js/pdf.built.js') }}" type="text/javascript"></script>
<style type="text/css"> <style type="text/css">
@ -639,6 +642,8 @@
var clientMap = {}; var clientMap = {};
var $clientSelect = $('select#client'); var $clientSelect = $('select#client');
var invoiceDesigns = {!! $invoiceDesigns !!}; var invoiceDesigns = {!! $invoiceDesigns !!};
var invoiceFonts = {!! $invoiceFonts !!};
$(function() { $(function() {
// create client dictionary // create client dictionary

View File

@ -4,11 +4,15 @@
@parent @parent
@include('money_script') @include('money_script')
@foreach (Auth::user()->account->getFontFolders() as $font)
<script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script>
@endforeach
<script src="{{ asset('js/pdf.built.js') }}" type="text/javascript"></script> <script src="{{ asset('js/pdf.built.js') }}" type="text/javascript"></script>
<script> <script>
var invoiceDesigns = {!! $invoiceDesigns !!}; var invoiceDesigns = {!! $invoiceDesigns !!};
var invoiceFonts = {!! $invoiceFonts !!};
var currentInvoice = {!! $invoice !!}; var currentInvoice = {!! $invoice !!};
var versionsJson = {!! $versionsJson !!}; var versionsJson = {!! $versionsJson !!};

View File

@ -76,6 +76,8 @@
NINJA.primaryColor = "{{ $account->primary_color }}"; NINJA.primaryColor = "{{ $account->primary_color }}";
NINJA.secondaryColor = "{{ $account->secondary_color }}"; NINJA.secondaryColor = "{{ $account->secondary_color }}";
NINJA.fontSize = {{ $account->font_size }}; NINJA.fontSize = {{ $account->font_size }};
NINJA.headerFont = {!! json_encode(Auth::user()->account->getHeaderFontName()) !!};
NINJA.bodyFont = {!! json_encode(Auth::user()->account->getBodyFontName()) !!};
@endif @endif
var invoiceLabels = {!! json_encode($account->getInvoiceLabels()) !!}; var invoiceLabels = {!! json_encode($account->getInvoiceLabels()) !!};

View File

@ -5,6 +5,9 @@
@include('money_script') @include('money_script')
@foreach ($invoice->client->account->getFontFolders() as $font)
<script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script>
@endforeach
<script src="{{ asset('js/pdf.built.js') }}" type="text/javascript"></script> <script src="{{ asset('js/pdf.built.js') }}" type="text/javascript"></script>
<style type="text/css"> <style type="text/css">

View File

@ -24,8 +24,6 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="msapplication-config" content="none"/> <meta name="msapplication-config" content="none"/>
<link href="//fonts.googleapis.com/css?family=Roboto:400,700,900,100&subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=Roboto+Slab:400,300,700&subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link rel="canonical" href="{{ NINJA_APP_URL }}/{{ Request::path() }}" /> <link rel="canonical" href="{{ NINJA_APP_URL }}/{{ Request::path() }}" />
<script src="{{ asset('js/built.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script> <script src="{{ asset('js/built.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script>

View File

@ -19,6 +19,8 @@
NINJA.primaryColor = "{{ Auth::user()->account->primary_color }}"; NINJA.primaryColor = "{{ Auth::user()->account->primary_color }}";
NINJA.secondaryColor = "{{ Auth::user()->account->secondary_color }}"; NINJA.secondaryColor = "{{ Auth::user()->account->secondary_color }}";
NINJA.fontSize = {{ Auth::user()->account->font_size ?: DEFAULT_FONT_SIZE }}; NINJA.fontSize = {{ Auth::user()->account->font_size ?: DEFAULT_FONT_SIZE }};
NINJA.headerFont = {!! json_encode(Auth::user()->account->getHeaderFontName()) !!};
NINJA.bodyFont = {!! json_encode(Auth::user()->account->getBodyFontName()) !!};
@else @else
NINJA.fontSize = {{ DEFAULT_FONT_SIZE }}; NINJA.fontSize = {{ DEFAULT_FONT_SIZE }};
@endif @endif

View File

@ -1,9 +1,14 @@
@extends('master') @extends('master')
@section('head') @section('head')
@if (!empty($clientFontUrl))
<link href="{!! $clientFontUrl !!}" rel="stylesheet" type="text/css">
@else
<link href="//fonts.googleapis.com/css?family=Roboto:400,700,900,100" rel="stylesheet" type="text/css">
@endif
<link href="{{ asset('css/built.public.css') }}?no_cache={{ NINJA_VERSION }}" rel="stylesheet" type="text/css"/> <link href="{{ asset('css/built.public.css') }}?no_cache={{ NINJA_VERSION }}" rel="stylesheet" type="text/css"/>
@if (!empty($clientViewCSS)) @if (!empty($clientViewCSS))
<style>{!! $clientViewCSS !!}</style> <style type="text/css">{!! $clientViewCSS !!}</style>
@endif @endif
@stop @stop