{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"3854b824-3162-4c02-a47b-af2012073033","name":"wFirma.pl","description":"# Autoryzacja\n\n## API Key\n\nAPI Key jest kluczem interfejsu programistycznego aplikacji pozwalającym posiadaczowi na uwierzytelnienie akcji wykonywanych po stronie wfirma.pl za pomocą interfejsu API.\n\n##### Niezbędne informacje\n\nPo stronie systemu wFirma w zakładce Ustawienia >> Bezpieczeństwo >> Aplikacje >> Klucze API możliwe jest utworzenie dwóch kluczy API (**accessKey** oraz **secretKey**).\n\nDo poprawnego działania autoryzacji API Key wymagane są 3 klucze:\n\n- **accessKey** - uzyskiwany według powyżej przedstawionej instrukcji\n    \n- **secretKey** - uzyskiwany według powyżej przedstawionej instrukcji\n    \n- **appKey** - dostarczane przez wfirma.pl indywidualnie dla każdej aplikacji\n    \n\nUżytkownik powinien mieć na uwadze, że **secretKey** zostanie wyświetlony wyłącznie **raz** podczas tworzenia kluczy oraz że **każda** modyfikacja klucza aplikacji z poziomu zakładki Ustawienia >> Bezpieczeństwo >> Aplikacje >> Klucze, będzie skutkowała zmianą **accessKey** oraz **secretKey**.\n\n##### Uzyskiwanie appKey\n\nKlucz AppKey, jest kluczem wymaganym dla twórców integracji. Ma on na celu zautoryzować zapytania wysyłane przez daną integrację (jeden klucz appKey może obsłużyć wiele kont użytkowników w systemie wFirma). W celu uzyskania appKey konieczne jest uzupełnienie formularza dostępnego [tutaj](https://wfirma.pl/kontakt/1#appKey).\n\nW formularzu proszę zawrzeć informacje:\n\n- nazwa aplikacji\n    \n- numer telefonu\n    \n- adres e-mail\n    \n- adres www\n    \n\nPo uzupełnieniu formularza, na podany adres e-mail zostanie wysłana wiadomość z kluczem appKey.\n\n##### Pobieranie danych z API\n\nPo uzyskaniu 3 wcześniej wymienionych kluczy należy je przesłać w nagłówkach zapytania:\n\n- **accessKey**: \"{accessKey}\"\n    \n- **secretKey**: \"{secretKey}\"\n    \n- **appKey**: \"{appKey}\"\n    \n\nW odróżnieniu od metod autoryzacji oAuth, w przypadku wykorzystania API Key nie ma potrzeby dodawania do zapytania żadnego parametru określającego rodzaj autoryzacji.\n\nPrzykład wprowadzonych kluczy w nagłówkach zapytania:\n\n```\n--header 'accessKey: ********************************' \\\n--header 'secretKey: ********************************' \\\n--header 'appKey: ********************************' \\\n\n ```\n\n## OAuth\n\nOAuth jest otwartym standardem autoryzacyjnym umożliwiającym wykonanie autoryzacji po stronie wfirma.pl. Użytkownik logujący się do wfirma.pl uwierzytelnia aplikację do konkretnych modułów. Więcej o OAuth na wikipedia.org oraz oauth.net.\n\n### Oauth 1.0a\n\nW wfirma.pl możliwa jest autoryzacja po OAuth w wersji 1.0a. Serwis akceptuje jedynie zapytania, które nie są szyfrowane na poziomie protokołu OAuth (signature method = plaintext), więc komunikacja powinna odbywać się przez SSL z użyciem protokołu HTTPS. Zapytania requestToken i accessToken powinny być wykonane metodą GET.\n\nZapytania URL nie różnią się w żaden sposób od zapytań realizowanych przy autoryzacji przez mechanizm HTTP Basic Auth. Jedyne zmiany wynikają z dodatkowych nagłówków, koniecznych przy OAuth oraz komunikacji przez HTTPS, zamiast HTTP.\n\n##### Niezbędne informacje\n\n- **consumer_key, consumer_secret** - dostarczane przez wfirma.pl indywidualnie dla każdej aplikacji\n    \n- **server_uri** - [https://api2.wfirma.pl](https://api2.wfirma.pl)\n    \n- **signature_method** - PLAINTEXT\n    \n- **request_token_uri** - [https://wfirma.pl/oauth/requestToken](https://wfirma.pl/oauth/requestToken)\n    \n- **authorize_uri** - [https://wfirma.pl/oauth/authorize](https://wfirma.pl/oauth/authorize)\n    \n- **access_token_uri** - [https://wfirma.pl/oauth/accessToken](https://wfirma.pl/oauth/accessToken)\n    \n\n##### Uzyskiwanie consumer_key oraz consumer_secret\n\nW celu uzyskania consumer_key oraz consumer_secret (varchar(32)) konieczne jest wysłanie wiadomości na adres e-mail [pomoc@wfirma.pl](https://mailto:pomoc@wfirma.pl). W wiadomości proszę zawrzeć informacje:\n\n- nazwa producenta\n    \n- numer telefonu producenta\n    \n- adres e-mail producenta\n    \n- adres www producenta\n    \n- nazwa aplikacji\n    \n- krótki opis aplikacji\n    \n\n##### Uprawnienia aplikacji\n\nPlatforma API została podzielona na zakresy (scopes). Możliwe jest uzyskanie dostępu do jednego lub więcej zakresów jednocześnie. Każdy moduł API dzieli się na dwa zakresy: do odczytu i do zapisu. Zakresy określane są w następujący sposób: -, np. invoices-read lub invoices-write. Zakres do odczytu najczęściej określa dostęp do metod find/get, natomiast zakres do zapisu add/edit/delete.\n\nW przypadku próby zapytania do zakresu, do którego nie ma się dostępu zwracany jest komunikat błędu DENIED_SCOPE_REQUESTED. Taka sytuacja powinna być obsłużona po stronie aplikacji.\n\n##### Uzyskanie autoryzacji użytkownika\n\nUzyskanie autoryzacji aplikacji przez użytkownika skutkuje przydzieleniem access_token oraz access_token_secret (varchar(32)), które powinny być zapamiętane po stronie aplikacji, ponieważ konieczne jest ich wykorzystanie przy każdym zapytaniu do API.\n\nUzyskiwanie tych danych odbywa się zgodnie z dokumentacją OAuth. Przykładową implementację można znaleźć poniżej.\n\nImplementacja podstawowych funkcji przy korzystaniu z biblioteki [OAuth w PHP](https://www.php.net/manual/en/book.oauth.php).\n\n##### Zgoda użytkownika na dostęp do danych\n\n```\nfunction requestToken() {\n    $consumerKey = 'tutaj nadany consumer_key';\n    $consumerSecret = 'tutaj nadany consumer_secret';\n    $oAuth = new OAuth($consumerKey, $consumerSecret, OAUTH_SIG_METHOD_PLAINTEXT);\n    $scope = 'invoices-read,invoices-write,contractors-read,contractors-write';\n    $callback = 'http://mypage.example.com/callback.php';\n    try {\n        $tokenInfo = $oAuth->getRequestToken(\n            'https://wfirma.pl/oauth/requestToken?scope=' . $scope,\n            $callback,\n            'GET'\n        );\n        $_SESSION['oauthSecret'] = $tokenInfo['oauth_token_secret'];\n        header('Location: https://wfirma.pl/oauth/authorize?oauth_token=' . $tokenInfo['oauth_token']);\n    } catch (OAuthException $exception) {\n    }\n}\n\n ```\n\n##### Uzyskanie access_token oraz access_token_secret\n\n```\nfunction accessToken() {\n    $oAuth = new OAuth(CONSUMER_KEY, CONSUMER_SECRET, OAUTH_SIG_METHOD_PLAINTEXT);\n    $oAuth->setToken($_GET['oauth_token'], $_SESSION['oauthSecret']);\n    unset($_SESSION['oauthSecret']);\n    try {\n        $tokenInfo = $oAuth->getAccessToken(\n            'https://wfirma.pl/oauth/accessToken?oauth_verifier=' . $_GET['oauth_verifier'],\n            null,\n            null,\n            'GET'\n        );\n    } catch (OAuthException $exception) {\n        // Wystąpił błąd podczas autoryzacji.\n        return;\n    }\n    $_SESSION['oauth_token_secret'] = $tokenInfo['oauth_token_secret'];\n    $_SESSION['oauth_token'] = $tokenInfo['oauth_token'];\n    header('Location: /');\n}\n\n ```\n\n##### Pobieranie danych z API\n\n```\nfunction oauthRequest($action, $data = []) {\n    $oAuth = new OAuth(CONSUMER_KEY, CONSUMER_SECRET, OAUTH_SIG_METHOD_PLAINTEXT);\n    $oAuth->setToken($_SESSION['oauth_token'], $_SESSION['oauth_token_secret']);\n    try {\n        $oAuth->fetch(\n            'https://api2.wfirma.pl/' . $action,\n            !empty($data) ? $data : '',\n            OAUTH_HTTP_METHOD_POST\n        );\n    } catch (Exception $exception) {\n        return false;\n    }\n    return $oAuth->getLastResponse();\n}\n\n ```\n\n## Oauth 2.0\n\n### Tworzenie aplikacji\n\nPo stronie systemu wFirma w zakładce Ustawienia >> Bezpieczeństwo >> Aplikacje >> Aplikacje OAuth 2.0 możliwe jest utworzenie aplikacji, gdzie należy uzupełnić pola:\n\n- **Nazwę aplikacji**\n    \n- **Zakres (scope)** umożliwiający dostęp do wybranych zasobów\n    \n- **Adres zwrotny (redirect_uri)**\n    \n- **Adres IP klienta**\n    \n\nUtworzenie aplikacji możliwe jest wyłacznie w przypadku posiadania [zweryfikowanej firmy](https://pomoc.wfirma.pl/-weryfikacja-firmy) w systemie.  \nPo utworzeniu aplikacji zostanie ona poddana weryfikacji przez pracowników wFirma.\n\nDo zweryfikowanej aplikacji zostaną przydzielone indywidualne klucze (**client_id** oraz **client_secret**) widoczne po kliknięciu w nazwę aplikacji.\n\n### Autoryzacja użytkownika\n\nUdostępniamy autoryzację typu **Authorization Code**.  \nKorzystając ze sparametryzowanego żadania HTTP do zasobu pozwalającego na uwierzytelnienie użytkownika:\n\n```\nhttps://wfirma.pl/oauth2/auth?response_type=code&client_id={client_id}&scope=invoices-read invoices-write&redirect_uri=https://example.com\n\n ```\n\n##### Wymagane Parametry\n\n- **response_type**\n    \n- **client_id**\n    \n- **scope**\n    \n- **redirect_uri**\n    \n\nWówczas w odpowiedzi serwera zostanie zwrócony authorization_code, który należy przesłać wysyłając żądanie:\n\n```\nhttps://api2.wfirma.pl/oauth2/token?oauth_version=2\n\n ```\n\n##### Wymagane pola\n\n- **grant_type**: \"authorization_code\"\n    \n- **code**: \"{authorization_code}\"\n    \n- **redirect_uri**: \"{redirect_uri}\"\n    \n- **client_id**: \"{client_id}\"\n    \n- **client_secret**: \"{client_secret}\"\n    \n\nW odpowiedzi serwera zostanie zwrócony access_token, który służy do uwierzytelnienia użytkownika podczas wyciągania zasobów z API. Należy go przesłać w nagłówku **Authorization** (Bearer) podczas wysyłania zapytań do API.  \nOdpytywanie API odbywa się standarowo korzystając z dostępnych akcji. Dodatkowo należy przekazać parametr:\n\n```\n?oauth_version=2\n\n ```\n\n# Komunikacja\n\n## Konwencja nazw akcji\n\nNazewnictwo akcji z założenia jest stałe:\n\n- get\n    \n- find\n    \n- add\n    \n- edit\n    \n- delete\n    \n\nZdarzają się dodatkowe akcje, które nie zawierają się w powyższej liście, np. `/invoices/download`.\n\nSzczegółowy opis akcji dostępnych w danym module znajduje się przy dokumentacji konkretnego modułu.\n\nOdnośniki URL akcji tworzone są w konwencji: `https://api2.wfirma.pl/NAZWA_MODUŁU/NAZWA_AKCJI`. Podawanie id do akcji odbywa się w sposób: `https://api2.wfirma.pl/NAZWA_MODUŁU/NAZWA_AKCJI/IDENTYFIKATOR`, chyba że jest napisane inaczej.\n\n## Parametr company_id\n\nW przypadku jeśli użytkownik posiada wiele firm w systemie wFirma, powinien wybrać odpowiednią firmę do odpytania za pomocą parametru `comapny_id`.  \nPrzykładowe wykorzystanie: `https://api2.wfirma.pl/invoices/find?outputFormat=xml&inputFormat=xml&company_id=ID_FIRMY`.  \nBrak podania danego parametru może wiązać się z tym, że zapytanie zostanie wysłane do niepożądenj firmy użytkownika w systemie.\n\n## Format wymiany danych\n\nKażdorazowo w każdym zapytaniu lub odpowiedzi mamy do czynienia z maksymalnie dwoma gałęziami najwyższego poziomu. W formacie XML objęte są one gałęzią **api**. Dwie główne gałęzie to:\n\n- **status** - zawiera w sobie gałąź code z ogólnym kodem zapytania.\n    \n- Gałąź o nazwie modułu w formie mnogiej, np. **invoices**. Gałąź ta zawiera w sobie gałęzie:\n    \n    - **parameters** - parametry zapytania\n        \n    - Gałąź o nazwie modułu w formie pojedynczej, np. **invoice**. Ilość tych gałęzi może być dowolna. Przy formacie JSON takie gałęzie **muszą być zawsze** numerowane za pomocą klucza (nawet jeśli istnieje tylko jedna taka gałąź). Od tej gałęzi wychodzą kolejne gałęzie, których kolejność nie ma znaczenia i mogą to być:\n        \n        - Identyfikujące poszczególne pola, np. **id**, **date**. Szczegółowe opisy pól gałęzi można znaleźć na podstronach poszczególnych modułów.\n            \n        - Gałęzie identyfikujące powiązane moduły, np: zawartość faktury (**invoice_content**) wewnątrz rekordu faktury (**invoice**).  \n            Szczegółowe informacje na temat możliwych powiązań modułów można znaleźć przy opisie każdego z modułów\n            \n            - Forma skrócona: gałąź zawiera jedynie pole **id**. O szczegółowe dane należy dopytać się osobnym zapytaniem.\n                \n            - Forma pełna: gałąź zawiera wszystkie pola powiązanego modułu. Opisy poszczególnych pól można znaleźć w sekcji nt. modułu powiązanego.\n                \n            - Typ pojedynczy - nazwa gałęzi jest w formie pojedynczej: powiązany jest maksymalnie jeden rekord tego modułu (np. **company_details**).\n                \n            - Typ mnogi - nazwa gałęzi jest w formie mnogiej: możliwe powiązanie większej ilości rekordów tego modułu. Każdy z rekordów znajduje się w osobnej gałęzi o nazwie modułu w formie pojedynczej.\n                \n\n##### Przykładowa odpowiedź\n\n```\n<invoices>\n   <invoice> \n      <id>1207242</id> \n      <date>2011-12-22</date> \n      <company_detail>\n         <id>702218</id>\n         <name>PPHU Komputery-Kowalski</name>\n         <altname>Komputery-Kowalski</altname>\n         <nip>8982073475</nip>\n         <street>Legnicka</street>\n         <building_number>33</building_number>\n         <flat_number>12</flat_number>\n         <zip>54-162</zip>\n         <post>Wrocław</post>\n         <city>Wrocław</city>\n         <bank_name>BZWBK</bank_name>\n         <bank_account>59 1111 2222 3333 4444 5555 6666</bank_account>\n         <bank_swift></bank_swift>\n         <bank_address></bank_address>\n         <created>2011-12-22 11:23:12</created>\n         <modified>2011-12-22 11:23:12</modified>\n      </company_detail>\n      <invoicecontents>\n         <invoicecontent>\n            <id>3187305</id>\n            <name>makulatura 2011</name>\n            <classification></classification>\n            <unit>kg</unit>\n            <count>4850.0000</count>\n            <price>0.20</price>\n            <price_modified>0</price_modified>\n            <discount>1</discount>\n            <discount_percent>0.00</discount_percent>\n            <netto>970.00</netto>\n            <brutto>1193.10</brutto>\n            <lumpcode></lumpcode>\n            <created>2011-12-22 11:23:12</created>\n            <modified>2011-12-22 11:23:12</modified>\n            <vat>23</vat>\n            <good>\n               <id>0</id>\n            </good>\n            <invoice>\n               <id>1207242</id>\n            </invoice>\n            <tangiblefixedasset>\n               <id>0</id>\n            </tangiblefixedasset>\n            <equipment>\n               <id>0</id>\n            </equipment>\n            <vehicle>\n               <id></id>\n            </vehicle>\n         </invoicecontent>\n      </invoicecontents>\n      <series>\n         <id>1</id>\n      </series>\n      <translation_language>\n         <id>0</id>\n      </translation_language>\n   </invoice>\n   <parameters>\n      <limit>20</limit>\n      <page>1</page>\n      <total>11</total>\n   </parameters>\n</invoices>\n<status>\n   <code>OK</code>\n</status>\n\n ```\n\n## Implementacja\n\nImplementacja po stronie klienta API nie powinna zwracać uwagi na kolejność gałęzi o różnych nazwach.\n\nJeżeli mamy do czynienia z dwoma gałęziami o tej samej nazwie, to ich kolejność może mieć znaczenie (np. w przypadku akcji /invoices/find segregowanej po dacie wystawienia).\n\nW przyszłości wraz z rozrostem API mogą znaleźć się w odpowiedzi gałęzie, których teraz nie przewidziano. Powinno się wziąć to pod uwagę podczas implementacji klienta API - dodatkowe elementy w odpowiedzi nie powinny mieć znaczenia przy realizacji danej akcji.\n\nObie poniższe gałęzie są równoważne\n\n```\n<user>\n    <id>124233</id>\n    <login>jan@kowalski.com</login>\n</user>\n\n ```\n\n```\n<user>\n    <login>jan@kowalski.com</login>\n    <id>124233</id>\n</user>\n\n ```\n\n## Format wejściowy / wyjściowy\n\nWybór preferowanego formatu przez klienta API odbywa się za pomocą dodatkowych parametrów (inputFormat i outputFormat) przekazanych w URL'u, np: `https://api2.wfirma.pl/companies/add?inputFormat=json&outputFormat=xml`.\n\nDozwolone wartości to: **xml** (domyślny) i **json**.\n\nJeśli nie został ustawiony format wyjściowy, to jest on tożsamy z formatem wejściowym.\n\nSerwer API w transparentny sposób konwertuje z/do każdego obsługiwanego formatu.\n\n> Poniżej jest przykładowa, standardowa odpowiedź na /users/get/124233, /users/add lub /users/edit/124233  \nusers > user to jest nowo dodany / zmodyfikowany / znaleziony rekord  \nid, login, created, modified są polami rekordu  \nstatus > code - ogólny status odpowiedzi \n  \n\n##### Odpowiedź w XML\n\n```\n <api>\n     <users>\n         <user>\n             <id>124233</id>\n             <login>jan@kowalski.com</login>\n             <created>0000-00-00 00:00:00</created>\n             <modified>0000-00-00 00:00:00</modified>\n         </user>\n     </users>\n     <status>\n         <code>OK</code>\n     </status>\n </api>\n\n ```\n\n##### Odpowiedź w JSON\n\n```\n{\n   \"users\":{\n      \"0\":{\n         \"user\":{\n            \"id\":\"USER_ID\",\n            \"login\":\"EMAIL\",\n            \"created\":\"0000-00-00 00:00:00\",\n            \"modified\":\"0000-00-00 00:00:00\"\n         }\n      }\n   },\n   \"status\":{\n      \"code\":\"OK\"\n   }\n}\n\n ```\n\n## Komunikaty błędów\n\n##### Przerywające komunikaty błędów\n\n- **ACCESS DENIED** - Uprawnienia nie pozwalają na wykonanie akcji.\n    \n- **ACTION NOT FOUND** - Wywoływana akcja nie istnieje. Sprawdź czy w poprawny sposób podałeś odnośnik.\n    \n- **AUTH** - Wykonanie akcji wymaga podania nazwy użytkownika i hasła. Ten błąd wyświetla się także w przypadku niepoprawnej nazwy użytkownika lub hasła.\n    \n- **AUTH FAILED LIMIT WAIT 5 MINUTES** - Przekroczono limit nieudanych prób logowania.\n    \n- **COMPANY ID REQUIRED** - W przypadku gdy konto powiązane jest z wieloma firmami, należy podać id firmy w parametrze url-a ?company_id. Listę firm można pobrać akcją /user_companies/find.\n    \n- **DENIED SCOPE REQUESTED** - Próba wywołania zakresu do którego nie ma się dostępu (tylko przy autoryzacji przez OAuth).\n    \n- **ERROR** - Podczas próby dodania lub modyfikacji obiektu wystąpiły błędy walidacji. Szczegółowe informacje na temat błędów walidacji znajdują się niżej.\n    \n- **FATAL** - Wewnętrzny błąd API. Nie powinien nastąpić. Takie zdarzenia będą monitorowane i analizowane indywidualnie.\n    \n- **INPUT ERROR** - Podane dane wejściowe są niepoprawne. Np. struktura XML jest nieprawidłowa.\n    \n- **NOT FOUND** - Podany obiekt nie istnieje.\n    \n- **OUT OF SERVICE** - Serwis API tymczasowo wyłączony. Proszę spróbować później. Wyłączenia serwisu można się spodziewać podczas aktualizacji wfirma.pl lub samego API.\n    \n- **SNAPSHOT LOCK** - Trwa odtwarzanie danych firmy z kopii zapasowej. Wszystkie operacje są zablokowane.\n    \n- **TOTAL REQUESTS LIMIT EXCEEDED** - Przekroczono limit liczby zapytań do API.\n    \n- **TOTAL EXECUTION TIME LIMIT EXCEEDED** - Przekroczono limit czasu wykonywania zapytań do API.  \n    Z uwagi na to, że limity zależne są od aktualnego obciążenia serwera, zalecane jest wykonywanie zapytań w nocy. Należy również w miarę możliwości unikać wysyłania wielu zapytań w krótkich odstępach czasu.\n    \n\n##### Przykład\n\n```\n<api>\n    <status>\n        <code>TYP BŁĘDU</code>\n    </status>\n</api>\n\n ```\n\n## Walidacyjne komunikaty błędów\n\nWalidacyjne komunikaty błędów doklejają do wysłanych wejściowych błędy i wysyłają je jako dane wyjściowe. Błędy są doklejane w gałęzi pojedynczego rekordu (np. api > invoices > invoice).\n\nCechy błędów walidacji:\n\n- Może istnieć wiele gałęzi errors > error.\n    \n- Gałąź errors > error > method > parameters zostaje pusta, jeśli parametry nie istnieją.\n    \n- W przypadku wystąpienia błędu walidacji ogólny status (api > status > code) przyjmuje wartość ERROR.\n    \n\n##### Struktura błędu walidacji\n\n```\n<errors>\n    <error>\n        <field>nazwa pola</field>\n        <message>wiadomość walidacyjna</message>\n        <method>\n            <name>typ błędu</name>\n            <parameters>\n                parametr_1,parametr_2,parametr_3\n            </parameters>\n        </method>\n    </error>\n</errors>\n\n ```\n\n##### Przykładowy rekord z błędami walidacji\n\n```\n<api>\n    <invoices>\n        <invoice>\n            <paymentmethod>cash</paymentmethod>\n            <paymentdate>2011-08-15</paymentdate>\n            <type>normal</type>\n            <errors>\n                <error>\n                    <field>date</field>\n                    <message>Data musi być w formacie RRRR-MM-DD</message>\n                </error>\n            </errors>\n            <contractor>\n                <errors>\n                    <error>\n                        <field>name</field>\n                        <message>Pole nie może być puste</message>\n                    </error>\n                    <error>\n                        <field>street</field>\n                        <message>Pole nie może być puste</message>\n                    </error>\n                    <error>\n                        <field>zip</field>\n                        <message>Pole nie może być puste</message>\n                    </error>\n                    <error>\n                        <field>city</field>\n                        <message>Pole nie może być puste</message>\n                    </error>\n                </errors>\n            </contractor>\n            <invoicecontents>\n                <invoicecontent>\n                    <name>nazwa produktu</name>\n                    <unit>szt.</unit>\n                    <count>1</count>\n                    <price>100</price>\n                    <price_modified>0</price_modified>\n                    <vat>23</vat>\n                </invoicecontent>\n                <invoicecontent>\n                    <unit>szt.</unit>\n                    <count>1</count>\n                    <price>100</price>\n                    <price_modified>0</price_modified>\n                    <vat>23</vat>\n                    <errors>\n                        <error>\n                            <field>name</field>\n                            <message>Treść nie moze być pusta</message>\n                        </error>\n                    </errors>\n                </invoicecontent>\n            </invoicecontents>\n        </invoice>\n    </invoices>\n    <status>\n        <code>ERROR</code>\n    </status>\n</api>\n\n ```\n\n## Konstruowanie zapytań find\n\nMetoda find w każdym dostępnym module API umożliwia przekazywanie dodatkowych warunków do zapytania, możliwe jest przekazanie:\n\n- ilości wyników na stronę\n    \n- nr strony z wynikami (page: liczone od 1)\n    \n    ##### Zapytanie o **2 stronę** wyników z limitem **10 na stronę**\n    \n    ```\n                <api>\n                  <goods>\n                      <parameters>\n                          <page>2</page>\n                          <limit>10</limit>\n                      </parameters>\n                  </goods>\n                </api>\n    \n     ```\n    \n- Ograniczenie zbioru wyników wyszukiwania do określonych pól. Parametr może w znacznym stopniu poprawić wydajność zapytań.\n    \n    ```\n                <api>\n                  <invoices>\n                      <parameters>\n                          <fields>\n                              <field>Invoice.id</field>\n                              <field>Invoice.fullnumber</field>\n                              <field>Invoice.date</field>\n                              <field>InvoiceContent.name</field>\n                              <field>InvoiceContent.price</field>\n                          </fields>\n                      </parameters>\n                  </invoices>\n                </api>\n    \n     ```\n    \n- Warunki zapytania (conditions, odpowiednik WHERE w SQL). Można w nich wykorzystywać pola powiązanych modułów, które są w relacji 1-1.\n    \n    - sekcja **conditions** może zawierać jedną lub więcej sekcji **condition**\n        \n    - domyślnym spójnikiem jest AND\n        \n    - warunki można łączyć\n        \n    - pole **operator** może przyjmować następujące wartości:\n        \n        - **eq** - równa się\n            \n        - **ne** - nie równa się\n            \n        - **gt** - większe niż\n            \n        - **lt** - mniejsze niż\n            \n        - **ge** - większe lub równe\n            \n        - **le** - mniejsze lub równe\n            \n        - **like** - odpowiednik MySQL'owego LIKE\n            \n        - **not like** - odpowiednik MySQL'owego NOT LIKE\n            \n        - **is null** - odpowiednik MySQL'owego IS NULL\n            \n        - **is not null** - odpowiednik MySQL'owego IS NOT NULL\n            \n        - **in** - odpowiednik MySQL-owego IN\n            \n\n```\n<api>\n    <goods>\n        <parameters>\n            <conditions>\n                <condition>\n                    <field>name</field>\n                    <operator>eq</operator>\n                    <value>test</value>\n                </condition>\n                <!-- AND -->\n                <condition>\n                    <field>count</field>\n                    <operator>gt</operator>\n                    <value>0</value>\n                </condition>\n            </conditions>\n        </parameters>\n    </goods>\n</api>\n\n ```\n\n```\n<api>\n    <invoices>\n        <parameters>\n            <conditions>\n                <or>    \n                    <condition>\n                        <field>fullnumber</field>\n                        <operator>like</operator>\n                        <value>FV 234/2015</value>\n                    </condition>\n                    <condition>\n                        <field>number</field>\n                        <operator>lt</operator>\n                        <value>200</value>\n                    </condition>\n                </or>\n                <and>\n                    <condition>\n                        <field>Invoice.remaining</field>\n                        <operator>gt</operator>\n                        <value>0</value>\n                    </condition>\n                    <condition>\n                        <field>ContractorDetail.nip</field>\n                        <operator>in</operator>\n                        <value>8982167294,8982073475</value>\n                    </condition>\n                </and>\n            </conditions>\n        </parameters>\n    </invoices>\n</api>\n\n ```\n\n```\n<api>\n    <goods>\n        <parameters>\n            <conditions>\n                <not>\n                    <condition>\n                        <field>name</field>\n                        <operator>eq</operator>\n                        <value>test</value>\n                    </condition>\n                </not>\n            </conditions>\n        </parameters>\n    </goods>\n</api>\n\n ```\n\n- Wyniki można sortować po polach modułu głównego oraz powiązanych modułach, które są w relacji 1-1.\n    \n\n```\n<api>\n    <goods>\n        <parameters>\n            <order>\n                <asc>name</asc>\n                <desc>count</desc>\n                <desc>modified</desc>\n            </order>\n        </parameters>\n    </goods>\n</api>\n\n ```\n\n# Moduły","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"10072824","team":262559,"collectionId":"3854b824-3162-4c02-a47b-af2012073033","publishedId":"UVJfkvxJ","public":true,"publicUrl":"https://doc.wfirma.pl","privateUrl":"https://go.postman.co/documentation/10072824-3854b824-3162-4c02-a47b-af2012073033","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"EF5B25"},"documentationLayout":"classic-double-column","customisation":null,"version":"8.10.1","publishDate":"2021-12-03T08:35:00.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{},"logos":{}},"statusCode":200},"environments":[],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/769f8590b1c5cd2b31ca87c510055859284a7b83863843ea500b12d03024f224","favicon":"https://wfirma.pl/favicon.ico"},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"}],"canonicalUrl":"https://doc.wfirma.pl/view/metadata/UVJfkvxJ"}