mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Support filtering invoice/product reports by multiple statuses
This commit is contained in:
parent
8524d3f401
commit
f7d5a132d4
@ -99,7 +99,7 @@ class ReportController extends BaseController
|
|||||||
$isExport = $action == 'export';
|
$isExport = $action == 'export';
|
||||||
$config = [
|
$config = [
|
||||||
'date_field' => $dateField,
|
'date_field' => $dateField,
|
||||||
'invoice_status' => request()->invoice_status,
|
'status_ids' => request()->status_ids,
|
||||||
'group_dates_by' => request()->group_dates_by,
|
'group_dates_by' => request()->group_dates_by,
|
||||||
'document_filter' => request()->document_filter,
|
'document_filter' => request()->document_filter,
|
||||||
'currency_type' => request()->currency_type,
|
'currency_type' => request()->currency_type,
|
||||||
|
@ -460,6 +460,38 @@ class Invoice extends EntityModel implements BalanceAffecting
|
|||||||
return $query->where('invoice_type_id', '=', $typeId);
|
return $query->where('invoice_type_id', '=', $typeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $query
|
||||||
|
* @param $typeId
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function scopeStatusIds($query, $statusIds)
|
||||||
|
{
|
||||||
|
if (! $statusIds || (is_array($statusIds) && ! count($statusIds))) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->where(function ($query) use ($statusIds) {
|
||||||
|
foreach ($statusIds as $statusId) {
|
||||||
|
$query->orWhere('invoice_status_id', '=', $statusId);
|
||||||
|
}
|
||||||
|
if (in_array(INVOICE_STATUS_UNPAID, $statusIds)) {
|
||||||
|
$query->orWhere(function ($query) {
|
||||||
|
$query->where('balance', '>', 0)
|
||||||
|
->where('is_public', '=', true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (in_array(INVOICE_STATUS_OVERDUE, $statusIds)) {
|
||||||
|
$query->orWhere(function ($query) {
|
||||||
|
$query->where('balance', '>', 0)
|
||||||
|
->where('due_date', '<', date('Y-m-d'))
|
||||||
|
->where('is_public', '=', true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $typeId
|
* @param $typeId
|
||||||
*
|
*
|
||||||
|
@ -22,21 +22,17 @@ class InvoiceReport extends AbstractReport
|
|||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
$account = Auth::user()->account;
|
$account = Auth::user()->account;
|
||||||
$status = $this->options['invoice_status'];
|
$statusIds = $this->options['status_ids'];
|
||||||
$exportFormat = $this->options['export_format'];
|
$exportFormat = $this->options['export_format'];
|
||||||
|
|
||||||
$clients = Client::scope()
|
$clients = Client::scope()
|
||||||
->orderBy('name')
|
->orderBy('name')
|
||||||
->withArchived()
|
->withArchived()
|
||||||
->with('contacts')
|
->with('contacts')
|
||||||
->with(['invoices' => function ($query) use ($status) {
|
->with(['invoices' => function ($query) use ($statusIds) {
|
||||||
if ($status == 'draft') {
|
|
||||||
$query->whereIsPublic(false);
|
|
||||||
} elseif (in_array($status, ['paid', 'unpaid', 'sent'])) {
|
|
||||||
$query->whereIsPublic(true);
|
|
||||||
}
|
|
||||||
$query->invoices()
|
$query->invoices()
|
||||||
->withArchived()
|
->withArchived()
|
||||||
|
->statusIds($statusIds)
|
||||||
->where('invoice_date', '>=', $this->startDate)
|
->where('invoice_date', '>=', $this->startDate)
|
||||||
->where('invoice_date', '<=', $this->endDate)
|
->where('invoice_date', '<=', $this->endDate)
|
||||||
->with(['payments' => function ($query) {
|
->with(['payments' => function ($query) {
|
||||||
@ -65,17 +61,12 @@ class InvoiceReport extends AbstractReport
|
|||||||
foreach ($client->invoices as $invoice) {
|
foreach ($client->invoices as $invoice) {
|
||||||
$payments = count($invoice->payments) ? $invoice->payments : [false];
|
$payments = count($invoice->payments) ? $invoice->payments : [false];
|
||||||
foreach ($payments as $payment) {
|
foreach ($payments as $payment) {
|
||||||
if (! $payment && $status == 'paid') {
|
|
||||||
continue;
|
|
||||||
} elseif ($payment && $status == 'unpaid') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$this->data[] = [
|
$this->data[] = [
|
||||||
$this->isExport ? $client->getDisplayName() : $client->present()->link,
|
$this->isExport ? $client->getDisplayName() : $client->present()->link,
|
||||||
$this->isExport ? $invoice->invoice_number : $invoice->present()->link,
|
$this->isExport ? $invoice->invoice_number : $invoice->present()->link,
|
||||||
$invoice->present()->invoice_date,
|
$invoice->present()->invoice_date,
|
||||||
$account->formatMoney($invoice->amount, $client),
|
$account->formatMoney($invoice->amount, $client),
|
||||||
$invoice->present()->status(),
|
$invoice->statusLabel(),
|
||||||
$payment ? $payment->present()->payment_date : '',
|
$payment ? $payment->present()->payment_date : '',
|
||||||
$payment ? $account->formatMoney($payment->getCompletedAmount(), $client) : '',
|
$payment ? $account->formatMoney($payment->getCompletedAmount(), $client) : '',
|
||||||
$payment ? $payment->present()->method : '',
|
$payment ? $payment->present()->method : '',
|
||||||
|
@ -22,20 +22,16 @@ class ProductReport extends AbstractReport
|
|||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
$account = Auth::user()->account;
|
$account = Auth::user()->account;
|
||||||
$status = $this->options['invoice_status'];
|
$statusIds = $this->options['status_ids'];
|
||||||
|
|
||||||
$clients = Client::scope()
|
$clients = Client::scope()
|
||||||
->orderBy('name')
|
->orderBy('name')
|
||||||
->withArchived()
|
->withArchived()
|
||||||
->with('contacts')
|
->with('contacts')
|
||||||
->with(['invoices' => function ($query) use ($status) {
|
->with(['invoices' => function ($query) use ($statusIds) {
|
||||||
if ($status == 'draft') {
|
|
||||||
$query->whereIsPublic(false);
|
|
||||||
} elseif (in_array($status, ['paid', 'unpaid', 'sent'])) {
|
|
||||||
$query->whereIsPublic(true);
|
|
||||||
}
|
|
||||||
$query->invoices()
|
$query->invoices()
|
||||||
->withArchived()
|
->withArchived()
|
||||||
|
->statusIds($statusIds)
|
||||||
->where('invoice_date', '>=', $this->startDate)
|
->where('invoice_date', '>=', $this->startDate)
|
||||||
->where('invoice_date', '<=', $this->endDate)
|
->where('invoice_date', '<=', $this->endDate)
|
||||||
->with(['invoice_items']);
|
->with(['invoice_items']);
|
||||||
@ -43,11 +39,6 @@ class ProductReport extends AbstractReport
|
|||||||
|
|
||||||
foreach ($clients->get() as $client) {
|
foreach ($clients->get() as $client) {
|
||||||
foreach ($client->invoices as $invoice) {
|
foreach ($client->invoices as $invoice) {
|
||||||
if (! $invoice->isPaid() && $status == 'paid') {
|
|
||||||
continue;
|
|
||||||
} elseif ($invoice->isPaid() && $status == 'unpaid') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
foreach ($invoice->invoice_items as $item) {
|
foreach ($invoice->invoice_items as $item) {
|
||||||
$this->data[] = [
|
$this->data[] = [
|
||||||
$this->isExport ? $client->getDisplayName() : $client->present()->link,
|
$this->isExport ? $client->getDisplayName() : $client->present()->link,
|
||||||
|
@ -9,11 +9,19 @@
|
|||||||
<link href="{{ asset('css/tablesorter.css') }}" rel="stylesheet" type="text/css"/>
|
<link href="{{ asset('css/tablesorter.css') }}" rel="stylesheet" type="text/css"/>
|
||||||
<script src="{{ asset('js/tablesorter.min.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('js/tablesorter.min.js') }}" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<link href="{{ asset('css/select2.css') }}" rel="stylesheet" type="text/css"/>
|
||||||
|
<script src="{{ asset('js/select2.min.js') }}" type="text/javascript"></script>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
table.tablesorter th {
|
table.tablesorter th {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #777 !important;
|
background-color: #777 !important;
|
||||||
}
|
}
|
||||||
|
.select2-selection {
|
||||||
|
background-color: #f9f9f9 !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@stop
|
@stop
|
||||||
@ -146,12 +154,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="statusField" style="display:none">
|
<div id="statusField" style="display:none">
|
||||||
{!! Former::select('invoice_status')->label('status')
|
|
||||||
->addOption(trans('texts.status_all'), 'all')
|
<div class="form-group">
|
||||||
->addOption(trans('texts.status_draft'), 'draft')
|
<label for="status_ids" class="control-label col-lg-4 col-sm-4">{{ trans('texts.status') }}</label>
|
||||||
->addOption(trans('texts.status_sent'), 'sent')
|
<div class="col-lg-8 col-sm-8">
|
||||||
->addOption(trans('texts.status_unpaid'), 'unpaid')
|
<select name="status_ids[]" class="form-control" style="width: 100%;" id="statuses_{{ ENTITY_INVOICE }}" multiple="true">
|
||||||
->addOption(trans('texts.status_paid'), 'paid') !!}
|
@foreach (\App\Models\EntityModel::getStatusesFor(ENTITY_INVOICE) as $key => $value)
|
||||||
|
<option value="{{ $key }}">{{ $value }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="dateField" style="display:none">
|
<div id="dateField" style="display:none">
|
||||||
@ -467,6 +480,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
|
var statusIds = isStorageSupported() ? (localStorage.getItem('last:report_status_ids') || '') : '';
|
||||||
|
$('#statuses_{{ ENTITY_INVOICE }}').select2({
|
||||||
|
//allowClear: true,
|
||||||
|
}).val(statusIds.split(',')).trigger('change')
|
||||||
|
.on('change', function() {
|
||||||
|
if (isStorageSupported()) {
|
||||||
|
var filter = $('#statuses_{{ ENTITY_INVOICE }}').val();
|
||||||
|
if (filter) {
|
||||||
|
filter = filter.join(',');
|
||||||
|
} else {
|
||||||
|
filter = '';
|
||||||
|
}
|
||||||
|
console.log('set value: %s', filter);
|
||||||
|
localStorage.setItem('last:report_status_ids', filter);
|
||||||
|
}
|
||||||
|
}).maximizeSelect2Height();
|
||||||
|
|
||||||
$(".tablesorter-data").tablesorter({
|
$(".tablesorter-data").tablesorter({
|
||||||
@if (! request()->group_when_sorted)
|
@if (! request()->group_when_sorted)
|
||||||
sortList: [[0,0]],
|
sortList: [[0,0]],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user