Create XInvoice automatically, when enabled

This commit is contained in:
Lars Kusch 2023-03-13 08:28:46 +01:00
parent d4bc9de472
commit a765153642
4 changed files with 107 additions and 9 deletions

View File

@ -11,6 +11,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
class CreateXInvoice implements ShouldQueue class CreateXInvoice implements ShouldQueue
@ -28,9 +29,9 @@ class CreateXInvoice implements ShouldQueue
* Execute the job. * Execute the job.
* *
* *
* @return void * @return string
*/ */
public function handle(): void public function handle(): string
{ {
$invoice = $this->invoice; $invoice = $this->invoice;
$company = $invoice->company; $company = $invoice->company;
@ -127,14 +128,20 @@ class CreateXInvoice implements ShouldQueue
$xrechnung->addDocumentTax("S", "VAT", $taxnet_2, $taxAmount_2, $invoice->tax_rate2); $xrechnung->addDocumentTax("S", "VAT", $taxnet_2, $taxAmount_2, $invoice->tax_rate2);
} }
if (strlen($invoice->tax_name3) > 1) { 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"); $xrechnung->writeFile(explode(".", $client->invoice_filepath($invoice->invitations->first()))[0] . "-xinvoice.xml");
// TODO: Inject XML into PDF $filepath_pdf = $client->invoice_filepath($invoice->invitations->first());
$pdfBuilder = new ZugferdDocumentPdfBuilder($xrechnung, $client->invoice_filepath($invoice->invitations->first())); $disk = config('filesystems.default');
$pdfBuilder->generateDocument();
$pdfBuilder->saveDocument($client->invoice_filepath($invoice->invitations->first())); $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 private function getItemTaxable($item, $invoice_total): float
{ {

View File

@ -78,13 +78,19 @@ class ZipInvoices implements ShouldQueue
$this->invoices->each(function ($invoice) { $this->invoices->each(function ($invoice) {
(new CreateEntityPdf($invoice->invitations()->first()))->handle(); (new CreateEntityPdf($invoice->invitations()->first()))->handle();
if ($this->company->getSetting("create_xinvoice")){
(new CreateXInvoice($invoice))->handle();
}
}); });
try { try {
foreach ($this->invoices as $invoice) { foreach ($this->invoices as $invoice) {
$file = $invoice->service()->getInvoicePdf(); $file = $invoice->service()->getInvoicePdf();
$xinvoice = $invoice->service()->getXInvoice();
$zip_file_name = basename($file); $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)); //$download_file = file_get_contents($invoice->pdf_file_path($invitation, 'url', true));
//$zipFile->addFromString(basename($invoice->pdf_file_path($invitation)), $download_file); //$zipFile->addFromString(basename($invoice->pdf_file_path($invitation)), $download_file);

View File

@ -0,0 +1,56 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Services\Invoice;
use App\Jobs\Invoice\CreateXInvoice;
use App\Models\ClientContact;
use App\Models\Invoice;
use App\Services\AbstractService;
use Illuminate\Support\Facades\Storage;
class GetInvoiceXInvoice extends AbstractService
{
public function __construct(Invoice $invoice, ClientContact $contact = null)
{
$this->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;
}
}

View File

@ -14,6 +14,7 @@ namespace App\Services\Invoice;
use App\Events\Invoice\InvoiceWasArchived; use App\Events\Invoice\InvoiceWasArchived;
use App\Jobs\Entity\CreateEntityPdf; use App\Jobs\Entity\CreateEntityPdf;
use App\Jobs\Inventory\AdjustProductInventory; use App\Jobs\Inventory\AdjustProductInventory;
use App\Jobs\Invoice\CreateXInvoice;
use App\Libraries\Currency\Conversion\CurrencyApi; use App\Libraries\Currency\Conversion\CurrencyApi;
use App\Models\CompanyGateway; use App\Models\CompanyGateway;
use App\Models\Expense; use App\Models\Expense;
@ -184,6 +185,11 @@ class InvoiceService
return (new GenerateDeliveryNote($invoice, $contact))->run(); return (new GenerateDeliveryNote($invoice, $contact))->run();
} }
public function getXInvoice($contact = null)
{
return (new GetInvoiceXInvoice($this->invoice))->run();
}
public function sendEmail($contact = null) public function sendEmail($contact = null)
{ {
$send_email = new SendEmail($this->invoice, null, $contact); $send_email = new SendEmail($this->invoice, null, $contact);
@ -293,7 +299,7 @@ class InvoiceService
} elseif ($this->invoice->balance < 0 || $this->invoice->balance > 0) { } elseif ($this->invoice->balance < 0 || $this->invoice->balance > 0) {
$this->invoice->status_id = Invoice::STATUS_SENT; $this->invoice->status_id = Invoice::STATUS_SENT;
} }
return $this; return $this;
} }
@ -351,6 +357,27 @@ class InvoiceService
return $this; 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() public function removeUnpaidGatewayFees()
{ {
$balance = $this->invoice->balance; $balance = $this->invoice->balance;
@ -421,6 +448,7 @@ class InvoiceService
if ($force) { if ($force) {
$this->invoice->invitations->each(function ($invitation) { $this->invoice->invitations->each(function ($invitation) {
(new CreateEntityPdf($invitation))->handle(); (new CreateEntityPdf($invitation))->handle();
// Add XInvoice
}); });
return $this; return $this;
@ -428,6 +456,7 @@ class InvoiceService
$this->invoice->invitations->each(function ($invitation) { $this->invoice->invitations->each(function ($invitation) {
CreateEntityPdf::dispatch($invitation); CreateEntityPdf::dispatch($invitation);
// Add XInvoice
}); });
} catch (\Exception $e) { } catch (\Exception $e) {
nlog('failed creating invoices in Touch PDF'); nlog('failed creating invoices in Touch PDF');