mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Working on default documents
This commit is contained in:
parent
df46330d5f
commit
25699f43c7
@ -332,6 +332,14 @@ class Account extends Eloquent
|
|||||||
return $this->hasMany('App\Models\Product');
|
return $this->hasMany('App\Models\Product');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function defaultDocuments()
|
||||||
|
{
|
||||||
|
return $this->hasMany('App\Models\Document')->whereIsDefault(true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
|
@ -24,6 +24,7 @@ class Document extends EntityModel
|
|||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'invoice_id',
|
'invoice_id',
|
||||||
'expense_id',
|
'expense_id',
|
||||||
|
'is_default',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +20,10 @@ class AddLateFees extends Migration
|
|||||||
$table->decimal('late_fee3_amount', 13, 2)->nullable();
|
$table->decimal('late_fee3_amount', 13, 2)->nullable();
|
||||||
$table->decimal('late_fee3_percent', 13, 3)->nullable();
|
$table->decimal('late_fee3_percent', 13, 3)->nullable();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::table('documents', function ($table) {
|
||||||
|
$table->boolean('is_default')->default(false)->nullable();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,5 +41,9 @@ class AddLateFees extends Migration
|
|||||||
$table->dropColumn('late_fee3_amount');
|
$table->dropColumn('late_fee3_amount');
|
||||||
$table->dropColumn('late_fee3_percent');
|
$table->dropColumn('late_fee3_percent');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::table('documents', function ($table) {
|
||||||
|
$table->dropColumn('is_default');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1043,7 +1043,7 @@ $LANG = array(
|
|||||||
'invoice_item_fields' => 'Invoice Item Fields',
|
'invoice_item_fields' => 'Invoice Item Fields',
|
||||||
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
|
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
|
||||||
'recurring_invoice_number' => 'Recurring Number',
|
'recurring_invoice_number' => 'Recurring Number',
|
||||||
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
|
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices.',
|
||||||
|
|
||||||
// Client Passwords
|
// Client Passwords
|
||||||
'enable_portal_password' => 'Password Protect Invoices',
|
'enable_portal_password' => 'Password Protect Invoices',
|
||||||
@ -2316,6 +2316,7 @@ $LANG = array(
|
|||||||
'downloaded_invoices' => 'An email will be sent with the invoice PDFs',
|
'downloaded_invoices' => 'An email will be sent with the invoice PDFs',
|
||||||
'downloaded_quotes' => 'An email will be sent with the quote PDFs',
|
'downloaded_quotes' => 'An email will be sent with the quote PDFs',
|
||||||
'clone_expense' => 'Clone Expense',
|
'clone_expense' => 'Clone Expense',
|
||||||
|
'default_documents' => 'Default Documents',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@
|
|||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">{!! trans('texts.default_messages') !!}</h3>
|
<h3 class="panel-title">{!! trans('texts.defaults') !!}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body form-padding-right">
|
<div class="panel-body form-padding-right">
|
||||||
|
|
||||||
@ -337,6 +337,9 @@
|
|||||||
<li role="presentation" class="active"><a href="#invoice_terms" aria-controls="invoice_terms" role="tab" data-toggle="tab">{{ trans('texts.invoice_terms') }}</a></li>
|
<li role="presentation" class="active"><a href="#invoice_terms" aria-controls="invoice_terms" role="tab" data-toggle="tab">{{ trans('texts.invoice_terms') }}</a></li>
|
||||||
<li role="presentation"><a href="#invoice_footer" aria-controls="invoice_footer" role="tab" data-toggle="tab">{{ trans('texts.invoice_footer') }}</a></li>
|
<li role="presentation"><a href="#invoice_footer" aria-controls="invoice_footer" role="tab" data-toggle="tab">{{ trans('texts.invoice_footer') }}</a></li>
|
||||||
<li role="presentation"><a href="#quote_terms" aria-controls="quote_terms" role="tab" data-toggle="tab">{{ trans('texts.quote_terms') }}</a></li>
|
<li role="presentation"><a href="#quote_terms" aria-controls="quote_terms" role="tab" data-toggle="tab">{{ trans('texts.quote_terms') }}</a></li>
|
||||||
|
@if ($account->hasFeature(FEATURE_DOCUMENTS))
|
||||||
|
<li role="presentation"><a href="#documents" aria-controls="documents" role="tab" data-toggle="tab">{{ trans('texts.documents') }}</a></li>
|
||||||
|
@endif
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
@ -362,6 +365,30 @@
|
|||||||
->rows(4) !!}
|
->rows(4) !!}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@if ($account->hasFeature(FEATURE_DOCUMENTS))
|
||||||
|
<div role="tabpanel" class="tab-pane" id="documents">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="public_notes" class="control-label col-lg-4 col-sm-4">
|
||||||
|
{{trans('texts.default_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">
|
||||||
|
<div class="dropzone">
|
||||||
|
<!--
|
||||||
|
<div data-bind="foreach: documents">
|
||||||
|
<input type="hidden" name="document_ids[]" data-bind="value: public_id"/>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -484,6 +511,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var defaultDocuments = {!! $account->defaultDocuments()->get() !!};
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
setQuoteNumberEnabled();
|
setQuoteNumberEnabled();
|
||||||
onNumberTypeChange('invoice');
|
onNumberTypeChange('invoice');
|
||||||
@ -499,6 +528,9 @@
|
|||||||
toggleDatePicker('reset_counter_date');
|
toggleDatePicker('reset_counter_date');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@if ($account->hasFeature(FEATURE_DOCUMENTS))
|
||||||
|
@include('partials.dropzone', ['documentSource' => 'defaultDocuments', 'isDefault' => true])
|
||||||
|
@endif
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -203,7 +203,8 @@
|
|||||||
</label>
|
</label>
|
||||||
<div class="col-lg-8 col-sm-8">
|
<div class="col-lg-8 col-sm-8">
|
||||||
<div role="tabpanel" class="tab-pane" id="attached-documents" style="position:relative;z-index:9">
|
<div role="tabpanel" class="tab-pane" id="attached-documents" style="position:relative;z-index:9">
|
||||||
<div id="document-upload" class="dropzone">
|
<div id="document-upload">
|
||||||
|
<div class="dropzone">
|
||||||
<div data-bind="foreach: documents">
|
<div data-bind="foreach: documents">
|
||||||
<input type="hidden" name="document_ids[]" data-bind="value: public_id"/>
|
<input type="hidden" name="document_ids[]" data-bind="value: public_id"/>
|
||||||
</div>
|
</div>
|
||||||
@ -211,6 +212,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -254,8 +256,6 @@
|
|||||||
{!! Former::close() !!}
|
{!! Former::close() !!}
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
Dropzone.autoDiscover = false;
|
|
||||||
|
|
||||||
var vendors = {!! $vendors !!};
|
var vendors = {!! $vendors !!};
|
||||||
var clients = {!! $clients !!};
|
var clients = {!! $clients !!};
|
||||||
var categories = {!! $categories !!};
|
var categories = {!! $categories !!};
|
||||||
@ -417,51 +417,8 @@
|
|||||||
toggleDatePicker('payment_date');
|
toggleDatePicker('payment_date');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initialize document upload
|
@include('partials.dropzone', ['documentSource' => 'model.documents()'])
|
||||||
dropzone = new Dropzone('#document-upload', {
|
|
||||||
url:{!! json_encode(url('documents')) !!},
|
|
||||||
params:{
|
|
||||||
_token:"{{ Session::getToken() }}"
|
|
||||||
},
|
|
||||||
acceptedFiles:{!! json_encode(implode(',',\App\Models\Document::$allowedMimes)) !!},
|
|
||||||
addRemoveLinks:true,
|
|
||||||
dictRemoveFileConfirmation:"{{trans('texts.are_you_sure')}}",
|
|
||||||
@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{{ Utils::toClassCase($key) }}" : "{!! strip_tags(addslashes(trans('texts.dropzone_'.$key))) !!}",
|
|
||||||
@endforeach
|
|
||||||
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);
|
|
||||||
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,
|
|
||||||
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
|
@endif
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -575,51 +532,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.countUploadingDocuments = 0;
|
function addDocument(file) {
|
||||||
|
|
||||||
function handleDocumentAdded(file){
|
|
||||||
// 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;
|
file.index = model.documents().length;
|
||||||
model.addDocument({name:file.name, size:file.size, type:file.type});
|
model.addDocument({name:file.name, size:file.size, type:file.type});
|
||||||
window.countUploadingDocuments++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDocumentRemoved(file){
|
function addedDocument(file, response) {
|
||||||
model.removeDocument(file.public_id);
|
|
||||||
$.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);
|
model.documents()[file.index].update(response.document);
|
||||||
if(response.document.preview_url){
|
|
||||||
dropzone.emit('thumbnail', file, response.document.preview_url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDocumentCanceled() {
|
function deleteDocument(file) {
|
||||||
window.countUploadingDocuments--;
|
model.removeDocument(file.public_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDocumentError() {
|
function onInvoiceDocumentsChange() {
|
||||||
window.countUploadingDocuments--;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onInvoiceDocumentsChange()
|
|
||||||
{
|
|
||||||
if (isStorageSupported()) {
|
if (isStorageSupported()) {
|
||||||
var checked = $('#invoice_documents').is(':checked');
|
var checked = $('#invoice_documents').is(':checked');
|
||||||
localStorage.setItem('last:invoice_documents', checked || '');
|
localStorage.setItem('last:invoice_documents', checked || '');
|
||||||
|
@ -1041,51 +1041,8 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.dropzone = new Dropzone('#document-upload .dropzone', {
|
@include('partials.dropzone', ['documentSource' => 'model.invoice().documents()'])
|
||||||
url:{!! json_encode(url('documents')) !!},
|
|
||||||
params:{
|
|
||||||
_token:"{{ Session::getToken() }}"
|
|
||||||
},
|
|
||||||
acceptedFiles:{!! json_encode(implode(',',\App\Models\Document::$allowedMimes)) !!},
|
|
||||||
addRemoveLinks:true,
|
|
||||||
dictRemoveFileConfirmation:"{{trans('texts.are_you_sure')}}",
|
|
||||||
@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{{ Utils::toClassCase($key) }}" : "{!! strip_tags(addslashes(trans('texts.dropzone_'.$key))) !!}",
|
|
||||||
@endforeach
|
|
||||||
maxFilesize:{{floatval(MAX_DOCUMENT_SIZE/1000)}},
|
|
||||||
parallelUploads:1,
|
|
||||||
});
|
|
||||||
if(dropzone instanceof Dropzone){
|
|
||||||
dropzone.on("addedfile",handleDocumentAdded);
|
|
||||||
dropzone.on("removedfile",handleDocumentRemoved);
|
|
||||||
dropzone.on("success",handleDocumentUploaded);
|
|
||||||
dropzone.on("canceled",handleDocumentCanceled);
|
|
||||||
dropzone.on("error",handleDocumentError);
|
|
||||||
for (var i=0; i<model.invoice().documents().length; i++) {
|
|
||||||
var document = model.invoice().documents()[i];
|
|
||||||
var mockFile = {
|
|
||||||
name:document.name(),
|
|
||||||
size:document.size(),
|
|
||||||
type:document.type(),
|
|
||||||
public_id:document.public_id(),
|
|
||||||
status:Dropzone.SUCCESS,
|
|
||||||
accepted:true,
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
else if(document.type()=='jpeg' || document.type()=='png' || document.type()=='svg'){
|
|
||||||
dropzone.emit('thumbnail', mockFile, document.url());
|
|
||||||
}
|
|
||||||
dropzone.files.push(mockFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
@endif
|
@endif
|
||||||
});
|
});
|
||||||
@ -1637,53 +1594,21 @@
|
|||||||
model.invoice().invoice_number(number);
|
model.invoice().invoice_number(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.countUploadingDocuments = 0;
|
function addDocument(file) {
|
||||||
|
|
||||||
function handleDocumentAdded(file){
|
|
||||||
// open document when clicked
|
|
||||||
if (file.url) {
|
|
||||||
file.previewElement.addEventListener("click", function() {
|
|
||||||
window.open(file.url, '_blank');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if(file.mock)return;
|
|
||||||
file.index = model.invoice().documents().length;
|
file.index = model.invoice().documents().length;
|
||||||
model.invoice().addDocument({name:file.name, size:file.size, type:file.type});
|
model.invoice().addDocument({name:file.name, size:file.size, type:file.type});
|
||||||
window.countUploadingDocuments++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDocumentRemoved(file){
|
function addedDocument(file, response) {
|
||||||
model.invoice().removeDocument(file.public_id);
|
|
||||||
refreshPDF(true);
|
|
||||||
$.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.invoice().documents()[file.index].update(response.document);
|
model.invoice().documents()[file.index].update(response.document);
|
||||||
@if ($account->invoice_embed_documents)
|
@if ($account->invoice_embed_documents)
|
||||||
refreshPDF(true);
|
refreshPDF(true);
|
||||||
@endif
|
@endif
|
||||||
if(response.document.preview_url){
|
|
||||||
dropzone.emit('thumbnail', file, response.document.preview_url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDocumentCanceled() {
|
function deleteDocument(file) {
|
||||||
window.countUploadingDocuments--;
|
model.invoice().removeDocument(file.public_id);
|
||||||
}
|
refreshPDF(true);
|
||||||
|
|
||||||
function handleDocumentError(file) {
|
|
||||||
dropzone.removeFile(file);
|
|
||||||
window.countUploadingDocuments--;
|
|
||||||
swal("{!! trans('texts.error_refresh_page') !!}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user