mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
#1226-add-pdf-export-on-report
This commit is contained in:
parent
3fa08417e0
commit
04d9fe30eb
@ -14,6 +14,7 @@ class AbstractReport
|
|||||||
public $totals = [];
|
public $totals = [];
|
||||||
public $columns = [];
|
public $columns = [];
|
||||||
public $data = [];
|
public $data = [];
|
||||||
|
public $columns_labeled = [];
|
||||||
|
|
||||||
public function __construct($startDate, $endDate, $isExport, $options = false)
|
public function __construct($startDate, $endDate, $isExport, $options = false)
|
||||||
{
|
{
|
||||||
@ -52,9 +53,7 @@ class AbstractReport
|
|||||||
$this->totals[$currencyId][$dimension][$field] += $value;
|
$this->totals[$currencyId][$dimension][$field] += $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tableHeader()
|
public function tableHeaderArray() {
|
||||||
{
|
|
||||||
$str = '';
|
|
||||||
|
|
||||||
foreach ($this->columns as $key => $val) {
|
foreach ($this->columns as $key => $val) {
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
@ -75,8 +74,18 @@ class AbstractReport
|
|||||||
|
|
||||||
$class = count($class) ? implode(' ', $class) : 'group-false';
|
$class = count($class) ? implode(' ', $class) : 'group-false';
|
||||||
$label = trans("texts.{$field}");
|
$label = trans("texts.{$field}");
|
||||||
$str .= "<th class=\"{$class}\">{$label}</th>";
|
|
||||||
|
$this->columns_labeled[] = ['label' => $label, 'class' => $class, 'key' => $field];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tableHeader()
|
||||||
|
{
|
||||||
|
$this->tableHeaderArray();
|
||||||
|
$str = '';
|
||||||
|
|
||||||
|
foreach ($this->columns_labeled as $field => $attr)
|
||||||
|
$str .= "<th class=\"{$attr['class']}\">{$attr['label']}</th>";
|
||||||
|
|
||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
|
@ -2389,6 +2389,7 @@ $LANG = array(
|
|||||||
'currency_peruvian_sol' => 'Peruvian Sol',
|
'currency_peruvian_sol' => 'Peruvian Sol',
|
||||||
|
|
||||||
'use_english_version' => 'Make sure to use the English version of the files.<br/>We use the column headers to match the fields.',
|
'use_english_version' => 'Make sure to use the English version of the files.<br/>We use the column headers to match the fields.',
|
||||||
|
'download_pdf' => 'Download PDF'
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@foreach ($account->getFontFolders() as $font)
|
||||||
|
<script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script>
|
||||||
|
@endforeach
|
||||||
|
<script src="{{ asset('pdf.built.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script>
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@ -34,8 +38,9 @@
|
|||||||
var chartStartDate = moment("{{ $startDate }}");
|
var chartStartDate = moment("{{ $startDate }}");
|
||||||
var chartEndDate = moment("{{ $endDate }}");
|
var chartEndDate = moment("{{ $endDate }}");
|
||||||
var dateRanges = {!! $account->present()->dateRangeOptions !!};
|
var dateRanges = {!! $account->present()->dateRangeOptions !!};
|
||||||
|
window.invoiceFonts = {!! json_encode(Cache::get('fonts')) !!};
|
||||||
|
|
||||||
$(function() {
|
$(function () {
|
||||||
|
|
||||||
if (isStorageSupported()) {
|
if (isStorageSupported()) {
|
||||||
var lastRange = localStorage.getItem('last:report_range');
|
var lastRange = localStorage.getItem('last:report_range');
|
||||||
@ -106,7 +111,8 @@
|
|||||||
{{ trans('texts.date_range') }}
|
{{ trans('texts.date_range') }}
|
||||||
</label>
|
</label>
|
||||||
<div class="col-lg-8 col-sm-8">
|
<div class="col-lg-8 col-sm-8">
|
||||||
<div id="reportrange" style="background: #f9f9f9; cursor: pointer; padding: 9px 14px; border: 1px solid #dfe0e1; margin-top: 0px;">
|
<div id="reportrange"
|
||||||
|
style="background: #f9f9f9; cursor: pointer; padding: 9px 14px; border: 1px solid #dfe0e1; margin-top: 0px;">
|
||||||
<i class="glyphicon glyphicon-calendar fa fa-calendar"></i>
|
<i class="glyphicon glyphicon-calendar fa fa-calendar"></i>
|
||||||
<span></span> <b class="caret"></b>
|
<span></span> <b class="caret"></b>
|
||||||
</div>
|
</div>
|
||||||
@ -118,7 +124,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="statusField" style="display:{{ in_array($reportType, [ENTITY_INVOICE, ENTITY_PRODUCT]) ? 'block' : 'none' }}">
|
<div id="statusField"
|
||||||
|
style="display:{{ in_array($reportType, [ENTITY_INVOICE, ENTITY_PRODUCT]) ? 'block' : 'none' }}">
|
||||||
{!! Former::select('invoice_status')->label('status')
|
{!! Former::select('invoice_status')->label('status')
|
||||||
->addOption(trans('texts.all'), 'all')
|
->addOption(trans('texts.all'), 'all')
|
||||||
->addOption(trans('texts.draft'), 'draft')
|
->addOption(trans('texts.draft'), 'draft')
|
||||||
@ -149,7 +156,7 @@
|
|||||||
|
|
||||||
@if (!Auth::user()->hasFeature(FEATURE_REPORTS))
|
@if (!Auth::user()->hasFeature(FEATURE_REPORTS))
|
||||||
<script>
|
<script>
|
||||||
$(function() {
|
$(function () {
|
||||||
$('form.report-form').find('input, button').prop('disabled', true);
|
$('form.report-form').find('input, button').prop('disabled', true);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -157,6 +164,12 @@
|
|||||||
|
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
|
@if(request()->report_type)
|
||||||
|
{!! Button::warning(trans('texts.download_pdf'))
|
||||||
|
->withAttributes(array('onclick' => 'exportPDF()'))
|
||||||
|
->appendIcon(Icon::create('save'))
|
||||||
|
->large() !!}
|
||||||
|
@endif
|
||||||
{!! Button::primary(trans('texts.export'))
|
{!! Button::primary(trans('texts.export'))
|
||||||
->withAttributes(array('onclick' => 'onExportClick()'))
|
->withAttributes(array('onclick' => 'onExportClick()'))
|
||||||
->appendIcon(Icon::create('export'))
|
->appendIcon(Icon::create('export'))
|
||||||
@ -166,7 +179,8 @@
|
|||||||
->submit()
|
->submit()
|
||||||
->appendIcon(Icon::create('play'))
|
->appendIcon(Icon::create('play'))
|
||||||
->large() !!}
|
->large() !!}
|
||||||
</center><br/>
|
</center>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
{!! Former::close() !!}
|
{!! Former::close() !!}
|
||||||
@ -264,15 +278,15 @@
|
|||||||
sumColumns.push("{{ in_array($column, ['amount', 'paid', 'balance', 'cost', 'duration']) ? trans("texts.{$column}") : false }}");
|
sumColumns.push("{{ in_array($column, ['amount', 'paid', 'balance', 'cost', 'duration']) ? trans("texts.{$column}") : false }}");
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
$(function() {
|
$(function () {
|
||||||
$('.start_date .input-group-addon').click(function() {
|
$('.start_date .input-group-addon').click(function () {
|
||||||
toggleDatePicker('start_date');
|
toggleDatePicker('start_date');
|
||||||
});
|
});
|
||||||
$('.end_date .input-group-addon').click(function() {
|
$('.end_date .input-group-addon').click(function () {
|
||||||
toggleDatePicker('end_date');
|
toggleDatePicker('end_date');
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#report_type').change(function() {
|
$('#report_type').change(function () {
|
||||||
var val = $('#report_type').val();
|
var val = $('#report_type').val();
|
||||||
if (val == '{{ ENTITY_TAX_RATE }}') {
|
if (val == '{{ ENTITY_TAX_RATE }}') {
|
||||||
$('#dateField').fadeIn();
|
$('#dateField').fadeIn();
|
||||||
@ -300,36 +314,36 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$(function(){
|
$(function () {
|
||||||
$(".tablesorter-data").tablesorter({
|
$(".tablesorter-data").tablesorter({
|
||||||
@if (! request()->group_when_sorted)
|
@if (! request()->group_when_sorted)
|
||||||
sortList: [[0,0]],
|
sortList: [[0, 0]],
|
||||||
@endif
|
@endif
|
||||||
theme: 'bootstrap',
|
theme: 'bootstrap',
|
||||||
widgets: ['zebra', 'uitheme', 'filter'{!! request()->group_when_sorted ? ", 'group'" : "" !!}, 'columnSelector'],
|
widgets: ['zebra', 'uitheme', 'filter'{!! request()->group_when_sorted ? ", 'group'" : "" !!}, 'columnSelector'],
|
||||||
headerTemplate : '{content} {icon}',
|
headerTemplate: '{content} {icon}',
|
||||||
@if ($report)
|
@if ($report)
|
||||||
dateFormat: '{{ $report->convertDateFormat() }}',
|
dateFormat: '{{ $report->convertDateFormat() }}',
|
||||||
@endif
|
@endif
|
||||||
numberSorter: function(a, b, direction) {
|
numberSorter: function (a, b, direction) {
|
||||||
var a = convertStringToNumber(a);
|
var a = convertStringToNumber(a);
|
||||||
var b = convertStringToNumber(b);
|
var b = convertStringToNumber(b);
|
||||||
return direction ? a - b : b - a;
|
return direction ? a - b : b - a;
|
||||||
},
|
},
|
||||||
widgetOptions : {
|
widgetOptions: {
|
||||||
columnSelector_container : $('#columnSelector'),
|
columnSelector_container: $('#columnSelector'),
|
||||||
filter_cssFilter: 'form-control',
|
filter_cssFilter: 'form-control',
|
||||||
group_collapsed: true,
|
group_collapsed: true,
|
||||||
group_saveGroups: false,
|
group_saveGroups: false,
|
||||||
//group_formatter : function(txt, col, table, c, wo, data) {},
|
//group_formatter : function(txt, col, table, c, wo, data) {},
|
||||||
group_callback: function ($cell, $rows, column, table) {
|
group_callback: function ($cell, $rows, column, table) {
|
||||||
for (var i=0; i<sumColumns.length; i++) {
|
for (var i = 0; i < sumColumns.length; i++) {
|
||||||
var label = sumColumns[i];
|
var label = sumColumns[i];
|
||||||
if (!label) {
|
if (!label) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var subtotal = 0;
|
var subtotal = 0;
|
||||||
$rows.each(function() {
|
$rows.each(function () {
|
||||||
var txt = $(this).find("td").eq(i).text();
|
var txt = $(this).find("td").eq(i).text();
|
||||||
subtotal += convertStringToNumber(txt);
|
subtotal += convertStringToNumber(txt);
|
||||||
});
|
});
|
||||||
@ -351,13 +365,133 @@
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$summary = [];
|
||||||
|
$summary[] = array_merge([
|
||||||
|
trans("texts.totals")
|
||||||
|
], array_map(function ($key) {
|
||||||
|
return ['text' => trans("texts.{$key}"),
|
||||||
|
'style' => 'tableHeader'
|
||||||
|
];
|
||||||
|
}, array_keys(array_values(array_values($reportTotals)[0])[0])));
|
||||||
|
|
||||||
|
foreach ($reportTotals as $currencyId => $each) {
|
||||||
|
foreach ($each as $dimension => $val) {
|
||||||
|
$tmp = [];
|
||||||
|
$tmp[] = Utils::getFromCache($currencyId, 'currencies')->name . (($dimension) ? ' - ' . $dimension : '');
|
||||||
|
|
||||||
|
foreach ($val as $id => $field) $tmp[] = Utils::formatMoney($field, $currencyId);
|
||||||
|
|
||||||
|
$summary[] = $tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
function addFont(font){
|
||||||
|
if(window.ninjaFontVfs[font.folder]){
|
||||||
|
folder = 'fonts/'+font.folder;
|
||||||
|
pdfMake.fonts[font.name] = {
|
||||||
|
normal: folder+'/'+font.normal,
|
||||||
|
italics: folder+'/'+font.italics,
|
||||||
|
bold: folder+'/'+font.bold,
|
||||||
|
bolditalics: folder+'/'+font.bolditalics
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pdfMake.fonts = {}
|
||||||
|
fonts = window.invoiceFonts || invoice.invoice_fonts;
|
||||||
|
|
||||||
|
// Add only the loaded fonts
|
||||||
|
$.each(fonts, function(i,font){
|
||||||
|
addFont(font);
|
||||||
|
});
|
||||||
|
var dd = {!! html_entity_decode(json_encode( [
|
||||||
|
'pageOrientation' => 'landscape',
|
||||||
|
'content' => [
|
||||||
|
[
|
||||||
|
'text' => $reportTypes[$reportType],
|
||||||
|
'style' => 'header'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'style' => 'reportTable',
|
||||||
|
'table' => [
|
||||||
|
'headerRows' => 1,
|
||||||
|
'widths' => '*',
|
||||||
|
'body' => $summary
|
||||||
|
],
|
||||||
|
'layout' => 'lightHorizontalLines'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'style' => 'reportTable',
|
||||||
|
'table' => [
|
||||||
|
'headerRows' => 1,
|
||||||
|
'widths' => '*',
|
||||||
|
'body' =>
|
||||||
|
array_merge(
|
||||||
|
[array_map(function($array) {
|
||||||
|
return [
|
||||||
|
'text' => $array['label'],
|
||||||
|
'style' => 'tableHeader'
|
||||||
|
];
|
||||||
|
}, $report->columns_labeled)]
|
||||||
|
, array_map(function($row) {
|
||||||
|
return array_map(function($col) {
|
||||||
|
if(strpos($col, "<a href") !== FALSE) {
|
||||||
|
$hrefs = [];
|
||||||
|
preg_match('#<a.*href=[\'"](.*)["\'].*>(.*)<.*#', $col, $hrefs);
|
||||||
|
return [
|
||||||
|
'text' => $hrefs[2],
|
||||||
|
'link' => $hrefs[1]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $col;
|
||||||
|
}, $row);
|
||||||
|
}, $displayData))
|
||||||
|
|
||||||
|
],
|
||||||
|
'layout' => 'lightHorizontalLines'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'styles' => [
|
||||||
|
'header' => [
|
||||||
|
'fontSize' => 18,
|
||||||
|
'bold' => true,
|
||||||
|
'margin' => [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
10
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'reportTable' => [
|
||||||
|
'margin' => [
|
||||||
|
0,
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
50
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'tableHeader' => [
|
||||||
|
'bold' => true,
|
||||||
|
'fontSize' => 13,
|
||||||
|
'color' => 'black'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'defaultStyle' => [
|
||||||
|
'font' => Cache::get('fonts')[0]['name']
|
||||||
|
]
|
||||||
|
] , JSON_PRETTY_PRINT)) !!}
|
||||||
|
function exportPDF() {
|
||||||
|
pdfMake.createPdf(dd).download($('#reportrange').data('daterangepicker').startDate.format('YYYY-MM-DD') + '-' + $('#reportrange').data('daterangepicker').endDate.format('YYYY-MM-DD')+'_'+'{{'-invoiceninja-'.$reportTypes[$reportType].'-report'}}');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@stop
|
||||||
@stop
|
|
||||||
|
|
||||||
|
|
||||||
@section('onReady')
|
@section('onReady')
|
||||||
|
|
||||||
$('#start_date, #end_date').datepicker({
|
$('#start_date, #end_date').datepicker({
|
||||||
autoclose: true,
|
autoclose: true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user