diff --git a/app/Http/Controllers/ExpenseController.php b/app/Http/Controllers/ExpenseController.php
index b7f5bdaaccdd..9630fb5ee18c 100644
--- a/app/Http/Controllers/ExpenseController.php
+++ b/app/Http/Controllers/ExpenseController.php
@@ -172,17 +172,12 @@ class ExpenseController extends BaseController
return Redirect::to('expenses');
}
- if ($expense->should_be_invoiced == 0) {
- Session::flash('error', trans('texts.expense_error_should_not_be_invoiced'));
- return Redirect::to('expenses');
- }
-
$account = Auth::user()->account;
$data[] = [
'publicId' => $expense->public_id,
'description' => $expense->public_notes,
'qty' => 1,
- 'cost' => $expense->amount,
+ 'cost' => $expense->present()->converted_amount,
];
}
diff --git a/app/Models/Expense.php b/app/Models/Expense.php
index a4340d9b7674..f1bea2625a98 100644
--- a/app/Models/Expense.php
+++ b/app/Models/Expense.php
@@ -16,6 +16,9 @@ class Expense extends EntityModel
protected $presenter = 'App\Ninja\Presenters\ExpensePresenter';
protected $fillable = [
+ 'client_id',
+ 'vendor_id',
+ 'currency_id',
'amount',
'foreign_amount',
'exchange_rate',
diff --git a/app/Ninja/Presenters/ExpensePresenter.php b/app/Ninja/Presenters/ExpensePresenter.php
index 3c7237d39d64..9cede24d039e 100644
--- a/app/Ninja/Presenters/ExpensePresenter.php
+++ b/app/Ninja/Presenters/ExpensePresenter.php
@@ -15,4 +15,9 @@ class ExpensePresenter extends Presenter {
{
return Utils::fromSqlDate($this->entity->expense_date);
}
+
+ public function converted_amount()
+ {
+ return round($this->entity->amount * $this->entity->exchange_rate, 2);
+ }
}
\ No newline at end of file
diff --git a/app/Ninja/Repositories/ExpenseRepository.php b/app/Ninja/Repositories/ExpenseRepository.php
index b8083cb0f157..a4d971d56186 100644
--- a/app/Ninja/Repositories/ExpenseRepository.php
+++ b/app/Ninja/Repositories/ExpenseRepository.php
@@ -50,7 +50,6 @@ class ExpenseRepository extends BaseRepository
->where('expenses.account_id', '=', $accountid)
->select('expenses.account_id',
'expenses.amount',
- 'expenses.converted_amount',
'expenses.currency_id',
'expenses.deleted_at',
'expenses.exchange_rate',
@@ -94,48 +93,15 @@ class ExpenseRepository extends BaseRepository
// First auto fill
$expense->fill($input);
- // We can have an expense without a vendor
- if (isset($input['vendor_id'])) {
- $expense->vendor_id = $input['vendor_id'];
- }
-
$expense->expense_date = Utils::toSqlDate($input['expense_date']);
- $expense->amount = Utils::parseFloat($input['amount']);
-
- if (isset($input['converted_amount'])) {
- $expense->converted_amount = Utils::parseFloat($input['converted_amount']);
- }
-
$expense->private_notes = trim($input['private_notes']);
$expense->public_notes = trim($input['public_notes']);
-
- if (isset($input['exchange_rate'])) {
- $expense->exchange_rate = Utils::parseFloat($input['exchange_rate']);
- } else {
- $expense->exchange_rate = 100;
- }
-
- if ($expense->exchange_rate == 0) {
- $expense->exchange_rate = 100;
- }
-
- // set the currency
- if (isset($input['currency_id'])) {
- $expense->currency_id = $input['currency_id'];
- }
-
- if ($expense->currency_id == 0) {
- $expense->currency_id = Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY);
- }
-
- // Calculate the amount cur
- $expense->converted_amount = ($expense->amount / 100) * $expense->exchange_rate;
-
$expense->should_be_invoiced = isset($input['should_be_invoiced']) || $expense->client_id ? true : false;
- if (isset($input['client_id'])) {
- $expense->client_id = $input['client_id'];
- }
+ $rate = isset($input['exchange_rate']) ? Utils::parseFloat($input['exchange_rate']) : 1;
+ $expense->exchange_rate = round($rate, 4);
+ $expense->amount = round(Utils::parseFloat($input['amount']), 2);
+
$expense->save();
return $expense;
diff --git a/database/migrations/2016_01_04_175228_create_vendors_table.php b/database/migrations/2016_01_04_175228_create_vendors_table.php
index 7c63933c00dd..8bc26c59efd4 100644
--- a/database/migrations/2016_01_04_175228_create_vendors_table.php
+++ b/database/migrations/2016_01_04_175228_create_vendors_table.php
@@ -75,7 +75,7 @@ class CreateVendorsTable extends Migration
$table->boolean('is_deleted')->default(false);
$table->decimal('amount', 13, 2);
$table->decimal('foreign_amount', 13, 2);
- $table->decimal('exchange_rate', 13, 2);
+ $table->decimal('exchange_rate', 13, 4);
$table->date('expense_date')->nullable();
$table->text('private_notes');
$table->text('public_notes');
diff --git a/public/js/built.js b/public/js/built.js
index 0fc348bfa966..f6b8bc173938 100644
--- a/public/js/built.js
+++ b/public/js/built.js
@@ -30260,19 +30260,6 @@ if (window.ko) {
}
};
- ko.bindingHandlers.fadeVisible = {
- init: function(element, valueAccessor) {
- // Initially set the element to be instantly visible/hidden depending on the value
- var value = valueAccessor();
- $(element).toggle(ko.unwrap(value)); // Use "unwrapObservable" so we can handle values that may or may not be observable
- },
- update: function(element, valueAccessor) {
- // Whenever the value subsequently changes, slowly fade the element in or out
- var value = valueAccessor();
- ko.unwrap(value) ? $(element).fadeIn() : $(element).fadeOut();
- }
- };
-
ko.bindingHandlers.datePicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
@@ -30841,6 +30828,11 @@ function roundToTwo(num, toString) {
return toString ? val.toFixed(2) : (val || 0);
}
+function roundToFour(num, toString) {
+ var val = +(Math.round(num + "e+4") + "e-4");
+ return toString ? val.toFixed(4) : (val || 0);
+}
+
function truncate(str, length) {
return (str && str.length > length) ? (str.substr(0, length-1) + '...') : str;
}
diff --git a/public/js/script.js b/public/js/script.js
index 02dbc4b0c462..f1d32879302d 100644
--- a/public/js/script.js
+++ b/public/js/script.js
@@ -950,6 +950,11 @@ function roundToTwo(num, toString) {
return toString ? val.toFixed(2) : (val || 0);
}
+function roundToFour(num, toString) {
+ var val = +(Math.round(num + "e+4") + "e-4");
+ return toString ? val.toFixed(4) : (val || 0);
+}
+
function truncate(str, length) {
return (str && str.length > length) ? (str.substr(0, length-1) + '...') : str;
}
diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php
index a152021756c4..b2d035a0c4d2 100644
--- a/resources/lang/en/texts.php
+++ b/resources/lang/en/texts.php
@@ -1055,7 +1055,6 @@ return array(
'invoice_expense' => 'Invoice Expense',
'expense_error_multiple_clients' =>'The expenses can\'t belong to different clients',
'expense_error_invoiced' => 'Expense have already been invoiced',
- 'expense_error_should_not_be_invoiced' => 'Expense maked not to be invoiced',
'convert_currency' => 'Convert currency',
// Payment terms
diff --git a/resources/views/expenses/edit.blade.php b/resources/views/expenses/edit.blade.php
index 2ad3559650b8..6eb092af3670 100644
--- a/resources/views/expenses/edit.blade.php
+++ b/resources/views/expenses/edit.blade.php
@@ -27,6 +27,7 @@
{!! Former::text('amount')
->label(trans('texts.amount'))
+ ->data_bind("value: amount, valueUpdate: 'afterkeydown'")
->addGroupClass('amount')
->append($account->present()->currencyCode) !!}
@@ -42,10 +43,12 @@
->data_bind('combobox: client_id')
->addGroupClass('client-select') !!}
- {!! Former::checkbox('should_be_invoiced')
- ->text(trans('texts.should_be_invoiced'))
- ->data_bind('checked: should_be_invoiced() || client_id(), enable: !client_id()')
- ->label(' ') !!}
+ @if (!$expense || ($expense && !$expense->invoice_id))
+ {!! Former::checkbox('should_be_invoiced')
+ ->text(trans('texts.should_be_invoiced'))
+ ->data_bind('checked: should_be_invoiced() || client_id(), enable: !client_id()')
+ ->label(' ') !!}
+ @endif
{!! Former::select('currency_id')->addOption('','')
@@ -60,11 +63,11 @@
{!! Former::text('exchange_rate')
- ->data_bind('enable: enableExchangeRate') !!}
+ ->data_bind("value: exchange_rate, enable: enableExchangeRate, valueUpdate: 'afterkeydown'") !!}
{!! Former::text('converted_amount')
->addGroupClass('converted-amount')
- ->data_bind('enable: enableExchangeRate')
+ ->data_bind("value: convertedAmount, enable: enableExchangeRate")
->append('') !!}
@@ -127,8 +130,15 @@
onClientChange();
});
- window.model = new ViewModel();
- ko.applyBindings(model);
+ @if ($data)
+ // this means we failed so we'll reload the previous state
+ window.model = new ViewModel({!! $data !!});
+ @else
+ // otherwise create blank model
+ window.model = new ViewModel({!! $expense !!});
+
+ ko.applyBindings(model);
+ @endif
@if (!$expense && $clientPublicId)
onClientChange();
@@ -141,15 +151,30 @@
@endif
});
- var ViewModel = function() {
+ var ViewModel = function(data) {
var self = this;
self.client_id = ko.observable({{ $clientPublicId }});
self.vendor_id = ko.observable({{ $vendorPublicId }});
- self.currency_id = ko.observable({{ $expense && $expense->currency_id ? $expense->currency_id : null }});
- self.should_be_invoiced = ko.observable({{ $expense && ($expense->should_be_invoiced || $expense->client_id) ? 'true' : 'false' }});
+ self.currency_id = ko.observable();
+ self.amount = ko.observable();
+ self.exchange_rate = ko.observable(1);
+ self.should_be_invoiced = ko.observable();
self.account_currency_id = ko.observable({{ $account->getCurrencyId() }});
+ if (data) {
+ ko.mapping.fromJS(data, {}, this);
+ }
+
+ self.convertedAmount = ko.computed({
+ read: function () {
+ return roundToTwo(self.amount() * self.exchange_rate()).toFixed(2);
+ },
+ write: function(value) {
+ self.exchange_rate(roundToFour(value / self.amount()));
+ }
+ }, self);
+
self.currencyCode = ko.computed(function() {
var currencyId = self.currency_id() || self.account_currency_id();
var currency = currencyMap[currencyId];
@@ -159,6 +184,7 @@
self.currencyName = ko.computed(function() {
var currencyId = self.currency_id() || self.account_currency_id();
var currency = currencyMap[currencyId];
+ console.log(currencyId);
return currency.name;
});