Files
opensourcepos/tests/Libraries/InvoiceAttachment/PdfAttachmentTest.php
jekkos 833c06c718 Add Peppol (UBL) invoice support for Phase 1
Implementation of UBL 2.1 invoice generation to comply with Belgium's 2026 Peppol mandate.

Key changes:
- Add num-num/ubl-invoice dependency via composer.json
- Create Ubl_generator library to convert OSPOS sale data to UBL format
- Create country_helper.php to map country names to ISO 3166-1 alpha-2 codes
- Extend Email_lib to support multiple attachments for PDF+UBL emails
- Add getUblInvoice() method in Sales controller for UBL download
- Modify getSendPdf() to optionally attach UBL based on invoice_format config
- Add database migration for invoice_format configuration (pdf_only/ubl_only/both)
- Add UBL download button to invoice view
- Add UBL download link to sales manage table
- Add language keys for UBL-related UI elements

Data mapping:
- Company name/address -> Supplier Party
- account_number -> Company VAT number
- Customer address/country -> Customer Party with ISO country code
- Customer tax_id -> Customer VAT number
- Cart items -> InvoiceLines
- Taxes -> TaxCategory and TaxTotal
- Totals -> LegalMonetaryTotal

Features:
- Generate valid UBL 2.1 XML invoices
- Download UBL from invoice view and manage table
- Email with PDF, UBL, or both based on configuration
- Support for multiple customer countries with ISO code mapping
- Graceful handling of missing optional customer fields
2026-04-02 23:20:35 +02:00

70 lines
2.2 KiB
PHP

<?php
namespace Tests\Libraries\InvoiceAttachment;
use CodeIgniter\Test\CIUnitTestCase;
use App\Libraries\InvoiceAttachment\PdfAttachment;
class PdfAttachmentTest extends CIUnitTestCase
{
private PdfAttachment $attachment;
protected function setUp(): void
{
parent::setUp();
$this->attachment = new PdfAttachment();
}
public function testGetFileExtensionReturnsPdf(): void
{
$this->assertEquals('pdf', $this->attachment->getFileExtension());
}
public function testGetEnabledConfigValuesReturnsCorrectArray(): void
{
$values = $this->attachment->getEnabledConfigValues();
$this->assertIsArray($values);
$this->assertContains('pdf_only', $values);
$this->assertContains('both', $values);
$this->assertCount(2, $values);
}
public function testIsApplicableForTypeReturnsTrueForInvoice(): void
{
$this->assertTrue($this->attachment->isApplicableForType('invoice', []));
}
public function testIsApplicableForTypeReturnsTrueForTaxInvoice(): void
{
$this->assertTrue($this->attachment->isApplicableForType('tax_invoice', []));
}
public function testIsApplicableForTypeReturnsTrueForQuote(): void
{
$this->assertTrue($this->attachment->isApplicableForType('quote', []));
}
public function testIsApplicableForTypeReturnsTrueForWorkOrder(): void
{
$this->assertTrue($this->attachment->isApplicableForType('work_order', []));
}
public function testIsApplicableForTypeReturnsTrueForReceipt(): void
{
$this->assertTrue($this->attachment->isApplicableForType('receipt', []));
}
public function testIsApplicableForTypeReturnsTrueForAnyType(): void
{
// PDF should work for any document type
$this->assertTrue($this->attachment->isApplicableForType('random_type', []));
}
public function testIsApplicableForTypeIgnoresSaleData(): void
{
// PDF attachment doesn't depend on invoice_number
$this->assertTrue($this->attachment->isApplicableForType('invoice', ['invoice_number' => null]));
$this->assertTrue($this->attachment->isApplicableForType('invoice', ['invoice_number' => 'INV-001']));
}
}