1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-08 20:22:42 +01:00

Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
David Bomba 2016-02-25 09:32:41 +11:00
commit ed6c35cc8c
15 changed files with 494 additions and 190 deletions

View File

@ -10,6 +10,9 @@ use DatePeriod;
use Session;
use View;
use App\Models\Account;
use App\Models\Client;
use App\Models\Payment;
use App\Models\Expense;
class ReportController extends BaseController
{
@ -47,6 +50,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;
@ -55,6 +59,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;
@ -76,6 +81,8 @@ class ReportController extends BaseController
ENTITY_CLIENT => trans('texts.client'),
ENTITY_INVOICE => trans('texts.invoice'),
ENTITY_PAYMENT => trans('texts.payment'),
ENTITY_EXPENSE => trans('texts.expenses'),
ENTITY_TAX_RATE => trans('texts.taxes'),
];
$params = [
@ -94,10 +101,11 @@ class ReportController extends BaseController
if (Auth::user()->account->isPro()) {
if ($enableReport) {
$params = array_merge($params, self::generateReport($reportType, $groupBy, $startDate, $endDate));
$isExport = $action == 'export';
$params = array_merge($params, self::generateReport($reportType, $startDate, $endDate, $dateField, $isExport));
if ($action == 'export') {
self::export($params['exportData'], $params['reportTotals']);
if ($isExport) {
self::export($params['displayData'], $params['columns'], $params['reportTotals']);
}
}
if ($enableChart) {
@ -212,165 +220,310 @@ class ReportController extends BaseController
];
}
private function generateReport($reportType, $groupBy, $startDate, $endDate)
private function generateReport($reportType, $startDate, $endDate, $dateField, $isExport)
{
if ($reportType == ENTITY_CLIENT) {
$columns = ['client', 'amount', 'paid', 'balance'];
return $this->generateClientReport($startDate, $endDate, $isExport);
} elseif ($reportType == ENTITY_INVOICE) {
$columns = ['client', 'invoice_number', 'invoice_date', 'amount', 'paid', 'balance'];
} else {
$columns = ['client', 'invoice_number', 'invoice_date', 'amount', 'payment_date', 'paid', 'method'];
return $this->generateInvoiceReport($startDate, $endDate, $isExport);
} elseif ($reportType == ENTITY_PAYMENT) {
return $this->generatePaymentReport($startDate, $endDate, $isExport);
} elseif ($reportType == ENTITY_TAX_RATE) {
return $this->generateTaxRateReport($startDate, $endDate, $dateField, $isExport);
} elseif ($reportType == ENTITY_EXPENSE) {
return $this->generateExpenseReport($startDate, $endDate, $isExport);
}
}
$query = DB::table('invoices')
->join('accounts', 'accounts.id', '=', 'invoices.account_id')
->join('clients', 'clients.id', '=', 'invoices.client_id')
->join('contacts', 'contacts.client_id', '=', 'clients.id')
->where('invoices.account_id', '=', Auth::user()->account_id)
->where('invoices.is_deleted', '=', false)
->where('clients.is_deleted', '=', false)
->where('contacts.deleted_at', '=', null)
->where('invoices.invoice_date', '>=', $startDate->format('Y-m-d'))
->where('invoices.invoice_date', '<=', $endDate->format('Y-m-d'))
->where('invoices.is_quote', '=', false)
->where('invoices.is_recurring', '=', false)
->where('contacts.is_primary', '=', true);
private function generateTaxRateReport($startDate, $endDate, $dateField, $isExport)
{
$columns = ['tax_name', 'tax_rate', 'amount', 'paid'];
$select = [
DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'),
'accounts.country_id',
'contacts.first_name',
'contacts.last_name',
'contacts.email',
'clients.name as client_name',
'clients.public_id as client_public_id',
'invoices.public_id as invoice_public_id'
];
if ($reportType == ENTITY_CLIENT) {
$query->groupBy('clients.id');
array_push($select, DB::raw('sum(invoices.amount) amount'), DB::raw('sum(invoices.balance) balance'), DB::raw('sum(invoices.amount - invoices.balance) paid'));
} else {
$query->orderBy('invoices.id');
array_push($select, 'invoices.invoice_number', 'invoices.amount', 'invoices.balance', 'invoices.invoice_date');
if ($reportType == ENTITY_INVOICE) {
array_push($select, DB::raw('(invoices.amount - invoices.balance) paid'));
} else {
$query->join('payments', 'payments.invoice_id', '=', 'invoices.id')
->leftJoin('payment_types', 'payment_types.id', '=', 'payments.payment_type_id')
->leftJoin('account_gateways', 'account_gateways.id', '=', 'payments.account_gateway_id')
->leftJoin('gateways', 'gateways.id', '=', 'account_gateways.gateway_id');
array_push($select, 'payments.payment_date', 'payments.amount as paid', 'payment_types.name as payment_type', 'gateways.name as gateway');
}
}
$query->select($select);
$data = $query->get();
$lastInvoiceId = null;
$sameAsLast = false;
$account = Auth::user()->account;
$displayData = [];
$reportTotals = [];
$exportData = [];
$reportTotals = [
'amount' => [],
'balance' => [],
'paid' => [],
];
$clients = Client::scope()
->withArchived()
->with('contacts')
->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 ($data as $record) {
$sameAsLast = ($lastInvoiceId == $record->invoice_public_id);
$lastInvoiceId = $record->invoice_public_id;
foreach ($clients->get() as $client) {
$currencyId = $client->currency_id ?: Auth::user()->account->getCurrencyId();
$amount = 0;
$paid = 0;
$taxTotals = [];
$displayRow = [];
if ($sameAsLast) {
array_push($displayRow, '', '', '', '');
} else {
array_push($displayRow, link_to('/clients/'.$record->client_public_id, Utils::getClientDisplayName($record)));
if ($reportType != ENTITY_CLIENT) {
array_push($displayRow,
link_to('/invoices/'.$record->invoice_public_id, $record->invoice_number),
Utils::fromSqlDate($record->invoice_date, true)
);
foreach ($client->invoices as $invoice) {
foreach ($invoice->getTaxes(true) as $key => $tax) {
if ( ! isset($taxTotals[$currencyId])) {
$taxTotals[$currencyId] = [];
}
if (isset($taxTotals[$currencyId][$key])) {
$taxTotals[$currencyId][$key]['amount'] += $tax['amount'];
$taxTotals[$currencyId][$key]['paid'] += $tax['paid'];
} else {
$taxTotals[$currencyId][$key] = $tax;
}
}
array_push($displayRow, Utils::formatMoney($record->amount, $record->currency_id, $record->country_id));
}
if ($reportType != ENTITY_PAYMENT) {
array_push($displayRow, Utils::formatMoney($record->paid, $record->currency_id, $record->country_id));
}
if ($reportType == ENTITY_PAYMENT) {
array_push($displayRow,
Utils::fromSqlDate($record->payment_date, true),
Utils::formatMoney($record->paid, $record->currency_id, $record->country_id),
$record->gateway ?: $record->payment_type
);
} else {
array_push($displayRow, Utils::formatMoney($record->balance, $record->currency_id, $record->country_id));
$amount += $invoice->amount;
$paid += $invoice->getAmountPaid();
}
// export data
$exportRow = [];
if ($sameAsLast) {
$exportRow[trans('texts.client')] = ' ';
$exportRow[trans('texts.invoice_number')] = ' ';
$exportRow[trans('texts.invoice_date')] = ' ';
$exportRow[trans('texts.amount')] = ' ';
} else {
$exportRow[trans('texts.client')] = Utils::getClientDisplayName($record);
if ($reportType != ENTITY_CLIENT) {
$exportRow[trans('texts.invoice_number')] = $record->invoice_number;
$exportRow[trans('texts.invoice_date')] = Utils::fromSqlDate($record->invoice_date, true);
foreach ($taxTotals as $currencyId => $taxes) {
foreach ($taxes as $tax) {
$displayData[] = [
$tax['name'],
$tax['rate'],
$account->formatMoney($tax['amount'], $client),
$account->formatMoney($tax['paid'], $client)
];
}
$exportRow[trans('texts.amount')] = Utils::formatMoney($record->amount, $record->currency_id, $record->country_id);
$reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'amount', $tax['amount']);
$reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'paid', $tax['paid']);
}
if ($reportType != ENTITY_PAYMENT) {
$exportRow[trans('texts.paid')] = Utils::formatMoney($record->paid, $record->currency_id, $record->country_id);
}
if ($reportType == ENTITY_PAYMENT) {
$exportRow[trans('texts.payment_date')] = Utils::fromSqlDate($record->payment_date, true);
$exportRow[trans('texts.payment_amount')] = Utils::formatMoney($record->paid, $record->currency_id, $record->country_id);
$exportRow[trans('texts.method')] = $record->gateway ?: $record->payment_type;
} else {
$exportRow[trans('texts.balance')] = Utils::formatMoney($record->balance, $record->currency_id, $record->country_id);
}
$displayData[] = $displayRow;
$exportData[] = $exportRow;
$accountCurrencyId = Auth::user()->account->currency_id;
$currencyId = $record->currency_id ? $record->currency_id : ($accountCurrencyId ? $accountCurrencyId : DEFAULT_CURRENCY);
if (!isset($reportTotals['amount'][$currencyId])) {
$reportTotals['amount'][$currencyId] = 0;
$reportTotals['balance'][$currencyId] = 0;
$reportTotals['paid'][$currencyId] = 0;
}
if (!$sameAsLast) {
$reportTotals['amount'][$currencyId] += $record->amount;
$reportTotals['balance'][$currencyId] += $record->balance;
}
$reportTotals['paid'][$currencyId] += $record->paid;
}
return [
'columns' => $columns,
'displayData' => $displayData,
'reportTotals' => $reportTotals,
'exportData' => $exportData
];
}
private function generatePaymentReport($startDate, $endDate, $isExport)
{
$columns = ['client', 'invoice_number', 'invoice_date', 'amount', 'payment_date', 'paid', 'method'];
$account = Auth::user()->account;
$displayData = [];
$reportTotals = [];
$payments = Payment::scope()
->withTrashed()
->where('is_deleted', '=', false)
->whereHas('client', function($query) {
$query->where('is_deleted', '=', false);
})
->whereHas('invoice', function($query) {
$query->where('is_deleted', '=', false);
})
->with('client.contacts', 'invoice', 'payment_type', 'account_gateway.gateway')
->where('payment_date', '>=', $startDate)
->where('payment_date', '<=', $endDate);
foreach ($payments->get() as $payment) {
$invoice = $payment->invoice;
$client = $payment->client;
$displayData[] = [
$isExport ? $client->getDisplayName() : $client->present()->link,
$isExport ? $invoice->invoice_number : $invoice->present()->link,
$invoice->present()->invoice_date,
$account->formatMoney($invoice->amount, $client),
$payment->present()->payment_date,
$account->formatMoney($payment->amount, $client),
$payment->present()->method,
];
$reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'amount', $invoice->amount);
$reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'paid', $payment->amount);
}
return [
'columns' => $columns,
'displayData' => $displayData,
'reportTotals' => $reportTotals,
];
}
private function export($data, $totals)
private function generateInvoiceReport($startDate, $endDate, $isExport)
{
$columns = ['client', 'invoice_number', 'invoice_date', 'amount', 'paid', 'balance'];
$account = Auth::user()->account;
$displayData = [];
$reportTotals = [];
$clients = Client::scope()
->withTrashed()
->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)
->with(['payments' => function($query) {
$query->withTrashed()
->with('payment_type', 'account_gateway.gateway')
->where('is_deleted', '=', false);
}, 'invoice_items'])
->withTrashed();
}]);
foreach ($clients->get() as $client) {
$currencyId = $client->currency_id ?: Auth::user()->account->getCurrencyId();
foreach ($client->invoices as $invoice) {
$displayData[] = [
$isExport ? $client->getDisplayName() : $client->present()->link,
$isExport ? $invoice->invoice_number : $invoice->present()->link,
$invoice->present()->invoice_date,
$account->formatMoney($invoice->amount, $client),
$account->formatMoney($invoice->getAmountPaid(), $client),
$account->formatMoney($invoice->balance, $client),
];
$reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'amount', $invoice->amount);
$reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'paid', $invoice->getAmountPaid());
$reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'balance', $invoice->balance);
}
}
return [
'columns' => $columns,
'displayData' => $displayData,
'reportTotals' => $reportTotals,
];
}
private function generateClientReport($startDate, $endDate, $isExport)
{
$columns = ['client', 'amount', 'paid', 'balance'];
$account = Auth::user()->account;
$displayData = [];
$reportTotals = [];
$clients = Client::scope()
->withArchived()
->with('contacts')
->with(['invoices' => function($query) use ($startDate, $endDate) {
$query->where('invoice_date', '>=', $startDate)
->where('invoice_date', '<=', $endDate)
->withArchived();
}]);
foreach ($clients->get() as $client) {
$amount = 0;
$paid = 0;
foreach ($client->invoices as $invoice) {
$amount += $invoice->amount;
$paid += $invoice->getAmountPaid();
}
$displayData[] = [
$isExport ? $client->getDisplayName() : $client->present()->link,
$account->formatMoney($amount, $client),
$account->formatMoney($paid, $client),
$account->formatMoney($amount - $paid, $client)
];
$reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'amount', $amount);
$reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'paid', $paid);
$reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'balance', $amount - $paid);
}
return [
'columns' => $columns,
'displayData' => $displayData,
'reportTotals' => $reportTotals,
];
}
private function generateExpenseReport($startDate, $endDate, $isExport)
{
$columns = ['vendor', 'client', 'date', 'expense_amount', 'invoiced_amount'];
$account = Auth::user()->account;
$displayData = [];
$reportTotals = [];
$expenses = Expense::scope()
->withTrashed()
->with('client.contacts', 'vendor')
->where('expense_date', '>=', $startDate)
->where('expense_date', '<=', $endDate);
foreach ($expenses->get() as $expense) {
$amount = $expense->amount;
$invoiced = $expense->present()->invoiced_amount;
$displayData[] = [
$expense->vendor ? ($isExport ? $expense->vendor->name : $expense->vendor->present()->link) : '',
$expense->client ? ($isExport ? $expense->client->getDisplayName() : $expense->client->present()->link) : '',
$expense->present()->expense_date,
Utils::formatMoney($amount, $expense->currency_id),
Utils::formatMoney($invoiced, $expense->invoice_currency_id),
];
$reportTotals = $this->addToTotals($reportTotals, $expense->expense_currency_id, 'amount', $amount);
$reportTotals = $this->addToTotals($reportTotals, $expense->invoice_currency_id, 'amount', 0);
$reportTotals = $this->addToTotals($reportTotals, $expense->invoice_currency_id, 'invoiced', $invoiced);
$reportTotals = $this->addToTotals($reportTotals, $expense->expense_currency_id, 'invoiced', 0);
}
return [
'columns' => $columns,
'displayData' => $displayData,
'reportTotals' => $reportTotals,
];
}
private function addToTotals($data, $currencyId, $field, $value) {
$currencyId = $currencyId ?: Auth::user()->account->getCurrencyId();
if (!isset($data[$currencyId][$field])) {
$data[$currencyId][$field] = 0;
}
$data[$currencyId][$field] += $value;
return $data;
}
private function export($data, $columns, $totals)
{
$output = fopen('php://output', 'w') or Utils::fatalError();
header('Content-Type:application/csv');
header('Content-Disposition:attachment;filename=ninja-report.csv');
Utils::exportData($output, $data);
Utils::exportData($output, $data, Utils::trans($columns));
fwrite($output, trans('texts.totals'));
foreach ($totals as $currencyId => $fields) {
foreach ($fields as $key => $value) {
fwrite($output, ',' . trans("texts.{$key}"));
}
fwrite($output, "\n");
break;
}
foreach (['amount', 'paid', 'balance'] as $type) {
$csv = trans("texts.{$type}").',';
foreach ($totals[$type] as $currencyId => $amount) {
$csv .= Utils::formatMoney($amount, $currencyId).',';
foreach ($totals as $currencyId => $fields) {
$csv = Utils::getFromCache($currencyId, 'currencies')->name . ',';
foreach ($fields as $key => $value) {
$csv .= '"' . Utils::formatMoney($value, $currencyId).'",';
}
fwrite($output, $csv."\n");
}

View File

@ -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');

View File

@ -767,9 +767,11 @@ class Utils
return $str;
}
public static function exportData($output, $data)
public static function exportData($output, $data, $headers = false)
{
if (count($data) > 0) {
if ($headers) {
fputcsv($output, $headers);
} elseif (count($data) > 0) {
fputcsv($output, array_keys($data[0]));
}

View File

@ -272,6 +272,11 @@ class Client extends EntityModel
return $token ? "https://dashboard.stripe.com/customers/{$token}" : false;
}
public function getAmount()
{
return $this->balance + $this->paid_to_date;
}
public function getCurrencyId()
{
if ($this->currency_id) {

View File

@ -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;

View File

@ -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()
@ -752,6 +760,98 @@ class Invoice extends EntityModel implements BalanceAffecting
return Utils::decodePDF($pdfString);
}
public function getItemTaxable($invoiceItem, $invoiceTotal)
{
$total = $invoiceItem->qty * $invoiceItem->cost;
if ($this->discount > 0) {
if ($this->is_amount_discount) {
$total -= $invoiceTotal ? ($total / $invoiceTotal * $this->discount) : 0;
} else {
$total *= (100 - $this->discount) / 100;
$total = round($total, 2);
}
}
return $total;
}
public function getTaxable()
{
$total = 0;
foreach ($this->invoice_items as $invoiceItem) {
$total += $invoiceItem->qty * $invoiceItem->cost;
}
if ($this->discount > 0) {
if ($this->is_amount_discount) {
$total -= $this->discount;
} else {
$total *= (100 - $this->discount) / 100;
$total = round($total, 2);
}
}
if ($this->custom_value1 && $this->custom_taxes1) {
$total += $this->custom_value1;
}
if ($this->custom_value2 && $this->custom_taxes2) {
$total += $this->custom_value2;
}
return $total;
}
public function getTaxes($calculatePaid = false)
{
$taxes = [];
$taxable = $this->getTaxable();
if ($this->tax_rate && $this->tax_name) {
$taxAmount = $taxable * ($this->tax_rate / 100);
$taxAmount = round($taxAmount, 2);
if ($taxAmount) {
$taxes[$this->tax_name.$this->tax_rate] = [
'name' => $this->tax_name,
'rate' => $this->tax_rate,
'amount' => $taxAmount,
'paid' => round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2)
];
}
}
foreach ($this->invoice_items as $invoiceItem) {
if ( ! $invoiceItem->tax_rate || ! $invoiceItem->tax_name) {
continue;
}
$taxAmount = $this->getItemTaxable($invoiceItem, $taxable);
$taxAmount = $taxable * ($invoiceItem->tax_rate / 100);
$taxAmount = round($taxAmount, 2);
if ($taxAmount) {
$key = $invoiceItem->tax_name.$invoiceItem->tax_rate;
if ( ! isset($taxes[$key])) {
$taxes[$key] = [
'amount' => 0,
'paid' => 0
];
}
$taxes[$key]['amount'] += $taxAmount;
$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;
}
}
return $taxes;
}
}
Invoice::creating(function ($invoice) {

View File

@ -26,6 +26,10 @@ class ClientPresenter extends Presenter {
}
return "<span class=\"label label-{$class}\">{$text}</span>";
}
public function link()
{
return link_to('/clients/' . $this->entity->public_id, $this->entity->getDisplayName());
}
}

View File

@ -20,4 +20,14 @@ class ExpensePresenter extends Presenter {
{
return round($this->entity->amount * $this->entity->exchange_rate, 2);
}
public function invoiced_amount()
{
return $this->entity->invoice_id ? $this->converted_amount() : 0;
}
public function link()
{
return link_to('/expenses/' . $this->entity->public_id, $this->entity->name);
}
}

View File

@ -55,4 +55,9 @@ class InvoicePresenter extends Presenter {
return Utils::fromSqlDate($this->entity->due_date);
}
public function link()
{
return link_to('/invoices/' . $this->entity->public_id, $this->entity->invoice_number);
}
}

View File

@ -9,4 +9,9 @@ class VendorPresenter extends Presenter {
{
return $this->entity->country ? $this->entity->country->name : '';
}
public function link()
{
return link_to('/vendors/' . $this->entity->public_id, $this->entity->name);
}
}

View File

@ -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) {

View File

@ -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'
);
}
}

View File

@ -1034,10 +1034,19 @@ $LANG = array(
'list_clients' => 'List Clients',
'list_quotes' => 'List Quotes',
'list_tasks' => 'List Tasks',
'list_expensess' => 'List Expenses',
'list_expenses' => 'List Expenses',
'list_recurring_invoices' => 'List Recurring Invoices',
'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',
'invoiced_amount' => 'Invoiced Amount',
);
return $LANG;

View File

@ -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>

View File

@ -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">
@ -54,12 +54,17 @@
@endif
</div>
</div>
<div class="col-md-6">
{!! Former::checkbox('enable_report')->text(trans('texts.enable')) !!}
{!! Former::select('report_type')->options($reportTypes, $reportType)->label(trans('texts.group_by')) !!}
{!! 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>&nbsp;</p>
{!! Former::checkbox('enable_chart')->text(trans('texts.enable')) !!}
{!! Former::checkbox('enable_chart')->text(trans('texts.enable')) !!}
{!! Former::select('group_by')->options($dateTypes, $groupBy) !!}
{!! Former::select('chart_type')->options($chartTypes, $chartType) !!}
@ -77,56 +82,48 @@
<thead>
<tr>
@foreach ($columns as $column)
<th>
{{ trans("texts.{$column}") }}
</th>
<th>{{ trans("texts.{$column}") }}</th>
@endforeach
</tr>
</tr>
</thead>
<tbody>
@foreach ($displayData as $record)
<tr>
@foreach ($record as $field)
<td>
{!! $field !!}
</td>
<td>{!! $field !!}</td>
@endforeach
</tr>
@endforeach
</tbody>
<tfoot>
<tr>
<td><b>{{ trans('texts.totals') }}</b></td>
@if ($reportType != ENTITY_CLIENT)
<td></td>
<td></td>
@endif
<td>
@foreach ($reportTotals['amount'] as $currencyId => $total)
<b>{{ Utils::formatMoney($total, $currencyId) }}</b><br/>
@endforeach
</td>
@if ($reportType == ENTITY_PAYMENT)
<td></td>
@endif
<td>
@foreach ($reportTotals['paid'] as $currencyId => $total)
<b>{{ Utils::formatMoney($total, $currencyId) }}</b><br/>
@endforeach
</td>
@if ($reportType != ENTITY_PAYMENT)
<td>
@foreach ($reportTotals['balance'] as $currencyId => $total)
<b>{{ Utils::formatMoney($total, $currencyId) }}</b><br/>
@endforeach
</td>
@endif
</tr>
</tfoot>
</table>
<p>&nbsp;</p>
@if (count(array_values($reportTotals)))
<table class="table table-striped invoice-table">
<thead>
<tr>
<th>{{ trans("texts.totals") }}</th>
@foreach (array_values($reportTotals)[0] as $key => $val)
<th>{{ trans("texts.{$key}") }}</th>
@endforeach
</tr>
</thead>
<tbody>
@foreach ($reportTotals as $currencyId => $val)
<tr>
<td>{!! Utils::getFromCache($currencyId, 'currencies')->name !!}</td>
@foreach ($val as $id => $field)
<td>{!! Utils::formatMoney($field, $currencyId) !!}</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
@endif
</div>
</div>
</div>
@endif
@if ($enableChart)
@ -194,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();
}
});
})