From 9fc9ab933d787e65e99bc4dc31bbbdbce24255b7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 15 Oct 2025 11:08:10 +1100 Subject: [PATCH] Updates for logic with Verifactu --- .../Invoice/VerifactuAmountCheck.php | 21 +++++++++++-------- .../Validation/Verifactu/InvoiceValidator.php | 4 ++-- .../Standards/Verifactu/Models/Invoice.php | 4 ++-- app/Services/Invoice/HandleCancellation.php | 18 ++++++++-------- app/Services/Invoice/InvoiceService.php | 2 +- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/app/Http/ValidationRules/Invoice/VerifactuAmountCheck.php b/app/Http/ValidationRules/Invoice/VerifactuAmountCheck.php index 36c52375b1..2db7a1f25d 100644 --- a/app/Http/ValidationRules/Invoice/VerifactuAmountCheck.php +++ b/app/Http/ValidationRules/Invoice/VerifactuAmountCheck.php @@ -76,7 +76,8 @@ class VerifactuAmountCheck implements ValidationRule $fail("Invoice already credited in full"); } - \DB::connection(config('database.default'))->beginTransaction(); + // \DB::connection(config('database.default'))->beginTransaction(); + $array_data = request()->all(); unset($array_data['client_id']); @@ -84,7 +85,7 @@ class VerifactuAmountCheck implements ValidationRule $invoice->fill($array_data); /** Calculate the gross total of the cancellation invoice. */ - $total = $invoice->calc()->getTotal(); + // $total = $invoice->calc()->getTotal(); // $items = $array_data['line_items']; @@ -106,10 +107,12 @@ class VerifactuAmountCheck implements ValidationRule // $invoice->line_items = $items; - // /** Total WITHOUT IRPF */ - // $ex_iprf_total = $invoice->calc()->getTotal(); + /** Total WITHOUT IRPF */ + $total = $invoice->calc()->getTotal(); - \DB::connection(config('database.default'))->rollBack(); + $invoice->refresh(); + + // \DB::connection(config('database.default'))->rollBack(); if($total > 0) { $fail("Only negative invoices can rectify a invoice."); @@ -119,18 +122,18 @@ class VerifactuAmountCheck implements ValidationRule $adjustable_amount = $invoice->backup->adjustable_amount - $child_invoices_sum; /** The client facing amount that can be cancelled This is the amount that will NOT contain IRPF amounts */ - $client_facing_adjustable_amount = ($child_invoices_sum / $invoice->backup->adjustable_amount) * $total; + $client_facing_adjustable_amount = ($invoice->amount / $invoice->backup->adjustable_amount) * $adjustable_amount; nlog("total: " . $total); + nlog("invoice->amount: " . $invoice->amount); nlog("adjustable_amount: " . $adjustable_amount); nlog("child_invoices_sum: " . $child_invoices_sum); nlog("invoice->backup->adjustable_amount: " . $invoice->backup->adjustable_amount); nlog("client_facing_adjustable_amount: " . $client_facing_adjustable_amount); - if(abs($total) > $adjustable_amount) { - $total = abs($total); // The rectification invoice amount cannot be greater than the original invoice amount - $fail("Total de ajuste {$client_facing_adjustable_amount} no puede exceder el saldo de la factura {$total}"); + if(abs($total) > $client_facing_adjustable_amount) { + $fail("Total de ajuste {$total} no puede exceder el saldo de la factura {$client_facing_adjustable_amount}"); } } diff --git a/app/Services/EDocument/Standards/Validation/Verifactu/InvoiceValidator.php b/app/Services/EDocument/Standards/Validation/Verifactu/InvoiceValidator.php index 3462fd10c3..fde3ba640e 100644 --- a/app/Services/EDocument/Standards/Validation/Verifactu/InvoiceValidator.php +++ b/app/Services/EDocument/Standards/Validation/Verifactu/InvoiceValidator.php @@ -139,8 +139,8 @@ class InvoiceValidator $errors = []; // Check for required fields based on invoice type - if ($invoice->getTipoFactura() === 'R2' && !$invoice->getTipoRectificativa()) { - $errors[] = "Rectification invoices (R2) must specify TipoRectificativa"; + if (in_array($invoice->getTipoFactura(), ['R1','R2']) && !$invoice->getTipoRectificativa()) { + $errors[] = "Rectification invoices (R1/R2) must specify TipoRectificativa"; } // Check for simplified invoice requirements diff --git a/app/Services/EDocument/Standards/Verifactu/Models/Invoice.php b/app/Services/EDocument/Standards/Verifactu/Models/Invoice.php index 7030821f79..39f83b7c05 100644 --- a/app/Services/EDocument/Standards/Verifactu/Models/Invoice.php +++ b/app/Services/EDocument/Standards/Verifactu/Models/Invoice.php @@ -779,12 +779,12 @@ class Invoice extends BaseXmlModel implements XmlModelInterface $root->appendChild($this->createElement($doc, 'TipoFactura', $this->tipoFactura)); // 5. TipoRectificativa (only for R1 invoices) - if (in_array($this->tipoFactura, [self::TIPO_FACTURA_SUSTITUIDA, self::TIPO_FACTURA_RECTIFICATIVA]) && $this->tipoRectificativa !== null) { + if (in_array($this->tipoFactura, [self::TIPO_FACTURA_SUSTITUIDA, self::TIPO_FACTURA_RECTIFICATIVA, self::TIPO_FACTURA_RECTIFICATIVA_PARTIAL]) && $this->tipoRectificativa !== null) { $root->appendChild($this->createElement($doc, 'TipoRectificativa', $this->tipoRectificativa)); } // 6. FacturasRectificadas (only for R1 invoices) - if ($this->tipoFactura === self::TIPO_FACTURA_RECTIFICATIVA && $this->facturasRectificadas !== null) { + if (in_array($this->tipoFactura, [self::TIPO_FACTURA_RECTIFICATIVA_PARTIAL, self::TIPO_FACTURA_RECTIFICATIVA]) && $this->facturasRectificadas !== null) { $facturasRectificadasElement = $this->createElement($doc, 'FacturasRectificadas'); foreach ($this->facturasRectificadas as $facturaRectificada) { diff --git a/app/Services/Invoice/HandleCancellation.php b/app/Services/Invoice/HandleCancellation.php index 96d36e28dc..bc321ed60f 100644 --- a/app/Services/Invoice/HandleCancellation.php +++ b/app/Services/Invoice/HandleCancellation.php @@ -83,19 +83,19 @@ class HandleCancellation extends AbstractService $this->invoice->service()->workFlow()->save(); // R2 Cancellation - do not create a separate document - if($this->invoice->backup->document_type === 'R2'){ // You cannot cancel a cancellation!!!!! + if(in_array($this->invoice->backup->document_type, ['R1','R2'])){ // You cannot cancel a cancellation!!!!! - $parent = Invoice::withTrashed()->find($this->decodePrimaryKey($this->invoice->backup->parent_invoice_id)); + // empty catch + // $parent = Invoice::withTrashed()->find($this->decodePrimaryKey($this->invoice->backup->parent_invoice_id)); - if(!$parent) { - return $this->invoice; - } + // if(!$parent) { + // return $this->invoice; + // } - $parent->backup->adjustable_amount -= $this->invoice->amount; - $parent->backup->child_invoice_ids->reject(fn($id) => $id === $this->invoice->hashed_id); - $parent->save(); + // $parent->backup->child_invoice_ids->reject(fn($id) => $id === $this->invoice->hashed_id); + // $parent->save(); - $this->invoice->service()->cancelVerifactu(); + // $this->invoice->service()->cancelVerifactu(); } else { $replicated_invoice = $this->invoice->replicate(); diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index e4b1b31064..c3cddf5910 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -753,7 +753,7 @@ class InvoiceService ->get() ->sum('backup.adjustable_amount'); - //@modified->amount may not have the correct totals due to IRPF. + //@todo verifactu - this won't be accurate as the invoice->amount will be the ex IPRF amount. modified->amount may not have the correct totals due to IRPF. if(\App\Utils\BcMath::greaterThan(abs($child_invoice_amounts), $modified_invoice->amount)) { $modified_invoice->status_id = Invoice::STATUS_CANCELLED; $modified_invoice->saveQuietly();