mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-09-20 08:21:34 +02:00
Improve expense XML parsing
This commit is contained in:
parent
57866333a8
commit
af73fc2e51
@ -60,7 +60,7 @@ class ProjectFilters extends QueryFilters
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if (!is_array($sort_col) || count($sort_col) != 2) {
|
||||
if (!is_array($sort_col) || count($sort_col) != 2 || !in_array($sort_col[0], \Illuminate\Support\Facades\Schema::getColumnListing('projects'))) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
|
@ -584,14 +584,15 @@ class ExpenseController extends BaseController
|
||||
return $this->itemResponse($expense->fresh());
|
||||
}
|
||||
|
||||
public function edocument(EDocumentRequest $request): string
|
||||
public function edocument(EDocumentRequest $request)
|
||||
{
|
||||
if ($request->hasFile("documents")) {
|
||||
return (new ImportEDocument($request->file("documents")[0]->get(), $request->file("documents")[0]->getClientOriginalName()))->handle();
|
||||
}
|
||||
else {
|
||||
return "No file found";
|
||||
$user = auth()->user();
|
||||
|
||||
foreach($request->file("documents") as $file) {
|
||||
ImportEDocument::dispatch($file->get(), $file->getClientOriginalName(), $user->company());
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'Processing....'], 200);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ class EDocumentRequest extends Request
|
||||
$rules = [];
|
||||
|
||||
if ($this->file('documents') && is_array($this->file('documents'))) {
|
||||
$rules['documents.*'] = $this->fileValidation();
|
||||
$rules['documents.*'] = 'required|file|max:1000000|mimes:xml';
|
||||
} elseif ($this->file('documents')) {
|
||||
$rules['documents'] = $this->fileValidation();
|
||||
$rules['documents'] = 'required|file|max:1000000|mimes:xml';
|
||||
}
|
||||
return $rules;
|
||||
}
|
||||
|
@ -11,14 +11,16 @@
|
||||
|
||||
namespace App\Jobs\EDocument;
|
||||
|
||||
use App\Models\Expense;
|
||||
use App\Services\EDocument\Imports\ZugferdEDocument;
|
||||
use Exception;
|
||||
use App\Models\Company;
|
||||
use App\Models\Expense;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
||||
use App\Services\EDocument\Imports\ZugferdEDocument;
|
||||
|
||||
class ImportEDocument implements ShouldQueue
|
||||
{
|
||||
@ -27,14 +29,10 @@ class ImportEDocument implements ShouldQueue
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
public $deleteWhenMissingModels = true;
|
||||
private string $file_name;
|
||||
private readonly string $file_content;
|
||||
public $tries = 1;
|
||||
|
||||
public function __construct(string $file_content, string $file_name)
|
||||
public function __construct(private readonly string $file_content, private string $file_name, private Company $company)
|
||||
{
|
||||
$this->file_content = $file_content;
|
||||
$this->file_name = $file_name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,20 +43,30 @@ class ImportEDocument implements ShouldQueue
|
||||
*/
|
||||
public function handle(): Expense
|
||||
{
|
||||
if (str_contains($this->file_name, ".xml")){
|
||||
|
||||
switch (true) {
|
||||
case stristr($this->file_content, "urn:cen.eu:en16931:2017"):
|
||||
case stristr($this->file_content, "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0"):
|
||||
case stristr($this->file_content, "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_2.1"):
|
||||
case stristr($this->file_content, "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_2.0"):
|
||||
return (new ZugferdEDocument($this->file_content, $this->file_name))->run();
|
||||
return (new ZugferdEDocument($this->file_content, $this->file_name, $this->company))->run();
|
||||
default:
|
||||
throw new Exception("E-Invoice standard not supported");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception("File type not supported");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function middleware()
|
||||
{
|
||||
return [new WithoutOverlapping($this->company->company_key)];
|
||||
}
|
||||
|
||||
public function failed($exception = null)
|
||||
{
|
||||
if ($exception) {
|
||||
nlog("EXCEPTION:: ImportEDocument:: ".$exception->getMessage());
|
||||
}
|
||||
|
||||
config(['queue.failed.driver' => null]);
|
||||
}
|
||||
}
|
||||
|
@ -11,19 +11,20 @@
|
||||
|
||||
namespace App\Services\EDocument\Imports;
|
||||
|
||||
use App\Factory\ExpenseFactory;
|
||||
use App\Factory\VendorFactory;
|
||||
use App\Jobs\Util\UploadFile;
|
||||
use App\Models\Country;
|
||||
use App\Models\Currency;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Vendor;
|
||||
use App\Services\AbstractService;
|
||||
use App\Utils\TempFile;
|
||||
use Exception;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\Company;
|
||||
use App\Models\Country;
|
||||
use App\Models\Expense;
|
||||
use App\Utils\TempFile;
|
||||
use App\Models\Currency;
|
||||
use App\Jobs\Util\UploadFile;
|
||||
use App\Factory\VendorFactory;
|
||||
use App\Factory\ExpenseFactory;
|
||||
use App\Services\AbstractService;
|
||||
use horstoeko\zugferd\ZugferdDocumentReader;
|
||||
use horstoeko\zugferdvisualizer\renderer\ZugferdVisualizerLaravelRenderer;
|
||||
use horstoeko\zugferdvisualizer\ZugferdVisualizer;
|
||||
use horstoeko\zugferdvisualizer\renderer\ZugferdVisualizerLaravelRenderer;
|
||||
|
||||
class ZugferdEDocument extends AbstractService {
|
||||
public ZugferdDocumentReader|string $document;
|
||||
@ -31,7 +32,7 @@ class ZugferdEDocument extends AbstractService {
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(public string $tempdocument, public string $documentname)
|
||||
public function __construct(public string $tempdocument, public string $documentname, public Company $company)
|
||||
{
|
||||
# curl -X POST http://localhost:8000/api/v1/edocument/upload -H "Content-Type: multipart/form-data" -H "X-API-TOKEN: 7tdDdkz987H3AYIWhNGXy8jTjJIoDhkAclCDLE26cTCj1KYX7EBHC66VEitJwWhn" -H "X-Requested-With: XMLHttpRequest" -F _method=PUT -F documents[]=@einvoice.xml
|
||||
}
|
||||
@ -42,13 +43,14 @@ class ZugferdEDocument extends AbstractService {
|
||||
public function run(): Expense
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
$user = $this->company->owner();
|
||||
|
||||
$this->document = ZugferdDocumentReader::readAndGuessFromContent($this->tempdocument);
|
||||
$this->document->getDocumentInformation($documentno, $documenttypecode, $documentdate, $invoiceCurrency, $taxCurrency, $documentname, $documentlanguage, $effectiveSpecifiedPeriod);
|
||||
$this->document->getDocumentSummation($grandTotalAmount, $duePayableAmount, $lineTotalAmount, $chargeTotalAmount, $allowanceTotalAmount, $taxBasisTotalAmount, $taxTotalAmount, $roundingAmount, $totalPrepaidAmount);
|
||||
|
||||
/** @var \App\Models\Expense $expense */
|
||||
$expense = Expense::where("company_id", $user->company()->id)->where('amount', $grandTotalAmount)->where("transaction_reference", $documentno)->whereDate("date", $documentdate)->first();
|
||||
$expense = Expense::where("company_id", $this->company->id)->where('amount', $grandTotalAmount)->where("transaction_reference", $documentno)->whereDate("date", $documentdate)->first();
|
||||
if (!$expense) {
|
||||
// The document does not exist as an expense
|
||||
// Handle accordingly
|
||||
@ -59,10 +61,10 @@ class ZugferdEDocument extends AbstractService {
|
||||
$visualizer->setPdfPaperSize('A4-P');
|
||||
$visualizer->setTemplate('edocument.xinvoice');
|
||||
|
||||
$expense = ExpenseFactory::create($user->company()->id, $user->id);
|
||||
$expense = ExpenseFactory::create($this->company->id, $user->id);
|
||||
$expense->date = $documentdate;
|
||||
$expense->public_notes = $documentno;
|
||||
$expense->currency_id = Currency::whereCode($invoiceCurrency)->first()->id ?? $user->company()->settings->currency_id;
|
||||
$expense->currency_id = Currency::whereCode($invoiceCurrency)->first()->id ?? $this->company->settings->currency_id;
|
||||
$expense->save();
|
||||
|
||||
$origin_file = TempFile::UploadedFileFromRaw($this->tempdocument, $this->documentname, "application/xml");
|
||||
@ -98,7 +100,7 @@ class ZugferdEDocument extends AbstractService {
|
||||
// Vendor found
|
||||
$expense->vendor_id = $vendor->id;
|
||||
} else {
|
||||
$vendor = VendorFactory::create($user->company()->id, $user->id);
|
||||
$vendor = VendorFactory::create($this->company->id, $user->id);
|
||||
$vendor->name = $name;
|
||||
if ($taxid != null) {
|
||||
$vendor->vat_number = $taxid;
|
||||
|
Loading…
Reference in New Issue
Block a user