Refactor error handling and enhance API interactions across Filament pages

- Introduced `ApiErrorTranslator` to normalize and translate API error messages, providing clearer feedback in French.
- Updated all Filament pages (Articles, Documents, Divers, Journaux, Tiers, TablesExplorer) to utilize the new error translation mechanism, improving user experience during API interactions.
- Added validation for required fields before API calls, ensuring users receive immediate feedback when mandatory inputs are missing.
- Implemented tracking properties to distinguish between "never searched" and "searched without results," enhancing the user interface.
- Removed the obsolete `$results` property from the Articles page and added a new `$barcode` property to align with API requirements.
- Updated documentation to reflect changes in API behavior and error handling, including new metadata returned by the `art_list` endpoint.
- Added new tests to verify the functionality of the barcode handling and validation logic.
This commit is contained in:
2026-02-23 10:15:17 +01:00
parent 7df94b64fa
commit bb1bbc2904
29 changed files with 1075 additions and 157 deletions

View File

@@ -49,6 +49,7 @@ it('searches documents via document_list', function () {
->set('select', 'jnl,number')
->set('thirdId', 'CUST001')
->call('searchDocuments')
->assertSet('hasSearchedDocs', true)
->assertSet('data', [['jnl' => 'VEN', 'number' => '1']]);
});
@@ -143,12 +144,13 @@ it('calls Document_GetPDF endpoint', function () {
]),
]);
Livewire::test(Documents::class)
$component = Livewire::test(Documents::class)
->set('pdfJnl', 'VEN')
->set('pdfNumber', '2026/0001')
->set('pdfLayout', 'DEFAULT')
->call('getPdf')
->assertSet('errorMessage', 'Layout not found');
->call('getPdf');
expect($component->get('errorMessage'))->toContain('Layout not found');
});
it('adds a document via document_add', function () {
@@ -209,12 +211,92 @@ it('modifies a document via document_mod', function () {
});
});
it('does not call getStatusList when statusJnl is empty', function () {
it('shows validation error when statusJnl is empty', function () {
Http::fake();
Livewire::test(Documents::class)
->call('getStatusList')
->assertSet('statusData', []);
->assertSet('hasStatus', false)
->assertSet('errorMessage', 'Le champ code journal (jnl) est obligatoire.');
Http::assertNothingSent();
});
it('shows validation error when document_detail fields are empty', function () {
Http::fake();
Livewire::test(Documents::class)
->call('getDocumentDetail')
->assertSet('hasDetail', false)
->assertSet('errorMessage', 'Les champs code journal (jnl) et numero de document (number) sont obligatoires.');
Http::assertNothingSent();
});
it('shows validation error when getUnitPriceAndVat fields are empty', function () {
Http::fake();
Livewire::test(Documents::class)
->call('getUnitPriceAndVat')
->assertSet('hasPrice', false)
->assertSet('errorMessage', 'Tous les champs sont obligatoires : ARTID, QTY (format string), JNL, THIRDID et DATE.');
Http::assertNothingSent();
});
it('shows validation error when getDueDate fields are empty', function () {
Http::fake();
Livewire::test(Documents::class)
->call('getDueDate')
->assertSet('hasDueDate', false)
->assertSet('errorMessage', 'Les champs delai de paiement (paydelay) et date de depart (date) sont obligatoires.');
Http::assertNothingSent();
});
it('shows validation error when getAttachListThumbnail fields are empty', function () {
Http::fake();
Livewire::test(Documents::class)
->call('getAttachListThumbnail')
->assertSet('hasAttach', false)
->assertSet('errorMessage', 'Les champs code journal (JNL) et numero de document (NUMBER) sont obligatoires.');
Http::assertNothingSent();
});
it('shows validation error when getPdf fields are empty', function () {
Http::fake();
Livewire::test(Documents::class)
->call('getPdf')
->assertSet('hasPdf', false)
->assertSet('errorMessage', 'Les champs code journal (JNL), numero de document (NUMBER) et mise en page (LAYOUT) sont obligatoires.');
Http::assertNothingSent();
});
it('shows validation error when addDocument required fields are empty', function () {
Http::fake();
Livewire::test(Documents::class)
->set('mode', 'write')
->call('addDocument')
->assertSet('hasAdded', false)
->assertSet('errorMessage', 'Les champs ThirdId, Date, Artid, Qty, Saleprice et JNL sont obligatoires.');
Http::assertNothingSent();
});
it('shows validation error when modDocument required fields are empty', function () {
Http::fake();
Livewire::test(Documents::class)
->set('mode', 'write')
->call('modDocument')
->assertSet('hasModified', false)
->assertSet('errorMessage', 'Les champs numero de document (number) et code journal (JNL) sont obligatoires.');
Http::assertNothingSent();
});
@@ -228,7 +310,8 @@ it('displays error message on API failure', function () {
]),
]);
Livewire::test(Documents::class)
->call('searchDocuments')
->assertSet('errorMessage', 'Invalid API key');
$component = Livewire::test(Documents::class)
->call('searchDocuments');
expect($component->get('errorMessage'))->toContain('Invalid API key');
});