issueInvoice(); self::assertSame(InvoiceStatus::Issued, $invoice->status()); self::assertSame('ext-order-1', $invoice->externalOrderId); self::assertCount(1, $invoice->lines()); } public function test_issue_invoice_records_event(): void { $invoice = $this->issueInvoice(); $events = $invoice->releaseEvents(); self::assertCount(1, $events); self::assertInstanceOf(InvoiceIssued::class, $events[0]); } public function test_invoice_without_lines_throws(): void { $this->expectException(\DomainException::class); Invoice::issueForExternalOrder( InvoiceId::fromString('inv-1'), 'INV-000001', 'ext-order-1', new BillingParty('Acme', '1 Rue Test'), [], new \DateTimeImmutable(), ); } public function test_total_coherent_with_lines(): void { $invoice = Invoice::issueForExternalOrder( InvoiceId::fromString('inv-1'), 'INV-000001', 'ext-order-1', new BillingParty('Acme', '1 Rue Test'), [ new InvoiceLine('Widget', 2, 1000, 'EUR', TaxRate::standard()), new InvoiceLine('Gadget', 1, 2500, 'EUR', TaxRate::standard()), ], new \DateTimeImmutable(), ); self::assertSame(4500, $invoice->totalExclTax()); self::assertSame(5400, $invoice->totalInclTax()); } public function test_mark_as_sent(): void { $invoice = $this->issueInvoice(); $invoice->markAsSent(); self::assertSame(InvoiceStatus::Sent, $invoice->status()); } public function test_mark_as_sent_twice_throws(): void { $this->expectException(\DomainException::class); $invoice = $this->issueInvoice(); $invoice->markAsSent(); $invoice->markAsSent(); } private function issueInvoice(): Invoice { return Invoice::issueForExternalOrder( InvoiceId::fromString('inv-1'), 'INV-000001', 'ext-order-1', new BillingParty('Acme', '1 Rue Test'), [new InvoiceLine('Widget', 2, 1500, 'EUR', TaxRate::standard())], new \DateTimeImmutable(), ); } }