Intercept reason for rectification

This commit is contained in:
David Bomba 2025-10-16 14:27:48 +11:00
parent ef5b692424
commit c0db1de1de
10 changed files with 49 additions and 63 deletions

View File

@ -59,6 +59,7 @@ class InvoiceBackupCast implements CastsAttributes
'child_invoice_ids' => $value->child_invoice_ids->toArray(), 'child_invoice_ids' => $value->child_invoice_ids->toArray(),
'redirect' => $value->redirect, 'redirect' => $value->redirect,
'adjustable_amount' => $value->adjustable_amount, 'adjustable_amount' => $value->adjustable_amount,
'notes' => $value->notes,
]) ])
]; ];
} }

View File

@ -31,6 +31,7 @@ class InvoiceBackup implements Castable
* @param Collection $child_invoice_ids The collection of child invoice IDs * @param Collection $child_invoice_ids The collection of child invoice IDs
* @param string $redirect The redirect url for the invoice * @param string $redirect The redirect url for the invoice
* @param float $adjustable_amount The adjustable amount for the invoice * @param float $adjustable_amount The adjustable amount for the invoice
* @param string $notes The notes field - can be multi purpose, but general usage for Verifactu cancellation reason
* @return void * @return void
*/ */
public function __construct( public function __construct(
@ -42,6 +43,7 @@ class InvoiceBackup implements Castable
public Collection $child_invoice_ids = new Collection(), public Collection $child_invoice_ids = new Collection(),
public ?string $redirect = null, public ?string $redirect = null,
public float $adjustable_amount = 0, public float $adjustable_amount = 0,
public ?string $notes = null,
) {} ) {}
/** /**
@ -65,6 +67,7 @@ class InvoiceBackup implements Castable
child_invoice_ids: isset($data['child_invoice_ids']) ? collect($data['child_invoice_ids']) : new Collection(), child_invoice_ids: isset($data['child_invoice_ids']) ? collect($data['child_invoice_ids']) : new Collection(),
redirect: $data['redirect'] ?? null, redirect: $data['redirect'] ?? null,
adjustable_amount: $data['adjustable_amount'] ?? 0, adjustable_amount: $data['adjustable_amount'] ?? 0,
notes: $data['notes'] ?? null,
); );
} }

View File

@ -18,7 +18,6 @@ use App\Utils\Traits\MakesHash;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use App\Utils\Traits\CleanLineItems; use App\Utils\Traits\CleanLineItems;
use App\Http\ValidationRules\Project\ValidProjectForClient; use App\Http\ValidationRules\Project\ValidProjectForClient;
use App\Http\ValidationRules\Invoice\CanGenerateModificationInvoice;
use App\Http\ValidationRules\Invoice\VerifactuAmountCheck; use App\Http\ValidationRules\Invoice\VerifactuAmountCheck;
class StoreInvoiceRequest extends Request class StoreInvoiceRequest extends Request

View File

@ -66,8 +66,6 @@ class VerifactuDocumentValidator extends XsltDocumentValidator
// Detect document type to determine which validation to apply // Detect document type to determine which validation to apply
$documentType = $this->detectDocumentType($businessContent); $documentType = $this->detectDocumentType($businessContent);
nlog("Detected document type: " . $documentType);
// For modifications, we need to use a different validation approach // For modifications, we need to use a different validation approach
// since the standard XSD doesn't support modification structure // since the standard XSD doesn't support modification structure
if ($documentType === 'modification') { if ($documentType === 'modification') {

View File

@ -190,8 +190,6 @@ class Verifactu extends AbstractService
public function calculateQrCode(VerifactuLog $log) public function calculateQrCode(VerifactuLog $log)
{ {
nlog($log->toArray());
try{ try{
$csv = $log->status; $csv = $log->status;
$nif = $log->nif; $nif = $log->nif;
@ -222,35 +220,18 @@ class Verifactu extends AbstractService
return $result->getString(); return $result->getString();
} catch (\Exception $e) { } catch (\Exception $e) {
nlog($e->getMessage()); nlog("VERIFACTU ERROR: [qr]" . $e->getMessage());
return ''; return '';
} }
} }
public function send(string $soapXml): array public function send(string $soapXml): array
{ {
nlog(["sending", $soapXml]); nlog("VERIFACTU: [send]" . $soapXml);
$response = $this->aeat_client->send($soapXml); $response = $this->aeat_client->send($soapXml);
if($response['success'] || $response['status'] == 'ParcialmenteCorrecto'){ if($response['success'] || $response['status'] == 'ParcialmenteCorrecto'){
// if($this->invoice->backup->document_type == 'F1'){
// $this->invoice->backup->adjustable_amount = $this->registro_alta->calc->getTotal();
// $this->invoice->saveQuietly();
// }
// elseif(in_array($this->invoice->backup->document_type, ['R1','R2'])){
// // $_parent = Invoice::withTrashed()->find($this->decodePrimaryKey($this->invoice->backup->parent_invoice_id));
// // if($_parent){
// // $_parent->backup->adjustable_amount += $this->registro_alta->calc->getTotal();
// // $_parent->saveQuietly();
// // }
// $this->invoice->backup->adjustable_amount = $this->registro_alta->calc->getTotal();
// $this->invoice->saveQuietly();
// //@todo calculate if the invoice has been fully cancelled, if it has tag it as CANCELLED
// }
$this->writeLog($response); $this->writeLog($response);
} }

View File

@ -333,9 +333,6 @@ class RegistroAlta
throw new \Exception('Parent invoice not found'); throw new \Exception('Parent invoice not found');
} }
nlog("invoice amount: " . $this->invoice->amount);
nlog("parent invoice amount: " . $_i->amount);
if(BcMath::lessThan(abs($this->invoice->amount), $_i->amount)) { if(BcMath::lessThan(abs($this->invoice->amount), $_i->amount)) {
$document_type = 'R1'; $document_type = 'R1';
} }
@ -343,6 +340,9 @@ class RegistroAlta
$this->v_invoice->setTipoFactura($document_type); $this->v_invoice->setTipoFactura($document_type);
$this->v_invoice->setTipoRectificativa('I'); // S for substitutive rectification $this->v_invoice->setTipoRectificativa('I'); // S for substitutive rectification
if(strlen($this->invoice->backup->notes ?? '') > 0) {
$this->v_invoice->setDescripcionOperacion($this->invoice->backup->notes);
}
// Set up rectified invoice information // Set up rectified invoice information
$facturasRectificadas = [ $facturasRectificadas = [
[ [

View File

@ -113,6 +113,7 @@ class HandleCancellation extends AbstractService
$replicated_invoice->backup->parent_invoice_id = $this->invoice->hashed_id; $replicated_invoice->backup->parent_invoice_id = $this->invoice->hashed_id;
$replicated_invoice->backup->parent_invoice_number = $this->invoice->number; $replicated_invoice->backup->parent_invoice_number = $this->invoice->number;
$replicated_invoice->backup->document_type = 'R2'; // Full Credit Note Generated for the invoice $replicated_invoice->backup->document_type = 'R2'; // Full Credit Note Generated for the invoice
$replicated_invoice->backup->notes = $this->reason;
$invoice_repository = new InvoiceRepository(); $invoice_repository = new InvoiceRepository();
$replicated_invoice = $invoice_repository->save([], $replicated_invoice); $replicated_invoice = $invoice_repository->save([], $replicated_invoice);

View File

@ -720,9 +720,7 @@ class InvoiceService
* *
*/ */
/** New Invoice - F1 Type */ /** New Invoice - F1 Type */
if(empty($this->invoice->client->vat_number) || if(empty($this->invoice->client->vat_number) || !in_array($this->invoice->client->country->iso_3166_2, (new \App\DataMapper\Tax\BaseRule())->eu_country_codes)) {
!in_array($this->invoice->client->country->iso_3166_2, (new \App\DataMapper\Tax\BaseRule())->eu_country_codes)
) {
$this->invoice->backup->guid = 'exempt'; $this->invoice->backup->guid = 'exempt';
$this->invoice->saveQuietly(); $this->invoice->saveQuietly();
@ -749,6 +747,11 @@ class InvoiceService
} }
$modified_invoice->backup->child_invoice_ids->push($this->invoice->hashed_id); $modified_invoice->backup->child_invoice_ids->push($this->invoice->hashed_id);
if(isset($invoice_array['reason'])) {
$this->invoice->backup->notes = $invoice_array['reason'];
}
$modified_invoice->save(); $modified_invoice->save();
$this->markSent(); $this->markSent();

View File

@ -857,12 +857,12 @@ Motivo de la rectificación: Corrección de base imponible<br/>
Tipo de rectificación: I (Por diferencias)\n Tipo de rectificación: I (Por diferencias)\n
Código seguro de verificación (CSV): {$verifactu_log->status}"; Código seguro de verificación (CSV): {$verifactu_log->status}";
$text = match($this->entity->backup->document_type) { $text = match($this->entity->backup->document_type) {
'F1' => $f1_text, 'F1' => $f1_text,
'R2' => $r2_text,
'R1' => $r1_text, 'R1' => $r1_text,
'R2' => $r2_text,
default => '', default => '',
}; };
return "<tr><td>{$text}</td></tr><tr><td><img src=\"data:image/png;base64,{$qr_code}\" alt=\"Verifactu QR Code\"></td></tr>"; return "<tr><td>{$text}</td></tr><tr><td><img src=\"data:image/png;base64,{$qr_code}\" alt=\"Verifactu QR Code\"></td></tr>";
} }