mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Added check to ensure expense currency matches client\invoice currency
This commit is contained in:
parent
e245b6f639
commit
25f5cdbcdd
@ -182,22 +182,30 @@ class ExpenseController extends BaseController
|
|||||||
switch($action)
|
switch($action)
|
||||||
{
|
{
|
||||||
case 'invoice':
|
case 'invoice':
|
||||||
$expenses = Expense::scope($ids)->get();
|
$expenses = Expense::scope($ids)->with('client')->get();
|
||||||
$clientId = null;
|
$clientPublicId = null;
|
||||||
$data = [];
|
$currencyId = null;
|
||||||
|
$data = [];
|
||||||
|
|
||||||
// Validate that either all expenses do not have a client or if there is a client, it is the same client
|
// Validate that either all expenses do not have a client or if there is a client, it is the same client
|
||||||
foreach ($expenses as $expense)
|
foreach ($expenses as $expense)
|
||||||
{
|
{
|
||||||
if ($expense->client_id) {
|
if ($expense->client) {
|
||||||
if (!$clientId) {
|
if (!$clientPublicId) {
|
||||||
$clientId = $expense->client_id;
|
$clientPublicId = $expense->client->public_id;
|
||||||
} elseif ($clientId != $expense->client_id) {
|
} elseif ($clientPublicId != $expense->client->public_id) {
|
||||||
Session::flash('error', trans('texts.expense_error_multiple_clients'));
|
Session::flash('error', trans('texts.expense_error_multiple_clients'));
|
||||||
return Redirect::to('expenses');
|
return Redirect::to('expenses');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$currencyId) {
|
||||||
|
$currencyId = $expense->getCurrencyId();
|
||||||
|
} elseif ($currencyId != $expense->getCurrencyId() && $expense->getCurrencyId()) {
|
||||||
|
Session::flash('error', trans('texts.expense_error_multiple_currencies'));
|
||||||
|
return Redirect::to('expenses');
|
||||||
|
}
|
||||||
|
|
||||||
if ($expense->invoice_id) {
|
if ($expense->invoice_id) {
|
||||||
Session::flash('error', trans('texts.expense_error_invoiced'));
|
Session::flash('error', trans('texts.expense_error_invoiced'));
|
||||||
return Redirect::to('expenses');
|
return Redirect::to('expenses');
|
||||||
@ -212,8 +220,9 @@ class ExpenseController extends BaseController
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$clientPublicId = $clientId ? Client::findOrFail($clientId)->public_id : '';
|
return Redirect::to("invoices/create/{$clientPublicId}")
|
||||||
return Redirect::to("invoices/create/{$clientPublicId}")->with('expenses', $data);
|
->with('expenseCurrencyId', $currencyId)
|
||||||
|
->with('expenses', $data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -320,6 +320,7 @@ class InvoiceController extends BaseController
|
|||||||
'invoiceLabels' => Auth::user()->account->getInvoiceLabels(),
|
'invoiceLabels' => Auth::user()->account->getInvoiceLabels(),
|
||||||
'tasks' => Session::get('tasks') ? json_encode(Session::get('tasks')) : null,
|
'tasks' => Session::get('tasks') ? json_encode(Session::get('tasks')) : null,
|
||||||
'expenses' => Session::get('expenses') ? json_encode(Session::get('expenses')) : null,
|
'expenses' => Session::get('expenses') ? json_encode(Session::get('expenses')) : null,
|
||||||
|
'expenseCurrencyId' => Session::get('expenseCurrencyId') ?: null,
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,11 @@ class Expense extends EntityModel
|
|||||||
return $this->public_id;
|
return $this->public_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCurrencyId()
|
||||||
|
{
|
||||||
|
return $this->client ? $this->client->currency_id : $this->currency_id;
|
||||||
|
}
|
||||||
|
|
||||||
public function getDisplayName()
|
public function getDisplayName()
|
||||||
{
|
{
|
||||||
return $this->getName();
|
return $this->getName();
|
||||||
|
@ -64,9 +64,9 @@ class ExpenseRepository extends BaseRepository
|
|||||||
->orWhere('contacts.is_primary', '=', null);
|
->orWhere('contacts.is_primary', '=', null);
|
||||||
})
|
})
|
||||||
->select(
|
->select(
|
||||||
|
DB::raw('COALESCE(clients.currency_id, expenses.currency_id, accounts.currency_id) currency_id'),
|
||||||
'expenses.account_id',
|
'expenses.account_id',
|
||||||
'expenses.amount',
|
'expenses.amount',
|
||||||
'expenses.currency_id',
|
|
||||||
'expenses.deleted_at',
|
'expenses.deleted_at',
|
||||||
'expenses.exchange_rate',
|
'expenses.exchange_rate',
|
||||||
'expenses.expense_date',
|
'expenses.expense_date',
|
||||||
|
@ -90,11 +90,13 @@ class ExpenseService extends BaseService
|
|||||||
'amount',
|
'amount',
|
||||||
function ($model) {
|
function ($model) {
|
||||||
// show both the amount and the converted amount
|
// show both the amount and the converted amount
|
||||||
$str = Utils::formatMoney($model->amount, $model->account_currency_id, $model->account_country_id);
|
|
||||||
if ($model->exchange_rate != 1) {
|
if ($model->exchange_rate != 1) {
|
||||||
$str .= ' | ' . Utils::formatMoney(round($model->amount * $model->exchange_rate,2), $model->currency_id, $model->client_country_id);
|
$converted = round($model->amount * $model->exchange_rate, 2);
|
||||||
|
return Utils::formatMoney($model->amount, $model->account_currency_id, $model->account_country_id) . ' | ' .
|
||||||
|
Utils::formatMoney($converted, $model->currency_id, $model->client_country_id);
|
||||||
|
} else {
|
||||||
|
return Utils::formatMoney($model->amount, $model->currency_id, $model->account_country_id);
|
||||||
}
|
}
|
||||||
return $str;
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
@ -29883,6 +29883,7 @@ var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Const
|
|||||||
var isEdge = navigator.userAgent.indexOf('Edge/') >= 0;
|
var isEdge = navigator.userAgent.indexOf('Edge/') >= 0;
|
||||||
var isChrome = !!window.chrome && !isOpera && !isEdge; // Chrome 1+
|
var isChrome = !!window.chrome && !isOpera && !isEdge; // Chrome 1+
|
||||||
var isChromium = isChrome && navigator.userAgent.indexOf('Chromium') >= 0;
|
var isChromium = isChrome && navigator.userAgent.indexOf('Chromium') >= 0;
|
||||||
|
var isChrome48 = isChrome && navigator.userAgent.indexOf('Chrome/48') >= 0;
|
||||||
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
|
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
|
||||||
|
|
||||||
var refreshTimer;
|
var refreshTimer;
|
||||||
|
@ -5,6 +5,8 @@ var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Const
|
|||||||
var isEdge = navigator.userAgent.indexOf('Edge/') >= 0;
|
var isEdge = navigator.userAgent.indexOf('Edge/') >= 0;
|
||||||
var isChrome = !!window.chrome && !isOpera && !isEdge; // Chrome 1+
|
var isChrome = !!window.chrome && !isOpera && !isEdge; // Chrome 1+
|
||||||
var isChromium = isChrome && navigator.userAgent.indexOf('Chromium') >= 0;
|
var isChromium = isChrome && navigator.userAgent.indexOf('Chromium') >= 0;
|
||||||
|
// https://code.google.com/p/chromium/issues/detail?id=574648
|
||||||
|
var isChrome48 = isChrome && navigator.userAgent.indexOf('Chrome/48') >= 0;
|
||||||
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
|
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
|
||||||
|
|
||||||
var refreshTimer;
|
var refreshTimer;
|
||||||
|
@ -1131,4 +1131,6 @@ return array(
|
|||||||
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
|
'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)',
|
||||||
|
|
||||||
'iframe_url_help3' => 'Note: if you plan on accepting credit cards we strongly recommend having HTTPS enabled on your site.',
|
'iframe_url_help3' => 'Note: if you plan on accepting credit cards we strongly recommend having HTTPS enabled on your site.',
|
||||||
|
'expense_error_multiple_currencies' => 'The expenses can\'t have different currencies.',
|
||||||
|
'expense_error_mismatch_currencies' => 'The client\'s currency does not match the expense currency.',
|
||||||
);
|
);
|
||||||
|
@ -745,6 +745,8 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if (isset($expenses) && $expenses)
|
@if (isset($expenses) && $expenses)
|
||||||
|
model.expense_currency_id({{ $expenseCurrencyId }});
|
||||||
|
|
||||||
// move the blank invoice line item to the end
|
// move the blank invoice line item to the end
|
||||||
var blank = model.invoice().invoice_items.pop();
|
var blank = model.invoice().invoice_items.pop();
|
||||||
var expenses = {!! $expenses !!};
|
var expenses = {!! $expenses !!};
|
||||||
@ -1109,6 +1111,15 @@
|
|||||||
model.showClientForm();
|
model.showClientForm();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check currency matches for expenses
|
||||||
|
var expenseCurrencyId = model.expense_currency_id();
|
||||||
|
var clientCurrencyId = model.invoice().client().currency_id() || {{ $account->getCurrencyId() }};
|
||||||
|
if (expenseCurrencyId != clientCurrencyId) {
|
||||||
|
alert("{!! trans('texts.expense_error_mismatch_currencies') !!}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
onPartialChange(true);
|
onPartialChange(true);
|
||||||
$('#action').val(value);
|
$('#action').val(value);
|
||||||
$('#submitButton').click();
|
$('#submitButton').click();
|
||||||
|
@ -6,6 +6,7 @@ function ViewModel(data) {
|
|||||||
|
|
||||||
//self.invoice = data ? false : new InvoiceModel();
|
//self.invoice = data ? false : new InvoiceModel();
|
||||||
self.invoice = ko.observable(data ? false : new InvoiceModel());
|
self.invoice = ko.observable(data ? false : new InvoiceModel());
|
||||||
|
self.expense_currency_id = ko.observable();
|
||||||
self.tax_rates = ko.observableArray();
|
self.tax_rates = ko.observableArray();
|
||||||
self.tax_rates.push(new TaxRateModel()); // add blank row
|
self.tax_rates.push(new TaxRateModel()); // add blank row
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
function refreshPDFCB(string) {
|
function refreshPDFCB(string) {
|
||||||
if (!string) return;
|
if (!string) return;
|
||||||
PDFJS.workerSrc = '{{ asset('js/pdf_viewer.worker.js') }}';
|
PDFJS.workerSrc = '{{ asset('js/pdf_viewer.worker.js') }}';
|
||||||
if ({{ Auth::check() && Auth::user()->force_pdfjs ? 'false' : 'true' }} && (isFirefox || isChrome)) {
|
if ({{ Auth::check() && Auth::user()->force_pdfjs ? 'false' : 'true' }} && (isFirefox || (isChrome && !isChrome48))) {
|
||||||
$('#theFrame').attr('src', string).show();
|
$('#theFrame').attr('src', string).show();
|
||||||
} else {
|
} else {
|
||||||
if (isRefreshing) {
|
if (isRefreshing) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user