mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 17:14:28 -04:00
Improvements to the tax report
This commit is contained in:
parent
1c864f4304
commit
a1d13cc84c
@ -49,6 +49,7 @@ class ReportController extends BaseController
|
||||
$groupBy = Input::get('group_by');
|
||||
$chartType = Input::get('chart_type');
|
||||
$reportType = Input::get('report_type');
|
||||
$dateField = Input::get('date_field');
|
||||
$startDate = Utils::toSqlDate(Input::get('start_date'), false);
|
||||
$endDate = Utils::toSqlDate(Input::get('end_date'), false);
|
||||
$enableReport = Input::get('enable_report') ? true : false;
|
||||
@ -57,6 +58,7 @@ class ReportController extends BaseController
|
||||
$groupBy = 'MONTH';
|
||||
$chartType = 'Bar';
|
||||
$reportType = ENTITY_INVOICE;
|
||||
$dateField = FILTER_INVOICE_DATE;
|
||||
$startDate = Utils::today(false)->modify('-3 month');
|
||||
$endDate = Utils::today(false);
|
||||
$enableReport = true;
|
||||
@ -98,7 +100,7 @@ class ReportController extends BaseController
|
||||
if (Auth::user()->account->isPro()) {
|
||||
if ($enableReport) {
|
||||
$isExport = $action == 'export';
|
||||
$params = array_merge($params, self::generateReport($reportType, $startDate, $endDate, $isExport));
|
||||
$params = array_merge($params, self::generateReport($reportType, $startDate, $endDate, $dateField, $isExport));
|
||||
|
||||
if ($isExport) {
|
||||
self::export($params['displayData'], $params['columns'], $params['reportTotals']);
|
||||
@ -216,7 +218,7 @@ class ReportController extends BaseController
|
||||
];
|
||||
}
|
||||
|
||||
private function generateReport($reportType, $startDate, $endDate, $isExport)
|
||||
private function generateReport($reportType, $startDate, $endDate, $dateField, $isExport)
|
||||
{
|
||||
if ($reportType == ENTITY_CLIENT) {
|
||||
return $this->generateClientReport($startDate, $endDate, $isExport);
|
||||
@ -225,11 +227,11 @@ class ReportController extends BaseController
|
||||
} elseif ($reportType == ENTITY_PAYMENT) {
|
||||
return $this->generatePaymentReport($startDate, $endDate, $isExport);
|
||||
} elseif ($reportType == ENTITY_TAX_RATE) {
|
||||
return $this->generateTaxRateReport($startDate, $endDate, $isExport);
|
||||
return $this->generateTaxRateReport($startDate, $endDate, $dateField, $isExport);
|
||||
}
|
||||
}
|
||||
|
||||
private function generateTaxRateReport($startDate, $endDate, $isExport)
|
||||
private function generateTaxRateReport($startDate, $endDate, $dateField, $isExport)
|
||||
{
|
||||
$columns = ['tax_name', 'tax_rate', 'amount', 'paid'];
|
||||
|
||||
@ -238,14 +240,25 @@ class ReportController extends BaseController
|
||||
$reportTotals = [];
|
||||
|
||||
$clients = Client::scope()
|
||||
->withTrashed()
|
||||
->withArchived()
|
||||
->with('contacts')
|
||||
->where('is_deleted', '=', false)
|
||||
->with(['invoices' => function($query) use ($startDate, $endDate) {
|
||||
$query->where('invoice_date', '>=', $startDate)
|
||||
->where('invoice_date', '<=', $endDate)
|
||||
->where('is_deleted', '=', false)
|
||||
->withTrashed();
|
||||
->with(['invoices' => function($query) use ($startDate, $endDate, $dateField) {
|
||||
$query->withArchived();
|
||||
if ($dateField == FILTER_PAYMENT_DATE) {
|
||||
$query->where('invoice_date', '>=', $startDate)
|
||||
->where('invoice_date', '<=', $endDate)
|
||||
->whereHas('payments', function($query) use ($startDate, $endDate) {
|
||||
$query->where('payment_date', '>=', $startDate)
|
||||
->where('payment_date', '<=', $endDate)
|
||||
->withArchived();
|
||||
})
|
||||
->with(['payments' => function($query) use ($startDate, $endDate) {
|
||||
$query->where('payment_date', '>=', $startDate)
|
||||
->where('payment_date', '<=', $endDate)
|
||||
->withArchived()
|
||||
->with('payment_type', 'account_gateway.gateway');
|
||||
}, 'invoice_items']);
|
||||
}
|
||||
}]);
|
||||
|
||||
foreach ($clients->get() as $client) {
|
||||
@ -255,7 +268,7 @@ class ReportController extends BaseController
|
||||
$taxTotals = [];
|
||||
|
||||
foreach ($client->invoices as $invoice) {
|
||||
foreach ($invoice->getTaxes() as $key => $tax) {
|
||||
foreach ($invoice->getTaxes(true) as $key => $tax) {
|
||||
if ( ! isset($taxTotals[$currencyId])) {
|
||||
$taxTotals[$currencyId] = [];
|
||||
}
|
||||
@ -331,7 +344,7 @@ class ReportController extends BaseController
|
||||
$reportTotals = $this->addToTotals($reportTotals, $client, 'amount', $invoice->amount);
|
||||
$reportTotals = $this->addToTotals($reportTotals, $client, 'paid', $payment->amount);
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
'columns' => $columns,
|
||||
'displayData' => $displayData,
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Routes
|
||||
@ -572,6 +573,9 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('REMINDER_FIELD_DUE_DATE', 1);
|
||||
define('REMINDER_FIELD_INVOICE_DATE', 2);
|
||||
|
||||
define('FILTER_INVOICE_DATE', 'invoice_date');
|
||||
define('FILTER_PAYMENT_DATE', 'payment_date');
|
||||
|
||||
define('SOCIAL_GOOGLE', 'Google');
|
||||
define('SOCIAL_FACEBOOK', 'Facebook');
|
||||
define('SOCIAL_GITHUB', 'GitHub');
|
||||
|
@ -81,6 +81,11 @@ class EntityModel extends Eloquent
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function scopeWithArchived($query)
|
||||
{
|
||||
return $query->withTrashed()->where('is_deleted', '=', false);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->public_id;
|
||||
|
@ -129,13 +129,21 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getAmountPaid()
|
||||
public function getAmountPaid($calculate = false)
|
||||
{
|
||||
if ($this->is_quote || $this->is_recurring) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ($this->amount - $this->balance);
|
||||
if ($calculate) {
|
||||
$amount = 0;
|
||||
foreach ($this->payments as $payment) {
|
||||
$amount += $payment->amount;
|
||||
}
|
||||
return $amount;
|
||||
} else {
|
||||
return ($this->amount - $this->balance);
|
||||
}
|
||||
}
|
||||
|
||||
public function trashed()
|
||||
@ -797,7 +805,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
return $total;
|
||||
}
|
||||
|
||||
public function getTaxes()
|
||||
public function getTaxes($calculatePaid = false)
|
||||
{
|
||||
$taxes = [];
|
||||
$taxable = $this->getTaxable();
|
||||
@ -811,7 +819,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
'name' => $this->tax_name,
|
||||
'rate' => $this->tax_rate,
|
||||
'amount' => $taxAmount,
|
||||
'paid' => $this->getAmountPaid() / $this->amount * $taxAmount
|
||||
'paid' => round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2)
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -836,7 +844,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
}
|
||||
|
||||
$taxes[$key]['amount'] += $taxAmount;
|
||||
$taxes[$key]['paid'] += $this->amount && $taxAmount ? ($this->getAmountPaid() / $this->amount * $taxAmount) : 0;
|
||||
$taxes[$key]['paid'] += $this->amount && $taxAmount ? round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2) : 0;
|
||||
$taxes[$key]['name'] = $invoiceItem->tax_name;
|
||||
$taxes[$key]['rate'] = $invoiceItem->tax_rate;
|
||||
}
|
||||
|
@ -130,11 +130,6 @@ class AccountRepository
|
||||
|
||||
private function getNavigationSearchData()
|
||||
{
|
||||
$features = [
|
||||
['dashboard', '/dashboard'],
|
||||
['customize_design', '/settings/customize_design'],
|
||||
];
|
||||
|
||||
$entityTypes = [
|
||||
ENTITY_INVOICE,
|
||||
ENTITY_CLIENT,
|
||||
@ -157,6 +152,12 @@ class AccountRepository
|
||||
];
|
||||
}
|
||||
|
||||
$features[] = ['dashboard', '/dashboard'];
|
||||
$features[] = ['customize_design', '/settings/customize_design'];
|
||||
$features[] = ['new_tax_rate', '/tax_rates/create'];
|
||||
$features[] = ['new_product', '/products/create'];
|
||||
$features[] = ['new_user', '/users/create'];
|
||||
|
||||
$settings = array_merge(Account::$basicSettings, Account::$advancedSettings);
|
||||
|
||||
foreach ($settings as $setting) {
|
||||
|
@ -223,11 +223,6 @@ class AppServiceProvider extends ServiceProvider {
|
||||
'Illuminate\Contracts\Auth\Registrar',
|
||||
'App\Services\Registrar'
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'App\Ninja\Import\DataImporterServiceInterface',
|
||||
'App\Ninja\Import\FreshBooks\FreshBooksDataImporterService'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1039,7 +1039,12 @@ $LANG = array(
|
||||
'list_payments' => 'List Payments',
|
||||
'list_credits' => 'List Credits',
|
||||
'tax_name' => 'Tax Name',
|
||||
|
||||
'report_settings' => 'Report Settings',
|
||||
'search_hotkey' => 'shortcut is /',
|
||||
|
||||
'new_user' => 'New User',
|
||||
'new_product' => 'New Product',
|
||||
'new_tax_rate' => 'New Tax Rate',
|
||||
);
|
||||
|
||||
return $LANG;
|
||||
|
@ -498,7 +498,7 @@
|
||||
<form id="search-form" class="navbar-form navbar-right" role="search" style="display:none">
|
||||
<div class="form-group">
|
||||
<input type="text" id="search" style="width: 240px;padding-top:0px;padding-bottom:0px"
|
||||
class="form-control" placeholder="{{ trans('texts.search') }}">
|
||||
class="form-control" placeholder="{{ trans('texts.search') . ': ' . trans('texts.search_hotkey')}}">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{!! trans('texts.settings') !!}</h3>
|
||||
<h3 class="panel-title">{!! trans('texts.report_settings') !!}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
@ -58,6 +58,11 @@
|
||||
<div class="col-md-6">
|
||||
{!! Former::checkbox('enable_report')->text(trans('texts.enable')) !!}
|
||||
{!! Former::select('report_type')->options($reportTypes, $reportType)->label(trans('texts.type')) !!}
|
||||
<div id="dateField" style="display:{{ $reportType == ENTITY_TAX_RATE ? 'block' : 'none' }}">
|
||||
{!! Former::select('date_field')->label(trans('texts.filter'))
|
||||
->addOption(trans('texts.invoice_date'), FILTER_INVOICE_DATE)
|
||||
->addOption(trans('texts.payment_date'), FILTER_PAYMENT_DATE) !!}
|
||||
</div>
|
||||
<p> </p>
|
||||
{!! Former::checkbox('enable_chart')->text(trans('texts.enable')) !!}
|
||||
{!! Former::select('group_by')->options($dateTypes, $groupBy) !!}
|
||||
@ -186,6 +191,15 @@
|
||||
$('.end_date .input-group-addon').click(function() {
|
||||
toggleDatePicker('end_date');
|
||||
});
|
||||
|
||||
$('#report_type').change(function() {
|
||||
var val = $('#report_type').val();
|
||||
if (val == '{{ ENTITY_TAX_RATE }}') {
|
||||
$('#dateField').fadeIn();
|
||||
} else {
|
||||
$('#dateField').fadeOut();
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user