Refactor to use generate parent/child ids

This commit is contained in:
David Bomba 2025-08-12 12:29:36 +10:00
parent 1836ccc434
commit 8d23ba14d4
5 changed files with 60 additions and 42 deletions

View File

@ -46,14 +46,11 @@ class InvoiceBackupCast implements CastsAttributes
'adjustment' => $value->cancellation->adjustment, 'adjustment' => $value->cancellation->adjustment,
'status_id' => $value->cancellation->status_id, 'status_id' => $value->cancellation->status_id,
] : [], ] : [],
'cancelled_invoice_id' => $value->cancelled_invoice_id, 'parent_invoice_id' => $value->parent_invoice_id,
'cancelled_invoice_number' => $value->cancelled_invoice_number, 'parent_invoice_number' => $value->parent_invoice_number,
'cancellation_reason' => $value->cancellation_reason, 'reason' => $value->reason,
'credit_invoice_id' => $value->credit_invoice_id, 'child_invoice_ids' => $value->child_invoice_ids->toArray(),
'credit_invoice_number' => $value->credit_invoice_number,
'redirect' => $value->redirect, 'redirect' => $value->redirect,
'modified_invoice_id' => $value->modified_invoice_id,
'replaced_invoice_id' => $value->replaced_invoice_id,
]) ])
]; ];
} }

View File

@ -15,6 +15,7 @@ namespace App\DataMapper;
use App\Casts\InvoiceBackupCast; use App\Casts\InvoiceBackupCast;
use App\DataMapper\Cancellation; use App\DataMapper\Cancellation;
use Illuminate\Contracts\Database\Eloquent\Castable; use Illuminate\Contracts\Database\Eloquent\Castable;
use Illuminate\Support\Collection;
/** /**
* InvoiceBackup. * InvoiceBackup.
@ -24,14 +25,11 @@ class InvoiceBackup implements Castable
public function __construct( public function __construct(
public string $guid = '', // The E-INVOICE SENT GUID reference public string $guid = '', // The E-INVOICE SENT GUID reference
public Cancellation $cancellation = new Cancellation(0,0), public Cancellation $cancellation = new Cancellation(0,0),
public ?string $cancelled_invoice_id = null, // The id of the invoice that was cancelled public ?string $parent_invoice_id = null, // The id of the invoice that was cancelled
public ?string $cancelled_invoice_number = null, // The number of the invoice that was cancelled public ?string $parent_invoice_number = null, // The number of the invoice that was cancelled
public ?string $cancellation_reason = null, // The reason for the cancellation public ?string $reason = null, // The reason for the cancellation
public ?string $credit_invoice_id = null, // The id of the credit invoice that was created public Collection $child_invoice_ids = new Collection(), // Collection of child invoice IDs
public ?string $credit_invoice_number = null, // The number of the credit invoice that was created
public ?string $redirect = null, // The redirect url for the invoice public ?string $redirect = null, // The redirect url for the invoice
public ?string $modified_invoice_id = null, // The id of the modified invoice (replaces the invoice with replaced_invoice_id)
public ?string $replaced_invoice_id = null // The id of the replaced invoice (The previous invoice that was replaced by the modified invoice)
) {} ) {}
/** /**
@ -49,15 +47,44 @@ class InvoiceBackup implements Castable
return new self( return new self(
guid: $data['guid'] ?? '', guid: $data['guid'] ?? '',
cancellation: Cancellation::fromArray($data['cancellation'] ?? []), cancellation: Cancellation::fromArray($data['cancellation'] ?? []),
cancelled_invoice_id: $data['cancelled_invoice_id'] ?? null, parent_invoice_id: $data['parent_invoice_id'] ?? null,
cancelled_invoice_number: $data['cancelled_invoice_number'] ?? null, parent_invoice_number: $data['parent_invoice_number'] ?? null,
cancellation_reason: $data['cancellation_reason'] ?? null, reason: $data['reason'] ?? null,
credit_invoice_id: $data['credit_invoice_id'] ?? null, child_invoice_ids: isset($data['child_invoice_ids']) ? collect($data['child_invoice_ids']) : new Collection(),
credit_invoice_number: $data['credit_invoice_number'] ?? null, redirect: $data['redirect'] ?? null
redirect: $data['redirect'] ?? null,
modified_invoice_id: $data['modified_invoice_id'] ?? null,
replaced_invoice_id: $data['replaced_invoice_id'] ?? null
); );
} }
/**
* Add a child invoice ID to the collection
*/
public function addChildInvoiceId(string $invoiceId): void
{
$this->child_invoice_ids->push($invoiceId);
}
/**
* Remove a child invoice ID from the collection
*/
public function removeChildInvoiceId(string $invoiceId): void
{
$this->child_invoice_ids = $this->child_invoice_ids->reject($invoiceId);
}
/**
* Check if a child invoice ID exists
*/
public function hasChildInvoiceId(string $invoiceId): bool
{
return $this->child_invoice_ids->contains($invoiceId);
}
/**
* Get all child invoice IDs as an array
*/
public function getChildInvoiceIds(): array
{
return $this->child_invoice_ids->toArray();
}
} }

View File

@ -86,17 +86,15 @@ class HandleCancellation extends AbstractService
} }
$replicated_invoice->line_items = $items; $replicated_invoice->line_items = $items;
$replicated_invoice->backup->cancelled_invoice_id = $this->invoice->hashed_id; $replicated_invoice->backup->parent_invoice_id = $this->invoice->hashed_id;
$replicated_invoice->backup->cancelled_invoice_number = $this->invoice->number; $replicated_invoice->backup->parent_invoice_number = $this->invoice->number;
$replicated_invoice->backup->cancellation_reason = $this->reason ?? 'R3'; $replicated_invoice->backup->reason = $this->reason ?? 'R3';
$invoice_repository = new InvoiceRepository(); $invoice_repository = new InvoiceRepository();
$replicated_invoice = $invoice_repository->save([], $replicated_invoice); $replicated_invoice = $invoice_repository->save([], $replicated_invoice);
$replicated_invoice->service()->markSent()->sendVerifactu()->save(); $replicated_invoice->service()->markSent()->sendVerifactu()->save();
$this->invoice->backup->credit_invoice_id = $replicated_invoice->hashed_id; $this->invoice->backup->child_invoice_ids->push($replicated_invoice->hashed_id);
$this->invoice->backup->credit_invoice_number = $replicated_invoice->number;
$this->invoice->backup->cancellation_reason = $this->reason ?? 'R3';
$this->invoice->saveQuietly(); $this->invoice->saveQuietly();
$this->invoice->fresh(); $this->invoice->fresh();

View File

@ -727,12 +727,12 @@ class InvoiceService
$modified_invoice->status_id = Invoice::STATUS_REPLACED; $modified_invoice->status_id = Invoice::STATUS_REPLACED;
} }
$modified_invoice->backup->modified_invoice_id = $this->invoice->hashed_id; $modified_invoice->backup->child_invoice_ids->push($this->invoice->hashed_id);
$modified_invoice->save(); $modified_invoice->save();
$this->markSent(); $this->markSent();
//Update the client balance by the delta amount from the previous invoice to this one. //Update the client balance by the delta amount from the previous invoice to this one.
$this->invoice->backup->replaced_invoice_id = $modified_invoice->hashed_id; $this->invoice->backup->parent_invoice_id = $modified_invoice->hashed_id;
$this->invoice->saveQuietly(); $this->invoice->saveQuietly();
$this->invoice->client->service()->updateBalance(round(($this->invoice->amount - $modified_invoice->amount), 2)); $this->invoice->client->service()->updateBalance(round(($this->invoice->amount - $modified_invoice->amount), 2));

View File

@ -109,8 +109,6 @@ class VerifactuApiTest extends TestCase
$this->assertEquals(121, $invoice->balance); $this->assertEquals(121, $invoice->balance);
$this->assertEquals(131, $this->client->fresh()->balance); $this->assertEquals(131, $this->client->fresh()->balance);
$this->assertNull($invoice->backup->modified_invoice_id);
$invoice2 = $this->buildData(); $invoice2 = $this->buildData();
$items = $invoice2->line_items; $items = $invoice2->line_items;
@ -140,12 +138,12 @@ class VerifactuApiTest extends TestCase
$this->assertEquals($arr['data']['status_id'], Invoice::STATUS_SENT); $this->assertEquals($arr['data']['status_id'], Invoice::STATUS_SENT);
$this->assertEquals($arr['data']['amount'], 242); $this->assertEquals($arr['data']['amount'], 242);
$this->assertEquals($arr['data']['balance'], 242); $this->assertEquals($arr['data']['balance'], 242);
$this->assertEquals($arr['data']['backup']['replaced_invoice_id'], $invoice->hashed_id); $this->assertEquals($arr['data']['backup']['parent_invoice_id'], $invoice->hashed_id);
$invoice = $invoice->fresh(); $invoice = $invoice->fresh();
$this->assertEquals(Invoice::STATUS_REPLACED, $invoice->status_id); $this->assertEquals(Invoice::STATUS_REPLACED, $invoice->status_id);
$this->assertEquals($arr['data']['id'], $invoice->backup->modified_invoice_id); $this->assertTrue($invoice->backup->child_invoice_ids->contains($arr['data']['id']));
$this->assertEquals(615, $this->client->fresh()->balance); $this->assertEquals(615, $this->client->fresh()->balance);
@ -283,24 +281,22 @@ class VerifactuApiTest extends TestCase
$response->assertStatus(200); $response->assertStatus(200);
$arr = $response->json(); $arr = $response->json();
// nlog($arr);
$this->assertEquals($arr['data'][0]['status_id'], Invoice::STATUS_CANCELLED); $this->assertEquals($arr['data'][0]['status_id'], Invoice::STATUS_CANCELLED);
$this->assertEquals($arr['data'][0]['balance'], 121); $this->assertEquals($arr['data'][0]['balance'], 121);
$this->assertEquals($arr['data'][0]['amount'], 121); $this->assertEquals($arr['data'][0]['amount'], 121);
$this->assertNotNull($arr['data'][0]['backup']['credit_invoice_id']); $this->assertNotNull($arr['data'][0]['backup']['child_invoice_ids'][0]);
$this->assertNotNull($arr['data'][0]['backup']['credit_invoice_number']);
$this->assertEquals($arr['data'][0]['backup']['cancellation_reason'], 'R3');
$credit_invoice = Invoice::find($this->decodePrimaryKey($arr['data'][0]['backup']['credit_invoice_id'])); $credit_invoice = Invoice::find($this->decodePrimaryKey($arr['data'][0]['backup']['child_invoice_ids'][0]));
nlog($credit_invoice->toArray());
$this->assertNotNull($credit_invoice); $this->assertNotNull($credit_invoice);
$this->assertEquals($credit_invoice->status_id, Invoice::STATUS_SENT); $this->assertEquals($credit_invoice->status_id, Invoice::STATUS_SENT);
$this->assertEquals($credit_invoice->balance, -121); $this->assertEquals($credit_invoice->balance, -121);
$this->assertEquals($credit_invoice->amount, -121); $this->assertEquals($credit_invoice->amount, -121);
$this->assertEquals($credit_invoice->backup->cancelled_invoice_id, $invoice->hashed_id); $this->assertEquals($credit_invoice->backup->parent_invoice_id, $invoice->hashed_id);
$this->assertEquals($credit_invoice->backup->cancelled_invoice_number, $invoice->number); $this->assertEquals($credit_invoice->backup->parent_invoice_number, $invoice->number);
$this->assertEquals($credit_invoice->backup->cancellation_reason, 'R3');
} }
public function test_restore_invoice_validation() public function test_restore_invoice_validation()