Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Import E-Invoice as Expense #9493

Draft
wants to merge 14 commits into
base: v5-develop
Choose a base branch
from

Conversation

LarsK1
Copy link
Contributor

@LarsK1 LarsK1 commented May 1, 2024

No description provided.

@LarsK1
Copy link
Contributor Author

LarsK1 commented May 8, 2024

@turbo124 can you maybe give me a little help. I'm currently stuck, in transfering the file from the curl-requests to the handling-part of the code. Can you maybe have a look at the classes and advise, what to change so, that the class zugferdedocument recieve the given xml-file?

@turbo124
Copy link
Member

turbo124 commented May 8, 2024

@turbo124 can you maybe give me a little help. I'm currently stuck, in transfering the file from the curl-requests to the handling-part of the code. Can you maybe have a look at the classes and advise, what to change so, that the class zugferdedocument recieve the given xml-file?

I would suggest extracting the files in the request and then passing each file into the handling clas()->handle(). I would not pass the entire request into the next method.

@LarsK1
Copy link
Contributor Author

LarsK1 commented May 12, 2024

Hi @turbo124 ,
I resolved many bugs, but can't test, because I'm constantly getting an 400-error with "{"message":"No query results for model [App\Models\Expense]."

This is my "test-code":

import requests

headers = {"X-Api-Token": "7tdDdkz987H3AYIWhNGXy8jTjJIoDhkAclCDLE26cTCj1KYX7EBHC66VEitJwWhn", "X-Requested-With": "XMLHttpRequest", "accept": "application/json"}

s = requests.session()

url = 'http://localhost:8000/api/v1/expenses/edocument'
with open(r"C:\Users\Lars-\Downloads\Rechnung_R00458.xml", 'rb') as edoc:
	file = {"document": edoc, "_method": "PUT"}
	r = s.put(url, files=file, headers=headers)

print(r, r.text)

Can you maybe assisst?

@turbo124
Copy link
Member

@LarsK1 I am assuming that you create the expense from the contents of the .xml ?

If this is the case, you will need to create the expense itself, and then attach the .xml file to that expense.

It appears you are attempting to upload the doc first, and then process the expense.. however the documents table requires the entity ID, (which you don't have at this stage)

@LarsK1
Copy link
Contributor Author

LarsK1 commented May 12, 2024

Hi @turbo124 ,
it's unfortunately failing much earlier. I'm not able to transport the xml-file to my handling class. In my opinion, the framework doesn't recognize the route at all - but I must admit I'm not really into the routing of laravel. Therefore it seems to handle my requests in the index-funtion?

@turbo124
Copy link
Member

@LarsK1 Are using the PUT verb or POST for this?

To upload, you need to ensure you use the POST verb and add the _method = PUT

@LarsK1
Copy link
Contributor Author

LarsK1 commented May 13, 2024

Hi,
I was using post, but were getting 404, when using put I got at least the 400 error.

See the code above for reference

@turbo124
Copy link
Member

@LarsK1 I meant this line:

	r = s.put(url, files=file, headers=headers)

try s.post()

the route file should remain ::put

@LarsK1 LarsK1 marked this pull request as draft May 13, 2024 06:03
@LarsK1
Copy link
Contributor Author

LarsK1 commented May 13, 2024

@turbo124 ,
that gives me: <Response [404]> {"message":"Method not supported for this route"}

@turbo124
Copy link
Member

@LarsK1

I see the issue here: couple of changes needed.

In your api.php file

    Route::resource('expenses', ExpenseController::class); // name = (expenses. index / create / show / update / destroy / edit
    Route::put('expenses/{expense}/upload', [ExpenseController::class, 'upload']);
    Route::post('expenses/bulk', [ExpenseController::class, 'bulk'])->name('expenses.bulk');
    Route::post('export', [ExportController::class, 'index'])->name('export.index');
    Route::put('expenses/edocument/upload', [ExpenseController::class, "edocument"])->name("expenses.edocument");

move the route to the bottom, and change it by appending /upload

the system is trying to resolve edocument as a model.

also, in edocument request, change

return $user->can('edit', $this->expense);

to

        return $user->isAdmin();

routes/api.php Outdated
Route::post('export', [ExportController::class, 'index'])->name('export.index');
Route::put('expenses/edocument/upload', [ExpenseController::class, "edocument"])->name("expenses.edocument");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @turbo124 ,
changed the files according to your help. But still getting 404 not found?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this and it works as expected, have you run php artisan optimize to update the routes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Can you send me your curl command to mitigate any incompatibility between python and PHP...?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curl -X POST
http://ninja.test:8000/api/v1/expenses/edocument/upload
-H 'Content-Type: multipart/form-data'
-H 'X-API-TOKEN: company-token-test'
-H 'X-Requested-With: XMLHttpRequest'
-F _method=PUT
-F documents[]=@/path/Invoice.xml;

/**
* @throws Exception
*/
public function run(): string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please let it return the expense, so it can be reused by the InboundMailEngine :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// TODO find vendor
$vendors_registration = VendorRepository::class;
$vendor = $vendors_registration->findVendorByNumber($this->document->getDocumentSeller()->getGlobalID());
return "";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@turbo124 when creating an expense through the api the following events are thrown:

event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(null))); // @turbo124 please check, I copied from API-Controller
event('eloquent.created: App\Models\Expense', $expense); // @turbo124 please check, I copied from API-Controller

should they also be present here?

@paulwer
Copy link
Contributor

paulwer commented May 22, 2024

@turbo124 @LarsK1 an additional thought about this topic from me:
we have already talked about using ocr services like mindee in addition to eInvoice standards.
Maybe the endpoint design should have a single route for guessing documents later, which can then determine which services to use in the background to create the right expense.

$expense->public_notes = $documentno;
$expense->currency_id = Currency::whereCode($invoiceCurrency)->first()->id;
$expense->save();
$expense->documents()->create(["content" => $visualizer->renderPdf()]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@turbo124 I'm having my difficulties with this line. How can I save a string-file to the documents of an expense?

Copy link
Contributor

@paulwer paulwer May 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from my perspective i think you should just use the UploadedFile object from the request instead of a stringfile. (because its not job within a queue and can be passed to saveDocuments function directly)

i also added some helperclasses with my PR at:
app/Utils/TempFile.php

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants