219 lines
7.6 KiB
PHP
219 lines
7.6 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\EInvoice\Verifactu;
|
|
|
|
use Tests\TestCase;
|
|
use App\Models\User;
|
|
use App\Models\Client;
|
|
use App\Models\Account;
|
|
use App\Models\Company;
|
|
use App\Models\Invoice;
|
|
use Faker\Factory as Faker;
|
|
use App\Models\CompanyToken;
|
|
use App\Models\ClientContact;
|
|
use App\DataMapper\InvoiceItem;
|
|
use App\DataMapper\ClientSettings;
|
|
use App\DataMapper\CompanySettings;
|
|
use App\Factory\CompanyUserFactory;
|
|
|
|
class VerifactuFeatureTest extends TestCase
|
|
{
|
|
private $account;
|
|
private $company;
|
|
private $user;
|
|
private $cu;
|
|
private $token;
|
|
private $client;
|
|
private $faker;
|
|
|
|
private string $test_company_nif = 'A39200019';
|
|
private string $test_client_nif = 'A39200019';
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->faker = Faker::create();
|
|
}
|
|
|
|
private function buildData($settings = null)
|
|
{
|
|
$this->account = Account::factory()->create([
|
|
'hosted_client_count' => 1000,
|
|
'hosted_company_count' => 1000,
|
|
]);
|
|
|
|
$this->account->num_users = 3;
|
|
$this->account->save();
|
|
|
|
$this->user = User::factory()->create([
|
|
'account_id' => $this->account->id,
|
|
'confirmation_code' => 'xyz123',
|
|
'email' => $this->faker->unique()->safeEmail(),
|
|
]);
|
|
|
|
if(!$settings) {
|
|
$settings = CompanySettings::defaults();
|
|
$settings->client_online_payment_notification = false;
|
|
$settings->client_manual_payment_notification = false;
|
|
$settings->country_id = 724;
|
|
$settings->currency_id = 3;
|
|
$settings->address1 = 'Calle Mayor 123'; // Main Street 123
|
|
$settings->city = 'Madrid';
|
|
$settings->state = 'Madrid';
|
|
$settings->postal_code = '28001';
|
|
$settings->vat_number = 'B12345678'; // Spanish VAT number format
|
|
$settings->payment_terms = '10';
|
|
$settings->vat_number = $this->test_company_nif;
|
|
}
|
|
|
|
$this->company = Company::factory()->create([
|
|
'account_id' => $this->account->id,
|
|
'settings' => $settings,
|
|
]);
|
|
|
|
$this->company->settings = $settings;
|
|
$this->company->save();
|
|
|
|
$this->cu = CompanyUserFactory::create($this->user->id, $this->company->id, $this->account->id);
|
|
$this->cu->is_owner = true;
|
|
$this->cu->is_admin = true;
|
|
$this->cu->is_locked = false;
|
|
$this->cu->save();
|
|
|
|
$this->token = \Illuminate\Support\Str::random(64);
|
|
|
|
$company_token = new CompanyToken();
|
|
$company_token->user_id = $this->user->id;
|
|
$company_token->company_id = $this->company->id;
|
|
$company_token->account_id = $this->account->id;
|
|
$company_token->name = 'test token';
|
|
$company_token->token = $this->token;
|
|
$company_token->is_system = true;
|
|
|
|
$company_token->save();
|
|
|
|
$client_settings = ClientSettings::defaults();
|
|
$client_settings->currency_id = '3';
|
|
|
|
$this->client = Client::factory()->create([
|
|
'user_id' => $this->user->id,
|
|
'company_id' => $this->company->id,
|
|
'is_deleted' => 0,
|
|
'name' => 'bob',
|
|
'address1' => 'Calle Mayor 123',
|
|
'city' => 'Madrid',
|
|
'state' => 'Madrid',
|
|
'postal_code' => '28001',
|
|
'country_id' => 724,
|
|
'vat_number' => $this->test_client_nif,
|
|
'balance' => 0,
|
|
'paid_to_date' => 0,
|
|
'settings' => $client_settings,
|
|
]);
|
|
|
|
ClientContact::factory()->create([
|
|
'user_id' => $this->user->id,
|
|
'client_id' => $this->client->id,
|
|
'company_id' => $this->company->id,
|
|
'is_primary' => 1,
|
|
'first_name' => 'john',
|
|
'last_name' => 'doe',
|
|
'email' => 'john@doe.com',
|
|
'send_email' => true,
|
|
]);
|
|
|
|
$line_items = [];
|
|
|
|
$item = new InvoiceItem();
|
|
$item->product_key = '1234567890';
|
|
$item->qty = 1;
|
|
$item->cost = 100;
|
|
$item->notes = 'Test item';
|
|
$item->tax_name1 = 'IVA';
|
|
$item->tax_rate1 = 21;
|
|
|
|
$line_items[] = $item;
|
|
|
|
$invoice = Invoice::factory()->create([
|
|
'user_id' => $this->user->id,
|
|
'company_id' => $this->company->id,
|
|
'client_id' => $this->client->id,
|
|
'date' => now()->addSeconds($this->client->timezone_offset())->format('Y-m-d'),
|
|
'next_send_date' => null,
|
|
'due_date' => now()->addSeconds($this->client->timezone_offset())->addDays(5)->format('Y-m-d'),
|
|
'last_sent_date' => now()->addSeconds($this->client->timezone_offset()),
|
|
'reminder_last_sent' => null,
|
|
'status_id' => Invoice::STATUS_DRAFT,
|
|
'amount' => 10,
|
|
'balance' => 10,
|
|
'line_items' => $line_items,
|
|
]);
|
|
|
|
$invoice = $invoice->calc()
|
|
->getInvoice()
|
|
->service()
|
|
->markSent()
|
|
->save();
|
|
|
|
return $invoice;
|
|
}
|
|
|
|
public function test_construction_and_validation()
|
|
{
|
|
|
|
$invoice = $this->buildData();
|
|
|
|
$this->assertNotNull($invoice);
|
|
}
|
|
|
|
public function testInvoiceCancellation()
|
|
{
|
|
// Create a sample invoice
|
|
$invoice = $this->buildData();
|
|
|
|
// Create cancellation from invoice
|
|
$cancellation = \App\Services\EDocument\Standards\Verifactu\Models\InvoiceCancellation::fromInvoice(
|
|
$invoice,
|
|
'ABCD1234EF5678901234567890ABCDEF1234567890ABCDEF1234567890ABCDEF12'
|
|
);
|
|
|
|
// Set custom cancellation details
|
|
$cancellation->setEstado('02') // 02 = Invoice cancelled
|
|
->setDescripcionEstado('Factura anulada por error');
|
|
|
|
// Generate XML
|
|
$xmlString = $cancellation->toXmlString();
|
|
|
|
// Verify XML structure
|
|
$this->assertNotEmpty($xmlString);
|
|
$this->assertStringContainsString('SuministroLRFacturas', $xmlString);
|
|
$this->assertStringContainsString('LRFacturaEntrada', $xmlString);
|
|
$this->assertStringContainsString('IDFactura', $xmlString);
|
|
$this->assertStringContainsString('EstadoFactura', $xmlString);
|
|
$this->assertStringContainsString('Estado', $xmlString);
|
|
$this->assertStringContainsString('02', $xmlString); // Cancelled status
|
|
|
|
// Generate SOAP envelope
|
|
$soapEnvelope = $cancellation->toSoapEnvelope();
|
|
|
|
// Verify SOAP structure
|
|
$this->assertNotEmpty($soapEnvelope);
|
|
$this->assertStringContainsString('soapenv:Envelope', $soapEnvelope);
|
|
$this->assertStringContainsString('RegFactuSistemaFacturacion', $soapEnvelope);
|
|
|
|
// Test serialization
|
|
$serialized = $cancellation->serialize();
|
|
$this->assertNotEmpty($serialized);
|
|
|
|
// Test deserialization
|
|
$deserialized = \App\Services\EDocument\Standards\Verifactu\Models\InvoiceCancellation::unserialize($serialized);
|
|
$this->assertEquals($cancellation->getNumSerieFacturaEmisor(), $deserialized->getNumSerieFacturaEmisor());
|
|
$this->assertEquals($cancellation->getEstado(), $deserialized->getEstado());
|
|
|
|
// Test from XML
|
|
$fromXml = \App\Services\EDocument\Standards\Verifactu\Models\InvoiceCancellation::fromXml($xmlString);
|
|
$this->assertEquals($cancellation->getNumSerieFacturaEmisor(), $fromXml->getNumSerieFacturaEmisor());
|
|
$this->assertEquals($cancellation->getEstado(), $fromXml->getEstado());
|
|
}
|
|
} |