mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 20:52:56 +01:00
Add support for uploading documents on older browsers
This commit is contained in:
parent
1ddd2769ac
commit
bff6782026
@ -122,9 +122,19 @@ class DocumentController extends BaseController
|
||||
return $response;
|
||||
}
|
||||
|
||||
$document = Input::all();
|
||||
|
||||
$response = $this->documentRepo->upload($document);
|
||||
return $response;
|
||||
$result = $this->documentRepo->upload(Input::all()['file'], $doc_array);
|
||||
|
||||
if(is_string($result)){
|
||||
return Response::json([
|
||||
'error' => $result,
|
||||
'code' => 400
|
||||
], 400);
|
||||
} else {
|
||||
return Response::json([
|
||||
'error' => false,
|
||||
'document' => $doc_array,
|
||||
'code' => 200
|
||||
], 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -406,6 +406,7 @@ class InvoiceController extends BaseController
|
||||
public function update(SaveInvoiceWithClientRequest $request)
|
||||
{
|
||||
$data = $request->input();
|
||||
$data['documents'] = $request->file('documents');
|
||||
|
||||
if(!$this->checkUpdatePermission($data, $response)){
|
||||
return $response;
|
||||
|
@ -57,10 +57,8 @@ class DocumentRepository extends BaseRepository
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function upload($input)
|
||||
public function upload($uploaded, &$doc_array=null)
|
||||
{
|
||||
$uploaded = $input['file'];
|
||||
|
||||
$extension = strtolower($uploaded->extension());
|
||||
if(empty(Document::$types[$extension]) && !empty(Document::$extraExtensions[$extension])){
|
||||
$documentType = Document::$extraExtensions[$extension];
|
||||
@ -70,10 +68,7 @@ class DocumentRepository extends BaseRepository
|
||||
}
|
||||
|
||||
if(empty(Document::$types[$documentType])){
|
||||
return Response::json([
|
||||
'error' => 'Unsupported extension',
|
||||
'code' => 400
|
||||
], 400);
|
||||
return 'Unsupported extension';
|
||||
}
|
||||
|
||||
$documentTypeData = Document::$types[$documentType];
|
||||
@ -83,10 +78,7 @@ class DocumentRepository extends BaseRepository
|
||||
$size = filesize($filePath);
|
||||
|
||||
if($size/1000 > MAX_DOCUMENT_SIZE){
|
||||
return Response::json([
|
||||
'error' => 'File too large',
|
||||
'code' => 400
|
||||
], 400);
|
||||
return 'File too large';
|
||||
}
|
||||
|
||||
|
||||
@ -183,11 +175,7 @@ class DocumentRepository extends BaseRepository
|
||||
$doc_array['base64'] = 'data:'.$mime.';base64,'.$base64;
|
||||
}
|
||||
|
||||
return Response::json([
|
||||
'error' => false,
|
||||
'document' => $doc_array,
|
||||
'code' => 200
|
||||
], 200);
|
||||
return $document;
|
||||
}
|
||||
|
||||
public function getClientDatatable($contactId, $entityType, $search)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use DB;
|
||||
use Utils;
|
||||
use Session;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceItem;
|
||||
use App\Models\Invitation;
|
||||
@ -14,13 +15,16 @@ use App\Ninja\Repositories\BaseRepository;
|
||||
|
||||
class InvoiceRepository extends BaseRepository
|
||||
{
|
||||
protected $documentRepo;
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\Invoice';
|
||||
}
|
||||
|
||||
public function __construct(PaymentService $paymentService)
|
||||
public function __construct(PaymentService $paymentService, DocumentRepository $documentRepo)
|
||||
{
|
||||
$this->documentRepo = $documentRepo;
|
||||
$this->paymentService = $paymentService;
|
||||
}
|
||||
|
||||
@ -399,7 +403,7 @@ class InvoiceRepository extends BaseRepository
|
||||
$invoice->invoice_items()->forceDelete();
|
||||
}
|
||||
|
||||
$document_ids = !empty($data['documents'])?array_map('intval', $data['documents']):array();;
|
||||
$document_ids = !empty($data['document_ids'])?array_map('intval', $data['document_ids']):array();;
|
||||
foreach ($document_ids as $document_id){
|
||||
$document = Document::scope($document_id)->first();
|
||||
if($document && !$checkSubPermissions || $document->canEdit()){
|
||||
@ -415,6 +419,25 @@ class InvoiceRepository extends BaseRepository
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($data['documents']) && Document::canCreate()){
|
||||
// Fallback upload
|
||||
$doc_errors = array();
|
||||
foreach($data['documents'] as $upload){
|
||||
$result = $this->documentRepo->upload($upload);
|
||||
if(is_string($result)){
|
||||
$doc_errors[] = $result;
|
||||
}
|
||||
else{
|
||||
$result->invoice_id = $invoice->id;
|
||||
$result->save();
|
||||
$document_ids[] = $result->public_id;
|
||||
}
|
||||
}
|
||||
if(!empty($doc_errors)){
|
||||
Session::flash('error', implode('<br>',array_map('htmlentities',$doc_errors)));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($invoice->documents as $document){
|
||||
if(!in_array($document->public_id, $document_ids)){
|
||||
// Removed
|
||||
|
7
public/css/built.css
vendored
7
public/css/built.css
vendored
@ -3213,4 +3213,11 @@ div.panel-body div.panel-body {
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dropzone .fallback-doc{
|
||||
display:none;
|
||||
}
|
||||
.dropzone.dz-browser-not-supported .fallback-doc{
|
||||
display:block;
|
||||
}
|
7
public/css/style.css
vendored
7
public/css/style.css
vendored
@ -1084,4 +1084,11 @@ div.panel-body div.panel-body {
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dropzone .fallback-doc{
|
||||
display:none;
|
||||
}
|
||||
.dropzone.dz-browser-not-supported .fallback-doc{
|
||||
display:block;
|
||||
}
|
@ -40,6 +40,7 @@
|
||||
->method($method)
|
||||
->addClass('warn-on-exit')
|
||||
->autocomplete('off')
|
||||
->attributes(array('enctype'=>'multipart/form-data'))
|
||||
->onsubmit('return onFormSubmit(event)')
|
||||
->rules(array(
|
||||
'client' => 'required',
|
||||
@ -308,11 +309,15 @@
|
||||
<div role="tabpanel" class="tab-pane" id="attached-documents" style="position:relative;z-index:9">
|
||||
<div id="document-upload" class="dropzone">
|
||||
<div class="fallback">
|
||||
<input name="file" type="file" multiple />
|
||||
<input name="documents[]" type="file" multiple />
|
||||
</div>
|
||||
<div data-bind="foreach: documents">
|
||||
<div class="fallback-doc">
|
||||
<a href="#" class="fallback-doc-remove" data-bind="click: $parent.removeDocument"><i class="fa fa-close"></i></a>
|
||||
<span data-bind="text:name"></span>
|
||||
<input type="hidden" name="document_ids[]" data-bind="value: public_id"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-bind="foreach: documents">
|
||||
<input type="hidden" name="documents[]" data-bind="value: public_id">
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@ -935,33 +940,34 @@
|
||||
maxFileSize:{{floatval(MAX_DOCUMENT_SIZE/1000)}},
|
||||
dictDefaultMessage:{!! json_encode(trans('texts.document_upload_message')) !!}
|
||||
});
|
||||
dropzone.on("addedfile",handleDocumentAdded);
|
||||
dropzone.on("removedfile",handleDocumentRemoved);
|
||||
dropzone.on("success",handleDocumentUploaded);
|
||||
|
||||
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.preview_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());
|
||||
if(dropzone instanceof Dropzone){
|
||||
dropzone.on("addedfile",handleDocumentAdded);
|
||||
dropzone.on("removedfile",handleDocumentRemoved);
|
||||
dropzone.on("success",handleDocumentUploaded);
|
||||
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.preview_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);
|
||||
}
|
||||
else if(document.type()=='jpeg' || document.type()=='png' || document.type()=='svg'){
|
||||
dropzone.emit('thumbnail', mockFile, document.url());
|
||||
}
|
||||
dropzone.files.push(mockFile);
|
||||
}
|
||||
@endif
|
||||
});
|
||||
|
@ -280,7 +280,8 @@ function InvoiceModel(data) {
|
||||
return documentModel;
|
||||
}
|
||||
|
||||
self.removeDocument = function(public_id) {
|
||||
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;
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user