diff --git a/app/Jobs/Invoice/CreateXInvoice.php b/app/Jobs/Invoice/CreateXInvoice.php index c012c4cc52e2..1970aad1874f 100644 --- a/app/Jobs/Invoice/CreateXInvoice.php +++ b/app/Jobs/Invoice/CreateXInvoice.php @@ -11,6 +11,7 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\Storage; class CreateXInvoice implements ShouldQueue @@ -28,9 +29,9 @@ class CreateXInvoice implements ShouldQueue * Execute the job. * * - * @return void + * @return string */ - public function handle(): void + public function handle(): string { $invoice = $this->invoice; $company = $invoice->company; @@ -127,14 +128,20 @@ class CreateXInvoice implements ShouldQueue $xrechnung->addDocumentTax("S", "VAT", $taxnet_2, $taxAmount_2, $invoice->tax_rate2); } if (strlen($invoice->tax_name3) > 1) { - $xrechnung->addDocumentTax("S", "VAT", $taxnet_3, $taxamount_3, $invoice->tax_rate3); + $xrechnung->addDocumentTax("CS", "VAT", $taxnet_3, $taxamount_3, $invoice->tax_rate3); } $xrechnung->writeFile(explode(".", $client->invoice_filepath($invoice->invitations->first()))[0] . "-xinvoice.xml"); - // TODO: Inject XML into PDF - $pdfBuilder = new ZugferdDocumentPdfBuilder($xrechnung, $client->invoice_filepath($invoice->invitations->first())); - $pdfBuilder->generateDocument(); - $pdfBuilder->saveDocument($client->invoice_filepath($invoice->invitations->first())); + $filepath_pdf = $client->invoice_filepath($invoice->invitations->first()); + $disk = config('filesystems.default'); + + $file = Storage::disk($disk)->exists($filepath_pdf); + if ($file) { + $pdfBuilder = new ZugferdDocumentPdfBuilder($xrechnung, $filepath_pdf); + $pdfBuilder->generateDocument(); + $pdfBuilder->saveDocument($client->invoice_filepath($invoice->invitations->first())); + } + return explode(".", $client->invoice_filepath($invoice->invitations->first()))[0] . "-xinvoice.xml"; } private function getItemTaxable($item, $invoice_total): float { diff --git a/app/Jobs/Invoice/ZipInvoices.php b/app/Jobs/Invoice/ZipInvoices.php index 9a0d4752c3a8..4d6dca8fe63a 100644 --- a/app/Jobs/Invoice/ZipInvoices.php +++ b/app/Jobs/Invoice/ZipInvoices.php @@ -78,13 +78,19 @@ class ZipInvoices implements ShouldQueue $this->invoices->each(function ($invoice) { (new CreateEntityPdf($invoice->invitations()->first()))->handle(); + if ($this->company->getSetting("create_xinvoice")){ + (new CreateXInvoice($invoice))->handle(); + } }); try { foreach ($this->invoices as $invoice) { $file = $invoice->service()->getInvoicePdf(); + $xinvoice = $invoice->service()->getXInvoice(); $zip_file_name = basename($file); - $zipFile->addFromString($zip_file_name, Storage::get($file)); + $xinvoice_zip_file_name = basename($xinvoice); + $zipFile->addFromString($zip_file_name, Storage::get($file)) + ->addDir($xinvoice_zip_file_name, Storage::get($xinvoice)); //$download_file = file_get_contents($invoice->pdf_file_path($invitation, 'url', true)); //$zipFile->addFromString(basename($invoice->pdf_file_path($invitation)), $download_file); diff --git a/app/Services/Invoice/GetInvoiceXInvoice.php b/app/Services/Invoice/GetInvoiceXInvoice.php new file mode 100644 index 000000000000..a4f2e0e37e9b --- /dev/null +++ b/app/Services/Invoice/GetInvoiceXInvoice.php @@ -0,0 +1,56 @@ +invoice = $invoice; + + $this->contact = $contact; + } + + public function run() + { + if (! $this->contact) { + $this->contact = $this->invoice->client->primary_contact()->first() ?: $this->invoice->client->contacts()->first(); + } + + $invitation = $this->invoice->invitations->where('client_contact_id', $this->contact->id)->first(); + + if (! $invitation) { + $invitation = $this->invoice->invitations->first(); + } + + $path = $this->invoice->client->invoice_filepath($invitation); + + $file_path = $path.$this->invoice->numberFormatter().'-xinvoice.xml'; + + // $disk = 'public'; + $disk = config('filesystems.default'); + + $file = Storage::disk($disk)->exists($file_path); + + if (! $file) { + $file_path = (new CreateXInvoice($this->invoice))->handle(); + } + + return $file_path; + } +} diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 6c4fe4882003..68cb3101ef32 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -14,6 +14,7 @@ namespace App\Services\Invoice; use App\Events\Invoice\InvoiceWasArchived; use App\Jobs\Entity\CreateEntityPdf; use App\Jobs\Inventory\AdjustProductInventory; +use App\Jobs\Invoice\CreateXInvoice; use App\Libraries\Currency\Conversion\CurrencyApi; use App\Models\CompanyGateway; use App\Models\Expense; @@ -184,6 +185,11 @@ class InvoiceService return (new GenerateDeliveryNote($invoice, $contact))->run(); } + public function getXInvoice($contact = null) + { + return (new GetInvoiceXInvoice($this->invoice))->run(); + } + public function sendEmail($contact = null) { $send_email = new SendEmail($this->invoice, null, $contact); @@ -293,7 +299,7 @@ class InvoiceService } elseif ($this->invoice->balance < 0 || $this->invoice->balance > 0) { $this->invoice->status_id = Invoice::STATUS_SENT; } - + return $this; } @@ -351,6 +357,27 @@ class InvoiceService return $this; } + public function deleteXInvoice() + { + $this->invoice->load('invitations'); + + $this->invoice->invitations->each(function ($invitation) { + try { + if (Storage::disk(config('filesystems.default'))->exists($this->invoice->client->invoice_filepath($invitation).$this->invoice->numberFormatter().'-xinvoice.xml')) { + Storage::disk(config('filesystems.default'))->delete($this->invoice->client->invoice_filepath($invitation).$this->invoice->numberFormatter().'-xinvoice.xml'); + } + + if (Ninja::isHosted() && Storage::disk('public')->exists($this->invoice->client->invoice_filepath($invitation).$this->invoice->numberFormatter().'-xinvoice.xml')) { + Storage::disk('public')->delete($this->invoice->client->invoice_filepath($invitation).$this->invoice->numberFormatter().'-xinvoice.xml'); + } + } catch (\Exception $e) { + nlog($e->getMessage()); + } + }); + + return $this; + } + public function removeUnpaidGatewayFees() { $balance = $this->invoice->balance; @@ -421,6 +448,7 @@ class InvoiceService if ($force) { $this->invoice->invitations->each(function ($invitation) { (new CreateEntityPdf($invitation))->handle(); + // Add XInvoice }); return $this; @@ -428,6 +456,7 @@ class InvoiceService $this->invoice->invitations->each(function ($invitation) { CreateEntityPdf::dispatch($invitation); + // Add XInvoice }); } catch (\Exception $e) { nlog('failed creating invoices in Touch PDF');