mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 17:14:28 -04:00
Working on expenses
This commit is contained in:
parent
b24a6109ba
commit
7a26dd610c
@ -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,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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');
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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(' ') !!}<br/>
|
||||
@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(' ') !!}<br/>
|
||||
@endif
|
||||
|
||||
<span style="display:none" data-bind="visible: !client_id()">
|
||||
{!! Former::select('currency_id')->addOption('','')
|
||||
@ -60,11 +63,11 @@
|
||||
</span>
|
||||
|
||||
{!! 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('<span data-bind="html: currencyCode"></span>') !!}
|
||||
|
||||
</div>
|
||||
@ -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;
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user