1
0
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:
Joshua Dwire 2016-03-24 15:13:54 -04:00
parent 1ddd2769ac
commit bff6782026
8 changed files with 96 additions and 53 deletions

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
});

View File

@ -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;
});