diff --git a/app/Console/Commands/CheckData.php b/app/Console/Commands/CheckData.php index 8f49531ea467..7d931c1022fa 100644 --- a/app/Console/Commands/CheckData.php +++ b/app/Console/Commands/CheckData.php @@ -35,6 +35,7 @@ use App\Models\BankTransaction; use App\Models\QuoteInvitation; use Illuminate\Console\Command; use App\Models\CreditInvitation; +use App\Models\RecurringInvoice; use App\Models\InvoiceInvitation; use App\DataMapper\ClientSettings; use Illuminate\Support\Facades\DB; diff --git a/app/DataMapper/InvoiceItem.php b/app/DataMapper/InvoiceItem.php index 49571d668fdf..cdb1953c9be4 100644 --- a/app/DataMapper/InvoiceItem.php +++ b/app/DataMapper/InvoiceItem.php @@ -61,8 +61,13 @@ class InvoiceItem public $tax_id = ''; + public $task_id = ''; + + public $expense_id = ''; public static $casts = [ + 'task_id' => 'string', + 'expense_id' => 'string', 'tax_id' => 'string', 'type_id' => 'string', 'quantity' => 'float', diff --git a/app/Http/Controllers/ClientPortal/InvoiceController.php b/app/Http/Controllers/ClientPortal/InvoiceController.php index f67ae6042705..265cc5f8961e 100644 --- a/app/Http/Controllers/ClientPortal/InvoiceController.php +++ b/app/Http/Controllers/ClientPortal/InvoiceController.php @@ -252,11 +252,20 @@ class InvoiceController extends Controller // create new archive $zipFile = new \PhpZip\ZipFile(); try { + foreach ($invoices as $invoice) { - //add it to the zip - $zipFile->addFromString(basename($invoice->pdf_file_path()), file_get_contents($invoice->pdf_file_path(null, 'url', true))); + + if ($invoice->client->getSetting('enable_e_invoice')) { + $xml = $invoice->service()->getEInvoice(); + $zipFile->addFromString($invoice->getFileName("xml"), $xml); + } + + $file = $invoice->service()->getRawInvoicePdf(); + $zip_file_name = $invoice->getFileName(); + $zipFile->addFromString($zip_file_name, $file); } + $filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.invoices')).'.zip'; $filepath = sys_get_temp_dir().'/'.$filename; diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index ec86da941082..626c22df9acc 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -850,6 +850,7 @@ class InvoiceController extends BaseController $invoice = $invitation->invoice; $file = $invoice->service()->getEInvoice($contact); + $file_name = $invoice->getFileName("xml"); $headers = ['Content-Type' => 'application/xml']; @@ -858,8 +859,8 @@ class InvoiceController extends BaseController } return response()->streamDownload(function () use ($file) { - echo Storage::get($file); - }, basename($file), $headers); + echo $file; + }, $file_name, $headers); } /** diff --git a/app/Http/Livewire/PdfSlot.php b/app/Http/Livewire/PdfSlot.php index 0990ac3ec76d..a97444ba89ee 100644 --- a/app/Http/Livewire/PdfSlot.php +++ b/app/Http/Livewire/PdfSlot.php @@ -12,7 +12,6 @@ namespace App\Http\Livewire; -use App\Services\Invoice\GetInvoiceEInvoice; use App\Utils\Number; use Livewire\Component; use App\Utils\HtmlEngine; @@ -22,6 +21,7 @@ use App\Models\QuoteInvitation; use App\Utils\VendorHtmlEngine; use App\Models\CreditInvitation; use App\Models\InvoiceInvitation; +use App\Jobs\Invoice\CreateEInvoice; use Illuminate\Support\Facades\Cache; use App\Models\PurchaseOrderInvitation; use App\Models\RecurringInvoiceInvitation; @@ -102,7 +102,7 @@ class PdfSlot extends Component $file_name = $this->entity->numberFormatter().'.xml'; - $file = (new GetInvoiceEInvoice($this->entity))->run(); + $file = (new CreateEInvoice($this->entity))->handle(); $headers = ['Content-Type' => 'application/xml']; diff --git a/app/Http/Requests/Shop/StoreShopClientRequest.php b/app/Http/Requests/Shop/StoreShopClientRequest.php index beffeeac2f1d..140dc08a904b 100644 --- a/app/Http/Requests/Shop/StoreShopClientRequest.php +++ b/app/Http/Requests/Shop/StoreShopClientRequest.php @@ -108,7 +108,7 @@ class StoreShopClientRequest extends Request $settings->currency_id = $this->getCurrencyCode($input['currency_code']); } - $input['settings'] = $settings; + $input['settings'] = (array)$settings; if (isset($input['contacts'])) { foreach ($input['contacts'] as $key => $contact) { diff --git a/app/Jobs/Entity/CreateEntityPdf.php b/app/Jobs/Entity/CreateEntityPdf.php index 6fdf3d7f309e..7ef89d2c3e81 100644 --- a/app/Jobs/Entity/CreateEntityPdf.php +++ b/app/Jobs/Entity/CreateEntityPdf.php @@ -11,38 +11,38 @@ namespace App\Jobs\Entity; -use App\Exceptions\FilePermissionsFailure; -use App\Jobs\Invoice\CreateEInvoice; -use App\Jobs\Invoice\MergeEInvoice; -use App\Libraries\MultiDB; +use App\Utils\Ninja; +use App\Models\Quote; use App\Models\Credit; -use App\Models\CreditInvitation; use App\Models\Design; use App\Models\Invoice; -use App\Models\InvoiceInvitation; -use App\Models\Quote; +use App\Utils\HtmlEngine; +use App\Libraries\MultiDB; +use Illuminate\Bus\Queueable; use App\Models\QuoteInvitation; +use App\Utils\Traits\MakesHash; +use App\Models\CreditInvitation; use App\Models\RecurringInvoice; +use App\Utils\PhantomJS\Phantom; +use App\Models\InvoiceInvitation; +use App\Utils\HostedPDF\NinjaPdf; +use App\Utils\Traits\Pdf\PdfMaker; +use Illuminate\Support\Facades\App; +use App\Jobs\Invoice\CreateEInvoice; +use App\Utils\Traits\NumberFormatter; +use App\Utils\Traits\MakesInvoiceHtml; +use Illuminate\Queue\SerializesModels; +use App\Utils\Traits\Pdf\PageNumbering; +use Illuminate\Support\Facades\Storage; +use Illuminate\Queue\InteractsWithQueue; +use App\Exceptions\FilePermissionsFailure; use App\Models\RecurringInvoiceInvitation; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use horstoeko\zugferd\ZugferdDocumentPdfBuilder; use App\Services\PdfMaker\Design as PdfDesignModel; use App\Services\PdfMaker\Design as PdfMakerDesign; use App\Services\PdfMaker\PdfMaker as PdfMakerService; -use App\Utils\HostedPDF\NinjaPdf; -use App\Utils\HtmlEngine; -use App\Utils\Ninja; -use App\Utils\PhantomJS\Phantom; -use App\Utils\Traits\MakesHash; -use App\Utils\Traits\MakesInvoiceHtml; -use App\Utils\Traits\NumberFormatter; -use App\Utils\Traits\Pdf\PageNumbering; -use App\Utils\Traits\Pdf\PdfMaker; -use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; -use Illuminate\Foundation\Bus\Dispatchable; -use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\App; -use Illuminate\Support\Facades\Storage; class CreateEntityPdf implements ShouldQueue { @@ -117,7 +117,8 @@ class CreateEntityPdf implements ShouldQueue } $entity_design_id = ''; - + $path = ''; + if ($this->entity instanceof Invoice) { $path = $this->client->invoice_filepath($this->invitation); $entity_design_id = 'invoice_design_id'; @@ -207,6 +208,11 @@ class CreateEntityPdf implements ShouldQueue info($maker->getCompiledHTML()); } + if($this->entity_string == "invoice" && $this->client->getSetting('enable_e_invoice')) + { + $pdf = $this->checkEInvoice($pdf); + } + if ($pdf) { try { Storage::disk($this->disk)->put($file_path, $pdf); @@ -214,11 +220,7 @@ class CreateEntityPdf implements ShouldQueue throw new FilePermissionsFailure($e->getMessage()); } } - if ($this->entity_string == "invoice" && $this->client->getSetting('enable_e_invoice')){ - (new CreateEInvoice($this->entity))->handle(); - (new MergeEInvoice($this->entity))->handle(); - - } + $this->invitation = null; // $this->entity = null; $this->company = null; @@ -227,10 +229,65 @@ class CreateEntityPdf implements ShouldQueue $maker = null; $state = null; - return $file_path; } + /** + * Switch to determine if we need to embed the xml into the PDF itself + * + * @param string $pdf + * @return string + */ + private function checkEInvoice(string $pdf): string + { + if(!$this->entity instanceof Invoice) + return $pdf; + + $e_invoice_type = $this->entity->client->getSetting('e_invoice_type'); + + switch ($e_invoice_type) { + case "EN16931": + case "XInvoice_2_2": + case "XInvoice_2_1": + case "XInvoice_2_0": + case "XInvoice_1_0": + case "XInvoice-Extended": + case "XInvoice-BasicWL": + case "XInvoice-Basic": + return $this->embedEInvoiceZuGFerD($pdf) ?? $pdf; + //case "Facturae_3.2": + //case "Facturae_3.2.1": + //case "Facturae_3.2.2": + // + default: + return $pdf; + } + + } + + /** + * Embed the .xml file into the PDF + * + * @param string $pdf + * @return string + */ + private function embedEInvoiceZuGFerD(string $pdf): string + { + try { + + $e_rechnung = (new CreateEInvoice($this->entity, true))->handle(); + $pdfBuilder = new ZugferdDocumentPdfBuilder($e_rechnung, $pdf); + $pdfBuilder->generateDocument(); + return $pdfBuilder->downloadString(basename($this->entity->getFileName())); + + } catch (\Exception $e) { + nlog("E_Invoice Merge failed - " . $e->getMessage()); + } + + return $pdf; + } + + public function failed($e) { } diff --git a/app/Jobs/Entity/CreateRawPdf.php b/app/Jobs/Entity/CreateRawPdf.php index 8c3b4d77f7f0..921879021c61 100644 --- a/app/Jobs/Entity/CreateRawPdf.php +++ b/app/Jobs/Entity/CreateRawPdf.php @@ -11,42 +11,43 @@ namespace App\Jobs\Entity; -use App\Exceptions\FilePermissionsFailure; -use App\Jobs\Invoice\MergeEInvoice; -use App\Libraries\MultiDB; +use App\Utils\Ninja; +use App\Models\Quote; use App\Models\Credit; -use App\Models\CreditInvitation; use App\Models\Design; use App\Models\Invoice; -use App\Models\InvoiceInvitation; -use App\Models\Quote; +use App\Utils\HtmlEngine; +use App\Libraries\MultiDB; +use Illuminate\Bus\Queueable; use App\Models\QuoteInvitation; +use App\Utils\Traits\MakesHash; +use App\Models\CreditInvitation; use App\Models\RecurringInvoice; +use App\Utils\PhantomJS\Phantom; +use App\Models\InvoiceInvitation; +use App\Utils\HostedPDF\NinjaPdf; +use App\Utils\Traits\Pdf\PdfMaker; +use Illuminate\Support\Facades\App; +use App\Jobs\Invoice\CreateEInvoice; +use App\Utils\Traits\NumberFormatter; +use App\Utils\Traits\MakesInvoiceHtml; +use Illuminate\Queue\SerializesModels; +use App\Utils\Traits\Pdf\PageNumbering; +use Illuminate\Queue\InteractsWithQueue; +use App\Exceptions\FilePermissionsFailure; use App\Models\RecurringInvoiceInvitation; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use horstoeko\zugferd\ZugferdDocumentPdfBuilder; use App\Services\PdfMaker\Design as PdfDesignModel; use App\Services\PdfMaker\Design as PdfMakerDesign; use App\Services\PdfMaker\PdfMaker as PdfMakerService; -use App\Utils\HostedPDF\NinjaPdf; -use App\Utils\HtmlEngine; -use App\Utils\Ninja; -use App\Utils\PhantomJS\Phantom; -use App\Utils\Traits\MakesHash; -use App\Utils\Traits\MakesInvoiceHtml; -use App\Utils\Traits\NumberFormatter; -use App\Utils\Traits\Pdf\PageNumbering; -use App\Utils\Traits\Pdf\PdfMaker; -use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; -use Illuminate\Foundation\Bus\Dispatchable; -use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\App; class CreateRawPdf implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, NumberFormatter, MakesInvoiceHtml, PdfMaker, MakesHash, PageNumbering; - public $entity; + public Invoice | Credit | Quote | RecurringInvoice $entity; public $company; @@ -104,6 +105,7 @@ class CreateRawPdf implements ShouldQueue } $entity_design_id = ''; + $path = ''; if ($this->entity instanceof Invoice) { $path = $this->entity->client->invoice_filepath($this->invitation); @@ -203,17 +205,67 @@ class CreateRawPdf implements ShouldQueue if ($pdf) { $maker =null; $state = null; - if ($this->invitation->invoice->client->getSetting('enable_e_invoice') && $this->entity_string == "invoice"){ - $filename = tempnam(sys_get_temp_dir(), 'InvoiceNinja').".pdf"; - file_put_contents($filename, $pdf); - (new \App\Services\Invoice\MergeEInvoice($this->invitation->invoice, $filename))->run(); - return file_get_contents($filename); - }; - return $pdf; + + return $this->checkEInvoice($pdf); } throw new FilePermissionsFailure('Unable to generate the raw PDF'); } + + /** + * Switch to determine if we need to embed the xml into the PDF itself + * + * @param string $pdf + * @return string + */ + private function checkEInvoice(string $pdf): string + { + if(!$this->entity instanceof Invoice) + return $pdf; + + $e_invoice_type = $this->entity->client->getSetting('e_invoice_type'); + + switch ($e_invoice_type) { + case "EN16931": + case "XInvoice_2_2": + case "XInvoice_2_1": + case "XInvoice_2_0": + case "XInvoice_1_0": + case "XInvoice-Extended": + case "XInvoice-BasicWL": + case "XInvoice-Basic": + return $this->embedEInvoiceZuGFerD($pdf) ?? $pdf; + //case "Facturae_3.2": + //case "Facturae_3.2.1": + //case "Facturae_3.2.2": + // + default: + return $pdf; + } + + } + + /** + * Embed the .xml file into the PDF + * + * @param string $pdf + * @return string + */ + private function embedEInvoiceZuGFerD(string $pdf): string + { + try { + + $e_rechnung = (new CreateEInvoice($this->entity, true))->handle(); + $pdfBuilder = new ZugferdDocumentPdfBuilder($e_rechnung, $pdf); + $pdfBuilder->generateDocument(); + return $pdfBuilder->downloadString(basename($this->entity->getFileName())); + + } catch (\Exception $e) { + nlog("E_Invoice Merge failed - " . $e->getMessage()); + } + + return $pdf; + } public function failed($e) { diff --git a/app/Jobs/Invoice/CreateEInvoice.php b/app/Jobs/Invoice/CreateEInvoice.php index 017c8fcac448..c68662c4b108 100644 --- a/app/Jobs/Invoice/CreateEInvoice.php +++ b/app/Jobs/Invoice/CreateEInvoice.php @@ -37,8 +37,7 @@ class CreateEInvoice implements ShouldQueue /** * Execute the job. * - * - * @return string + * @return string|ZugferdDocumentBuilder */ public function handle(): string|ZugferdDocumentBuilder { @@ -64,13 +63,18 @@ class CreateEInvoice implements ShouldQueue case "XInvoice-Extended": case "XInvoice-BasicWL": case "XInvoice-Basic": - return (new ZugferdEInvoice($this->invoice, $this->returnObject))->run(); + $zugferd = (new ZugferdEInvoice($this->invoice))->run(); + + return $this->returnObject ? $zugferd->xrechnung : $zugferd->getXml(); case "Facturae_3.2": case "Facturae_3.2.1": case "Facturae_3.2.2": return (new FacturaEInvoice($this->invoice, str_replace("Facturae_", "", $e_invoice_type)))->run(); default: - return (new ZugferdEInvoice($this->invoice, $this->returnObject))->run(); + + $zugferd = (new ZugferdEInvoice($this->invoice))->run(); + + return $this->returnObject ? $zugferd : $zugferd->getXml(); } diff --git a/app/Jobs/Invoice/MergeEInvoice.php b/app/Jobs/Invoice/MergeEInvoice.php deleted file mode 100644 index 1a33db8be1db..000000000000 --- a/app/Jobs/Invoice/MergeEInvoice.php +++ /dev/null @@ -1,68 +0,0 @@ -invoice->client->getSetting('e_invoice_type'); - switch ($e_invoice_type) { - case "EN16931": - case "XInvoice_2_2": - case "XInvoice_2_1": - case "XInvoice_2_0": - case "XInvoice_1_0": - case "XInvoice-Extended": - case "XInvoice-BasicWL": - case "XInvoice-Basic": - $this->embedEInvoiceZuGFerD(); - //case "Facturae_3.2": - //case "Facturae_3.2.1": - //case "Facturae_3.2.2": - // - default: - $this->embedEInvoiceZuGFerD(); - break; - } - } - - /** - * @throws \Exception - */ - private function embedEInvoiceZuGFerD(): void - { - $filepath_pdf = !empty($this->pdf_path) ? $this->pdf_path : $this->invoice->service()->getInvoicePdf(); - $disk = config('filesystems.default'); - $e_rechnung = (new CreateEInvoice($this->invoice, true))->handle(); - if (!empty($this->pdf_path)){ - $realpath_pdf = $filepath_pdf; - } - else { - $realpath_pdf = Storage::disk($disk)->path($filepath_pdf); - } - if (file_exists($realpath_pdf)){ - $pdfBuilder = new ZugferdDocumentPdfBuilder($e_rechnung, $realpath_pdf); - $pdfBuilder->generateDocument(); - $pdfBuilder->saveDocument($realpath_pdf); - } - else{ - nlog("E_Invoice Merge failed - file to merge not found"); - } - - } -} diff --git a/app/Jobs/Invoice/ZipInvoices.php b/app/Jobs/Invoice/ZipInvoices.php index c257e647ccb8..f7292988b0d1 100644 --- a/app/Jobs/Invoice/ZipInvoices.php +++ b/app/Jobs/Invoice/ZipInvoices.php @@ -73,28 +73,19 @@ class ZipInvoices implements ShouldQueue $invitation = $this->invoices->first()->invitations->first(); $path = $this->invoices->first()->client->invoice_filepath($invitation); - $this->invoices->each(function ($invoice) { - (new CreateEntityPdf($invoice->invitations()->first()))->handle(); - if ($invoice->client->getSetting('enable_e_invoice')){ - (new CreateEInvoice($invoice))->handle(); - (new MergeEInvoice($invoice))->handle(); - } - }); - try { + foreach ($this->invoices as $invoice) { - $file = $invoice->service()->getInvoicePdf(); - $zip_file_name = basename($file); - $zipFile->addFromString($zip_file_name, Storage::get($file)); - - if($invoice->client->getSetting('enable_e_invoice')){ - - $xinvoice = $invoice->service()->getEInvoice(); - $xinvoice_zip_file_name = basename($xinvoice); - $zipFile->addFromString($xinvoice_zip_file_name, Storage::get($xinvoice)); - + + if ($invoice->client->getSetting('enable_e_invoice')) { + $xml = $invoice->service()->getEInvoice(); + $zipFile->addFromString($invoice->getFileName("xml"), $xml); } + + $file = $invoice->service()->getRawInvoicePdf(); + $zip_file_name = $invoice->getFileName(); + $zipFile->addFromString($zip_file_name, $file); } Storage::put($path.$file_name, $zipFile->outputAsString()); diff --git a/app/Mail/TemplateEmail.php b/app/Mail/TemplateEmail.php index ff77463df864..2fcd68874a81 100644 --- a/app/Mail/TemplateEmail.php +++ b/app/Mail/TemplateEmail.php @@ -18,7 +18,6 @@ use App\Services\PdfMaker\Designs\Utilities\DesignHelpers; use App\Utils\HtmlEngine; use App\Utils\Ninja; use Illuminate\Mail\Mailable; -use Illuminate\Support\Facades\Storage; class TemplateEmail extends Mailable { @@ -111,7 +110,7 @@ class TemplateEmail extends Mailable if (Ninja::isHosted()) { $bccs = explode(',', str_replace(' ', '', $settings->bcc_email)); $this->bcc(array_slice($bccs, 0, 2)); - //$this->bcc(reset($bccs)); //remove whitespace if any has been inserted. + //$this->bcc(reset($bccs)); //remove whitespace if any has been inserted. } else { $this->bcc(explode(',', str_replace(' ', '', $settings->bcc_email))); }//remove whitespace if any has been inserted. @@ -149,16 +148,21 @@ class TemplateEmail extends Mailable if ($this->invitation && $this->invitation->invoice && $settings->ubl_email_attachment && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) { $ubl_string = (new CreateUbl($this->invitation->invoice))->handle(); + nlog("template {$ubl_string}"); + if ($ubl_string) { $this->attachData($ubl_string, $this->invitation->invoice->getFileName('xml')); } + } if ($this->invitation && $this->invitation->invoice && $this->invitation->invoice->client->getSetting('enable_e_invoice') && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) { - - $xinvoice_filepath = $this->invitation->invoice->service()->getEInvoice($this->invitation->contact); + $xml_string = $this->invitation->invoice->service()->getEInvoice($this->invitation->contact); - if(Storage::disk(config('filesystems.default'))->exists($xinvoice_filepath)) - $this->attach(Storage::disk(config('filesystems.default'))->path($xinvoice_filepath), ['as' => $this->invitation->invoice->getFileName("xml"), 'mime' => null]); + nlog("template {$xml_string}"); + + if($xml_string) { + $this->attachData($xml_string, $this->invitation->invoice->getEFileName("xml")); + } } diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php index 7f8c0d4bca69..eb4c1772236a 100644 --- a/app/Models/BaseModel.php +++ b/app/Models/BaseModel.php @@ -237,6 +237,15 @@ class BaseModel extends Model return $this->numberFormatter().'.'.$extension; } + /** + * @param string $extension + * @return string + */ + public function getEFileName($extension = 'pdf') + { + return ctrans("texts.e_invoice"). "_" . $this->numberFormatter().'.'.$extension; + } + public function numberFormatter() { $number = strlen($this->number) >= 1 ? $this->translate_entity() . "_" . $this->number : class_basename($this) . "_" . Str::random(5); @@ -276,6 +285,7 @@ class BaseModel extends Model /** * Returns the base64 encoded PDF string of the entity + * @deprecated - unused implementation */ public function fullscreenPdfViewer($invitation = null): string { diff --git a/app/Services/Email/EmailDefaults.php b/app/Services/Email/EmailDefaults.php index a374ddfa353c..e2d833fa9e31 100644 --- a/app/Services/Email/EmailDefaults.php +++ b/app/Services/Email/EmailDefaults.php @@ -322,10 +322,10 @@ class EmailDefaults } /** E-Invoice xml file */ if ($this->email->email_object->settings->enable_e_invoice && $this->email->email_object->entity instanceof Invoice) { - $xinvoice_path = $this->email->email_object->entity->service()->getEInvoice(); + $xml_string = $this->email->email_object->entity->service()->getEInvoice(); - if(Storage::disk(config('filesystems.default'))->exists($xinvoice_path)) - $this->email->email_object->attachments = array_merge($this->email->email_object->attachments, [['file' => base64_encode(Storage::get($xinvoice_path)), 'name' => explode(".", $this->email->email_object->entity->getFileName('xml'))[0]."-e_invoice.xml"]]); + if($xml_string) + $this->email->email_object->attachments = array_merge($this->email->email_object->attachments, [['file' => base64_encode($xml_string), 'name' => explode(".", $this->email->email_object->entity->getFileName('xml'))[0]."-e_invoice.xml"]]); } if (!$this->email->email_object->settings->document_email_attachment || !$this->email->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) { diff --git a/app/Services/Invoice/EInvoice/ZugferdEInvoice.php b/app/Services/Invoice/EInvoice/ZugferdEInvoice.php index 37d6ce32fe65..0410422a4d7e 100644 --- a/app/Services/Invoice/EInvoice/ZugferdEInvoice.php +++ b/app/Services/Invoice/EInvoice/ZugferdEInvoice.php @@ -22,12 +22,13 @@ use horstoeko\zugferd\codelists\ZugferdDutyTaxFeeCategories; class ZugferdEInvoice extends AbstractService { + public ZugferdDocumentBuilder $xrechnung; public function __construct(public Invoice $invoice, private readonly bool $returnObject = false, private array $tax_map = []) { } - public function run(): string|ZugferdDocumentBuilder + public function run(): self { $company = $this->invoice->company; @@ -45,10 +46,9 @@ class ZugferdEInvoice extends AbstractService default => ZugferdProfiles::PROFILE_EN16931, }; + $this->xrechnung = ZugferdDocumentBuilder::CreateNew($profile); - $xrechnung = ZugferdDocumentBuilder::CreateNew($profile); - - $xrechnung + $this->xrechnung ->setDocumentSupplyChainEvent(date_create($this->invoice->date)) ->setDocumentSeller($company->getSetting('name')) ->setDocumentSellerAddress($company->getSetting("address1"), $company->getSetting("address2"), "", $company->getSetting("postal_code"), $company->getSetting("city"), $company->country()->iso_3166_2, $company->getSetting("state")) @@ -59,32 +59,32 @@ class ZugferdEInvoice extends AbstractService ->addDocumentPaymentTerm(ctrans("texts.xinvoice_payable", ['payeddue' => date_create($this->invoice->date)->diff(date_create($this->invoice->due_date))->format("%d"), 'paydate' => $this->invoice->due_date])); if (!empty($this->invoice->public_notes)) { - $xrechnung->addDocumentNote($this->invoice->public_notes); + $this->xrechnung->addDocumentNote($this->invoice->public_notes); } if (empty($this->invoice->number)){ - $xrechnung->setDocumentInformation("DRAFT", "380", date_create($this->invoice->date), $this->invoice->client->getCurrencyCode()); + $this->xrechnung->setDocumentInformation("DRAFT", "380", date_create($this->invoice->date), $this->invoice->client->getCurrencyCode()); } else { - $xrechnung->setDocumentInformation($this->invoice->number, "380", date_create($this->invoice->date), $this->invoice->client->getCurrencyCode()); + $this->xrechnung->setDocumentInformation($this->invoice->number, "380", date_create($this->invoice->date), $this->invoice->client->getCurrencyCode()); } if (!empty($this->invoice->po_number)) { - $xrechnung->setDocumentBuyerOrderReferencedDocument($this->invoice->po_number); + $this->xrechnung->setDocumentBuyerOrderReferencedDocument($this->invoice->po_number); } if (empty($client->routing_id)) { - $xrechnung->setDocumentBuyerReference(ctrans("texts.xinvoice_no_buyers_reference")); + $this->xrechnung->setDocumentBuyerReference(ctrans("texts.xinvoice_no_buyers_reference")); } else { - $xrechnung->setDocumentBuyerReference($client->routing_id); + $this->xrechnung->setDocumentBuyerReference($client->routing_id); } if (!empty($client->shipping_address1)){ - $xrechnung->setDocumentShipToAddress($client->shipping_address1, $client->shipping_address2, "", $client->shipping_postal_code, $client->shipping_city, $client->shipping_country->iso_3166_2, $client->shipping_state); + $this->xrechnung->setDocumentShipToAddress($client->shipping_address1, $client->shipping_address2, "", $client->shipping_postal_code, $client->shipping_city, $client->shipping_country->iso_3166_2, $client->shipping_state); } - $xrechnung->addDocumentPaymentMean(68, ctrans("texts.xinvoice_online_payment")); + $this->xrechnung->addDocumentPaymentMean(68, ctrans("texts.xinvoice_online_payment")); if (str_contains($company->getSetting('vat_number'), "/")) { - $xrechnung->addDocumentSellerTaxRegistration("FC", $company->getSetting('vat_number')); + $this->xrechnung->addDocumentSellerTaxRegistration("FC", $company->getSetting('vat_number')); } else { - $xrechnung->addDocumentSellerTaxRegistration("VA", $company->getSetting('vat_number')); + $this->xrechnung->addDocumentSellerTaxRegistration("VA", $company->getSetting('vat_number')); } $invoicing_data = $this->invoice->calc(); @@ -92,29 +92,29 @@ class ZugferdEInvoice extends AbstractService //Create line items and calculate taxes foreach ($this->invoice->line_items as $index => $item) { /** @var \App\DataMapper\InvoiceItem $item **/ - $xrechnung->addNewPosition($index) + $this->xrechnung->addNewPosition($index) ->setDocumentPositionGrossPrice($item->gross_line_total) ->setDocumentPositionNetPrice($item->line_total); if (!empty($item->product_key)){ if (!empty($item->notes)){ - $xrechnung->setDocumentPositionProductDetails($item->product_key, $item->notes); + $this->xrechnung->setDocumentPositionProductDetails($item->product_key, $item->notes); } else { - $xrechnung->setDocumentPositionProductDetails($item->product_key); + $this->xrechnung->setDocumentPositionProductDetails($item->product_key); } } else { if (!empty($item->notes)){ - $xrechnung->setDocumentPositionProductDetails($item->notes); + $this->xrechnung->setDocumentPositionProductDetails($item->notes); } else { - $xrechnung->setDocumentPositionProductDetails("no product name defined"); + $this->xrechnung->setDocumentPositionProductDetails("no product name defined"); } } if (isset($item->task_id)) { - $xrechnung->setDocumentPositionQuantity($item->quantity, "HUR"); + $this->xrechnung->setDocumentPositionQuantity($item->quantity, "HUR"); } else { - $xrechnung->setDocumentPositionQuantity($item->quantity, "H87"); + $this->xrechnung->setDocumentPositionQuantity($item->quantity, "H87"); } $linenetamount = $item->line_total; if ($item->discount > 0) { @@ -124,18 +124,18 @@ class ZugferdEInvoice extends AbstractService $linenetamount -= $linenetamount * ($item->discount / 100); } } - $xrechnung->setDocumentPositionLineSummation($linenetamount); + $this->xrechnung->setDocumentPositionLineSummation($linenetamount); // According to european law, each line item can only have one tax rate if (!(empty($item->tax_name1) && empty($item->tax_name2) && empty($item->tax_name3))) { $taxtype = $this->getTaxType($item->tax_id); if (!empty($item->tax_name1)) { - $xrechnung->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate1); + $this->xrechnung->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate1); $this->addtoTaxMap($taxtype, $linenetamount, $item->tax_rate1); } elseif (!empty($item->tax_name2)) { - $xrechnung->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate2); + $this->xrechnung->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate2); $this->addtoTaxMap($taxtype, $linenetamount, $item->tax_rate2); } elseif (!empty($item->tax_name3)) { - $xrechnung->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate3); + $this->xrechnung->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate3); $this->addtoTaxMap($taxtype, $linenetamount, $item->tax_rate3); } else { nlog("Can't add correct tax position"); @@ -143,42 +143,45 @@ class ZugferdEInvoice extends AbstractService } else { if (!empty($this->invoice->tax_name1)) { $taxtype = $this->getTaxType($this->invoice->tax_name1); - $xrechnung->addDocumentPositionTax($taxtype, 'VAT', $this->invoice->tax_rate1); + $this->xrechnung->addDocumentPositionTax($taxtype, 'VAT', $this->invoice->tax_rate1); $this->addtoTaxMap($taxtype, $linenetamount, $this->invoice->tax_rate1); } elseif (!empty($this->invoice->tax_name2)) { $taxtype = $this->getTaxType($this->invoice->tax_name2); - $xrechnung->addDocumentPositionTax($taxtype, 'VAT', $this->invoice->tax_rate2); + $this->xrechnung->addDocumentPositionTax($taxtype, 'VAT', $this->invoice->tax_rate2); $this->addtoTaxMap($taxtype, $linenetamount, $this->invoice->tax_rate2); } elseif (!empty($this->invoice->tax_name3)) { $taxtype = $this->getTaxType($this->invoice->tax_name3); - $xrechnung->addDocumentPositionTax($taxtype, 'VAT', $this->invoice->tax_rate3); + $this->xrechnung->addDocumentPositionTax($taxtype, 'VAT', $this->invoice->tax_rate3); $this->addtoTaxMap($taxtype, $linenetamount, $this->invoice->tax_rate3); } else { $taxtype = ZugferdDutyTaxFeeCategories::ZERO_RATED_GOODS; - $xrechnung->addDocumentPositionTax($taxtype, 'VAT', 0); + $this->xrechnung->addDocumentPositionTax($taxtype, 'VAT', 0); $this->addtoTaxMap($taxtype, $linenetamount, 0); nlog("Can't add correct tax position"); } } } - $xrechnung->setDocumentSummation($this->invoice->amount, $this->invoice->balance, $invoicing_data->getSubTotal(), $invoicing_data->getTotalSurcharges(), $invoicing_data->getTotalDiscount(), $invoicing_data->getSubTotal(), $invoicing_data->getItemTotalTaxes(), 0.0, $this->invoice->amount-$this->invoice->balance); + $this->xrechnung->setDocumentSummation($this->invoice->amount, $this->invoice->balance, $invoicing_data->getSubTotal(), $invoicing_data->getTotalSurcharges(), $invoicing_data->getTotalDiscount(), $invoicing_data->getSubTotal(), $invoicing_data->getItemTotalTaxes(), 0.0, $this->invoice->amount-$this->invoice->balance); foreach ($this->tax_map as $item){ - $xrechnung->addDocumentTax($item["tax_type"], "VAT", $item["net_amount"], $item["tax_rate"]*$item["net_amount"], $item["tax_rate"]*100); - } - $disk = config('filesystems.default'); - - if (!Storage::disk($disk)->exists($client->e_invoice_filepath($this->invoice->invitations->first()))) { - Storage::makeDirectory($client->e_invoice_filepath($this->invoice->invitations->first())); + $this->xrechnung->addDocumentTax($item["tax_type"], "VAT", $item["net_amount"], $item["tax_rate"]*$item["net_amount"], $item["tax_rate"]*100); } - $xrechnung->writeFile(Storage::disk($disk)->path($client->e_invoice_filepath($this->invoice->invitations->first()) . $this->invoice->getFileName("xml"))); // The validity can be checked using https://portal3.gefeg.com/invoice/validation or https://e-rechnung.bayern.de/app/#/upload - if ($this->returnObject){ - return $xrechnung; - } - return $client->e_invoice_filepath($this->invoice->invitations->first()) . $this->invoice->getFileName("xml"); + return $this; + + } + + /** + * Returns the XML document + * in string format + * + * @return string + */ + public function getXml(): string + { + return $this->xrechnung->getContent(); } private function getTaxType($name): string diff --git a/app/Services/Invoice/GetInvoiceEInvoice.php b/app/Services/Invoice/GetInvoiceEInvoice.php deleted file mode 100644 index 0434b6917fd0..000000000000 --- a/app/Services/Invoice/GetInvoiceEInvoice.php +++ /dev/null @@ -1,52 +0,0 @@ -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(); - } - - $file_path = $this->invoice->client->e_invoice_filepath($this->invoice->invitations->first()). $this->invoice->getFileName("xml"); - - // $disk = 'public'; - $disk = config('filesystems.default'); - - $file = Storage::disk($disk)->exists($file_path); - - if (! $file) { - $file_path = (new CreateEInvoice($this->invoice))->handle(); - (new \App\Jobs\Invoice\MergeEInvoice($this->invoice))->handle(); - - } - return $file_path; - } -} diff --git a/app/Services/Invoice/GetInvoicePdf.php b/app/Services/Invoice/GetInvoicePdf.php index 8044e8a290d6..9211a15bb8fd 100644 --- a/app/Services/Invoice/GetInvoicePdf.php +++ b/app/Services/Invoice/GetInvoicePdf.php @@ -13,7 +13,6 @@ namespace App\Services\Invoice; use App\Jobs\Entity\CreateEntityPdf; use App\Jobs\Invoice\CreateEInvoice; -use App\Jobs\Invoice\MergeEInvoice; use App\Models\ClientContact; use App\Models\Invoice; use App\Services\AbstractService; @@ -49,10 +48,7 @@ class GetInvoicePdf extends AbstractService if (! $file) { $file_path = (new CreateEntityPdf($invitation))->handle(); } - if ($this->invoice->client->getSetting('enable_e_invoice')){ - (new CreateEInvoice($this->invoice))->handle(); - (new MergeEInvoice($this->invoice, $file_path))->handle(); - } + return $file_path; } } diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index d350d28a597c..148f0cae88d5 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -13,6 +13,7 @@ namespace App\Services\Invoice; use App\Events\Invoice\InvoiceWasArchived; use App\Jobs\Entity\CreateEntityPdf; +use App\Jobs\Entity\CreateRawPdf; use App\Jobs\Inventory\AdjustProductInventory; use App\Jobs\Invoice\CreateEInvoice; use App\Libraries\Currency\Conversion\CurrencyApi; @@ -187,6 +188,13 @@ class InvoiceService return (new GetInvoicePdf($this->invoice, $contact))->run(); } + public function getRawInvoicePdf($contact = null) + { + $invitation = $contact ? $this->invoice->invitations()->where('contact_id', $contact->id)->first() : $this->invoice->invitations()->first(); + + return (new CreateRawPdf($invitation, $invitation->company->db))->handle(); + } + public function getInvoiceDeliveryNote(Invoice $invoice, \App\Models\ClientContact $contact = null) { return (new GenerateDeliveryNote($invoice, $contact))->run(); @@ -194,13 +202,9 @@ class InvoiceService public function getEInvoice($contact = null) { - return (new GetInvoiceEInvoice($this->invoice, $contact))->run(); + return (new CreateEInvoice($this->invoice))->handle(); } - public function mergeEInvoice($contact = null): void - { - (new MergeEInvoice($this->invoice, $contact))->run(); - } public function sendEmail($contact = null) { $send_email = new SendEmail($this->invoice, null, $contact); @@ -464,13 +468,6 @@ class InvoiceService if ($force) { $this->invoice->invitations->each(function ($invitation) { (new CreateEntityPdf($invitation))->handle(); - - if ($invitation->invoice->client->getSetting('enable_e_invoice') && $invitation instanceof InvoiceInvitation) - { - (new CreateEInvoice($invitation->invoice))->handle(); - (new MergeEInvoice($invitation->invoice))->run(); - } - }); return $this; diff --git a/app/Services/Invoice/MergeEInvoice.php b/app/Services/Invoice/MergeEInvoice.php deleted file mode 100644 index ad80c49cd821..000000000000 --- a/app/Services/Invoice/MergeEInvoice.php +++ /dev/null @@ -1,29 +0,0 @@ -pdf_path)) { - (new \App\Jobs\Invoice\MergeEInvoice($this->invoice, $this->pdf_path))->handle(); - } - else { - (new \App\Jobs\Invoice\MergeEInvoice($this->invoice))->handle(); - } - - } -} diff --git a/app/Utils/Traits/Inviteable.php b/app/Utils/Traits/Inviteable.php index ed7c7056845c..13a161462aae 100644 --- a/app/Utils/Traits/Inviteable.php +++ b/app/Utils/Traits/Inviteable.php @@ -79,7 +79,7 @@ trait Inviteable if (Ninja::isHosted()) { $domain = $this->company->domain(); } else { - $domain = strlen($this->company->portal_domain) > 5 ? $this->company->portal_domain : config('ninja.app_url'); + $domain = strlen($this->company->portal_domain ?? '') > 5 ? $this->company->portal_domain : config('ninja.app_url'); } $entity_type = Str::snake(class_basename($this->entityType())); @@ -94,7 +94,7 @@ trait Inviteable if (Ninja::isHosted()) { $domain = $this->company->domain(); } else { - $domain = strlen($this->company->portal_domain) > 5 ? $this->company->portal_domain : config('ninja.app_url'); + $domain = strlen($this->company->portal_domain ?? '') > 5 ? $this->company->portal_domain : config('ninja.app_url'); } switch ($this->company->portal_mode) { @@ -119,7 +119,7 @@ trait Inviteable if (Ninja::isHosted()) { $domain = $this->company->domain(); } else { - $domain = strlen($this->company->portal_domain) > 5 ? $this->company->portal_domain : config('ninja.app_url'); + $domain = strlen($this->company->portal_domain ?? '') > 5 ? $this->company->portal_domain : config('ninja.app_url'); } switch ($this->company->portal_mode) { diff --git a/composer.lock b/composer.lock index 3d3cb2598a93..2be5001245e6 100644 --- a/composer.lock +++ b/composer.lock @@ -424,16 +424,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.278.3", + "version": "3.279.0", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "596534c0627d8b38597061341e99b460437d1a16" + "reference": "7b3d38cfccd393add0ea0ce281de91846967c61e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/596534c0627d8b38597061341e99b460437d1a16", - "reference": "596534c0627d8b38597061341e99b460437d1a16", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7b3d38cfccd393add0ea0ce281de91846967c61e", + "reference": "7b3d38cfccd393add0ea0ce281de91846967c61e", "shasum": "" }, "require": { @@ -442,11 +442,11 @@ "ext-pcre": "*", "ext-simplexml": "*", "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", - "guzzlehttp/promises": "^1.4.0", + "guzzlehttp/promises": "^1.4.0 || ^2.0", "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", "mtdowling/jmespath.php": "^2.6", - "php": ">=5.5", - "psr/http-message": "^1.0" + "php": ">=7.2.5", + "psr/http-message": "^1.0 || ^2.0" }, "require-dev": { "andrewsville/php-token-reflection": "^1.4", @@ -461,7 +461,7 @@ "ext-sockets": "*", "nette/neon": "^2.3", "paragonie/random_compat": ">= 2", - "phpunit/phpunit": "^4.8.35 || ^5.6.3 || ^9.5", + "phpunit/phpunit": "^5.6.3 || ^8.5 || ^9.5", "psr/cache": "^1.0", "psr/simple-cache": "^1.0", "sebastian/comparator": "^1.2.3 || ^4.0", @@ -513,9 +513,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.278.3" + "source": "https://github.com/aws/aws-sdk-php/tree/3.279.0" }, - "time": "2023-08-15T18:07:55+00:00" + "time": "2023-08-16T18:18:34+00:00" }, { "name": "bacon/bacon-qr-code", @@ -2832,29 +2832,33 @@ }, { "name": "guzzlehttp/promises", - "version": "1.5.3", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" + "reference": "111166291a0f8130081195ac4556a5587d7f1b5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "url": "https://api.github.com/repos/guzzle/promises/zipball/111166291a0f8130081195ac4556a5587d7f1b5d", + "reference": "111166291a0f8130081195ac4556a5587d7f1b5d", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" + "bamarni/composer-bin-plugin": "^1.8.1", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\Promise\\": "src/" } @@ -2891,7 +2895,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.3" + "source": "https://github.com/guzzle/promises/tree/2.0.1" }, "funding": [ { @@ -2907,7 +2911,7 @@ "type": "tidelift" } ], - "time": "2023-05-21T12:31:43+00:00" + "time": "2023-08-03T15:11:55+00:00" }, { "name": "guzzlehttp/psr7", @@ -3344,16 +3348,16 @@ }, { "name": "horstoeko/zugferd", - "version": "v1.0.20", + "version": "v1.0.23", "source": { "type": "git", "url": "https://github.com/horstoeko/zugferd.git", - "reference": "725c130ec0a09d72cf54b3d819840f3959a5502c" + "reference": "bb55417be4c4de8deb0113e832feeaf7b4d3984e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/horstoeko/zugferd/zipball/725c130ec0a09d72cf54b3d819840f3959a5502c", - "reference": "725c130ec0a09d72cf54b3d819840f3959a5502c", + "url": "https://api.github.com/repos/horstoeko/zugferd/zipball/bb55417be4c4de8deb0113e832feeaf7b4d3984e", + "reference": "bb55417be4c4de8deb0113e832feeaf7b4d3984e", "shasum": "" }, "require": { @@ -3411,9 +3415,9 @@ ], "support": { "issues": "https://github.com/horstoeko/zugferd/issues", - "source": "https://github.com/horstoeko/zugferd/tree/v1.0.20" + "source": "https://github.com/horstoeko/zugferd/tree/v1.0.23" }, - "time": "2023-07-04T15:21:32+00:00" + "time": "2023-08-16T17:39:36+00:00" }, { "name": "http-interop/http-factory-guzzle", @@ -5860,16 +5864,16 @@ }, { "name": "moneyphp/money", - "version": "v4.1.1", + "version": "v4.2.0", "source": { "type": "git", "url": "https://github.com/moneyphp/money.git", - "reference": "9682220995ffd396843be5b4ee1e5f2c2d6ecee2" + "reference": "f660ab7f1d7a4c2ffdd30f50c55ed2c95c26fc3f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/moneyphp/money/zipball/9682220995ffd396843be5b4ee1e5f2c2d6ecee2", - "reference": "9682220995ffd396843be5b4ee1e5f2c2d6ecee2", + "url": "https://api.github.com/repos/moneyphp/money/zipball/f660ab7f1d7a4c2ffdd30f50c55ed2c95c26fc3f", + "reference": "f660ab7f1d7a4c2ffdd30f50c55ed2c95c26fc3f", "shasum": "" }, "require": { @@ -5943,9 +5947,9 @@ ], "support": { "issues": "https://github.com/moneyphp/money/issues", - "source": "https://github.com/moneyphp/money/tree/v4.1.1" + "source": "https://github.com/moneyphp/money/tree/v4.2.0" }, - "time": "2023-04-11T09:18:34+00:00" + "time": "2023-08-16T14:31:24+00:00" }, { "name": "monolog/monolog", @@ -6248,25 +6252,29 @@ }, { "name": "nesbot/carbon", - "version": "2.68.1", + "version": "2.69.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "4f991ed2a403c85efbc4f23eb4030063fdbe01da" + "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4f991ed2a403c85efbc4f23eb4030063fdbe01da", - "reference": "4f991ed2a403c85efbc4f23eb4030063fdbe01da", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4308217830e4ca445583a37d1bf4aff4153fa81c", + "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c", "shasum": "" }, "require": { "ext-json": "*", "php": "^7.1.8 || ^8.0", + "psr/clock": "^1.0", "symfony/polyfill-mbstring": "^1.0", "symfony/polyfill-php80": "^1.16", "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" }, + "provide": { + "psr/clock-implementation": "1.0" + }, "require-dev": { "doctrine/dbal": "^2.0 || ^3.1.4", "doctrine/orm": "^2.7", @@ -6346,7 +6354,7 @@ "type": "tidelift" } ], - "time": "2023-06-20T18:29:04+00:00" + "time": "2023-08-03T09:00:52+00:00" }, { "name": "nette/schema", diff --git a/phpstan.neon b/phpstan.neon index ff93e96cc5b3..6bc4f9205594 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -13,6 +13,7 @@ parameters: - 'app/DataMapper/Analytics/*' - 'app/PaymentDrivers/Authorize/*' - 'app/Utils/Traits/*' + - 'resources/views/*' universalObjectCratesClasses: - App\DataMapper\Tax\RuleInterface - App\DataMapper\FeesAndLimits diff --git a/resources/views/portal/ninja2020/components/livewire/pdf-slot.blade.php b/resources/views/portal/ninja2020/components/livewire/pdf-slot.blade.php index 290de387db96..d15f748c6e23 100644 --- a/resources/views/portal/ninja2020/components/livewire/pdf-slot.blade.php +++ b/resources/views/portal/ninja2020/components/livewire/pdf-slot.blade.php @@ -1,5 +1,5 @@