diff --git a/.gitbook.yaml b/.gitbook.yaml
deleted file mode 100644
index 7353199..0000000
--- a/.gitbook.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-root: ./docs/
-
-structure:
- readme: README.md
- summary: SUMMARY.md
\ No newline at end of file
diff --git a/.phpunit.cache/test-results b/.phpunit.cache/test-results
index 9c647e6..d347c6e 100644
--- a/.phpunit.cache/test-results
+++ b/.phpunit.cache/test-results
@@ -1 +1 @@
-{"version":"pest_3.8.4","defects":{"P\\Tests\\Requests\\ManualEntries\\AddFileToAccountingEntryLineRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\Contacts\\BulkCreateContactsRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\CalendarYears\\CreateCalendarYearRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\AdditionalAddresses\\CreateAnAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":8,"P\\Tests\\Requests\\IbanPayments\\EditIbanPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\CalendarYears\\SearchCalendarYearsRequestTest::__pest_evaluable_it_can_perform_the_request":7,"P\\Tests\\Requests\\AdditionalAddresses\\EditAnAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":8,"P\\Tests\\Requests\\CalendarYears\\FetchAListOfCalendarYearsRequestTest::__pest_evaluable_it_can_perform_the_request":7,"P\\Tests\\Requests\\QrPayments\\EditQrPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\Files\\ShowFileUsageRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\Taxes\\FetchAListOfTaxesRequestTest::__pest_evaluable_it_can_perform_the_request":7,"P\\Tests\\Requests\\AdditionalAddresses\\FetchAListOfAdditionalAddressesRequestTest::__pest_evaluable_it_can_perform_the_request":7},"times":{"P\\Tests\\Requests\\ManualEntries\\FetchAListOfManualEntriesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ManualEntries\\GetNextReferenceNumberRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ManualEntries\\AddFileToAccountingEntryLineRequestTest::__pest_evaluable_it_can_perform_the_request":0.005,"P\\Tests\\Requests\\Invoices\\CreateAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0.005,"P\\Tests\\Requests\\BusinessYears\\FetchAListOfBusinessYearsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Files\\FetchAListOfFilesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Notes\\FetchANoteRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Reports\\JournalRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ManualEntries\\FetchFilesOfAccountingEntryRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\IssueAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_can_store_and_retrieve_an_authenticator":0.022,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_handles_serialization_and_unserialization_correctly":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_uses_configured_cache_store":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_falls_back_to_default_cache_store_when_bexio_cache_store_is_not_configured":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_returns_null_when_cached_data_cannot_be_decrypted":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_can_forget_cached_authenticator":0.001,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_returns_null_when_no_authenticator_is_cached":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_refreshes_expired_token_automatically":0.02,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_encrypts_the_authenticator_when_storing":0.003,"P\\Tests\\Requests\\ContactAdditionalAddresses\\FetchAListOfContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\DefaultPositions\\CreateADefaultPositionRequestTest::__pest_evaluable_it_can_perform_the_request":0.002,"P\\Tests\\Requests\\Contacts\\BulkCreateContactsRequestTest::__pest_evaluable_it_can_perform_the_request":0.002,"P\\Tests\\Requests\\ContactAdditionalAddresses\\DeleteAContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactGroups\\CreateContactGroupRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactRelations\\EditAContactRelationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\CalendarYears\\CreateCalendarYearRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Accounts\\SearchAccountsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Titles\\DeleteATitleRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ManualEntries\\FetchFileOfAccountingEntryLineRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Files\\EditAFileRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Languages\\FetchAListOfLanguagesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\CompanyProfiles\\FetchACompanyProfileRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Users\\FetchAuthenticatedUserRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AdditionalAddresses\\CreateAnAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Contacts\\EditAContactRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Contacts\\FetchAContactRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Currencies\\FetchAListOfCurrenciesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactGroups\\FetchAContactGroupRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactSectors\\FetchAListOfContactSectorsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Titles\\FetchAListOfTitlesRequestTest::__pest_evaluable_it_can_perform_the_request":0.003,"P\\Tests\\Requests\\CompanyProfiles\\FetchAListOfCompanyProfilesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Support\\DefaultBexioOAuthConfigResolverTest::__pest_evaluable_it_throws_exception_when_required_config_is_missing":0,"P\\Tests\\Support\\DefaultBexioOAuthConfigResolverTest::__pest_evaluable_it_returns_a_new_instance_each_time":0,"P\\Tests\\Support\\DefaultBexioOAuthConfigResolverTest::__pest_evaluable_it_resolves_to_a_ConnectWithOAuth_instance":0,"P\\Tests\\Support\\DefaultBexioOAuthConfigResolverTest::__pest_evaluable_it_returns_ConnectWithOAuth_with_config_values":0,"P\\Tests\\Requests\\Invoices\\SubPositions\\CreateASubPositionRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Core\\ArchTest::__pest_evaluable_it_will_not_use_any_debug_function":0.206,"P\\Tests\\Requests\\ContactAdditionalAddresses\\CreateContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_can_create_failed_result_with_custom_redirect":0.005,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_returns_success_result_for_connector_with_authenticator_without_refresh_token":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_always_returns_success_result_for_any_connector":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_can_create_failed_result_without_custom_redirect":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_returns_success_result_for_connector_with_expired_authenticator":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_can_create_success_result_using_static_method":0,"P\\Tests\\Requests\\Titles\\SearchTitlesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AdditionalAddresses\\FetchAnAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Files\\DownloadFIleRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\BankAccounts\\FetchAListOfBankAccountsRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Salutations\\FetchAListOfSalutationsRequestTest::__pest_evaluable_it_can_perform_the_request":0.003,"P\\Tests\\Requests\\Contacts\\SearchContactsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\IbanPayments\\EditIbanPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\ContactRelations\\CreateContactRelationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactRelations\\SearchContactRelationsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\CalendarYears\\SearchCalendarYearsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AdditionalAddresses\\FetchAListOfAdditionalAddressesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactGroups\\SearchContactGroupsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AdditionalAddresses\\EditAnAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Taxes\\DeleteATaxRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Contacts\\CreateContactRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Titles\\FetchATitleRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\CalendarYears\\FetchAListOfCalendarYearsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Notes\\DeleteANoteRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Contacts\\RestoreAContactRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Taxes\\FetchAListOfTaxesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Files\\GetASingleFileRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactRelations\\DeleteAContactRelationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\OAuth\\EndSessionRequestTest::__pest_evaluable_it_can_perform_the_request":0.002,"P\\Tests\\Requests\\Salutations\\EditASalutationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactAdditionalAddresses\\SearchContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\BusinessActivities\\FetchAListOfBusinessActivitiesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Salutations\\DeleteASalutationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\BankAccounts\\FetchASingleBankAccountRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Currencies\\DeleteACurrencyRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Notes\\CreateANoteRequestTest::__pest_evaluable_it_can_perform_the_request":0.002,"P\\Tests\\Requests\\Files\\DeleteAFileRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\IbanPayments\\CreateIbanPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\QrPayments\\EditQrPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Files\\SearchFilesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\BusinessYears\\FetchABusinessYearRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\DocumentSettings\\FetchAListOfDocumentSettingsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactSectors\\SearchContactSectorsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AccountGroups\\FetchAListOfAccountGroupsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Titles\\CreateATitleRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Taxes\\FetchATaxRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\QrPayments\\CreateQrPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Payments\\FetchAListOfPaymentsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Salutations\\FetchASalutationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Files\\ShowFileUsageRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\OAuth\\OpenIDConfigurationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Notes\\SearchNotesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ManualEntries\\DeleteFileOfAccountingEntryLineRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\OpenID\\FetchUserInfoRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Files\\GetAFilePreviewRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Contacts\\FetchAListOfContactsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\ShowPdfRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\VatPeriods\\FetchAVatPeriodRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Units\\FetchAListOfUnitsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Accounts\\FetchAListOfAccountsRequestTest::__pest_evaluable_it_can_perform_the_request":0.002,"P\\Tests\\Requests\\Users\\FetchAListOfUsersRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AdditionalAddresses\\DeleteAnAdditonalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\FetchAListOfInvoicesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Currencies\\FetchACurrencyRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactRelations\\FetchAListOfContactRelationsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\FetchAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactGroups\\EditAContactGroupRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\CalendarYears\\FetchACalendarYearRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AdditionalAddresses\\SearchAdditionalAddressesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\DeleteAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Salutations\\CreateASalutationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactAdditionalAddresses\\FetchAContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ManualEntries\\CreateManualEntryRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Salutations\\SearchSalutationsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Currencies\\EditACurrencyRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Notes\\EditANoteRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Notes\\FetchAListOfNotesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Files\\CreateAFileRequestTest::__pest_evaluable_it_can_perform_the_request":0.004,"P\\Tests\\Requests\\IbanPayments\\GetIbanPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Payments\\DeleteAPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Projects\\FetchAListOfProjectsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Currencies\\CreateCurrencyRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactAdditionalAddresses\\EditAContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\EditAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0.023,"P\\Tests\\Requests\\Invoices\\CancelAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactGroups\\DeleteAContactGroupRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\PaymentTypes\\FetchAListOfPaymentTypesRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Titles\\EditATitleRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\VatPeriods\\FetchAListOfVatPeriodsRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Contacts\\DeleteAContactRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Currencies\\FetchExchangeRatesForCurrenciesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\SetIssuedInvoiceToDraftRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Payments\\CancelAPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Currencies\\FetchAllPossibleCurrencyCodesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactRelations\\FetchAContactRelationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactGroups\\FetchAListOfContactGroupsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\QrPayments\\GetQrPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0.001}}
\ No newline at end of file
+{"version":"pest_3.8.4","defects":{"P\\Tests\\Requests\\ManualEntries\\AddFileToAccountingEntryLineRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\Contacts\\BulkCreateContactsRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\CalendarYears\\CreateCalendarYearRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\AdditionalAddresses\\CreateAnAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":8,"P\\Tests\\Requests\\IbanPayments\\EditIbanPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\CalendarYears\\SearchCalendarYearsRequestTest::__pest_evaluable_it_can_perform_the_request":7,"P\\Tests\\Requests\\AdditionalAddresses\\EditAnAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":8,"P\\Tests\\Requests\\CalendarYears\\FetchAListOfCalendarYearsRequestTest::__pest_evaluable_it_can_perform_the_request":7,"P\\Tests\\Requests\\QrPayments\\EditQrPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\Files\\ShowFileUsageRequestTest::__pest_evaluable_it_can_perform_the_request":1,"P\\Tests\\Requests\\Taxes\\FetchAListOfTaxesRequestTest::__pest_evaluable_it_can_perform_the_request":7,"P\\Tests\\Requests\\AdditionalAddresses\\FetchAListOfAdditionalAddressesRequestTest::__pest_evaluable_it_can_perform_the_request":7,"P\\Tests\\Requests\\Items\\CreateItemRequestTest::__pest_evaluable_it_can_perform_the_request":7,"P\\Tests\\Requests\\Items\\EditAnItemRequestTest::__pest_evaluable_it_can_perform_the_request":7,"P\\Tests\\Requests\\Items\\FetchAListOfItemsRequestTest::__pest_evaluable_it_can_perform_the_request":5,"P\\Tests\\Requests\\Items\\FetchAnItemRequestTest::__pest_evaluable_it_can_perform_the_request":7},"times":{"P\\Tests\\Requests\\ManualEntries\\FetchAListOfManualEntriesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ManualEntries\\GetNextReferenceNumberRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\ManualEntries\\AddFileToAccountingEntryLineRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Invoices\\CreateAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0.004,"P\\Tests\\Requests\\BusinessYears\\FetchAListOfBusinessYearsRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Files\\FetchAListOfFilesRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Notes\\FetchANoteRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Reports\\JournalRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ManualEntries\\FetchFilesOfAccountingEntryRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\IssueAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_can_store_and_retrieve_an_authenticator":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_handles_serialization_and_unserialization_correctly":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_uses_configured_cache_store":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_falls_back_to_default_cache_store_when_bexio_cache_store_is_not_configured":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_returns_null_when_cached_data_cannot_be_decrypted":0.001,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_can_forget_cached_authenticator":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_returns_null_when_no_authenticator_is_cached":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_refreshes_expired_token_automatically":0.001,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationStoreResolverTest::__pest_evaluable_it_encrypts_the_authenticator_when_storing":0.001,"P\\Tests\\Requests\\ContactAdditionalAddresses\\FetchAListOfContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\DefaultPositions\\CreateADefaultPositionRequestTest::__pest_evaluable_it_can_perform_the_request":0.002,"P\\Tests\\Requests\\Contacts\\BulkCreateContactsRequestTest::__pest_evaluable_it_can_perform_the_request":0.003,"P\\Tests\\Requests\\ContactAdditionalAddresses\\DeleteAContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactGroups\\CreateContactGroupRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactRelations\\EditAContactRelationRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\CalendarYears\\CreateCalendarYearRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Accounts\\SearchAccountsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Titles\\DeleteATitleRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\ManualEntries\\FetchFileOfAccountingEntryLineRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Files\\EditAFileRequestTest::__pest_evaluable_it_can_perform_the_request":0.002,"P\\Tests\\Requests\\Languages\\FetchAListOfLanguagesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\CompanyProfiles\\FetchACompanyProfileRequestTest::__pest_evaluable_it_can_perform_the_request":0.003,"P\\Tests\\Requests\\Users\\FetchAuthenticatedUserRequestTest::__pest_evaluable_it_can_perform_the_request":0.002,"P\\Tests\\Requests\\AdditionalAddresses\\CreateAnAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Contacts\\EditAContactRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Contacts\\FetchAContactRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Currencies\\FetchAListOfCurrenciesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactGroups\\FetchAContactGroupRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\ContactSectors\\FetchAListOfContactSectorsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Titles\\FetchAListOfTitlesRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\CompanyProfiles\\FetchAListOfCompanyProfilesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Support\\DefaultBexioOAuthConfigResolverTest::__pest_evaluable_it_throws_exception_when_required_config_is_missing":0.001,"P\\Tests\\Support\\DefaultBexioOAuthConfigResolverTest::__pest_evaluable_it_returns_a_new_instance_each_time":0.001,"P\\Tests\\Support\\DefaultBexioOAuthConfigResolverTest::__pest_evaluable_it_resolves_to_a_ConnectWithOAuth_instance":0.001,"P\\Tests\\Support\\DefaultBexioOAuthConfigResolverTest::__pest_evaluable_it_returns_ConnectWithOAuth_with_config_values":0,"P\\Tests\\Requests\\Invoices\\SubPositions\\CreateASubPositionRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Core\\ArchTest::__pest_evaluable_it_will_not_use_any_debug_function":0.212,"P\\Tests\\Requests\\ContactAdditionalAddresses\\CreateContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_can_create_failed_result_with_custom_redirect":0.001,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_returns_success_result_for_connector_with_authenticator_without_refresh_token":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_always_returns_success_result_for_any_connector":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_can_create_failed_result_without_custom_redirect":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_returns_success_result_for_connector_with_expired_authenticator":0,"P\\Tests\\Support\\DefaultBexioOAuthAuthenticationValidateResolverTest::__pest_evaluable_it_can_create_success_result_using_static_method":0,"P\\Tests\\Requests\\Titles\\SearchTitlesRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\AdditionalAddresses\\FetchAnAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Files\\DownloadFIleRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\BankAccounts\\FetchAListOfBankAccountsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Salutations\\FetchAListOfSalutationsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Contacts\\SearchContactsRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\IbanPayments\\EditIbanPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\ContactRelations\\CreateContactRelationRequestTest::__pest_evaluable_it_can_perform_the_request":0.019,"P\\Tests\\Requests\\ContactRelations\\SearchContactRelationsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\CalendarYears\\SearchCalendarYearsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AdditionalAddresses\\FetchAListOfAdditionalAddressesRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\ContactGroups\\SearchContactGroupsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AdditionalAddresses\\EditAnAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Taxes\\DeleteATaxRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Contacts\\CreateContactRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Titles\\FetchATitleRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\CalendarYears\\FetchAListOfCalendarYearsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Notes\\DeleteANoteRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Contacts\\RestoreAContactRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Taxes\\FetchAListOfTaxesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Files\\GetASingleFileRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\ContactRelations\\DeleteAContactRelationRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\OAuth\\EndSessionRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Salutations\\EditASalutationRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\ContactAdditionalAddresses\\SearchContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\BusinessActivities\\FetchAListOfBusinessActivitiesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Salutations\\DeleteASalutationRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\BankAccounts\\FetchASingleBankAccountRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Currencies\\DeleteACurrencyRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Notes\\CreateANoteRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Files\\DeleteAFileRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\IbanPayments\\CreateIbanPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\QrPayments\\EditQrPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Files\\SearchFilesRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\BusinessYears\\FetchABusinessYearRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\DocumentSettings\\FetchAListOfDocumentSettingsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactSectors\\SearchContactSectorsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AccountGroups\\FetchAListOfAccountGroupsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Titles\\CreateATitleRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Taxes\\FetchATaxRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\QrPayments\\CreateQrPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Payments\\FetchAListOfPaymentsRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Salutations\\FetchASalutationRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Files\\ShowFileUsageRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\OAuth\\OpenIDConfigurationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Notes\\SearchNotesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ManualEntries\\DeleteFileOfAccountingEntryLineRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\OpenID\\FetchUserInfoRequestTest::__pest_evaluable_it_can_perform_the_request":0.002,"P\\Tests\\Requests\\Files\\GetAFilePreviewRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Contacts\\FetchAListOfContactsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\ShowPdfRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\VatPeriods\\FetchAVatPeriodRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Units\\FetchAListOfUnitsRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Accounts\\FetchAListOfAccountsRequestTest::__pest_evaluable_it_can_perform_the_request":0.002,"P\\Tests\\Requests\\Users\\FetchAListOfUsersRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\AdditionalAddresses\\DeleteAnAdditonalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Invoices\\FetchAListOfInvoicesRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Currencies\\FetchACurrencyRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\ContactRelations\\FetchAListOfContactRelationsRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Invoices\\FetchAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactGroups\\EditAContactGroupRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\CalendarYears\\FetchACalendarYearRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\AdditionalAddresses\\SearchAdditionalAddressesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\DeleteAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Salutations\\CreateASalutationRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactAdditionalAddresses\\FetchAContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ManualEntries\\CreateManualEntryRequestTest::__pest_evaluable_it_can_perform_the_request":0.003,"P\\Tests\\Requests\\Salutations\\SearchSalutationsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Currencies\\EditACurrencyRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Notes\\EditANoteRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Notes\\FetchAListOfNotesRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Files\\CreateAFileRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\IbanPayments\\GetIbanPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Payments\\DeleteAPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Projects\\FetchAListOfProjectsRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Currencies\\CreateCurrencyRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactAdditionalAddresses\\EditAContactAdditionalAddressRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\EditAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Invoices\\CancelAnInvoiceRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactGroups\\DeleteAContactGroupRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\PaymentTypes\\FetchAListOfPaymentTypesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\Titles\\EditATitleRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\VatPeriods\\FetchAListOfVatPeriodsRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Contacts\\DeleteAContactRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Currencies\\FetchExchangeRatesForCurrenciesRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Invoices\\SetIssuedInvoiceToDraftRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Payments\\CancelAPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Currencies\\FetchAllPossibleCurrencyCodesRequestTest::__pest_evaluable_it_can_perform_the_request":0.001,"P\\Tests\\Requests\\ContactRelations\\FetchAContactRelationRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\ContactGroups\\FetchAListOfContactGroupsRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\QrPayments\\GetQrPaymentRequestTest::__pest_evaluable_it_can_perform_the_request":0,"P\\Tests\\Requests\\Items\\FetchAnItemRequestTest::__pest_evaluable_it_can_perform_the_request":0.357,"P\\Tests\\Requests\\Items\\SearchItemsRequestTest::__pest_evaluable_it_can_perform_the_request":0.25,"P\\Tests\\Requests\\Items\\CreateItemRequestTest::__pest_evaluable_it_can_perform_the_request":0.196,"P\\Tests\\Requests\\Items\\EditAnItemRequestTest::__pest_evaluable_it_can_perform_the_request":0.542,"P\\Tests\\Requests\\Items\\DeleteAnItemRequestTest::__pest_evaluable_it_can_perform_the_request":0.394,"P\\Tests\\Requests\\Items\\FetchAListOfItemsRequestTest::__pest_evaluable_it_can_perform_the_request":0.326}}
\ No newline at end of file
diff --git a/README.md b/README.md
index 0b61efb..a76a101 100644
--- a/README.md
+++ b/README.md
@@ -50,6 +50,7 @@ This package was developed to give you a quick start to the Bexio API.
- [Files](#files)
- [Iban Payments](#iban-payments)
- [Invoices](#invoices)
+ - [Items](#items)
- [Languages](#languages)
- [Manual Entries](#manual-entries)
- [Notes](#notes)
@@ -682,6 +683,7 @@ We provide enums for the following values:
| ContactSectors: OrderByEnum | ID(), ID_ASC(), ID_DESC(), NAME(), NAME_ASC(), NAME_DESC() |
| IbanPayments: AllowanceTypeEnum | FEE_PAID_BY_SENDER(), FEE_PAID_BY_RECIPIENT(), FEE_SPLIT(), NO_FEE() |
| IbanPayments: StatusEnum | OPEN(), TRANSFERRED(), DOWNLOADED(), ERROR(), CANCELLED() |
+| Items: OrderByEnum | ID(), ID_ASC(), ID_DESC(), INTERN_NAME(), INTERN_NAME_ASC(), INTERN_NAME_DESC() |
| ManualEntries: TypeEnum | MANUAL_SINGLE_ENTRY(), MANUAL_GROUP_ENTRY(), MANUAL_COMPOUND_ENTRY() |
| QrPayments: AllowanceTypeEnum | FEE_PAID_BY_SENDER(), FEE_PAID_BY_RECIPIENT(), FEE_SPLIT(), NO_FEE() |
| QrPayments: StatusEnum | OPEN(), TRANSFERRED(), DOWNLOADED(), ERROR(), CANCELLED() |
@@ -725,6 +727,8 @@ We provide DTOs for the following:
| InvoiceDTO |
| InvoicePositionDTO |
| InvoiceTaxDTO |
+| ItemDTO |
+| CreateEditItemDTO |
| PdfDTO |
| LanguageDTO |
| AddFileDTO |
@@ -2003,6 +2007,81 @@ $title = $connector->send(new DeleteATitleRequest(
));
```
+### Items
+```php
+/**
+ * Fetch A List Of Items
+ */
+$items = $connector->send(new FetchAListOfItemsRequest())->dto();
+```
+
+```php
+/**
+ * Fetch An Item
+ */
+$item = $connector->send(new FetchAnItemRequest(
+ article_id: 1
+))->dto();
+```
+
+```php
+/**
+ * Search Items
+ */
+$items = $connector->send(new SearchItemsRequest(
+ searchField: 'intern_name',
+ searchTerm: 'Something'
+))->dto();
+```
+
+```php
+/**
+ * Create Item
+ */
+$item = $connector->send(new CreateItemRequest(
+ data: new CreateEditItemDTO(
+ user_id: 1,
+ article_type_id: 1,
+ intern_code: 'ITEM-001',
+ intern_name: 'Test Item',
+ intern_description: 'Item Description',
+ sale_price: '20.00',
+ purchase_price: '10.00',
+ currency_id: 1,
+ tax_income_id: 14,
+ tax_expense_id: 21,
+ unit_id: 1,
+ )
+))->dto();
+```
+
+```php
+/**
+ * Edit Item
+ */
+$item = $connector->send(new EditAnItemRequest(
+ article_id: 1,
+ data: new CreateEditItemDTO(
+ user_id: 1,
+ article_type_id: 1,
+ intern_code: 'ITEM-001',
+ intern_name: 'Updated Item Name',
+ intern_description: 'Updated Description',
+ sale_price: '25.00',
+ purchase_price: '15.00',
+ )
+))->dto();
+```
+
+```php
+/**
+ * Delete Item
+ */
+$response = $connector->send(new DeleteAnItemRequest(
+ article_id: 1
+));
+```
+
### VAT Periods
```php
/**
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 7c66551..4d12b3d 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -22,6 +22,7 @@
+
diff --git a/src/Dto/Items/CreateEditItemDTO.php b/src/Dto/Items/CreateEditItemDTO.php
new file mode 100644
index 0000000..1a0920b
--- /dev/null
+++ b/src/Dto/Items/CreateEditItemDTO.php
@@ -0,0 +1,99 @@
+failed()) {
+ throw new \Exception('Failed to create DTO from Response');
+ }
+
+ $data = $response->json();
+
+ return self::fromArray($data);
+ }
+
+ public static function fromArray(array $data): self
+ {
+ if (! $data) {
+ throw new Exception('Unable to create DTO. Data missing from response.');
+ }
+
+ return new self(
+ user_id: Arr::get($data, 'user_id'),
+ article_type_id: Arr::get($data, 'article_type_id'),
+ contact_id: Arr::get($data, 'contact_id'),
+ deliverer_code: Arr::get($data, 'deliverer_code'),
+ deliverer_name: Arr::get($data, 'deliverer_name'),
+ deliverer_description: Arr::get($data, 'deliverer_description'),
+ intern_code: Arr::get($data, 'intern_code'),
+ intern_name: Arr::get($data, 'intern_name'),
+ intern_description: Arr::get($data, 'intern_description'),
+ purchase_price: Arr::get($data, 'purchase_price'),
+ sale_price: Arr::get($data, 'sale_price'),
+ purchase_total: Arr::get($data, 'purchase_total'),
+ sale_total: Arr::get($data, 'sale_total'),
+ currency_id: Arr::get($data, 'currency_id'),
+ tax_income_id: Arr::get($data, 'tax_income_id'),
+ tax_expense_id: Arr::get($data, 'tax_expense_id'),
+ unit_id: Arr::get($data, 'unit_id'),
+ is_stock: Arr::get($data, 'is_stock', false),
+ stock_id: Arr::get($data, 'stock_id'),
+ stock_place_id: Arr::get($data, 'stock_place_id'),
+ stock_nr: Arr::get($data, 'stock_nr', 0),
+ stock_min_nr: Arr::get($data, 'stock_min_nr', 0),
+ width: Arr::get($data, 'width'),
+ height: Arr::get($data, 'height'),
+ weight: Arr::get($data, 'weight'),
+ volume: Arr::get($data, 'volume'),
+ html_text: Arr::get($data, 'html_text'),
+ remarks: Arr::get($data, 'remarks'),
+ delivery_price: Arr::get($data, 'delivery_price'),
+ article_group_id: Arr::get($data, 'article_group_id'),
+ account_id: Arr::get($data, 'account_id'),
+ expense_account_id: Arr::get($data, 'expense_account_id'),
+ );
+ }
+}
diff --git a/src/Dto/Items/ItemDTO.php b/src/Dto/Items/ItemDTO.php
new file mode 100644
index 0000000..e0bd031
--- /dev/null
+++ b/src/Dto/Items/ItemDTO.php
@@ -0,0 +1,115 @@
+failed()) {
+ throw new \Exception('Failed to create DTO from Response');
+ }
+
+ $data = $response->json();
+
+ return self::fromArray($data);
+ }
+
+ public static function fromArray(array $data): self
+ {
+ if (! $data) {
+ throw new Exception('Unable to create DTO. Data missing from response.');
+ }
+
+ return new self(
+ id: Arr::get($data, 'id'),
+ user_id: Arr::get($data, 'user_id'),
+ article_type_id: Arr::get($data, 'article_type_id'),
+ contact_id: Arr::get($data, 'contact_id'),
+ master_id: Arr::get($data, 'master_id'),
+ deliverer_code: Arr::get($data, 'deliverer_code'),
+ deliverer_name: Arr::get($data, 'deliverer_name'),
+ deliverer_description: Arr::get($data, 'deliverer_description'),
+ intern_code: Arr::get($data, 'intern_code'),
+ intern_name: Arr::get($data, 'intern_name'),
+ intern_description: Arr::get($data, 'intern_description'),
+ purchase_price: Arr::get($data, 'purchase_price'),
+ sale_price: Arr::get($data, 'sale_price'),
+ purchase_total: Arr::get($data, 'purchase_total'),
+ sale_total: Arr::get($data, 'sale_total'),
+ currency_id: Arr::get($data, 'currency_id'),
+ tax_income_id: Arr::get($data, 'tax_income_id'),
+ tax_id: Arr::get($data, 'tax_id'),
+ tax_expense_id: Arr::get($data, 'tax_expense_id'),
+ unit_id: Arr::get($data, 'unit_id'),
+ is_stock: Arr::get($data, 'is_stock', false),
+ stock_id: Arr::get($data, 'stock_id'),
+ stock_place_id: Arr::get($data, 'stock_place_id'),
+ stock_nr: Arr::get($data, 'stock_nr', 0),
+ stock_min_nr: Arr::get($data, 'stock_min_nr', 0),
+ stock_reserved_nr: Arr::get($data, 'stock_reserved_nr', 0),
+ stock_available_nr: Arr::get($data, 'stock_available_nr', 0),
+ stock_picked_nr: Arr::get($data, 'stock_picked_nr', 0),
+ stock_disposed_nr: Arr::get($data, 'stock_disposed_nr', 0),
+ stock_ordered_nr: Arr::get($data, 'stock_ordered_nr', 0),
+ width: Arr::get($data, 'width'),
+ height: Arr::get($data, 'height'),
+ weight: Arr::get($data, 'weight'),
+ volume: Arr::get($data, 'volume'),
+ html_text: Arr::get($data, 'html_text'),
+ remarks: Arr::get($data, 'remarks'),
+ delivery_price: Arr::get($data, 'delivery_price'),
+ article_group_id: Arr::get($data, 'article_group_id'),
+ account_id: Arr::get($data, 'account_id'),
+ expense_account_id: Arr::get($data, 'expense_account_id'),
+ );
+ }
+}
diff --git a/src/Enums/Items/OrderByEnum.php b/src/Enums/Items/OrderByEnum.php
new file mode 100644
index 0000000..5eb3de1
--- /dev/null
+++ b/src/Enums/Items/OrderByEnum.php
@@ -0,0 +1,40 @@
+ 'id',
+ 'ID_ASC' => 'id_asc',
+ 'ID_DESC' => 'id_desc',
+ 'INTERN_NAME' => 'intern_name',
+ 'INTERN_NAME_ASC' => 'intern_name_asc',
+ 'INTERN_NAME_DESC' => 'intern_name_desc',
+ ];
+ }
+
+ protected static function labels(): array
+ {
+ return [
+ 'ID' => 'Id',
+ 'ID_ASC' => 'Id Ascending',
+ 'ID_DESC' => 'Id Descending',
+ 'INTERN_NAME' => 'Intern Name',
+ 'INTERN_NAME_ASC' => 'Intern Name Ascending',
+ 'INTERN_NAME_DESC' => 'Intern Name Descending',
+ ];
+ }
+}
diff --git a/src/Requests/Items/CreateItemRequest.php b/src/Requests/Items/CreateItemRequest.php
new file mode 100644
index 0000000..edeb430
--- /dev/null
+++ b/src/Requests/Items/CreateItemRequest.php
@@ -0,0 +1,48 @@
+data;
+
+ if (! $body instanceof CreateEditItemDTO) {
+ $body = CreateEditItemDTO::fromArray($body);
+ }
+
+ return $body->toArray();
+ }
+
+ public function createDtoFromResponse(Response $response): ItemDTO
+ {
+ if (! $response->successful()) {
+ throw new Exception('Request was not successful. Unable to create DTO.');
+ }
+
+ return ItemDTO::fromArray($response->json());
+ }
+}
diff --git a/src/Requests/Items/DeleteAnItemRequest.php b/src/Requests/Items/DeleteAnItemRequest.php
new file mode 100644
index 0000000..e97485b
--- /dev/null
+++ b/src/Requests/Items/DeleteAnItemRequest.php
@@ -0,0 +1,31 @@
+article_id;
+ }
+
+ public function createDtoFromResponse(Response $response): mixed
+ {
+ if (! $response->successful()) {
+ throw new Exception('Request was not successful. Unable to create DTO.');
+ }
+
+ return $response->json();
+ }
+}
diff --git a/src/Requests/Items/EditAnItemRequest.php b/src/Requests/Items/EditAnItemRequest.php
new file mode 100644
index 0000000..0965607
--- /dev/null
+++ b/src/Requests/Items/EditAnItemRequest.php
@@ -0,0 +1,53 @@
+article_id;
+ }
+
+ protected function defaultBody(): array
+ {
+ $body = $this->data;
+
+ if (! $body instanceof CreateEditItemDTO) {
+ $body = CreateEditItemDTO::fromArray($body);
+ }
+
+ $data = $body->toArray();
+
+ unset($data['article_type_id']);
+
+ return $data;
+ }
+
+ public function createDtoFromResponse(Response $response): ItemDTO
+ {
+ if (! $response->successful()) {
+ throw new Exception('Request was not successful. Unable to create DTO.');
+ }
+
+ return ItemDTO::fromArray($response->json());
+ }
+}
diff --git a/src/Requests/Items/FetchAListOfItemsRequest.php b/src/Requests/Items/FetchAListOfItemsRequest.php
new file mode 100644
index 0000000..2beaa23
--- /dev/null
+++ b/src/Requests/Items/FetchAListOfItemsRequest.php
@@ -0,0 +1,53 @@
+ $this->orderBy instanceof OrderByEnum ? $this->orderBy->value : $this->orderBy,
+ 'limit' => $this->limit,
+ 'offset' => $this->offset,
+ ];
+ }
+
+ public function createDtoFromResponse(Response $response): Collection
+ {
+ if (! $response->successful()) {
+ throw new Exception('Request was not successful. Unable to create DTO.');
+ }
+
+ $res = $response->json();
+
+ $items = collect();
+
+ foreach ($res as $item) {
+ $items->push(ItemDTO::fromArray($item));
+ }
+
+ return $items;
+ }
+}
diff --git a/src/Requests/Items/FetchAnItemRequest.php b/src/Requests/Items/FetchAnItemRequest.php
new file mode 100644
index 0000000..f4f9cc2
--- /dev/null
+++ b/src/Requests/Items/FetchAnItemRequest.php
@@ -0,0 +1,32 @@
+article_id;
+ }
+
+ public function createDtoFromResponse(Response $response): ItemDTO
+ {
+ if (! $response->successful()) {
+ throw new Exception('Request was not successful. Unable to create DTO.');
+ }
+
+ return ItemDTO::fromResponse($response);
+ }
+}
diff --git a/src/Requests/Items/SearchItemsRequest.php b/src/Requests/Items/SearchItemsRequest.php
new file mode 100644
index 0000000..91e62c4
--- /dev/null
+++ b/src/Requests/Items/SearchItemsRequest.php
@@ -0,0 +1,72 @@
+ $this->orderBy instanceof OrderByEnum ? $this->orderBy->value : $this->orderBy,
+ 'limit' => $this->limit,
+ 'offset' => $this->offset,
+ ];
+ }
+
+ protected function defaultBody(): array
+ {
+ return [
+ [
+ 'field' => $this->searchField,
+ 'value' => $this->searchTerm,
+ 'criteria' => $this->searchCriteria instanceof SearchCriteriaEnum ? $this->searchCriteria->value : $this->searchCriteria,
+ ],
+ ];
+ }
+
+ public function createDtoFromResponse(Response $response): Collection
+ {
+ if (! $response->successful()) {
+ throw new Exception('Request was not successful. Unable to create DTO.');
+ }
+
+ $res = $response->json();
+
+ $items = collect();
+
+ foreach ($res as $item) {
+ $items->push(ItemDTO::fromArray($item));
+ }
+
+ return $items;
+ }
+}
diff --git a/tests/Fixtures/Saloon/Items/create-item.json b/tests/Fixtures/Saloon/Items/create-item.json
new file mode 100644
index 0000000..1605918
--- /dev/null
+++ b/tests/Fixtures/Saloon/Items/create-item.json
@@ -0,0 +1,24 @@
+{
+ "statusCode": 201,
+ "headers": {
+ "Date": "Wed, 26 Nov 2025 11:03:45 GMT",
+ "Content-Type": "application\/json",
+ "Content-Length": "753",
+ "Connection": "keep-alive",
+ "CF-RAY": "9a48e6ace936ff00-ZRH",
+ "ratelimit-reset": "15",
+ "x-ratelimit-limit-minute": "400",
+ "x-ratelimit-remaining-minute": "384",
+ "ratelimit-limit": "400",
+ "ratelimit-remaining": "384",
+ "Cache-Control": "no-store",
+ "pragma": "no-cache",
+ "vary": "Origin",
+ "access-control-allow-origin": "https:\/\/office.bexio.com",
+ "via": "1.1 google",
+ "cf-cache-status": "DYNAMIC",
+ "Server": "cloudflare"
+ },
+ "data": "{\"id\":7,\"user_id\":1,\"article_type_id\":1,\"contact_id\":null,\"deliverer_code\":\"\",\"deliverer_name\":\"\",\"deliverer_description\":\"\",\"intern_code\":\"TEST-1764155025\",\"intern_name\":\"Test Item\",\"intern_description\":\"\",\"purchase_price\":null,\"sale_price\":null,\"purchase_total\":null,\"sale_total\":null,\"currency_id\":1,\"tax_income_id\":null,\"tax_id\":null,\"tax_expense_id\":null,\"unit_id\":null,\"is_stock\":false,\"stock_id\":null,\"stock_place_id\":null,\"stock_nr\":\"0\",\"stock_min_nr\":\"0\",\"stock_reserved_nr\":\"0\",\"stock_available_nr\":0,\"stock_picked_nr\":\"0\",\"stock_disposed_nr\":\"0\",\"stock_ordered_nr\":\"0\",\"width\":null,\"height\":null,\"weight\":null,\"volume\":null,\"html_text\":\"\",\"remarks\":\"\",\"delivery_price\":null,\"article_group_id\":null,\"account_id\":null,\"expense_account_id\":null}",
+ "context": []
+}
\ No newline at end of file
diff --git a/tests/Fixtures/Saloon/Items/delete-an-item.json b/tests/Fixtures/Saloon/Items/delete-an-item.json
new file mode 100644
index 0000000..8abfa33
--- /dev/null
+++ b/tests/Fixtures/Saloon/Items/delete-an-item.json
@@ -0,0 +1,24 @@
+{
+ "statusCode": 200,
+ "headers": {
+ "Date": "Wed, 26 Nov 2025 11:03:44 GMT",
+ "Content-Type": "application\/json",
+ "Content-Length": "16",
+ "Connection": "keep-alive",
+ "CF-RAY": "9a48e6a7aea92325-ZRH",
+ "x-ratelimit-remaining-minute": "387",
+ "x-ratelimit-limit-minute": "400",
+ "ratelimit-remaining": "387",
+ "ratelimit-limit": "400",
+ "ratelimit-reset": "16",
+ "Cache-Control": "no-store",
+ "pragma": "no-cache",
+ "vary": "Origin",
+ "access-control-allow-origin": "https:\/\/office.bexio.com",
+ "via": "1.1 google",
+ "cf-cache-status": "DYNAMIC",
+ "Server": "cloudflare"
+ },
+ "data": "{\"success\":true}",
+ "context": []
+}
\ No newline at end of file
diff --git a/tests/Fixtures/Saloon/Items/edit-an-item.json b/tests/Fixtures/Saloon/Items/edit-an-item.json
new file mode 100644
index 0000000..969d369
--- /dev/null
+++ b/tests/Fixtures/Saloon/Items/edit-an-item.json
@@ -0,0 +1,24 @@
+{
+ "statusCode": 200,
+ "headers": {
+ "Date": "Wed, 26 Nov 2025 11:03:45 GMT",
+ "Content-Type": "application\/json",
+ "Content-Length": "756",
+ "Connection": "keep-alive",
+ "CF-RAY": "9a48e6aacd3bbe70-ZRH",
+ "ratelimit-remaining": "385",
+ "ratelimit-reset": "15",
+ "x-ratelimit-limit-minute": "400",
+ "x-ratelimit-remaining-minute": "385",
+ "ratelimit-limit": "400",
+ "Cache-Control": "no-store",
+ "pragma": "no-cache",
+ "vary": "Origin",
+ "access-control-allow-origin": "https:\/\/office.bexio.com",
+ "via": "1.1 google",
+ "cf-cache-status": "DYNAMIC",
+ "Server": "cloudflare"
+ },
+ "data": "{\"id\":4,\"user_id\":1,\"article_type_id\":1,\"contact_id\":null,\"deliverer_code\":\"\",\"deliverer_name\":\"\",\"deliverer_description\":\"\",\"intern_code\":\"TEST-1764154703\",\"intern_name\":\"Updated Item Name\",\"intern_description\":\"\",\"purchase_price\":null,\"sale_price\":null,\"purchase_total\":null,\"sale_total\":null,\"currency_id\":null,\"tax_income_id\":null,\"tax_id\":null,\"tax_expense_id\":null,\"unit_id\":null,\"is_stock\":false,\"stock_id\":null,\"stock_place_id\":null,\"stock_nr\":\"0\",\"stock_min_nr\":\"0\",\"stock_reserved_nr\":0,\"stock_available_nr\":0,\"stock_picked_nr\":0,\"stock_disposed_nr\":0,\"stock_ordered_nr\":0,\"width\":null,\"height\":null,\"weight\":null,\"volume\":null,\"html_text\":\"\",\"remarks\":\"\",\"delivery_price\":null,\"article_group_id\":null,\"account_id\":null,\"expense_account_id\":null}",
+ "context": []
+}
\ No newline at end of file
diff --git a/tests/Fixtures/Saloon/Items/fetch-a-list-of-items.json b/tests/Fixtures/Saloon/Items/fetch-a-list-of-items.json
new file mode 100644
index 0000000..f58c8c7
--- /dev/null
+++ b/tests/Fixtures/Saloon/Items/fetch-a-list-of-items.json
@@ -0,0 +1,24 @@
+{
+ "statusCode": 200,
+ "headers": {
+ "Date": "Wed, 26 Nov 2025 11:03:45 GMT",
+ "Content-Type": "application\/json",
+ "Content-Length": "2227",
+ "Connection": "keep-alive",
+ "CF-RAY": "9a48e6a96c2bbe70-ZRH",
+ "x-ratelimit-remaining-minute": "386",
+ "ratelimit-limit": "400",
+ "ratelimit-remaining": "386",
+ "ratelimit-reset": "16",
+ "x-ratelimit-limit-minute": "400",
+ "Cache-Control": "no-store",
+ "pragma": "no-cache",
+ "vary": "Origin",
+ "access-control-allow-origin": "https:\/\/office.bexio.com",
+ "via": "1.1 google",
+ "cf-cache-status": "DYNAMIC",
+ "Server": "cloudflare"
+ },
+ "data": "[{\"id\":4,\"user_id\":1,\"article_type_id\":1,\"contact_id\":null,\"deliverer_code\":\"\",\"deliverer_name\":\"\",\"deliverer_description\":\"\",\"intern_code\":\"TEST-1764154703\",\"intern_name\":\"Test Item\",\"intern_description\":\"\",\"purchase_price\":null,\"sale_price\":null,\"purchase_total\":null,\"sale_total\":null,\"currency_id\":1,\"tax_income_id\":null,\"tax_id\":null,\"tax_expense_id\":null,\"unit_id\":null,\"is_stock\":false,\"stock_id\":null,\"stock_place_id\":null,\"stock_nr\":0,\"stock_min_nr\":0,\"stock_reserved_nr\":0,\"stock_available_nr\":0,\"stock_picked_nr\":0,\"stock_disposed_nr\":0,\"stock_ordered_nr\":0,\"width\":null,\"height\":null,\"weight\":null,\"volume\":null,\"html_text\":\"\",\"remarks\":\"\",\"delivery_price\":null,\"article_group_id\":null,\"account_id\":null,\"expense_account_id\":null},{\"id\":5,\"user_id\":1,\"article_type_id\":1,\"contact_id\":null,\"deliverer_code\":\"\",\"deliverer_name\":\"\",\"deliverer_description\":\"\",\"intern_code\":\"TEST-1764154888\",\"intern_name\":\"Test Item\",\"intern_description\":\"\",\"purchase_price\":null,\"sale_price\":null,\"purchase_total\":null,\"sale_total\":null,\"currency_id\":1,\"tax_income_id\":null,\"tax_id\":null,\"tax_expense_id\":null,\"unit_id\":null,\"is_stock\":false,\"stock_id\":null,\"stock_place_id\":null,\"stock_nr\":0,\"stock_min_nr\":0,\"stock_reserved_nr\":0,\"stock_available_nr\":0,\"stock_picked_nr\":0,\"stock_disposed_nr\":0,\"stock_ordered_nr\":0,\"width\":null,\"height\":null,\"weight\":null,\"volume\":null,\"html_text\":\"\",\"remarks\":\"\",\"delivery_price\":null,\"article_group_id\":null,\"account_id\":null,\"expense_account_id\":null},{\"id\":6,\"user_id\":1,\"article_type_id\":1,\"contact_id\":null,\"deliverer_code\":\"\",\"deliverer_name\":\"\",\"deliverer_description\":\"\",\"intern_code\":\"TEST-1764154940\",\"intern_name\":\"Test Item\",\"intern_description\":\"\",\"purchase_price\":null,\"sale_price\":null,\"purchase_total\":null,\"sale_total\":null,\"currency_id\":1,\"tax_income_id\":null,\"tax_id\":null,\"tax_expense_id\":null,\"unit_id\":null,\"is_stock\":false,\"stock_id\":null,\"stock_place_id\":null,\"stock_nr\":0,\"stock_min_nr\":0,\"stock_reserved_nr\":0,\"stock_available_nr\":0,\"stock_picked_nr\":0,\"stock_disposed_nr\":0,\"stock_ordered_nr\":0,\"width\":null,\"height\":null,\"weight\":null,\"volume\":null,\"html_text\":\"\",\"remarks\":\"\",\"delivery_price\":null,\"article_group_id\":null,\"account_id\":null,\"expense_account_id\":null}]",
+ "context": []
+}
\ No newline at end of file
diff --git a/tests/Fixtures/Saloon/Items/fetch-an-item.json b/tests/Fixtures/Saloon/Items/fetch-an-item.json
new file mode 100644
index 0000000..a068706
--- /dev/null
+++ b/tests/Fixtures/Saloon/Items/fetch-an-item.json
@@ -0,0 +1,24 @@
+{
+ "statusCode": 200,
+ "headers": {
+ "Date": "Wed, 26 Nov 2025 11:03:44 GMT",
+ "Content-Type": "application\/json",
+ "Content-Length": "752",
+ "Connection": "keep-alive",
+ "CF-RAY": "9a48e6a5bbafbc47-ZRH",
+ "x-ratelimit-remaining-minute": "389",
+ "ratelimit-limit": "400",
+ "ratelimit-remaining": "389",
+ "ratelimit-reset": "16",
+ "x-ratelimit-limit-minute": "400",
+ "Cache-Control": "no-store",
+ "pragma": "no-cache",
+ "vary": "Origin",
+ "access-control-allow-origin": "https:\/\/office.bexio.com",
+ "via": "1.1 google",
+ "cf-cache-status": "DYNAMIC",
+ "Server": "cloudflare"
+ },
+ "data": "{\"id\":3,\"user_id\":1,\"article_type_id\":1,\"contact_id\":null,\"deliverer_code\":\"\",\"deliverer_name\":\"\",\"deliverer_description\":\"\",\"intern_code\":\"TEST-1764154690\",\"intern_name\":\"Updated Item Name\",\"intern_description\":\"\",\"purchase_price\":null,\"sale_price\":null,\"purchase_total\":null,\"sale_total\":null,\"currency_id\":null,\"tax_income_id\":null,\"tax_id\":null,\"tax_expense_id\":null,\"unit_id\":null,\"is_stock\":false,\"stock_id\":null,\"stock_place_id\":null,\"stock_nr\":0,\"stock_min_nr\":0,\"stock_reserved_nr\":0,\"stock_available_nr\":0,\"stock_picked_nr\":0,\"stock_disposed_nr\":0,\"stock_ordered_nr\":0,\"width\":null,\"height\":null,\"weight\":null,\"volume\":null,\"html_text\":\"\",\"remarks\":\"\",\"delivery_price\":null,\"article_group_id\":null,\"account_id\":null,\"expense_account_id\":null}",
+ "context": []
+}
\ No newline at end of file
diff --git a/tests/Fixtures/Saloon/Items/search-items.json b/tests/Fixtures/Saloon/Items/search-items.json
new file mode 100644
index 0000000..051bd6d
--- /dev/null
+++ b/tests/Fixtures/Saloon/Items/search-items.json
@@ -0,0 +1,24 @@
+{
+ "statusCode": 200,
+ "headers": {
+ "Date": "Wed, 26 Nov 2025 11:03:45 GMT",
+ "Content-Type": "application\/json",
+ "Content-Length": "2",
+ "Connection": "keep-alive",
+ "CF-RAY": "9a48e6ae3e110396-ZRH",
+ "ratelimit-reset": "15",
+ "x-ratelimit-remaining-minute": "249",
+ "x-ratelimit-limit-minute": "250",
+ "ratelimit-remaining": "249",
+ "ratelimit-limit": "250",
+ "Cache-Control": "no-store",
+ "pragma": "no-cache",
+ "vary": "Origin",
+ "access-control-allow-origin": "https:\/\/office.bexio.com",
+ "via": "1.1 google",
+ "cf-cache-status": "DYNAMIC",
+ "Server": "cloudflare"
+ },
+ "data": "[]",
+ "context": []
+}
\ No newline at end of file
diff --git a/tests/Pest.php b/tests/Pest.php
index 46258fc..d35a8eb 100644
--- a/tests/Pest.php
+++ b/tests/Pest.php
@@ -12,3 +12,13 @@
Saloon::fake([]);
})
->in(__DIR__);
+
+/**
+ * Helper function to check if fixtures should be reset/regenerated.
+ * Set RESET_FIXTURES=true in phpunit.xml to regenerate fixtures from live API.
+ * Defaults to false (use existing fixtures).
+ */
+function shouldResetFixtures(): bool
+{
+ return filter_var(getenv('RESET_FIXTURES') ?: false, FILTER_VALIDATE_BOOLEAN);
+}
diff --git a/tests/Requests/Items/CreateItemRequestTest.php b/tests/Requests/Items/CreateItemRequestTest.php
new file mode 100644
index 0000000..1ce7c84
--- /dev/null
+++ b/tests/Requests/Items/CreateItemRequestTest.php
@@ -0,0 +1,41 @@
+ MockResponse::fixture('Items/create-item'),
+ ]);
+
+ $connector = new BexioConnector(new ConnectWithToken);
+
+ $response = $connector->send(new CreateItemRequest(
+ new CreateEditItemDTO(
+ user_id: null,
+ article_type_id: 1,
+ contact_id: null,
+ deliverer_code: null,
+ deliverer_name: null,
+ deliverer_description: null,
+ intern_code: 'TEST-'.time(),
+ intern_name: 'Test Item'
+ )
+ ));
+
+ expect($response->successful())->toBeTrue();
+ expect($response->dto())->toBeInstanceOf(ItemDTO::class);
+
+ Saloon::assertSent(CreateItemRequest::class);
+})->group('items');
diff --git a/tests/Requests/Items/DeleteAnItemRequestTest.php b/tests/Requests/Items/DeleteAnItemRequestTest.php
new file mode 100644
index 0000000..b567140
--- /dev/null
+++ b/tests/Requests/Items/DeleteAnItemRequestTest.php
@@ -0,0 +1,38 @@
+ MockResponse::fixture('Items/delete-an-item'),
+ FetchAListOfItemsRequest::class => MockResponse::fixture('Items/fetch-a-list-of-items'),
+ ]);
+
+ $connector = new BexioConnector(new ConnectWithToken);
+
+ $itemsResponse = $connector->send(new FetchAListOfItemsRequest);
+ $existingItem = $itemsResponse->dto()->first();
+
+ if (! $existingItem) {
+ $this->markTestSkipped('No items found in the system to delete');
+ }
+
+ $response = $connector->send(new DeleteAnItemRequest(article_id: $existingItem->id));
+
+ expect($response->successful())->toBeTrue();
+
+ Saloon::assertSent(DeleteAnItemRequest::class);
+})->group('items');
diff --git a/tests/Requests/Items/EditAnItemRequestTest.php b/tests/Requests/Items/EditAnItemRequestTest.php
new file mode 100644
index 0000000..1b9d5f4
--- /dev/null
+++ b/tests/Requests/Items/EditAnItemRequestTest.php
@@ -0,0 +1,53 @@
+ MockResponse::fixture('Items/edit-an-item'),
+ FetchAListOfItemsRequest::class => MockResponse::fixture('Items/fetch-a-list-of-items'),
+ ]);
+
+ $connector = new BexioConnector(new ConnectWithToken);
+
+ $itemsResponse = $connector->send(new FetchAListOfItemsRequest);
+ $existingItem = $itemsResponse->dto()->first();
+
+ if (! $existingItem) {
+ $this->markTestSkipped('No items found in the system to edit');
+ }
+
+ $response = $connector->send(new EditAnItemRequest(
+ article_id: $existingItem->id,
+ data: new CreateEditItemDTO(
+ user_id: $existingItem->user_id,
+ article_type_id: $existingItem->article_type_id,
+ contact_id: $existingItem->contact_id,
+ deliverer_code: $existingItem->deliverer_code,
+ deliverer_name: $existingItem->deliverer_name,
+ deliverer_description: $existingItem->deliverer_description,
+ intern_code: $existingItem->intern_code,
+ intern_name: 'Updated Item Name'
+ )
+ ));
+
+ expect($response->successful())->toBeTrue();
+ expect($response->dto())->toBeInstanceOf(ItemDTO::class);
+
+ Saloon::assertSent(EditAnItemRequest::class);
+})->group('items');
diff --git a/tests/Requests/Items/FetchAListOfItemsRequestTest.php b/tests/Requests/Items/FetchAListOfItemsRequestTest.php
new file mode 100644
index 0000000..9260ce9
--- /dev/null
+++ b/tests/Requests/Items/FetchAListOfItemsRequestTest.php
@@ -0,0 +1,28 @@
+ MockResponse::fixture('Items/fetch-a-list-of-items'),
+ ]);
+
+ $connector = new BexioConnector(new ConnectWithToken);
+ $response = $connector->send(new FetchAListOfItemsRequest);
+
+ expect($response->successful())->toBeTrue();
+ expect($response->dto())->toBeInstanceOf(Collection::class);
+
+ Saloon::assertSent(FetchAListOfItemsRequest::class);
+})->group('items');
diff --git a/tests/Requests/Items/FetchAnItemRequestTest.php b/tests/Requests/Items/FetchAnItemRequestTest.php
new file mode 100644
index 0000000..93e16f7
--- /dev/null
+++ b/tests/Requests/Items/FetchAnItemRequestTest.php
@@ -0,0 +1,40 @@
+ MockResponse::fixture('Items/fetch-an-item'),
+ FetchAListOfItemsRequest::class => MockResponse::fixture('Items/fetch-a-list-of-items'),
+ ]);
+
+ $connector = new BexioConnector(new ConnectWithToken);
+
+ $itemsResponse = $connector->send(new FetchAListOfItemsRequest);
+ $existingItem = $itemsResponse->dto()->first();
+
+ if (! $existingItem) {
+ $this->markTestSkipped('No items found in the system to fetch');
+ }
+
+ $response = $connector->send(new FetchAnItemRequest(article_id: $existingItem->id));
+
+ expect($response->successful())->toBeTrue();
+ expect($response->dto())->toBeInstanceOf(ItemDTO::class);
+
+ Saloon::assertSent(FetchAnItemRequest::class);
+})->group('items');
diff --git a/tests/Requests/Items/SearchItemsRequestTest.php b/tests/Requests/Items/SearchItemsRequestTest.php
new file mode 100644
index 0000000..09718cb
--- /dev/null
+++ b/tests/Requests/Items/SearchItemsRequestTest.php
@@ -0,0 +1,32 @@
+ MockResponse::fixture('Items/search-items'),
+ ]);
+
+ $connector = new BexioConnector(new ConnectWithToken);
+
+ $response = $connector->send(new SearchItemsRequest(
+ searchField: 'intern_name',
+ searchTerm: 'DocuWare'
+ ));
+
+ expect($response->successful())->toBeTrue();
+ expect($response->dto())->toBeInstanceOf(Collection::class);
+
+ Saloon::assertSent(SearchItemsRequest::class);
+})->group('items');