1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-20 00:11:35 +02:00

Added check to ensure expense currency matches client\invoice currency

This commit is contained in:
Hillel Coren 2016-01-31 15:10:33 +02:00
parent e245b6f639
commit 25f5cdbcdd
11 changed files with 48 additions and 14 deletions

View File

@ -182,22 +182,30 @@ class ExpenseController extends BaseController
switch($action)
{
case 'invoice':
$expenses = Expense::scope($ids)->get();
$clientId = null;
$data = [];
$expenses = Expense::scope($ids)->with('client')->get();
$clientPublicId = null;
$currencyId = null;
$data = [];
// 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)
{
if ($expense->client_id) {
if (!$clientId) {
$clientId = $expense->client_id;
} elseif ($clientId != $expense->client_id) {
if ($expense->client) {
if (!$clientPublicId) {
$clientPublicId = $expense->client->public_id;
} elseif ($clientPublicId != $expense->client->public_id) {
Session::flash('error', trans('texts.expense_error_multiple_clients'));
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) {
Session::flash('error', trans('texts.expense_error_invoiced'));
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}")->with('expenses', $data);
return Redirect::to("invoices/create/{$clientPublicId}")
->with('expenseCurrencyId', $currencyId)
->with('expenses', $data);
break;
default:

View File

@ -320,6 +320,7 @@ class InvoiceController extends BaseController
'invoiceLabels' => Auth::user()->account->getInvoiceLabels(),
'tasks' => Session::get('tasks') ? json_encode(Session::get('tasks')) : null,
'expenses' => Session::get('expenses') ? json_encode(Session::get('expenses')) : null,
'expenseCurrencyId' => Session::get('expenseCurrencyId') ?: null,
];
}

View File

@ -60,6 +60,11 @@ class Expense extends EntityModel
return $this->public_id;
}
public function getCurrencyId()
{
return $this->client ? $this->client->currency_id : $this->currency_id;
}
public function getDisplayName()
{
return $this->getName();

View File

@ -64,9 +64,9 @@ class ExpenseRepository extends BaseRepository
->orWhere('contacts.is_primary', '=', null);
})
->select(
DB::raw('COALESCE(clients.currency_id, expenses.currency_id, accounts.currency_id) currency_id'),
'expenses.account_id',
'expenses.amount',
'expenses.currency_id',
'expenses.deleted_at',
'expenses.exchange_rate',
'expenses.expense_date',

View File

@ -90,11 +90,13 @@ class ExpenseService extends BaseService
'amount',
function ($model) {
// 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) {
$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;
}
],
[

View File

@ -29883,6 +29883,7 @@ var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Const
var isEdge = navigator.userAgent.indexOf('Edge/') >= 0;
var isChrome = !!window.chrome && !isOpera && !isEdge; // Chrome 1+
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 refreshTimer;

View File

@ -5,6 +5,8 @@ var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Const
var isEdge = navigator.userAgent.indexOf('Edge/') >= 0;
var isChrome = !!window.chrome && !isOpera && !isEdge; // Chrome 1+
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 refreshTimer;

View File

@ -1131,4 +1131,6 @@ return array(
'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.',
'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.',
);

View File

@ -745,6 +745,8 @@
@endif
@if (isset($expenses) && $expenses)
model.expense_currency_id({{ $expenseCurrencyId }});
// move the blank invoice line item to the end
var blank = model.invoice().invoice_items.pop();
var expenses = {!! $expenses !!};
@ -1109,6 +1111,15 @@
model.showClientForm();
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);
$('#action').val(value);
$('#submitButton').click();

View File

@ -6,6 +6,7 @@ function ViewModel(data) {
//self.invoice = 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.push(new TaxRateModel()); // add blank row

View File

@ -98,7 +98,7 @@
function refreshPDFCB(string) {
if (!string) return;
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();
} else {
if (isRefreshing) {