Reporter.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. <?php
  2. namespace NavOnlineInvoice;
  3. use Exception;
  4. class Reporter {
  5. protected $connector;
  6. protected $config;
  7. /**
  8. *
  9. *
  10. * @param Config $config Config object (felhasználó adatok, szoftver adatok, URL, stb.)
  11. */
  12. function __construct($config) {
  13. $this->config = $config;
  14. $this->connector = new Connector($config);
  15. }
  16. /**
  17. * manageAnnulment operáció (1.8.1 fejezet)
  18. *
  19. * A /manageAnnulment operáció a technikai érvénytelenítések beküldésére szolgáló operáció.
  20. * Technikai érvénytelenítés csak olyan adatszolgáltatásra küldhető, amelynek a befogadása
  21. * a NAV oldalon DONE státusszal megtörtént.
  22. *
  23. * Paraméterben a technikai érvénytelenítést leíró XML-t, vagy egy InvoiceOperations példányt
  24. * kell átadni. Utóbbi esetben az InvoiceOperations példány több XML-t is tartalmazhat.
  25. *
  26. * A metódus visszaadja a transactionId-t, mellyel lekérdezhető a tranzakció eredménye.
  27. *
  28. * @param [type] $invoiceOperationsOrXml $invoiceOperationsOrXml
  29. * @return [type] $transactionId
  30. */
  31. public function manageAnnulment($invoiceOperationsOrXml) {
  32. // Ha nem InvoiceOperations példányt adtak át, akkor azzá konvertáljuk
  33. if ($invoiceOperationsOrXml instanceof InvoiceOperations) {
  34. $invoiceOperations = $invoiceOperationsOrXml;
  35. } else {
  36. $invoiceOperations = InvoiceOperations::convertFromXml($invoiceOperationsOrXml, "ANNUL");
  37. }
  38. if (!$invoiceOperations->isTechnicalAnnulment()) {
  39. throw new Exception("manageAnnulment() interfészen csak technikai érvénytelenítést lehet beküldeni.");
  40. }
  41. $token = $this->tokenExchange();
  42. $requestXml = new ManageAnnulmentRequestXml($this->config, $invoiceOperations, $token);
  43. $responseXml = $this->connector->post("/manageAnnulment", $requestXml);
  44. return (string)$responseXml->transactionId;
  45. }
  46. /**
  47. * manageInvoice operáció (1.8.2 fejezet)
  48. *
  49. * A /manageInvoice a számla adatszolgáltatás beküldésére szolgáló operáció, ezen keresztül van lehetőség számla,
  50. * módosító vagy stornó számla adatszolgáltatást a NAV részére beküldeni.
  51. *
  52. * Paraméterben a beküldendő számla XML-t kell átadni, illetve a hozzá tartozó műveletet (ManageInvocieOperationType): CREATE, MODIFY, STORNO
  53. *
  54. * Átadható egyszerre több számla is, ilyenkor első paraméterben InvoiceOperations példányt kell átadni (második paraméternek nincs szerepe ilyenkor).
  55. *
  56. * A metódus visszaadja a transactionId-t, mellyel lekérdezhető a tranzakció eredménye.
  57. *
  58. * @param InvoiceOperations|\SimpleXMLElement $invoiceOperationsOrXml
  59. * @param string $operation
  60. * @return string $transactionId
  61. */
  62. public function manageInvoice($invoiceOperationsOrXml, $operation = "CREATE") {
  63. // Ha nem InvoiceOperations példányt adtak át, akkor azzá konvertáljuk
  64. if ($invoiceOperationsOrXml instanceof InvoiceOperations) {
  65. $invoiceOperations = $invoiceOperationsOrXml;
  66. } else {
  67. $invoiceOperations = InvoiceOperations::convertFromXml($invoiceOperationsOrXml, $operation);
  68. }
  69. if ($invoiceOperations->isTechnicalAnnulment()) {
  70. throw new Exception("Technikai érvénytelenítésre a manageAnnulment() metódust kell használni a 2.0-ás API-tól kezdődően!");
  71. }
  72. $token = $this->tokenExchange();
  73. $requestXml = new ManageInvoiceRequestXml($this->config, $invoiceOperations, $token);
  74. $responseXml = $this->connector->post("/manageInvoice", $requestXml);
  75. return (string)$responseXml->transactionId;
  76. }
  77. /**
  78. * queryInvoiceData operáció (1.8.5 fejezet)
  79. *
  80. * A /queryInvoiceData egy számlaszám alapján működő lekérdező operáció, amely a számlán szereplő kiállító és a vevő
  81. * oldaláról is használható. Az operáció a megadott számlaszám teljes adattartalmát adja vissza a válaszban.
  82. *
  83. * @param array $invoiceNumberQuery Az invoiceNumberQuery-nek megfelelően összeállított lekérdezési adatok
  84. * @param boolean [$returnDecodedInvoiceData = false] invoiceDataResult helyett a dekódolt számla XML-t adja vissza a metódus
  85. * @return \SimpleXMLElement $invoiceDataResultXml A válasz XML invoiceDataResult része vagy a dekódolt számla XML
  86. */
  87. public function queryInvoiceData($invoiceNumberQuery, $returnDecodedInvoiceData = false) {
  88. $requestXml = new QueryInvoiceDataRequestXml($this->config, $invoiceNumberQuery);
  89. $responseXml = $this->connector->post("/queryInvoiceData", $requestXml);
  90. $result = $responseXml->invoiceDataResult;
  91. if ($returnDecodedInvoiceData) {
  92. if (empty($result->invoiceData)) {
  93. return null;
  94. }
  95. $isCompressed = $result->compressedContentIndicator;
  96. return InvoiceOperations::convertToXml($result->invoiceData, $isCompressed);
  97. }
  98. return $result;
  99. }
  100. /**
  101. * queryInvoiceDigest operáció (1.8.6 fejezet)
  102. *
  103. * A /queryInvoiceDigest üzleti keresőparaméterek alapján működő lekérdező operáció, amely a számlán szereplő
  104. * kiállító és a vevő oldaláról is használható. Az operáció a megadott keresőfeltételeknek megfelelő, lapozható
  105. * számla listát ad vissza a válaszban. A válasz nem tartalmazza a számlák összes üzleti adatát, hanem csak egy
  106. * kivonatot (digest-et). Amennyiben szükség van a listában szereplő valamely számla teljes adattartalmára, úgy
  107. * azt a számlaszám birtokában a /queryInvoiceData operációban lehet lekérdezni.
  108. *
  109. * @param array $invoiceQueryParams Az invoiceQueryParams-nak megfelelően összeállított lekérdezési adatok
  110. * @param Int [$page=1] Oldalszám (1-től kezdve a számozást)
  111. * @param string [$direction=OUTBOUND] A keresés iránya, a keresés elvégezhető kiállítóként és vevőként is [OUTBOUND, INBOUND]
  112. * @return \SimpleXMLElement $queryResultsXml A válasz XML invoiceDigestResult része
  113. */
  114. public function queryInvoiceDigest($invoiceQueryParams, $page = 1, $direction = "OUTBOUND") {
  115. $requestXml = new QueryInvoiceDigestRequestXml($this->config, $invoiceQueryParams, $page, $direction);
  116. $responseXml = $this->connector->post("/queryInvoiceDigest", $requestXml);
  117. return $responseXml->invoiceDigestResult;
  118. }
  119. /**
  120. * queryTransactionStatus operáció (1.8.8 fejezet)
  121. *
  122. * A /queryTransactionStatus a számla adatszolgáltatás feldolgozás aktuális állapotának és eredményének
  123. * lekérdezésére szolgáló operáció
  124. *
  125. * @param string $transactionId
  126. * @param boolean $returnOriginalRequest
  127. * @return \SimpleXMLElement $responseXml A teljes visszakapott XML, melyből a 'processingResults' elem releváns
  128. */
  129. public function queryTransactionStatus($transactionId, $returnOriginalRequest = false) {
  130. $requestXml = new QueryTransactionStatusRequestXml($this->config, $transactionId, $returnOriginalRequest);
  131. $responseXml = $this->connector->post("/queryTransactionStatus", $requestXml);
  132. return $responseXml;
  133. }
  134. /**
  135. * queryTransactionList operáció
  136. *
  137. * A /queryTransactionList a kérésben megadott időintervallumban, a technikai felhasználóhoz tartozó adószámhoz
  138. * beküldött számlaadat-szolgáltatások listázására szolgál.
  139. *
  140. * @param array $insDate DateTimeIntervalParamType-nak megfelelő mezők (lásd example)
  141. * @param integer $page
  142. * @return \SimpleXMLElement $transactionListResult A válasz XML transactionListResult része
  143. */
  144. public function queryTransactionList($insDate, $page = 1) {
  145. $requestXml = new QueryTransactionListRequestXml($this->config, $insDate, $page);
  146. $responseXml = $this->connector->post("/queryTransactionList", $requestXml);
  147. return $responseXml->transactionListResult;
  148. }
  149. /**
  150. * queryInvoiceChainDigest operáció
  151. *
  152. * A /queryInvoiceChainDigest egy számlaszám alapján működő lekérdező operáció, amely a számlán szereplő
  153. * kiállító és a vevő oldaláról is használható. Az operáció a megadott keresőfeltételeknek megfelelő,
  154. * lapozható számlalistát ad vissza a válaszban. A lista elemei a megadott alapszámlához tartozó számlalánc elemei.
  155. * A válasz nem tartalmazza a számlák összes üzleti adatát, hanem csak egy kivonatot (digest-et), elsősorban a
  156. * módosításra és tételsorok számára vonatkozóan
  157. *
  158. * @param Array $invoiceChainQuery
  159. * @param integer $page Oldalszám
  160. * @return \SimpleXMLElement $invoiceChainDigestResult A válasz XML invoiceChainDigestResult része
  161. */
  162. public function queryInvoiceChainDigest($invoiceChainQuery, $page = 1) {
  163. $requestXml = new QueryInvoiceChainDigestRequestXml($this->config, $invoiceChainQuery, $page);
  164. $responseXml = $this->connector->post("/queryInvoiceChainDigest", $requestXml);
  165. return $responseXml->invoiceChainDigestResult;
  166. }
  167. /**
  168. * queryTaxpayer operáció (1.8.9 fejezet)
  169. *
  170. * A /queryTaxpayer belföldi adószám validáló operáció, mely a számlakiállítás folyamatába építve képes
  171. * a megadott adószám valódiságáról és érvényességéről a NAV adatbázisa alapján adatot szolgáltatni.
  172. *
  173. * @param string $taxNumber Adószám, pattern: [0-9]{8}
  174. * @return bool|\SimpleXMLElement Nem létező adószám esetén `null`, érvénytelen adószám esetén `false` a visszatérési érték, valid adószám estén
  175. * pedig a válasz XML taxpayerData része (SimpleXMLElement), mely a nevet és címadatokat tartalmazza.
  176. */
  177. public function queryTaxpayer($taxNumber) {
  178. $requestXml = new QueryTaxpayerRequestXml($this->config, $taxNumber);
  179. $responseXml = $this->connector->post("/queryTaxpayer", $requestXml);
  180. // 1.9.8.2 fejezet alapján (QueryTaxpayerResponse) a taxpayerValidity tag csak akkor kerül a válaszba, ha a lekérdezett adószám létezik.
  181. // Nem létező adószámra csak egy <funcCode>OK</funcCode> kerül visszaadásra (funcCode===OK megléte a Connector-ban ellenőrizve van).
  182. if (!isset($responseXml->taxpayerValidity)) {
  183. return null;
  184. }
  185. // taxpayerValidity értéke lehet false is, ha az adószám létezik, de nem érvényes
  186. if (empty($responseXml->taxpayerValidity) or (string)($responseXml->taxpayerValidity) === "false") {
  187. return false;
  188. }
  189. // Az adószám valid, adózó adatainak visszaadása
  190. return $responseXml->taxpayerData;
  191. }
  192. /**
  193. * Token kérése manageInvoice művelethez.
  194. *
  195. * Ezt a metódust lehet használni tesztelésre is, hogy a megadott felhasználói adatok helyesek-e/a NAV szervere visszatér-e valami válasszal.
  196. *
  197. * Megjegyzés: csak a token kerül visszaadásra, az érvényességi idő nem. Ennek oka, hogy a tokent csak egy kéréshez (egyszer) lehet használni
  198. * NAV fórumon elhangzottak alapján (megerősítés szükséges!), és ez az egyszeri felhasználás azonnal megtörténik a token lekérése után (manageInvoice hívás).
  199. *
  200. * @return string Token
  201. */
  202. public function tokenExchange() {
  203. $requestXml = new TokenExchangeRequestXml($this->config);
  204. $responseXml = $this->connector->post("/tokenExchange", $requestXml);
  205. $encodedToken = (string)$responseXml->encodedExchangeToken;
  206. $token = $this->decodeToken($encodedToken);
  207. return $token;
  208. }
  209. /**
  210. * Utolsó REST hívás adatainak lekérdezése naplózási és hibakeresési céllal.
  211. *
  212. * A visszaadott array a következő elemeket tartalmazza: requestUrl, requestBody, responseBody, requestId, responseXml
  213. *
  214. * Megjegyzés: bizonyos műveletek (manageAnnulment és manageInvoice) kettő REST hívást is indítanak,
  215. * a tokenExchange hívást, illetve magát az adatküldést. Sikeres hívás esetén csak a tényleges adatküldés
  216. * eredménye érhető el, Exception esetén pedig mindig az utolsó hívás adata.
  217. *
  218. * @return array
  219. */
  220. public function getLastRequestData() {
  221. return $this->connector->getLastRequestData();
  222. }
  223. /**
  224. * Utolsó válasz XML lekérdezése (operáció hívása után)
  225. *
  226. * @return \SimpleXMLElement $xml
  227. */
  228. public function getLastResponseXml() {
  229. return $this->connector->getLastResponseXml();
  230. }
  231. protected function decodeToken($encodedToken) {
  232. return Util::aes128_decrypt($encodedToken, $this->config->user["exchangeKey"]);
  233. }
  234. /**
  235. * Paraméterben átadott adat XML-t validálja az XSD-vel és hiba esetén string-ként visszaadja a hibát.
  236. * Ha nincs hiba, akkor visszatérési érték `null`.
  237. *
  238. * @param \SimpleXMLElement $xml Számla XML
  239. * @return null|string Hibaüzenet, vagy `null`, ha helyes az XML
  240. */
  241. public static function getInvoiceValidationError($xml) {
  242. try {
  243. Xsd::validate($xml->asXML(), Config::getDataXsdFilename());
  244. } catch(XsdValidationError $ex) {
  245. return $ex->getMessage();
  246. }
  247. return null;
  248. }
  249. }