1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-11 05:32:39 +01:00
invoiceninja/resources/views/expenses/edit.blade.php

571 lines
23 KiB
PHP
Raw Normal View History

2016-01-08 19:01:00 +01:00
@extends('header')
@section('head')
@parent
2016-01-21 20:15:30 +01:00
@include('money_script')
2016-02-01 23:12:42 +01:00
<style type="text/css">
.input-group-addon {
min-width: 40px;
}
</style>
@stop
2016-01-08 19:01:00 +01:00
@section('content')
2016-05-15 22:16:08 +02:00
{!! Former::open($url)
->addClass('warn-on-exit main-form')
->onsubmit('return onFormSubmit(event)')
->method($method) !!}
2016-01-21 23:29:10 +01:00
<div style="display:none">
{!! Former::text('action') !!}
2017-01-29 21:51:12 +01:00
{!! Former::text('data')->data_bind('value: ko.mapping.toJSON(model)') !!}
2016-01-21 23:29:10 +01:00
</div>
2016-01-08 19:01:00 +01:00
@if ($expense)
{!! Former::populate($expense) !!}
{!! Former::populateField('should_be_invoiced', intval($expense->should_be_invoiced)) !!}
2016-08-21 17:25:35 +02:00
<div style="display:none">
{!! Former::text('public_id') !!}
{!! Former::text('invoice_id') !!}
</div>
2016-01-08 19:01:00 +01:00
@endif
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-md-6">
2016-07-05 20:49:47 +02:00
2016-01-21 20:15:30 +01:00
{!! Former::select('vendor_id')->addOption('', '')
->label(trans('texts.vendor'))
->addGroupClass('vendor-select') !!}
2016-01-21 20:15:30 +01:00
2016-07-07 10:03:43 +02:00
{!! Former::select('expense_category_id')->addOption('', '')
->label(trans('texts.category'))
->addGroupClass('expense-category-select') !!}
2016-07-05 20:49:47 +02:00
{!! Former::text('expense_date')
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))
2016-01-21 20:15:30 +01:00
->addGroupClass('expense_date')
->label(trans('texts.date'))
->append('<i class="glyphicon glyphicon-calendar"></i>') !!}
2016-01-21 20:15:30 +01:00
2016-02-01 23:07:09 +01:00
{!! Former::select('expense_currency_id')->addOption('','')
->data_bind('combobox: expense_currency_id')
->label(trans('texts.currency_id'))
->data_placeholder(Utils::getFromCache($account->getCurrencyId(), 'currencies')->name)
->fromQuery($currencies, 'name', 'id') !!}
{!! Former::text('amount')
->label(trans('texts.amount'))
->data_bind("value: amount, valueUpdate: 'afterkeydown'")
->addGroupClass('amount')
->append('<span data-bind="html: expenseCurrencyCode"></span>') !!}
@if ($expense && $expense->invoice_id)
{!! Former::plaintext()
->label('client')
->value($expense->client->getDisplayName()) !!}
@else
{!! Former::select('client_id')
->addOption('', '')
->label(trans('texts.client'))
->data_bind('combobox: client_id')
->addGroupClass('client-select') !!}
@endif
2016-01-21 20:15:30 +01:00
@if (!$expense || ($expense && !$expense->invoice_id && !$expense->client_id))
2016-01-21 21:36:49 +01:00
{!! Former::checkbox('should_be_invoiced')
->text(trans('texts.should_be_invoiced'))
->data_bind('checked: should_be_invoiced() || client_id(), enable: !client_id()')
->label(' ')
->value(1) !!}
2016-01-21 21:36:49 +01:00
@endif
2016-01-21 20:15:30 +01:00
@if (!$expense || ($expense && ! $expense->isExchanged()))
{!! Former::checkbox('convert_currency')
->text(trans('texts.convert_currency'))
->data_bind('checked: convert_currency')
->label(' ')
->value(1) !!}
@endif
2016-07-07 18:54:06 +02:00
<div style="display:none" data-bind="visible: enableExchangeRate">
2016-07-07 18:54:06 +02:00
<br/>
<span style="display:none" data-bind="visible: !client_id()">
{!! Former::select('invoice_currency_id')->addOption('','')
->label(trans('texts.invoice_currency'))
->data_placeholder(Utils::getFromCache($account->getCurrencyId(), 'currencies')->name)
->data_bind('combobox: invoice_currency_id, disable: true')
->fromQuery($currencies, 'name', 'id') !!}
</span>
<span style="display:none;" data-bind="visible: client_id">
{!! Former::plaintext('test')
->value('<span data-bind="html: invoiceCurrencyName"></span>')
->style('min-height:46px')
->label(trans('texts.invoice_currency')) !!}
</span>
{!! Former::text('exchange_rate')
->data_bind("value: exchange_rate, enable: enableExchangeRate, valueUpdate: 'afterkeydown'") !!}
{!! Former::text('invoice_amount')
->addGroupClass('converted-amount')
->data_bind("value: convertedAmount, enable: enableExchangeRate")
->append('<span data-bind="html: invoiceCurrencyCode"></span>') !!}
</div>
2016-07-07 18:54:06 +02:00
@if (!$expense || ($expense && (!$expense->tax_name1 && !$expense->tax_name2)))
{!! Former::checkbox('apply_taxes')
->text(trans('texts.apply_taxes'))
->data_bind('checked: apply_taxes')
->label(' ')
->value(1) !!}
2016-07-07 18:54:06 +02:00
@endif
<div style="display:none" data-bind="visible: apply_taxes">
<br/>
{!! Former::select('tax_select1')
->addOption('','')
->label(trans('texts.tax_rate'))
->onchange('taxSelectChange(event)')
->fromQuery($taxRates) !!}
<div style="display:none">
{!! Former::input('tax_rate1') !!}
{!! Former::input('tax_name1') !!}
</div>
<div style="display:{{ $account->enable_second_tax_rate ? 'block' : 'none' }}">
{!! Former::select('tax_select2')
->addOption('','')
->label(trans('texts.tax_rate'))
->onchange('taxSelectChange(event)')
->fromQuery($taxRates) !!}
<div style="display:none">
{!! Former::input('tax_rate2') !!}
{!! Former::input('tax_name2') !!}
</div>
</div>
</div>
2016-01-08 19:01:00 +01:00
</div>
<div class="col-md-6">
{!! Former::textarea('public_notes')->rows(6) !!}
{!! Former::textarea('private_notes')->rows(6) !!}
@if ($account->hasFeature(FEATURE_DOCUMENTS))
<div class="form-group">
<label for="public_notes" class="control-label col-lg-4 col-sm-4">
{{trans('texts.documents')}}
</label>
<div class="col-lg-8 col-sm-8">
<div role="tabpanel" class="tab-pane" id="attached-documents" style="position:relative;z-index:9">
<div id="document-upload" class="dropzone">
<div data-bind="foreach: documents">
<input type="hidden" name="document_ids[]" data-bind="value: public_id"/>
</div>
</div>
</div>
</div>
</div>
@endif
</div>
</div>
2016-01-08 19:01:00 +01:00
</div>
</div>
2016-10-10 10:40:04 +02:00
<center class="buttons">
{!! Button::normal(trans('texts.cancel'))
->asLinkTo(URL::to('/expenses'))
->appendIcon(Icon::create('remove-circle'))
->large() !!}
2016-10-10 10:40:04 +02:00
@if (Auth::user()->canCreateOrEdit(ENTITY_EXPENSE, $expense))
@if (Auth::user()->hasFeature(FEATURE_EXPENSES))
2016-10-10 10:40:04 +02:00
@if (!$expense || !$expense->is_deleted)
{!! Button::success(trans('texts.save'))
->appendIcon(Icon::create('floppy-disk'))
->large()
->submit() !!}
@endif
2016-10-10 10:40:04 +02:00
@if ($expense && !$expense->trashed())
{!! DropdownButton::normal(trans('texts.more_actions'))
->withContents($actions)
->large()
->dropup() !!}
@endif
2016-10-10 10:40:04 +02:00
@if ($expense && $expense->trashed())
{!! Button::primary(trans('texts.restore'))
->withAttributes(['onclick' => 'submitAction("restore")'])
->appendIcon(Icon::create('cloud-download'))
->large() !!}
@endif
2016-07-11 19:08:43 +02:00
@endif
2016-10-10 10:40:04 +02:00
@endif
</center>
2016-01-08 19:01:00 +01:00
{!! Former::close() !!}
2016-01-21 20:15:30 +01:00
<script type="text/javascript">
Dropzone.autoDiscover = false;
2016-01-09 06:24:43 +01:00
2016-01-21 20:15:30 +01:00
var vendors = {!! $vendors !!};
var clients = {!! $clients !!};
2016-07-07 10:03:43 +02:00
var categories = {!! $categories !!};
2016-07-07 18:54:06 +02:00
var taxRates = {!! $taxRates !!};
2016-01-09 06:24:43 +01:00
2016-01-21 20:15:30 +01:00
var clientMap = {};
var vendorMap = {};
var categoryMap = {};
2016-01-09 06:24:43 +01:00
for (var i=0; i<clients.length; i++) {
var client = clients[i];
2016-01-21 20:15:30 +01:00
clientMap[client.public_id] = client;
}
2016-01-09 06:24:43 +01:00
function onFormSubmit(event) {
if (window.countUploadingDocuments > 0) {
2016-07-28 18:55:23 +02:00
swal("{!! trans('texts.wait_for_upload') !!}");
return false;
}
@if (Auth::user()->canCreateOrEdit(ENTITY_EXPENSE, $expense))
return true;
@else
return false
@endif
}
2016-01-21 20:15:30 +01:00
function onClientChange() {
var clientId = $('select#client_id').val();
var client = clientMap[clientId];
if (client) {
2016-02-01 23:07:09 +01:00
model.invoice_currency_id(client.currency_id);
2016-01-21 20:15:30 +01:00
}
2016-01-09 06:24:43 +01:00
}
2016-08-21 17:25:35 +02:00
function submitAction(action, invoice_id) {
2016-01-21 23:29:10 +01:00
$('#action').val(action);
2016-08-21 17:25:35 +02:00
$('#invoice_id').val(invoice_id);
2016-01-21 23:29:10 +01:00
$('.main-form').submit();
}
function onDeleteClick() {
2016-07-28 18:55:23 +02:00
sweetConfirm(function() {
2016-01-21 23:29:10 +01:00
submitAction('delete');
2016-07-28 18:55:23 +02:00
});
2016-01-21 23:29:10 +01:00
}
2016-01-21 20:15:30 +01:00
$(function() {
var vendorId = {{ $vendorPublicId ?: 0 }};
2016-01-21 20:15:30 +01:00
var $vendorSelect = $('select#vendor_id');
@if (Auth::user()->can('create', ENTITY_VENDOR))
$vendorSelect.append(new Option("{{ trans('texts.create_vendor')}}: $name", '-1'));
@endif
2016-01-21 20:15:30 +01:00
for (var i = 0; i < vendors.length; i++) {
var vendor = vendors[i];
vendorMap[vendor.public_id] = vendor;
2016-01-21 20:15:30 +01:00
$vendorSelect.append(new Option(getClientDisplayName(vendor), vendor.public_id));
}
@include('partials/entity_combobox', ['entityType' => ENTITY_VENDOR])
if (vendorId) {
var vendor = vendorMap[vendorId];
setComboboxValue($('.vendor-select'), vendor.public_id, vendor.name);
}
2016-01-21 20:15:30 +01:00
var categoryId = {{ $categoryPublicId ?: 0 }};
var $expense_categorySelect = $('select#expense_category_id');
@if (Auth::user()->can('create', ENTITY_EXPENSE_CATEGORY))
$expense_categorySelect.append(new Option("{{ trans('texts.create_expense_category')}}: $name", '-1'));
@endif
2016-07-07 10:03:43 +02:00
for (var i = 0; i < categories.length; i++) {
var category = categories[i];
categoryMap[category.public_id] = category;
$expense_categorySelect.append(new Option(category.name, category.public_id));
}
@include('partials/entity_combobox', ['entityType' => ENTITY_EXPENSE_CATEGORY])
if (categoryId) {
var category = categoryMap[categoryId];
setComboboxValue($('.expense-category-select'), category.public_id, category.name);
2016-07-07 10:03:43 +02:00
}
2016-02-18 11:02:30 +01:00
$('#expense_date').datepicker('update', '{{ $expense ? $expense->expense_date : 'new Date()' }}');
2016-01-21 20:15:30 +01:00
$('.expense_date .input-group-addon').click(function() {
toggleDatePicker('expense_date');
});
var $clientSelect = $('select#client_id');
for (var i=0; i<clients.length; i++) {
var client = clients[i];
2016-07-13 11:03:39 +02:00
var clientName = getClientDisplayName(client);
if (!clientName) {
continue;
}
$clientSelect.append(new Option(clientName, client.public_id));
2016-01-21 20:15:30 +01:00
}
$clientSelect.combobox().change(function() {
onClientChange();
});
2016-07-07 18:54:06 +02:00
setTaxSelect(1);
setTaxSelect(2);
2016-01-21 21:36:49 +01:00
@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 !!});
@endif
2017-01-29 21:51:12 +01:00
ko.applyBindings(model);
2016-01-21 20:15:30 +01:00
@if (!$expense && $clientPublicId)
onClientChange();
@endif
@if (!$vendorPublicId)
$('.vendor-select input.form-control').focus();
@else
$('#amount').focus();
@endif
2016-05-15 22:16:08 +02:00
@if (Auth::user()->account->hasFeature(FEATURE_DOCUMENTS))
$('.main-form').submit(function(){
if($('#document-upload .fallback input').val())$(this).attr('enctype', 'multipart/form-data')
else $(this).removeAttr('enctype')
})
2016-05-15 22:16:08 +02:00
// Initialize document upload
dropzone = new Dropzone('#document-upload', {
url:{!! json_encode(url('documents')) !!},
params:{
_token:"{{ Session::getToken() }}"
},
acceptedFiles:{!! json_encode(implode(',',\App\Models\Document::$allowedMimes)) !!},
addRemoveLinks:true,
2016-05-26 18:02:53 +02:00
dictRemoveFileConfirmation:"{{trans('texts.are_you_sure')}}",
2016-05-15 22:16:08 +02:00
@foreach(['default_message', 'fallback_message', 'fallback_text', 'file_too_big', 'invalid_file_type', 'response_error', 'cancel_upload', 'cancel_upload_confirmation', 'remove_file'] as $key)
"dict{{strval($key)}}":"{{trans('texts.dropzone_'.Utils::toClassCase($key))}}",
2016-03-24 23:45:00 +01:00
@endforeach
2016-05-29 17:39:42 +02:00
maxFilesize:{{floatval(MAX_DOCUMENT_SIZE/1000)}},
});
if(dropzone instanceof Dropzone){
dropzone.on("addedfile",handleDocumentAdded);
dropzone.on("removedfile",handleDocumentRemoved);
dropzone.on("success",handleDocumentUploaded);
dropzone.on("canceled",handleDocumentCanceled);
2016-05-29 17:42:36 +02:00
dropzone.on("error",handleDocumentError);
for (var i=0; i<model.documents().length; i++) {
var document = model.documents()[i];
var mockFile = {
name:document.name(),
size:document.size(),
type:document.type(),
public_id:document.public_id(),
status:Dropzone.SUCCESS,
accepted:true,
2016-05-25 14:18:12 +02:00
url:document.url(),
mock:true,
index:i
};
dropzone.emit('addedfile', mockFile);
dropzone.emit('complete', mockFile);
if(document.preview_url()){
dropzone.emit('thumbnail', mockFile, document.preview_url()||document.url());
}
else if(document.type()=='jpeg' || document.type()=='png' || document.type()=='svg'){
dropzone.emit('thumbnail', mockFile, document.url());
}
dropzone.files.push(mockFile);
}
}
@endif
2016-01-21 20:15:30 +01:00
});
2016-01-21 21:36:49 +01:00
var ViewModel = function(data) {
2016-01-21 20:15:30 +01:00
var self = this;
2016-02-01 23:07:09 +01:00
self.expense_currency_id = ko.observable();
self.invoice_currency_id = ko.observable();
2016-03-25 00:55:56 +01:00
self.documents = ko.observableArray();
2016-01-21 21:36:49 +01:00
self.amount = ko.observable();
self.exchange_rate = ko.observable(1);
self.should_be_invoiced = ko.observable();
2016-07-27 12:54:00 +02:00
self.convert_currency = ko.observable({{ ($expense && $expense->isExchanged()) ? 'true' : 'false' }});
2016-07-07 18:54:06 +02:00
self.apply_taxes = ko.observable({{ ($expense && ($expense->tax_name1 || $expense->tax_name2)) ? 'true' : 'false' }});
2016-01-21 20:15:30 +01:00
2017-01-29 21:51:12 +01:00
self.account_currency_id = ko.observable({{ $account->getCurrencyId() }});
self.client_id = ko.observable({{ $clientPublicId }});
//self.vendor_id = ko.observable({{ $vendorPublicId }});
//self.expense_category_id = ko.observable({{ $categoryPublicId }});
2017-01-29 21:51:12 +01:00
self.mapping = {
'documents': {
create: function(options) {
return new DocumentModel(options.data);
}
}
}
2016-05-15 22:16:08 +02:00
2016-01-21 21:36:49 +01:00
if (data) {
ko.mapping.fromJS(data, self.mapping, this);
2016-01-21 21:36:49 +01:00
}
self.convertedAmount = ko.computed({
read: function () {
return roundToTwo(self.amount() * self.exchange_rate()).toFixed(2);
},
write: function(value) {
self.amount(roundToTwo(value / self.exchange_rate()));
2016-01-21 21:36:49 +01:00
}
}, self);
2016-02-01 23:07:09 +01:00
self.getCurrency = function(currencyId) {
return currencyMap[currencyId || self.account_currency_id()];
};
self.expenseCurrencyCode = ko.computed(function() {
return self.getCurrency(self.expense_currency_id()).code;
});
self.invoiceCurrencyCode = ko.computed(function() {
return self.getCurrency(self.invoice_currency_id()).code;
2016-01-21 20:15:30 +01:00
});
2016-02-01 23:07:09 +01:00
self.invoiceCurrencyName = ko.computed(function() {
return self.getCurrency(self.invoice_currency_id()).name;
2016-01-21 20:15:30 +01:00
});
self.enableExchangeRate = ko.computed(function() {
if (self.convert_currency()) {
return true;
}
2016-02-01 23:07:09 +01:00
var expenseCurrencyId = self.expense_currency_id() || self.account_currency_id();
var invoiceCurrencyId = self.invoice_currency_id() || self.account_currency_id();
2016-05-15 22:16:08 +02:00
return expenseCurrencyId != invoiceCurrencyId
|| invoiceCurrencyId != self.account_currency_id()
|| expenseCurrencyId != self.account_currency_id();
2016-01-21 20:15:30 +01:00
})
2016-05-15 22:16:08 +02:00
self.addDocument = function() {
var documentModel = new DocumentModel();
self.documents.push(documentModel);
return documentModel;
}
self.removeDocument = function(doc) {
var public_id = doc.public_id?doc.public_id():doc;
self.documents.remove(function(document) {
return document.public_id() == public_id;
});
}
2016-01-21 20:15:30 +01:00
};
function DocumentModel(data) {
var self = this;
self.public_id = ko.observable(0);
self.size = ko.observable(0);
self.name = ko.observable('');
self.type = ko.observable('');
self.url = ko.observable('');
self.update = function(data){
ko.mapping.fromJS(data, {}, this);
}
2016-01-21 20:15:30 +01:00
if (data) {
self.update(data);
2016-05-15 22:16:08 +02:00
}
}
2016-05-15 22:16:08 +02:00
window.countUploadingDocuments = 0;
function handleDocumentAdded(file){
2016-05-22 21:14:47 +02:00
// open document when clicked
if (file.url) {
file.previewElement.addEventListener("click", function() {
window.open(file.url, '_blank');
});
}
if(file.mock)return;
file.index = model.documents().length;
model.addDocument({name:file.name, size:file.size, type:file.type});
window.countUploadingDocuments++;
}
function handleDocumentRemoved(file){
model.removeDocument(file.public_id);
2016-05-26 18:02:53 +02:00
$.ajax({
url: '{{ '/documents/' }}' + file.public_id,
type: 'DELETE',
success: function(result) {
// Do something with the result
}
});
}
function handleDocumentUploaded(file, response){
window.countUploadingDocuments--;
file.public_id = response.document.public_id
model.documents()[file.index].update(response.document);
if(response.document.preview_url){
dropzone.emit('thumbnail', file, response.document.preview_url);
}
}
2016-05-29 17:42:36 +02:00
function handleDocumentCanceled() {
window.countUploadingDocuments--;
}
function handleDocumentError() {
window.countUploadingDocuments--;
}
2016-06-05 17:50:41 +02:00
2016-07-07 18:54:06 +02:00
function taxSelectChange(event) {
var $select = $(event.target);
var tax = $select.find('option:selected').text();
var index = tax.lastIndexOf(': ');
var taxName = tax.substring(0, index);
var taxRate = tax.substring(index + 2, tax.length - 1);
var selectName = $select.attr('name');
var instance = selectName.substring(selectName.length - 1);
$('#tax_name' + instance).val(taxName);
$('#tax_rate' + instance).val(taxRate);
}
function setTaxSelect(instance) {
var $select = $('#tax_select' + instance);
var taxName = $('#tax_name' + instance).val();
var taxRate = $('#tax_rate' + instance).val();
if (!taxRate || !taxName) {
return;
}
var tax = _.findWhere(taxRates, {name:taxName, rate:taxRate});
if (tax) {
$select.val(tax.public_id);
} else {
var option = new Option(taxName + ': ' + taxRate + '%', '');
option.selected = true;
$select.append(option);
}
}
2016-01-21 20:15:30 +01:00
</script>
2016-01-08 19:01:00 +01:00
2016-05-15 22:16:08 +02:00
@stop